body { font-family: serif; font-size: 1.1rem; margin: 1rem; line-height: 1.5; color: #000; background: #fff; }
a { color: #000; }
img { max-width: 100%; height: auto; }

/* Shared tap target. Sized for a finger, not a mouse: on a 6" e-ink panel
   (~758 CSS px over ~90mm of glass, ~8.4 px/mm) a bare text link is ~24px tall
   and lands well inside a 8-10mm fingertip contact patch. Padding alone gets
   this to ~44px, so no min-height is needed.
   The border is load-bearing, not decoration - it's what makes the target
   boundary visible, which an underline never did.
   Used on both <a> and <button>: rows mix links (Download) with form submits
   (Mark read), so `font: inherit` is required or the button reverts to the UA
   sans-serif. Spacing via margin - the target engine ignores flex `gap`. */
.btn { display: inline-block; border: 1px solid #000; padding: .55rem .7rem;
       margin: 0 .5rem .5rem 0; font: inherit; color: #000; background: #fff;
       text-decoration: none; line-height: 1.2; cursor: pointer; }
/* E-ink gives no hover and a slow repaint; an inverted press is the only
   feedback that reliably shows up. */
.btn:active { color: #fff; background: #000; }
/* Greyed rather than hidden. A real <button disabled> and not a styled span, so
   it is inert and announced as disabled without extra markup. */
.btn:disabled { color: #999; border-color: #ccc; cursor: default; }
.btn:disabled:active { color: #999; background: #fff; }
/* No flex `gap` / `object-fit` - the Tolino's browser ignores both. Use a
   fixed square cover slot (so text always starts at the same left offset) with
   a margin for spacing; the image keeps its natural ratio via max-width/height. */
/* float/overflow here are the fallback for an engine with no unprefixed `flex`
   (WebKit 533): float and clear are ignored on flex items, so a modern engine
   uses the flex row and an old one floats the cover with .body beside it. The
   overflow on the container contains that float, keeping the row's border under
   the taller of the two. */
.item { display: flex; align-items: flex-start; padding: .5rem 0; border-bottom: 1px solid #ccc; overflow: hidden; }
/* inline-block, not the default inline: the flex item is the wrapping
   .cover-link anchor, so .cover is an ordinary inline span and width/height are
   ignored on those. Without this the slot collapses to the content width - a
   narrow strip for a placeholder letter, nothing at all for a cover that fails
   to load - and the "text always starts at the same left offset" promise above
   silently doesn't hold. */
.item .cover-link { flex: 0 0 auto; float: left; }
.item .cover { display: inline-block; width: 72px; height: 72px; margin-right: 1rem; text-align: center; }
.item .cover img { max-width: 72px; max-height: 72px; width: auto; height: auto; }
/* Placeholder shown when an item has no cover (title initial in a grey box). */
.item .cover.placeholder { background: #eee; color: #999; font-size: 2rem; line-height: 72px; }
/* No max-width cap and no fixed side column any more: the actions live on their
   own line inside .body, so nothing sits beside the title to collide with. */
.item .body { flex: 1 1 auto; min-width: 0; overflow: hidden; }
nav.pager span { margin-right: 1rem; }
.sortbar { margin: .5rem 0; }
.sortbar-label { margin-right: .3rem; }
/* Padded boxes instead of "·"-separated text links - the padding IS the
   separation. Inline-block + margin (no flex gap) for the old engine. */
.sortbar a, .tabs a, .tabs span { display: inline-block; padding: .5rem .6rem; margin: 0 .25rem .25rem 0; }
/* Actions render below the title across the full row width rather than in a
   fixed 8.5rem column. Three boxes across ~660px puts their centres 15-25mm
   apart instead of 3.6mm, and the long German labels ("Als gelesen markieren")
   stop wrapping - the old column was what starved them. */
.item .actions { margin-top: .5rem; }
/* Inline so the form doesn't break the horizontal run of buttons. */
.item .actions .read-form, .item .actions .convert { display: inline; }
/* Any list of plain destinations: large, full-width, well-separated tap targets
   so a device tap doesn't land on the neighbouring entry. Block links (no flex
   gap for the Tolino). Used by the libraries index and the search page's series
   and author results - the reason it isn't named .libraries. */
.taplist { list-style: none; padding: 0; margin: 1rem 0; }
.taplist li { border-bottom: 1px solid #ccc; }
.taplist a { display: block; font-size: 1.3rem; line-height: 1.3; padding: .7rem .25rem; text-decoration: underline; }
.taplist small { display: block; padding: 0 .25rem .55rem; font-size: .9rem; color: #666; }
/* Logo mark beside the page heading. The explicit height is needed because the
   global `img { height:auto }` rule would otherwise blow it up to full width.
   No flex `gap` on the Tolino - the icon is inline with a margin instead. */
.page-title { margin: 0; float: left; }
.title-icon { height: 1.4em; width: auto; vertical-align: -0.25em; margin-right: .4rem; }
/* The float/clear pairs below are the fallback for an engine with no unprefixed
   `flex` (WebKit 533), where this would otherwise stack every control on its own
   line. Both properties are ignored on flex items, so a modern engine is
   unaffected; the overflow contains the floats. */
.page-head { display: flex; align-items: center; flex-wrap: wrap; margin: 1rem 0; overflow: hidden; }
.crumb-sep { color: #666; }
.fav-form { margin: 0 0 0 .6rem; float: left; }
/* Padding, not a bigger glyph: reaches a ~44px target without the star
   dominating the heading it sits next to. */
.fav-star { border: none; background: none; cursor: pointer; font-size: 1.8rem; line-height: 1; padding: .35rem .5rem; }
.logo { text-align: center; }
.logo img { max-width: 320px; width: 60%; height: auto; }
.login-form { max-width: 320px; margin: 0 auto; text-align: center; }
.login-form input { width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; padding: .3rem; }
/* Log in and the SSO button are the same kind of action, so they get the same
   shape: both full width, which also stops the longer SSO label making them look
   like two different controls. display:block because a <button> still
   shrink-to-fits with width alone on the target engine. */
.login-form .btn { display: block; width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; text-align: center; }
/* Always its own line, never "it happens to wrap": a full-width flex item can't
   share a line, so the breadcrumb row keeps a fixed shape whatever the library
   name's length. flex-basis AND width because the target engine honours the
   latter more reliably; either alone produces the break. */
.searchbar { flex: 0 0 100%; clear: both; width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; margin: .4rem 0 0; }
.searchbar input { padding: .5rem; font: inherit; }
/* Auto margin, so logout starts the right-hand control group and the cog sits
   beside it rather than across the header from it. */
/* The gap is PADDING, not a margin: margin-left is the auto that pushes this to
   the right under flex, and an auto margin resolves to zero on a float, so the
   old engine would glue the button to the title. */
.logout-form { margin: 0 0 0 auto; padding-left: .6rem; float: left; }
.tabs { margin: .5rem 0; font-weight: bold; }
.totop { font-weight: normal; font-size: .8em; text-decoration: none; margin-left: .5rem; display: inline-block; padding: .4rem .6rem; }
/* Exactly ONE auto margin may exist in .page-head - several would split the free
   space between them and float the earlier one into the middle of the header
   instead of pushing everything right. The cog carries it by default, since it
   is the only control on every page. On the index, logout precedes the cog and
   takes the auto over (above), so the pair travels right together; the cog then
   needs a plain margin or there would be two. */
.settings-link { margin-left: auto; flex: 0 0 auto; float: left; text-decoration: none; padding: .4rem; }
.logout-form ~ .settings-link { margin-left: .4rem; }
.home-link { text-decoration: none; }
.app-version { margin-top: 1.5rem; color: #666; }
/* The login page is centred throughout; a left-hugging version line reads as a
   mistake there. Elsewhere (the libraries page) it stays left with the content. */
.login-version { text-align: center; }
.settings-icon { display: block; height: 1.6em; width: auto; }
.settings-note { color: #555; margin: .4rem 0; }
.settings-form { margin: 1rem 0; }
/* The rule separates one SETTING from the next - it is deliberately on the block,
   not on each label. A setting's radio options and its explanation belong to it and
   must stay visually attached; a line between them reads as a new setting. */
.settings-form p { margin: 0; padding: .7rem .25rem; border-bottom: 1px solid #ccc; }
.settings-form p.settings-actions { border-bottom: none; }
/* Block label so the whole row toggles, not just the 13px box. */
.settings-form label { display: block; cursor: pointer; padding: .35rem 0; }
.settings-form .setting-title { display: block; margin-bottom: .1rem; }
/* display:block because the note follows inline-block fields now - as a plain
   inline span it continued on their line and wrapped mid-sentence. */
.settings-form .settings-note { display: block; margin: .35rem 0 0; }
/* Sizing a checkbox is honoured unevenly on old engines; if it is ignored this
   degrades to the browser default, which is what we have today anyway. */
.settings-form input[type=checkbox] { width: 1.2rem; height: 1.2rem; margin-right: .5rem; vertical-align: -.15rem; }
.settings-form select { font: inherit; padding: .5rem; margin-top: .3rem; }
/* The three override numbers sit on ONE line: inline-block, not flex - the target
   e-ink engine has no flex `gap`, and margins on inline-block are the boring thing
   that works everywhere. They wrap on a narrow phone, which is fine. */
.settings-form label.setting-num { display: inline-block; margin-right: 1rem; }
/* Narrow enough that three of them fit one line on an e-reader; the values are at
   most four digits or "1.875". */
.settings-form input[type=number], .settings-form input[type=text] { font: inherit; padding: .4rem; width: 5rem; }
/* A disabled field must LOOK disabled - the point of disabling it is to stop it
   implying it affects anything. Honoured in Chromium; the e-ink engine may ignore it. */
.settings-form input:disabled { color: #888; background: #eee; }
.settings-form button { margin-top: 1rem; }
.item .actions .read-form { margin: 0; }
/* .btn now carries the whole look. This rule only stops the browser's default
   button centring from fighting it - everything else it used to set (border,
   padding, underline) is the button style's job. */
.read-form .read-btn { text-align: left; }

/* Item detail page - same defensive rules as .item (no flex gap / object-fit). */
.detail { display: flex; align-items: flex-start; margin: 1rem 0; overflow: hidden; }
.detail-cover { flex: 0 0 160px; float: left; width: 160px; margin-right: 1rem; text-align: center; }
.detail-cover img { max-width: 160px; max-height: 240px; width: auto; height: auto; }
.cover-link { text-decoration: none; }
.detail-meta { flex: 1 1 auto; min-width: 0; overflow: hidden; }
.detail-meta h2 { margin: 0 0 .25rem; }
.detail-meta p { margin: .25rem 0; }
.subtitle { color: #666; }
.description { margin: 1rem 0; }
/* Block layout, not flex: the target e-ink engine mishandles flex-shrink of a
   long text node, overlapping the actions. Filename wraps freely on its own
   line; actions sit on a line below and never overlap. */
.file-row { padding: .5rem 0; border-bottom: 1px solid #ccc; }
.file-name { word-break: break-word; }
.file-format { margin-left: .5rem; color: #666; }
.file-actions { margin-top: .5rem; }
/* No nowrap: this is the one place ↻ still exists, and it carries a full label
   now, so the run must be free to wrap onto a second line. */
.file-row .convert { display: inline; }

/* Narrow screens (phones). One width breakpoint, deliberately not device
   detection: `@media (monochrome)` reports 0 on e-ink, and `(update: slow)` -
   the feature designed for exactly this - postdates the target engine by years,
   so it would work on hardware we don't have and not on hardware we do.
   `max-width` predates everything the engine could be missing.
   Nothing here is e-ink-specific: big targets and high contrast are simply the
   right design, and the phone layout only broke because a fixed side column
   didn't fit in 390px. */
@media (max-width: 600px) {
    body { margin: .5rem; }
    .item .cover { flex: 0 0 48px; width: 48px; height: 48px; margin-right: .6rem; }
    .item .cover img { max-width: 48px; max-height: 48px; }
    .item .cover.placeholder { font-size: 1.4rem; line-height: 48px; }
    /* Full-width stacked beats wrapped horizontal here - still ~44px tall, and
       the full width keeps neighbours unambiguous. width+border-box because a
       <button> with display:block still shrink-to-fits; only the <a>s would
       stretch otherwise, and Mark read would end up the odd one out. */
    .item .actions .btn { display: block; width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; margin-right: 0; }
    .item .actions .read-form, .item .actions .convert { display: block; }
    .detail-cover { flex: 0 0 96px; width: 96px; }
    .detail-cover img { max-width: 96px; max-height: 144px; }
}
