/* Stashbound Books wears its library identity: aged-paper ground, warm sepia
   ink, and serif display type (see the .brand/heading rules below) — the goal
   is "afternoon light in the stacks," in contrast to the Games app's dark
   arcade and the Screen app's darkened theater. */
:root {
  /* Page gutter, shared by the topbar, chip rows, toolbar and main grid so the
     phone layout tightens all of them from one place. */
  --gutter: 1.5rem;
  --bg: #faf4e8; /* aged paper */
  --bg-card: #ffffff;
  --ink: #4a3c3a;
  --ink-soft: #8a7873;
  --accent: #e2857a;
  --accent-soft: #f6ddd6;
  --accent-deep: #c96b5f;
  --accent-contrast: #ffffff; /* text painted ON an accent/green fill */
  --green: #8fb996;
  --green-soft: #e3efe3;
  --blue: #8fb3d9;
  --blue-soft: #e3ecf7;
  --yellow: #e8c468;
  --yellow-soft: #faf1dc;
  --grey: #b7aaa4;
  --grey-soft: #f0e9e5;
  --radius: 18px;
  --shadow: 0 4px 16px rgba(180, 130, 110, 0.14);
  color-scheme: light;

  /* Data-viz palette (validated against --bg-card #ffffff / #322827 — see dataviz skill).
     Kept separate from the UI accent colors above: those carry brand, these carry data. */
  --v-seq-track: #cde2fb;   /* documented sequential step 100 */
  --v-seq-fill: #2a78d6;    /* documented sequential step 450 / categorical slot 1 */
  --v-cat-1: #2a78d6; /* blue */
  --v-cat-2: #9b3fd6; /* purple */
  --v-cat-3: #1baf7a; /* aqua */
  --v-cat-4: #eda100; /* yellow */
  --v-cat-5: #e87ba4; /* magenta */
  --v-cat-6: #008300; /* green */
  --v-cat-7: #4a3aa7; /* violet */
  --v-cat-8: #e34948; /* red */
  --v-grid: #e1e0d9;
  --v-baseline: #c3c2b7;
}

/* Dark values apply either from the OS setting (media query, unless the manual
   toggle stamped data-theme="light" to override it) or from an explicit
   data-theme="dark" stamp (which wins over the OS being light). Same values,
   two gates — plain CSS has no mixin to share them, so they're duplicated below. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #241d1c;
    --bg-card: #322827;
    --ink: #f3e9e6;
    --ink-soft: #c2b2ad;
    --accent: #ec9186;
    --accent-soft: #4a332f;
    --accent-deep: #f0a89e;
    --accent-contrast: #241d1c; /* dark-mode accents are light — text on them goes dark */
    --green: #a3cca9;
    --green-soft: #2e3a2e;
    --blue: #a6c6e8;
    --blue-soft: #2a3540;
    --yellow: #ecce8c;
    --yellow-soft: #3a3120;
    --grey: #8f827c;
    --grey-soft: #3a302d;
    --shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
    color-scheme: dark;

    --v-seq-track: #2a3540;
    --v-seq-fill: #3987e5;
    --v-cat-1: #3987e5;
    --v-cat-2: #bb6be2;
    --v-cat-3: #199e70;
    --v-cat-4: #c98500;
    --v-cat-5: #d55181;
    --v-cat-6: #008300;
    --v-cat-7: #9085e9;
    --v-cat-8: #e66767;
    --v-grid: #2c2c2a;
    --v-baseline: #383835;
  }
}

:root[data-theme="dark"] {
  --bg: #241d1c;
  --bg-card: #322827;
  --ink: #f3e9e6;
  --ink-soft: #c2b2ad;
  --accent: #ec9186;
  --accent-soft: #4a332f;
  --accent-deep: #f0a89e;
  --accent-contrast: #241d1c;
  --green: #a3cca9;
  --green-soft: #2e3a2e;
  --blue: #a6c6e8;
  --blue-soft: #2a3540;
  --yellow: #ecce8c;
  --yellow-soft: #3a3120;
  --grey: #8f827c;
  --grey-soft: #3a302d;
  --shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
  color-scheme: dark;

  --v-seq-track: #2a3540;
  --v-seq-fill: #3987e5;
  --v-cat-1: #3987e5;
  --v-cat-2: #bb6be2;
  --v-cat-3: #199e70;
  --v-cat-4: #c98500;
  --v-cat-5: #d55181;
  --v-cat-6: #008300;
  --v-cat-7: #9085e9;
  --v-cat-8: #e66767;
  --v-grid: #2c2c2a;
  --v-baseline: #383835;
}

/* ================= Theme presets =================
   Themes are GENRE identities, not colour swatches — the app dresses itself in
   whatever the reader actually reads, and can match the shelf automatically.
   Parchment is the default aged-paper base and needs no class.
   Each theme reskins only the "identity" tokens (accent, page background, and
   corner radius where the genre earns it) — text, cards, greys, and the
   data-viz palette stay constant, so contrast and chart accessibility never
   depend on which theme is picked. Three declarations per theme: light, then
   the same values for OS-dark (guarded so an explicit light choice still wins),
   then again for the in-app dark stamp. */
body.theme-romance { --accent: #c2557d; --accent-soft: #f8dde6; --accent-deep: #9c3f63; --bg: #fdf1f5; --radius: 22px; }
body.theme-fantasy { --accent: #8a6a1f; --accent-soft: #f3e7c8; --accent-deep: #6d5316; --bg: #faf6ea; }
body.theme-mystery { --accent: #3f5675; --accent-soft: #dfe6f0; --accent-deep: #2f4259; --bg: #f2f5f9; --radius: 10px; }
body.theme-horror { --accent: #a3413a; --accent-soft: #f2dcda; --accent-deep: #82322d; --bg: #faf0ee; --radius: 4px; }
body.theme-scifi { --accent: #256f88; --accent-soft: #d8ecf3; --accent-deep: #1a5468; --bg: #eef7fa; --radius: 8px; }
body.theme-historical { --accent: #8a6236; --accent-soft: #efe2d1; --accent-deep: #6d4c28; --bg: #f9f3ea; }
body.theme-ya { --accent: #9040b0; --accent-soft: #f0dff6; --accent-deep: #73308e; --bg: #f9f1fb; --radius: 24px; }
body.theme-poetry { --accent: #8d4d75; --accent-soft: #f0dfe9; --accent-deep: #6f3a5c; --bg: #f9f2f7; }
body.theme-nonfiction { --accent: #4f7049; --accent-soft: #e2ecdf; --accent-deep: #3d5838; --bg: #f3f7f1; --radius: 8px; }
body.theme-humor { --accent: #a67a10; --accent-soft: #fbeec8; --accent-deep: #84610c; --bg: #fdf8e9; --radius: 22px; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body.theme-romance { --accent: #e79ab5; --accent-soft: #3d2029; --accent-deep: #f0b6c9; --bg: #241419; --radius: 22px; }
  :root:not([data-theme="light"]) body.theme-fantasy { --accent: #d9ae55; --accent-soft: #3b2f16; --accent-deep: #e6c47f; --bg: #241e12; }
  :root:not([data-theme="light"]) body.theme-mystery { --accent: #8fabd0; --accent-soft: #232f3f; --accent-deep: #adc4e2; --bg: #161c24; --radius: 10px; }
  :root:not([data-theme="light"]) body.theme-horror { --accent: #d98a83; --accent-soft: #3a1e1c; --accent-deep: #e4a8a2; --bg: #1a0f0e; --radius: 4px; }
  :root:not([data-theme="light"]) body.theme-scifi { --accent: #6cc3dd; --accent-soft: #12333d; --accent-deep: #96d7ea; --bg: #0e1f26; --radius: 8px; }
  :root:not([data-theme="light"]) body.theme-historical { --accent: #c9a173; --accent-soft: #33261a; --accent-deep: #dcbb95; --bg: #1f1811; }
  :root:not([data-theme="light"]) body.theme-ya { --accent: #c890e0; --accent-soft: #301c39; --accent-deep: #d9aeea; --bg: #1d1322; --radius: 24px; }
  :root:not([data-theme="light"]) body.theme-poetry { --accent: #c489ad; --accent-soft: #3a2432; --accent-deep: #d5a6c4; --bg: #241a21; }
  :root:not([data-theme="light"]) body.theme-nonfiction { --accent: #92b98a; --accent-soft: #263123; --accent-deep: #aed0a6; --bg: #1a211a; --radius: 8px; }
  :root:not([data-theme="light"]) body.theme-humor { --accent: #dcb545; --accent-soft: #3a2f12; --accent-deep: #e8c973; --bg: #231d0e; --radius: 22px; }
}

:root[data-theme="dark"] body.theme-romance { --accent: #e79ab5; --accent-soft: #3d2029; --accent-deep: #f0b6c9; --bg: #241419; --radius: 22px; }
:root[data-theme="dark"] body.theme-fantasy { --accent: #d9ae55; --accent-soft: #3b2f16; --accent-deep: #e6c47f; --bg: #241e12; }
:root[data-theme="dark"] body.theme-mystery { --accent: #8fabd0; --accent-soft: #232f3f; --accent-deep: #adc4e2; --bg: #161c24; --radius: 10px; }
:root[data-theme="dark"] body.theme-horror { --accent: #d98a83; --accent-soft: #3a1e1c; --accent-deep: #e4a8a2; --bg: #1a0f0e; --radius: 4px; }
:root[data-theme="dark"] body.theme-scifi { --accent: #6cc3dd; --accent-soft: #12333d; --accent-deep: #96d7ea; --bg: #0e1f26; --radius: 8px; }
:root[data-theme="dark"] body.theme-historical { --accent: #c9a173; --accent-soft: #33261a; --accent-deep: #dcbb95; --bg: #1f1811; }
:root[data-theme="dark"] body.theme-ya { --accent: #c890e0; --accent-soft: #301c39; --accent-deep: #d9aeea; --bg: #1d1322; --radius: 24px; }
:root[data-theme="dark"] body.theme-poetry { --accent: #c489ad; --accent-soft: #3a2432; --accent-deep: #d5a6c4; --bg: #241a21; }
:root[data-theme="dark"] body.theme-nonfiction { --accent: #92b98a; --accent-soft: #263123; --accent-deep: #aed0a6; --bg: #1a211a; --radius: 8px; }
:root[data-theme="dark"] body.theme-humor { --accent: #dcb545; --accent-soft: #3a2f12; --accent-deep: #e8c973; --bg: #231d0e; --radius: 22px; }

/* ===== Genre backdrops =====
   A generated photograph per genre theme (see generate_backgrounds.py — FLUX.2
   "Klein" on Rupert, committed as ~70KB WebP each, so nothing is fetched at
   runtime and the PWA still works offline).

   A scrim rides on top of every one of them: the art has to lose to the text,
   always, which is why the overlay is opaque enough to flatten any bright spot
   the model happened to paint. Unlike the Games app this one is LIGHT-first, so
   each theme carries two scrims — near-paper for light, near-ink for dark — and
   the plain --bg colour shows through underneath if an image ever 404s.

   Parchment (the base look) deliberately has no backdrop: bare aged paper IS
   its identity, and putting a photograph behind it would just be a different
   theme. Readers who want none of it: the theme modal's "Backdrop art" switch
   adds .no-bg-art, which drops the layer entirely. */
#bgArt {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Layer 1 = the theme scrim gradient (stretched full-bleed), layer 2 = a
     flat endpaper pattern (Klein-generated) tiled like real wallpaper —
     patterns tile crisply where a stretched scene would blur. */
  background-size: 100% 100%, 960px 960px;
  background-position: center;
  background-repeat: no-repeat, repeat;
}
body.no-bg-art #bgArt { display: none; }

body.theme-romance #bgArt { background-image: linear-gradient(rgba(253, 241, 245, 0.78), rgba(253, 241, 245, 0.86)), url('/backgrounds/romance.jpg'); }
body.theme-fantasy #bgArt { background-image: linear-gradient(rgba(250, 246, 234, 0.78), rgba(250, 246, 234, 0.86)), url('/backgrounds/fantasy.jpg'); }
body.theme-mystery #bgArt { background-image: linear-gradient(rgba(242, 245, 249, 0.78), rgba(242, 245, 249, 0.86)), url('/backgrounds/mystery.jpg'); }
body.theme-horror #bgArt { background-image: linear-gradient(rgba(250, 240, 238, 0.78), rgba(250, 240, 238, 0.86)), url('/backgrounds/horror.jpg'); }
body.theme-scifi #bgArt { background-image: linear-gradient(rgba(238, 247, 250, 0.78), rgba(238, 247, 250, 0.86)), url('/backgrounds/scifi.jpg'); }
body.theme-historical #bgArt { background-image: linear-gradient(rgba(249, 243, 234, 0.78), rgba(249, 243, 234, 0.86)), url('/backgrounds/historical.jpg'); }
body.theme-ya #bgArt { background-image: linear-gradient(rgba(249, 241, 251, 0.78), rgba(249, 241, 251, 0.86)), url('/backgrounds/ya.jpg'); }
body.theme-poetry #bgArt { background-image: linear-gradient(rgba(249, 242, 247, 0.78), rgba(249, 242, 247, 0.86)), url('/backgrounds/poetry.jpg'); }
body.theme-nonfiction #bgArt { background-image: linear-gradient(rgba(243, 247, 241, 0.78), rgba(243, 247, 241, 0.86)), url('/backgrounds/nonfiction.jpg'); }
body.theme-humor #bgArt { background-image: linear-gradient(rgba(253, 248, 233, 0.78), rgba(253, 248, 233, 0.86)), url('/backgrounds/humor.jpg'); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body.theme-romance #bgArt { background-image: linear-gradient(rgba(36, 20, 25, 0.66), rgba(36, 20, 25, 0.78)), url('/backgrounds/romance.jpg'); }
  :root:not([data-theme="light"]) body.theme-fantasy #bgArt { background-image: linear-gradient(rgba(36, 30, 18, 0.66), rgba(36, 30, 18, 0.78)), url('/backgrounds/fantasy.jpg'); }
  :root:not([data-theme="light"]) body.theme-mystery #bgArt { background-image: linear-gradient(rgba(22, 28, 36, 0.66), rgba(22, 28, 36, 0.78)), url('/backgrounds/mystery.jpg'); }
  :root:not([data-theme="light"]) body.theme-horror #bgArt { background-image: linear-gradient(rgba(26, 15, 14, 0.66), rgba(26, 15, 14, 0.78)), url('/backgrounds/horror.jpg'); }
  :root:not([data-theme="light"]) body.theme-scifi #bgArt { background-image: linear-gradient(rgba(14, 31, 38, 0.66), rgba(14, 31, 38, 0.78)), url('/backgrounds/scifi.jpg'); }
  :root:not([data-theme="light"]) body.theme-historical #bgArt { background-image: linear-gradient(rgba(31, 24, 17, 0.66), rgba(31, 24, 17, 0.78)), url('/backgrounds/historical.jpg'); }
  :root:not([data-theme="light"]) body.theme-ya #bgArt { background-image: linear-gradient(rgba(29, 19, 34, 0.66), rgba(29, 19, 34, 0.78)), url('/backgrounds/ya.jpg'); }
  :root:not([data-theme="light"]) body.theme-poetry #bgArt { background-image: linear-gradient(rgba(36, 26, 33, 0.66), rgba(36, 26, 33, 0.78)), url('/backgrounds/poetry.jpg'); }
  :root:not([data-theme="light"]) body.theme-nonfiction #bgArt { background-image: linear-gradient(rgba(26, 33, 26, 0.66), rgba(26, 33, 26, 0.78)), url('/backgrounds/nonfiction.jpg'); }
  :root:not([data-theme="light"]) body.theme-humor #bgArt { background-image: linear-gradient(rgba(35, 29, 14, 0.66), rgba(35, 29, 14, 0.78)), url('/backgrounds/humor.jpg'); }
}

:root[data-theme="dark"] body.theme-romance #bgArt { background-image: linear-gradient(rgba(36, 20, 25, 0.66), rgba(36, 20, 25, 0.78)), url('/backgrounds/romance.jpg'); }
:root[data-theme="dark"] body.theme-fantasy #bgArt { background-image: linear-gradient(rgba(36, 30, 18, 0.66), rgba(36, 30, 18, 0.78)), url('/backgrounds/fantasy.jpg'); }
:root[data-theme="dark"] body.theme-mystery #bgArt { background-image: linear-gradient(rgba(22, 28, 36, 0.66), rgba(22, 28, 36, 0.78)), url('/backgrounds/mystery.jpg'); }
:root[data-theme="dark"] body.theme-horror #bgArt { background-image: linear-gradient(rgba(26, 15, 14, 0.66), rgba(26, 15, 14, 0.78)), url('/backgrounds/horror.jpg'); }
:root[data-theme="dark"] body.theme-scifi #bgArt { background-image: linear-gradient(rgba(14, 31, 38, 0.66), rgba(14, 31, 38, 0.78)), url('/backgrounds/scifi.jpg'); }
:root[data-theme="dark"] body.theme-historical #bgArt { background-image: linear-gradient(rgba(31, 24, 17, 0.66), rgba(31, 24, 17, 0.78)), url('/backgrounds/historical.jpg'); }
:root[data-theme="dark"] body.theme-ya #bgArt { background-image: linear-gradient(rgba(29, 19, 34, 0.66), rgba(29, 19, 34, 0.78)), url('/backgrounds/ya.jpg'); }
:root[data-theme="dark"] body.theme-poetry #bgArt { background-image: linear-gradient(rgba(36, 26, 33, 0.66), rgba(36, 26, 33, 0.78)), url('/backgrounds/poetry.jpg'); }
:root[data-theme="dark"] body.theme-nonfiction #bgArt { background-image: linear-gradient(rgba(26, 33, 26, 0.66), rgba(26, 33, 26, 0.78)), url('/backgrounds/nonfiction.jpg'); }
:root[data-theme="dark"] body.theme-humor #bgArt { background-image: linear-gradient(rgba(35, 29, 14, 0.66), rgba(35, 29, 14, 0.78)), url('/backgrounds/humor.jpg'); }

* { box-sizing: border-box; }

.auth-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--bg);
}
.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 2rem 1.6rem;
}
.auth-brand { text-align: center; margin-bottom: 1.3rem; }
.auth-brand .brand-mark { font-size: 2.4rem; display: block; margin-bottom: 0.3rem; }
.auth-brand h1 { font-size: 1.4rem; letter-spacing: -0.02em; }
.auth-brand .tagline { margin: 0.2rem 0 0; font-size: 0.8rem; color: var(--ink-soft); }
.auth-tabs { display: flex; background: var(--grey-soft); border-radius: 999px; padding: 0.25rem; margin-bottom: 1.2rem; }
.auth-tab {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  font-weight: 700;
  font-size: 0.85rem;
  padding: 0.5rem 0;
  border-radius: 999px;
  cursor: pointer;
}
.auth-tab.active { background: var(--accent); color: var(--accent-contrast); }
#authForm { display: flex; flex-direction: column; gap: 0.9rem; }
#authForm label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
#authForm input {
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.6rem 0.75rem;
  border-radius: 12px;
  border: 1px solid var(--grey-soft);
  background: var(--bg);
  color: var(--ink);
}
.auth-error { font-size: 0.8rem; color: #d03b3b; margin: 0; }
.auth-submit { width: 100%; padding: 0.7rem; font-size: 0.95rem; margin-top: 0.2rem; }

/* An author-stylesheet rule (like .modal-backdrop{display:flex}) beats the
   browser's built-in [hidden]{display:none} regardless of specificity, so
   without this, "hidden" modals render anyway. Keep this !important. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Avenir, sans-serif;
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  padding-bottom: 3rem;
}

h1, h2, h3 { margin: 0; }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: calc(1.25rem + env(safe-area-inset-top)) var(--gutter) 0.75rem;
  flex-wrap: wrap;
}

/* Literary display type: bookish serifs for the brand, section headings, and
   book titles themselves — set in fonts every platform already ships — with an
   italic tagline. Body text stays sans for screen legibility, the way a well-
   set book keeps display and text faces distinct. */
.brand h1, .auth-brand h1, h2, .section-subhead,
.book-title, .detail-title, .search-result-title {
  font-family: ui-serif, Baskerville, Charter, Georgia, "Times New Roman", serif;
}
.tagline, .auth-brand .tagline { font-style: italic; }

/* Chapter-heading fleuron before each section subhead — the classic printer's
   ornament, in the accent color so every theme preset re-inks it. */
.section-subhead::before {
  content: '❧';
  color: var(--accent);
  margin-right: 0.45rem;
  font-size: 0.9em;
}

.brand { display: flex; align-items: center; gap: 0.7rem; }
.brand-mark { font-size: 2rem; }
.brand h1 { font-size: 1.5rem; letter-spacing: -0.02em; }
.tagline { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }

.topbar-actions { display: flex; gap: 0.6rem; align-items: center; }

/* On a wide screen Scan and Add sit in the topbar exactly as they always have;
   `contents` means the wrapper adds no box of its own. The phone layout below
   turns the same wrapper into a fixed bottom bar. */
.primary-actions { display: contents; }

.btn {
  border: none;
  border-radius: 999px;
  padding: 0.55rem 1.1rem;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.btn:active { transform: scale(0.96); }
.btn-primary { background: var(--accent); color: var(--accent-contrast); box-shadow: var(--shadow); }
.btn-accent { background: var(--yellow-soft); color: #7a5a1c; }
.btn-secondary { background: var(--blue-soft); color: #2c4a6b; }
.btn-danger { background: #f4d6d1; color: #8a3226; }
.btn-icon { padding: 0.55rem 0.7rem; font-size: 1rem; }

.theme-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 0.8rem;
  margin-top: 1rem;
}
.theme-swatch-btn {
  border: 2px solid transparent;
  background: var(--bg);
  border-radius: 14px;
  padding: 0.6rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  font-family: inherit;
}
.theme-swatch-btn.active { border-color: var(--ink); }
.theme-swatch-dot { width: 32px; height: 32px; border-radius: 50%; box-shadow: 0 2px 6px rgba(0,0,0,0.15); }
.theme-swatch-label { font-size: 0.72rem; color: var(--ink-soft); font-weight: 600; }
.theme-swatch-blurb { font-size: 0.66rem; color: var(--ink-soft); line-height: 1.35; text-align: center; opacity: 0.85; }
.bgart-toggle { display: flex; gap: 8px; align-items: flex-start; margin-top: 16px;
  padding-top: 14px; border-top: 1px solid var(--grey-soft);
  font-size: 0.72rem; color: var(--ink-soft); line-height: 1.4; cursor: pointer; }
.bgart-toggle input { margin-top: 2px; accent-color: var(--accent); cursor: pointer; }
.theme-suggestion { display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin: 0 0 14px; padding-bottom: 14px; border-bottom: 1px solid var(--grey-soft); }

.stats-strip {
  display: flex;
  gap: 0.6rem;
  overflow-x: auto;
  padding: 0.5rem var(--gutter) 1rem;
  -webkit-overflow-scrolling: touch;
}
.stat-pill {
  flex: 0 0 auto;
  background: var(--bg-card);
  border-radius: 999px;
  padding: 0.45rem 0.9rem;
  font-size: 0.8rem;
  box-shadow: var(--shadow);
  white-space: nowrap;
  border: none;
  cursor: pointer;
  font-family: inherit;
  color: var(--ink);
}
.stat-pill:active { transform: scale(0.96); }
.stat-pill b { color: var(--accent-deep); }

/* Fixed-order categorical accents (dataviz skill) — a subtle wash, never on the text itself */
.v-accent-1 { background: color-mix(in srgb, var(--v-cat-1) 16%, var(--bg-card)); }
.v-accent-2 { background: color-mix(in srgb, var(--v-cat-2) 16%, var(--bg-card)); }
.v-accent-3 { background: color-mix(in srgb, var(--v-cat-3) 16%, var(--bg-card)); }
.v-accent-4 { background: color-mix(in srgb, var(--v-cat-4) 16%, var(--bg-card)); }
.v-accent-5 { background: color-mix(in srgb, var(--v-cat-5) 16%, var(--bg-card)); }
.v-accent-6 { background: color-mix(in srgb, var(--v-cat-6) 16%, var(--bg-card)); }
.v-accent-7 { background: color-mix(in srgb, var(--v-cat-7) 16%, var(--bg-card)); }
.v-accent-8 { background: color-mix(in srgb, var(--v-cat-8) 16%, var(--bg-card)); }

.shelf-tabs {
  display: flex;
  gap: 0.4rem;
  padding: 0 var(--gutter) 1rem;
  overflow-x: auto;
}
.tab {
  border: none;
  background: var(--grey-soft);
  color: var(--ink-soft);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.tab.active { background: var(--accent); color: var(--accent-contrast); }
#customShelfTabs { display: contents; }
.tab-manage { background: var(--bg-card); box-shadow: var(--shadow); }

.shelf-emoji-input { flex: 0 0 auto; width: 3.2rem; text-align: center; }

.shelf-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.7rem;
  border-radius: 12px;
  background: var(--bg);
}
.shelf-row-name { flex: 1; font-weight: 700; font-size: 0.9rem; }
.shelf-row-count { font-size: 0.75rem; color: var(--ink-soft); }
.shelf-row-actions { display: flex; gap: 0.4rem; }
.shelf-row-actions .btn { padding: 0.4rem 0.6rem; font-size: 0.72rem; }
.shelf-rename-input { flex: 1; font-family: inherit; font-size: 0.9rem; padding: 0.4rem 0.6rem; border-radius: 10px; border: 1px solid var(--grey-soft); background: var(--bg-card); color: var(--ink); }

.list-toolbar {
  display: flex;
  gap: 0.5rem;
  padding: 0 var(--gutter) 0.9rem;
  align-items: center;
  flex-wrap: wrap;
}
.search-input {
  flex: 1;
  min-width: 140px;
  font-family: inherit;
  font-size: 0.85rem;
  padding: 0.5rem 0.8rem;
  border-radius: 999px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink);
}
.sort-select {
  font-family: inherit;
  font-size: 0.8rem;
  padding: 0.5rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink-soft);
}
.layout-toggle {
  display: flex;
  background: var(--bg-card);
  border-radius: 999px;
  padding: 0.2rem;
  gap: 0.2rem;
  flex: 0 0 auto;
}
.layout-btn {
  border: none;
  background: transparent;
  color: var(--ink-soft);
  width: 32px;
  height: 32px;
  border-radius: 999px;
  font-size: 0.95rem;
  cursor: pointer;
}
.layout-btn.active { background: var(--accent); color: var(--accent-contrast); }

main { padding: 0 var(--gutter); }

.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--ink-soft);
}
.empty-emoji { font-size: 2.5rem; margin: 0 0 0.5rem; }

.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1rem;
}

.book-grid.layout-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.book-grid.layout-list .book-card {
  flex-direction: row;
  align-items: center;
  border-radius: 14px;
}
.book-grid.layout-list .book-cover {
  width: 46px;
  height: 66px;
  aspect-ratio: unset;
  flex: 0 0 auto;
  font-size: 1.3rem;
  border-radius: 8px;
  margin: 0.5rem 0 0.5rem 0.5rem;
}
.book-grid.layout-list .book-info {
  padding: 0.5rem 0.9rem;
  flex-direction: row;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
}
.book-grid.layout-list .book-title { flex: 1 1 auto; min-width: 120px; }
.book-grid.layout-list .book-author { flex: 0 1 auto; }
.book-grid.layout-list .progress-track { margin-top: 0; width: 80px; flex: 0 0 auto; }
.book-grid.layout-list .progress-label { margin-top: 0.15rem; }
.book-grid.layout-list .reread-badge,
.book-grid.layout-list .custom-badge { position: static; display: inline-block; margin-right: 0.3rem; }

.book-card {
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  transition: transform 0.12s ease;
}
.book-card:active { transform: scale(0.98); }

.book-cover {
  aspect-ratio: 2 / 3;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.2rem;
  overflow: hidden;
  position: relative;
}
.book-cover img { width: 100%; height: 100%; object-fit: cover; }
/* The object on the shelf is a book: a sliver of stacked page edges down the
   cover's right side, and a soft spine shadow on the left. Pure decoration —
   pointer-events off so taps still land on the card. */
.book-cover::after {
  content: '';
  position: absolute;
  inset: 0 0 0 auto;
  width: 5px;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.55) 0 1.5px,
    rgba(120, 100, 80, 0.25) 1.5px 3px
  );
  pointer-events: none;
}
.book-cover::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 7px;
  background: linear-gradient(to right, rgba(60, 40, 30, 0.28), transparent);
  pointer-events: none;
  z-index: 1;
}

.reread-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  background: var(--yellow);
  color: #5a4207;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}

.custom-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  background: var(--blue-soft);
  color: #2c4a6b;
  font-size: 0.65rem;
  font-weight: 700;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
}

.book-info { padding: 0.7rem 0.75rem 0.85rem; flex: 1; display: flex; flex-direction: column; gap: 0.25rem; }
.book-title { font-size: 0.9rem; font-weight: 700; line-height: 1.25; }
.book-author { font-size: 0.78rem; color: var(--ink-soft); }
.popular-add-btn { margin-top: 0.4rem; font-size: 0.72rem; padding: 0.4rem 0.5rem; width: 100%; }

.popular-spotlight {
  display: flex;
  gap: 1rem;
  align-items: center;
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.1rem;
  margin-bottom: 1.2rem;
  border: 2px solid var(--accent);
}
.spotlight-badge {
  display: inline-block;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  margin-bottom: 0.4rem;
}
.spotlight-cover {
  flex: 0 0 auto;
  width: 90px;
  aspect-ratio: 2/3;
  border-radius: 10px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  overflow: hidden;
}
.spotlight-cover img { width: 100%; height: 100%; object-fit: cover; }
.spotlight-text { flex: 1; min-width: 0; }
.spotlight-title { font-size: 1.1rem; font-weight: 800; line-height: 1.25; }
.spotlight-author { font-size: 0.85rem; color: var(--ink-soft); margin-top: 0.2rem; }
.spotlight-add-btn { margin-top: 0.6rem; }

.landing-spotlight-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 0.3rem;
}
.landing-spotlight-row .popular-spotlight { margin-bottom: 0; }
@media (max-width: 640px) {
  .landing-spotlight-row { grid-template-columns: 1fr; }
}

.bestseller-row { align-items: center; }
.bestseller-rank {
  flex: 0 0 auto;
  width: 28px;
  text-align: center;
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.bestseller-trend { font-size: 0.72rem; font-weight: 700; }
.bestseller-trend.trend-up { color: #0ca30c; }
.bestseller-trend.trend-down { color: #d03b3b; }
.bestseller-trend.trend-new { color: var(--accent-deep); }
.bestseller-trend.trend-same { color: var(--ink-soft); }
.spotlight-badge.spotlight-badge-gold { background: #c98500; }

.card-rating {
  font-size: 0.7rem;
  color: var(--yellow);
  letter-spacing: 0.05em;
}

.progress-track {
  margin-top: auto;
  height: 6px;
  background: var(--grey-soft);
  border-radius: 999px;
  overflow: hidden;
}
.progress-fill { height: 100%; background: var(--green); }
.progress-label { font-size: 0.7rem; color: var(--ink-soft); margin-top: 0.2rem; }

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(40, 28, 25, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 50;
  backdrop-filter: blur(2px);
}
@media (min-width: 640px) {
  .modal-backdrop { align-items: center; }
}

.modal {
  background: var(--bg-card);
  border-radius: 22px 22px 0 0;
  padding: 1.5rem;
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 -6px 30px rgba(0,0,0,0.2);
}
@media (min-width: 640px) {
  .modal { border-radius: 22px; }
}

.modal-close {
  position: absolute;
  top: 0.9rem;
  right: 1rem;
  border: none;
  background: var(--grey-soft);
  color: var(--ink);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  font-size: 1.1rem;
  cursor: pointer;
}

#bookForm { display: flex; flex-direction: column; gap: 0.9rem; margin-top: 1rem; }
#bookForm label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
#bookForm input, #bookForm select, #bookForm textarea {
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.55rem 0.7rem;
  border-radius: 12px;
  border: 1px solid var(--grey-soft);
  background: var(--bg);
  color: var(--ink);
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
.checkbox-row { flex-direction: row !important; align-items: center; gap: 0.5rem !important; }
.checkbox-row input { width: auto; }

.isbn-row { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
.isbn-row input { flex: 1; padding: 0.55rem 0.7rem; border-radius: 12px; border: 1px solid var(--grey-soft); background: var(--bg); color: var(--ink); }
.lookup-status { font-size: 0.78rem; color: var(--ink-soft); min-height: 1.1em; }

.search-divider {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1rem 0 0;
  font-size: 0.72rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.search-divider::before, .search-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--grey-soft);
}

.search-results {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.6rem;
  max-height: 260px;
  overflow-y: auto;
}
.search-result {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  padding: 0.4rem;
  border-radius: 12px;
  background: var(--bg);
  border: 1px solid var(--grey-soft);
  cursor: pointer;
  text-align: left;
}
.search-result:active { background: var(--accent-soft); }
.search-result-cover {
  flex: 0 0 auto;
  width: 34px;
  height: 50px;
  border-radius: 4px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  overflow: hidden;
}
.search-result-cover img { width: 100%; height: 100%; object-fit: cover; }
.search-result-text { flex: 1; min-width: 0; }
.search-result-title { font-size: 0.82rem; font-weight: 700; line-height: 1.25; }
.search-result-meta { font-size: 0.72rem; color: var(--ink-soft); }

.modal-actions { display: flex; justify-content: space-between; gap: 0.6rem; margin-top: 0.4rem; }

#scanReader { border-radius: 14px; overflow: hidden; margin-top: 0.75rem; }
.scan-hint { font-size: 0.8rem; color: var(--ink-soft); margin: 0.25rem 0 0; }

.scan-video-wrap {
  position: relative;
  margin-top: 0.75rem;
  border-radius: 14px;
  overflow: hidden;
  background: #000;
  aspect-ratio: 4 / 3;
}
.scan-video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.scan-video-frame {
  position: absolute;
  left: 8%;
  right: 8%;
  top: 38%;
  bottom: 38%;
  border: 2px solid rgba(255, 255, 255, 0.85);
  border-radius: 8px;
  box-shadow: 0 0 0 999px rgba(0, 0, 0, 0.25);
  pointer-events: none;
}
.scan-capture-btn { width: 100%; margin-top: 0.75rem; font-size: 1rem; padding: 0.7rem; }
#scanManualBtn { width: 100%; margin-top: 0.5rem; }

.import-steps { margin: 0.9rem 0; padding-left: 1.2rem; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.7; }
.import-steps b { color: var(--ink); }
.import-template-box { background: var(--grey-soft); border-radius: 14px; padding: 0.8rem 1rem; margin-bottom: 1rem; }
.import-template-box .btn { font-size: 0.82rem; padding: 0.5rem 0.9rem; text-decoration: none; display: inline-block; }
#importFile { width: 100%; font-size: 0.85rem; margin-top: 0.4rem; }
.import-summary-box { background: var(--green-soft); border-radius: 14px; padding: 0.8rem 1rem; margin-top: 0.9rem; font-size: 0.85rem; line-height: 1.6; }
.transfer-heading { margin: 1.4rem 0 0.3rem; font-size: 0.95rem; color: var(--ink); }
.transfer-heading:first-of-type { margin-top: 0.6rem; }
.profile-body { margin: 0.8rem 0 1.1rem; }
.profile-row { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: 0.55rem 0; border-bottom: 1px solid var(--grey-soft); font-size: 0.88rem; }
.profile-row:last-child { border-bottom: 0; }
.profile-row span { color: var(--ink-soft); }
.profile-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.import-summary-box.has-errors { background: var(--yellow-soft); }
.import-errors { max-height: 140px; overflow-y: auto; margin-top: 0.5rem; font-size: 0.75rem; color: var(--ink-soft); }
.import-errors div { padding: 0.15rem 0; }

.toast {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--bg);
  padding: 0.6rem 1.1rem;
  border-radius: 999px;
  font-size: 0.85rem;
  box-shadow: var(--shadow);
  z-index: 100;
}

/* --- detail view --- */
.detail-cover { width: 110px; aspect-ratio: 2/3; border-radius: 10px; overflow: hidden; background: var(--accent-soft); float: left; margin-right: 1rem; display: flex; align-items: center; justify-content: center; font-size: 2rem; }
.detail-cover img { width: 100%; height: 100%; object-fit: cover; }
.detail-header { overflow: auto; margin-bottom: 0.75rem; }
.detail-title { font-size: 1.15rem; font-weight: 800; }
.detail-author { color: var(--ink-soft); font-size: 0.9rem; margin-top: 0.2rem; }
.detail-meta { font-size: 0.78rem; color: var(--ink-soft); margin-top: 0.4rem; line-height: 1.5; }

.progress-widget { clear: both; background: var(--green-soft); border-radius: 14px; padding: 0.9rem; margin: 0.75rem 0; }
.progress-mode-toggle { display: flex; gap: 0.4rem; margin-bottom: 0.6rem; }
.mode-btn { flex: 1; border: none; background: var(--bg-card); border-radius: 999px; padding: 0.35rem 0; font-size: 0.75rem; font-weight: 700; cursor: pointer; color: var(--ink-soft); }
.mode-btn.active { background: var(--green); color: var(--accent-contrast); }
.progress-input-row { display: flex; gap: 0.5rem; align-items: center; }
.progress-number {
  width: 4.6rem;
  flex: 0 0 auto;
  font-family: inherit;
  font-size: 0.85rem;
  padding: 0.35rem 0.45rem;
  border-radius: 10px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink);
  text-align: center;
}
.progress-input-row input[type="range"] { flex: 1; }
.progress-readout { font-size: 0.8rem; font-weight: 700; min-width: 4.5em; text-align: right; }

.notes-section { clear: both; margin-top: 1rem; }
.notes-section h4 { font-size: 0.85rem; color: var(--ink-soft); margin-bottom: 0.5rem; }

.shelf-chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.6rem; }
.shelf-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.3rem 0.5rem 0.3rem 0.7rem;
  border-radius: 999px;
}
.shelf-chip-remove {
  border: none;
  background: none;
  color: inherit;
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.15rem;
  opacity: 0.7;
}
.shelf-chip-remove:hover { opacity: 1; }
.shelf-chip-empty { font-size: 0.8rem; color: var(--ink-soft); }
.notes-section textarea {
  width: 100%;
  font-family: inherit;
  font-size: 0.88rem;
  padding: 0.6rem 0.7rem;
  border-radius: 12px;
  border: 1px solid var(--grey-soft);
  background: var(--bg);
  color: var(--ink);
  resize: vertical;
  margin-bottom: 0.5rem;
}

.entry-history { margin-top: 1rem; }
.entry-history h4 { font-size: 0.85rem; color: var(--ink-soft); margin-bottom: 0.5rem; }
.entry-row { display: flex; justify-content: space-between; align-items: center; padding: 0.5rem 0; border-bottom: 1px solid var(--grey-soft); font-size: 0.82rem; }
.entry-row:last-child { border-bottom: none; }
.entry-tag { font-size: 0.7rem; font-weight: 700; padding: 0.15rem 0.5rem; border-radius: 999px; }
.tag-reading { background: var(--blue-soft); color: #2c4a6b; }
.tag-read { background: var(--green-soft); color: #2e5c37; }
.tag-to_read { background: var(--grey-soft); color: var(--ink-soft); }
.tag-dnf { background: #f4d6d1; color: #8a3226; }

.detail-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.stars { font-size: 1.1rem; letter-spacing: 0.15em; cursor: pointer; margin: 0.3rem 0; }
.star { color: var(--grey); }
.star.filled { color: var(--yellow); }

/* ================= Goals & Stats page ================= */

.view-switch {
  display: flex;
  gap: 0.4rem;
  padding: 0 var(--gutter) 1rem;
}
.view-btn {
  border: none;
  background: var(--grey-soft);
  color: var(--ink-soft);
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
}
.view-btn.active { background: var(--ink); color: var(--bg); }

.goals-view { padding: 0 var(--gutter) 2rem; }
.goal-year-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1rem;
}
.goal-year-row h2 { font-size: 1.15rem; margin: 0; }
.date-filter-controls { display: flex; gap: 0.5rem; align-items: center; }
#yearSelect { padding: 0.5rem 0.7rem; }

.custom-range-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  background: var(--bg-card);
  border-radius: 14px;
  padding: 0.7rem 0.9rem;
  margin-bottom: 1rem;
  box-shadow: var(--shadow);
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.custom-range-row input[type="date"] {
  font-family: inherit;
  padding: 0.4rem 0.6rem;
  border-radius: 10px;
  border: 1px solid var(--grey-soft);
  background: var(--bg);
  color: var(--ink);
}

.goal-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.9rem;
  margin-bottom: 1.5rem;
}
.goal-card {
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1rem 1.1rem;
}
.goal-card-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.6rem; }
.goal-card-title { font-size: 0.85rem; font-weight: 700; color: var(--ink-soft); }
.goal-card-edit { background: none; border: none; color: var(--ink-soft); font-size: 0.75rem; cursor: pointer; text-decoration: underline; padding: 0; }
.goal-card-value { font-size: 1.5rem; font-weight: 800; font-variant-numeric: proportional-nums; margin-bottom: 0.5rem; }
.goal-card-value .goal-target { font-size: 1rem; font-weight: 600; color: var(--ink-soft); }
.goal-card-pace { font-size: 0.75rem; margin-top: 0.4rem; font-weight: 600; }
.goal-card-empty { font-size: 0.82rem; color: var(--ink-soft); }
.goal-set-form { display: flex; gap: 0.5rem; margin-top: 0.4rem; }
.goal-set-form input { width: 90px; padding: 0.4rem 0.6rem; border-radius: 10px; border: 1px solid var(--grey-soft); background: var(--bg); color: var(--ink); font-family: inherit; }

/* Meter: fill + a lighter same-ramp track (dataviz skill § figures) */
.meter-track {
  width: 100%;
  height: 10px;
  border-radius: 999px;
  background: var(--v-seq-track);
  overflow: hidden;
}
.meter-fill { height: 100%; background: var(--v-seq-fill); border-radius: 999px; transition: width 0.3s ease; }

.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 0.7rem;
  margin-bottom: 1.5rem;
}
.kpi-tile {
  background: var(--bg-card);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 0.8rem 0.9rem;
  border-left: 4px solid transparent;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  width: 100%;
}
.kpi-tile:active { transform: scale(0.97); }
.kpi-tile.v-border-1 { border-left-color: var(--v-cat-1); }
.kpi-tile.v-border-2 { border-left-color: var(--v-cat-2); }
.kpi-tile.v-border-3 { border-left-color: var(--v-cat-3); }
.kpi-tile.v-border-4 { border-left-color: var(--v-cat-4); }
.kpi-tile.v-border-5 { border-left-color: var(--v-cat-5); }
.kpi-tile.v-border-6 { border-left-color: var(--v-cat-6); }
.kpi-tile.v-border-7 { border-left-color: var(--v-cat-7); }
.kpi-tile.v-border-8 { border-left-color: var(--v-cat-8); }
.kpi-label { font-size: 0.72rem; color: var(--ink-soft); margin-bottom: 0.3rem; }
.kpi-value { font-size: 1.3rem; font-weight: 800; font-variant-numeric: proportional-nums; }

.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}
.chart-card {
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1rem 1.1rem 0.6rem;
}
.chart-card-wide { grid-column: 1 / -1; }
.chart-card h3 { font-size: 0.88rem; margin-bottom: 0.6rem; }
.chart-svg-wrap { position: relative; width: 100%; }
.chart-svg-wrap svg { width: 100%; height: auto; display: block; overflow: visible; }
.chart-empty { font-size: 0.8rem; color: var(--ink-soft); padding: 1.5rem 0; text-align: center; }

/* Mark specs: 2px surface gap between bars, thin gridlines, text never wears data color */
.v-bar { fill: var(--v-seq-fill); cursor: pointer; }
.v-bar:hover, .v-bar:focus { fill: var(--v-cat-1); outline: none; }
.v-bar-cat1 { fill: var(--v-cat-1); }
.v-bar-cat2 { fill: var(--v-cat-2); }
.v-bar-cat3 { fill: var(--v-cat-3); }
/* Donut slices: 2px surface-gap stroke between neighbors; hues in the
   documented categorical order; Other is always neutral. */
.v-donut-slice { stroke: var(--bg-card); stroke-width: 2; }
.v-donut-cat1 { fill: var(--v-cat-1); }
.v-donut-cat2 { fill: var(--v-cat-2); }
.v-donut-cat3 { fill: var(--v-cat-3); }
.v-donut-cat4 { fill: var(--v-cat-4); }
.v-donut-cat5 { fill: var(--v-cat-5); }
.v-donut-cat6 { fill: var(--v-cat-6); }
.v-donut-other { fill: var(--grey); }
.v-donut-hero { fill: var(--ink); font-size: 22px; font-weight: 800; font-family: inherit; }
.v-gridline { stroke: var(--v-grid); stroke-width: 1; }
.v-baseline { stroke: var(--v-baseline); stroke-width: 1; }
.v-axis-label { fill: var(--ink-soft); font-size: 10px; font-family: inherit; }
.v-value-label { fill: var(--ink); font-size: 10px; font-weight: 700; font-family: inherit; }
.v-value-label-inverse { fill: #ffffff; font-size: 10px; font-weight: 700; font-family: inherit; }

.v-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--ink);
  color: var(--bg);
  font-size: 0.75rem;
  padding: 0.35rem 0.6rem;
  border-radius: 8px;
  transform: translate(-50%, -100%);
  white-space: nowrap;
  z-index: 5;
  opacity: 0;
  transition: opacity 0.1s ease;
}
.v-tooltip.visible { opacity: 1; }
.v-tooltip b { font-variant-numeric: proportional-nums; }

.v-legend { display: flex; gap: 0.9rem; flex-wrap: wrap; font-size: 0.75rem; color: var(--ink-soft); margin-top: 0.4rem; }
.v-legend-item { display: flex; align-items: center; gap: 0.35rem; }
.v-legend-swatch { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }

.stat-detail-list { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 1rem; max-height: 60vh; overflow-y: auto; }
.stat-detail-row {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem;
  border-radius: 12px;
  background: var(--bg);
  cursor: pointer;
  text-align: left;
}
.stat-detail-row:active { background: var(--accent-soft); }
.stat-detail-cover {
  width: 34px; height: 50px; border-radius: 4px; background: var(--accent-soft);
  display: flex; align-items: center; justify-content: center; font-size: 1rem; overflow: hidden; flex: 0 0 auto;
}
.stat-detail-cover img { width: 100%; height: 100%; object-fit: cover; }
.stat-detail-text { flex: 1; min-width: 0; }
.stat-detail-title { font-size: 0.85rem; font-weight: 700; }
.stat-detail-meta { font-size: 0.72rem; color: var(--ink-soft); }
.stat-detail-empty { font-size: 0.85rem; color: var(--ink-soft); padding: 1rem 0; text-align: center; }

/* ================= Following & Popular ================= */

.section-subhead { font-size: 0.85rem; color: var(--ink-soft); margin: 1.1rem 0 0.5rem; text-transform: uppercase; letter-spacing: 0.04em; }
.followed-authors-list { display: flex; flex-direction: column; gap: 0.6rem; }
.author-card {
  background: var(--bg-card);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 0.9rem 1rem;
}
.author-card-info { display: flex; align-items: center; gap: 0.6rem; }
.author-card-name { font-weight: 700; font-size: 0.95rem; }
.author-card-badge {
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
}
.author-card-actions { display: flex; gap: 0.5rem; }
.author-card-actions .btn { padding: 0.45rem 0.8rem; font-size: 0.8rem; }

.release-row {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem;
  border-radius: 12px;
  background: var(--bg);
}
.release-row.release-in-library { opacity: 0.55; }
.release-row-actions { display: flex; gap: 0.4rem; flex: 0 0 auto; }
.release-row-actions .btn { padding: 0.4rem 0.6rem; font-size: 0.72rem; white-space: nowrap; }
.release-in-library-tag { font-size: 0.68rem; color: var(--ink-soft); font-style: italic; }

/* ================= Book Clubs ================= */

.field-label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
.field-label input, .field-label textarea {
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.6rem 0.75rem;
  border-radius: 12px;
  border: 1px solid var(--grey-soft);
  background: var(--bg);
  color: var(--ink);
  resize: vertical;
}

.club-card {
  background: var(--bg-card);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 0.9rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  cursor: pointer;
}
.club-card-cover {
  flex: 0 0 auto;
  width: 44px;
  height: 64px;
  border-radius: 6px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  overflow: hidden;
}
.club-card-cover img { width: 100%; height: 100%; object-fit: cover; }
.club-card-text { flex: 1; min-width: 0; }
.club-card-name { font-weight: 700; font-size: 0.92rem; }
.club-card-book { font-size: 0.78rem; color: var(--ink-soft); margin-top: 0.1rem; }
.club-card-meta { font-size: 0.72rem; color: var(--ink-soft); margin-top: 0.2rem; }

.club-book-selected {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--accent-soft);
  border-radius: 12px;
  padding: 0.5rem 0.7rem;
  margin-top: 0.5rem;
  font-size: 0.85rem;
}

.club-detail-header {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1rem;
  margin-bottom: 1rem;
}
.club-detail-header-cover {
  flex: 0 0 auto;
  width: 56px;
  height: 80px;
  border-radius: 8px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  overflow: hidden;
}
.club-detail-header-cover img { width: 100%; height: 100%; object-fit: cover; }
.club-detail-header-text { flex: 1; min-width: 0; }
.club-detail-header-name { font-size: 1.1rem; font-weight: 800; }
.club-detail-header-book { font-size: 0.82rem; color: var(--ink-soft); margin-top: 0.15rem; }
.club-detail-header-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.5rem; }
.club-detail-header-actions .btn { font-size: 0.72rem; padding: 0.35rem 0.6rem; }

.club-detail-tabs { display: flex; gap: 0.4rem; margin-bottom: 0.8rem; }
.club-pane { }

.club-messages {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 50vh;
  min-height: 200px;
  overflow-y: auto;
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1rem;
  margin-bottom: 0.7rem;
}
.club-message { max-width: 80%; }
.club-message.club-message-mine { align-self: flex-end; }
.club-message-meta { font-size: 0.68rem; color: var(--ink-soft); margin-bottom: 0.15rem; }
.club-message.club-message-mine .club-message-meta { text-align: right; }
.club-message-bubble {
  background: var(--grey-soft);
  border-radius: 14px 14px 14px 4px;
  padding: 0.55rem 0.8rem;
  font-size: 0.88rem;
  line-height: 1.4;
  word-break: break-word;
}
.club-message-mine .club-message-bubble {
  background: var(--accent);
  color: var(--accent-contrast);
  border-radius: 14px 14px 4px 14px;
}
.club-messages-empty { text-align: center; color: var(--ink-soft); font-size: 0.85rem; padding: 2rem 0; }

.club-message-form { display: flex; gap: 0.5rem; }
.club-message-form input {
  flex: 1;
  font-family: inherit;
  font-size: 0.9rem;
  padding: 0.65rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink);
}

.guide-card {
  background: var(--bg-card);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 0.9rem 1rem;
  margin-bottom: 0.6rem;
}
.guide-card-title { font-weight: 700; font-size: 0.92rem; margin-bottom: 0.3rem; }
.guide-card-body { font-size: 0.85rem; line-height: 1.5; white-space: pre-wrap; color: var(--ink); }
.guide-file-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 0.25rem 0.65rem;
  margin-bottom: 0.5rem;
  text-decoration: none;
}
.guide-file-link:hover { text-decoration: underline; }
.guide-card-meta { font-size: 0.7rem; color: var(--ink-soft); margin-top: 0.5rem; }
.guide-card-actions { display: flex; gap: 0.4rem; margin-top: 0.5rem; }
.guide-card-actions .btn { font-size: 0.72rem; padding: 0.35rem 0.6rem; }

/* Release-list status tags: your relationship with each of a followed author's
   books, so the unread ones pop while scanning. */
.release-status-tag {
  display: inline-block;
  margin-left: 0.45rem;
  font-size: 0.68rem;
  font-weight: 700;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  vertical-align: 1px;
}
.release-tag-read { background: var(--green-soft); color: var(--green); }
.release-tag-reading { background: var(--blue-soft); color: var(--blue); }
.release-tag-tbr { background: var(--yellow-soft); color: #7a5a1c; }
.release-tag-dnf { background: var(--grey-soft); color: var(--ink-soft); }

/* Notes write like marginalia: serif on faint ruled lines. Alignment contract:
   the gradient's period must equal the line box exactly, and both must start
   from the same origin — so the line height is a fixed px value (an em-based
   gradient rounds differently than the text layout and drifts after a few
   lines), background-origin is content-box (text begins inside the padding;
   by default the gradient would begin at the padding edge and sit offset by
   0.6rem forever), and background-attachment: local makes the rules scroll
   with the words. The rule lands at the bottom of each 24px line box, just
   under the baseline — where a notebook rules the page. */
.notes-section textarea {
  font-family: ui-serif, Baskerville, Charter, Georgia, serif;
  line-height: 24px;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 23px,
    var(--grey-soft) 23px 24px
  );
  background-origin: content-box;
  background-attachment: local;
}

/* ---------- followed-author bios ---------- */
.author-card-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; }
.author-photo { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; box-shadow: var(--shadow); }
.author-card-dates { font-weight: 400; font-size: 0.75rem; color: var(--ink-soft); }
.author-bio {
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--ink-soft);
  cursor: pointer;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.author-bio.expanded { -webkit-line-clamp: unset; display: block; }

.author-search-result .search-result-cover img { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }
.search-result-bio {
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--ink-soft);
  margin-top: 0.25rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Subject-tag chips in the detail view — the finer-grained companions to the
   single canonical genre in the meta line. */
.detail-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.45rem; }
.detail-tag {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--accent-deep);
  background: var(--accent-soft);
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
}

/* ---------- community ratings (detail modal) ---------- */
.community-ratings { margin-top: 0.35rem; min-height: 1em; }
.community-ratings .rating-count { opacity: 0.7; font-size: 0.9em; }

/* ---------- For You recommendations ---------- */
.rec-reason {
  display: inline-block;
  align-self: flex-start;
  background: var(--grey-soft);
  color: var(--ink-soft);
  font-size: 0.68rem;
  line-height: 1.3;
  padding: 0.2rem 0.5rem;
  border-radius: 8px;
}
.rec-actions { display: flex; gap: 0.4rem; margin-top: auto; padding-top: 0.4rem; }
.rec-actions .rec-add-btn { flex: 1; }
.rec-dismiss-btn { flex: 0 0 auto; }

/* Discovery detail modal (Popular / Bestsellers rows) */
.discovery-clickable { cursor: pointer; }
.discovery-description { font-size: 0.88rem; line-height: 1.55; color: var(--ink); max-height: 16rem; overflow-y: auto; white-space: pre-line; margin: 0.8rem 0 0; }

/* =====================================================================
   Phone + installed-app layout
   =====================================================================
   Added to the home screen there's no browser chrome at all: the app owns
   the notch, the status bar and the home-indicator strip, and nothing can
   be scrolled out of the way. So the phone layout (a) pays the safe-area
   insets itself, (b) keeps the primary actions in thumb reach at the
   bottom instead of the top corner, and (c) makes every chip row swipe
   horizontally rather than wrap into a wall of buttons. */

/* Safe areas apply at every width — a notched phone in landscape indents
   from the sides too. They're 0 on hardware without insets. */
body {
  padding-bottom: calc(3rem + env(safe-area-inset-bottom));
  -webkit-tap-highlight-color: transparent;
}
.topbar,
.stats-strip,
.shelf-tabs,
.list-toolbar,
.view-switch,
.goals-view,
main {
  padding-left: max(var(--gutter), env(safe-area-inset-left));
  padding-right: max(var(--gutter), env(safe-area-inset-right));
}

/* Swipeable chip rows shouldn't show a scrollbar gutter on the phone. */
.stats-strip::-webkit-scrollbar,
.shelf-tabs::-webkit-scrollbar,
.view-switch::-webkit-scrollbar { display: none; }
.stats-strip, .shelf-tabs, .view-switch { scrollbar-width: none; }

/* A modal is a sheet on touch — keep its scroll from chaining to the page
   underneath, which on iOS drags the whole app around. */
.modal-backdrop, .modal { overscroll-behavior: contain; }

@media (max-width: 640px) {
  :root { --gutter: 1rem; }

  /* Header stays put while the shelf scrolls — the installed app has no
     browser UI to fall back on for orientation. */
  .topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    flex-wrap: nowrap;
    gap: 0.5rem;
    padding-top: calc(0.7rem + env(safe-area-inset-top));
    padding-bottom: 0.6rem;
    /* Translucent COLOUR, never backdrop-filter: the filter (like transform)
       would make this the containing block for its position:fixed descendants
       and pin the bottom action bar under the title. A plain rgba background
       has no such effect, and letting the genre backdrop show through the
       header is the whole point of having one — a solid bar here is what made
       the horror art look like it had stopped working. */
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    border-bottom: 1px solid var(--grey-soft);
  }
  .brand { gap: 0.45rem; min-width: 0; }
  .brand-mark { font-size: 1.5rem; }
  .brand h1 { font-size: 1.1rem; white-space: nowrap; }
  .topbar .tagline { display: none; }
  .topbar-actions { gap: 0.35rem; flex: 0 0 auto; }

  /* Add / Scan move to a fixed bar at the bottom of the screen — reachable
     one-handed, and the shape a phone app is expected to have. */
  .primary-actions {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    gap: 0.5rem;
    align-items: center;
    padding: 0.55rem max(var(--gutter), env(safe-area-inset-left)) calc(0.55rem + env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-right));
    background: var(--bg-card);
    /* Same reasoning as the header — enough transparency that the backdrop
       carries through the bar, enough blur that the buttons stay readable. */
    background: color-mix(in srgb, var(--bg-card) 78%, transparent);
    backdrop-filter: blur(14px);
    border-top: 1px solid var(--grey-soft);
  }
  .primary-actions .btn { min-height: 46px; }
  #scanBtn, #addBtn { flex: 1 1 0; }

  /* Clearance so the last row of books and the toast clear that bar. */
  body { padding-bottom: calc(5.25rem + env(safe-area-inset-bottom)); }
  .toast { bottom: calc(5rem + env(safe-area-inset-bottom)); }

  /* Views swipe sideways instead of wrapping. */
  .view-switch { flex-wrap: nowrap; overflow-x: auto; }
  .view-btn, .tab { flex: 0 0 auto; min-height: 40px; }

  /* Comfortable touch targets. */
  .btn { min-height: 44px; padding: 0.6rem 1rem; }
  .btn-icon { padding: 0.6rem 0.75rem; }

  /* Two covers across on a phone, with a tighter gap than the desktop grid. */
  .book-grid { grid-template-columns: repeat(2, 1fr); gap: 0.7rem; }

  /* iOS zooms the page in on focus for anything under 16px. */
  .search-input, .sort-select, input, select, textarea { font-size: 16px; }

  /* Search gets its own full-width row — sharing one line with the sort menu
     squeezed it down to a couple of characters at phone widths. */
  .list-toolbar { flex-wrap: wrap; }
  .search-input { flex: 1 1 100%; min-width: 0; }
  .sort-select { flex: 1 1 auto; min-width: 0; }

  /* Sheets: dvh so the sheet isn't cut off by the URL bar in the browser,
     and bottom padding so the last control clears the home indicator. */
  .modal {
    max-height: 88dvh;
    padding-bottom: calc(1.5rem + env(safe-area-inset-bottom));
  }
  .modal-actions { flex-wrap: wrap; }
  .profile-actions .btn { flex: 1 1 auto; }
}

/* Installed-app-only polish: no rubber-band overscroll behind the app, and
   no long-press callout on the chrome (both read as "web page in a
   costume" otherwise). Left alone in the browser, where they're normal. */
@media (display-mode: standalone) {
  html, body { overscroll-behavior-y: none; }
  .btn, .tab, .view-btn, .stat-pill, .brand {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
}

/* ================= Account & settings sheet ================= */

.settings-identity {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 0.9rem 0 0.4rem;
}
.avatar {
  width: 64px;
  height: 64px;
  flex: 0 0 auto;
  border-radius: 50%;
  object-fit: cover;
  background: var(--grey-soft);
  display: grid;
  place-items: center;
  font-size: 1.8rem;
}
.settings-identity-text { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.settings-identity-text b { font-size: 1rem; overflow-wrap: anywhere; }
.settings-identity-text .scan-hint { margin: 0; overflow-wrap: anywhere; }
.settings-identity-actions { display: flex; gap: 0.4rem; margin-top: 0.35rem; flex-wrap: wrap; }
.settings-identity-actions .btn { font-size: 0.78rem; padding: 0.35rem 0.7rem; }

.topbar-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.settings-field { display: flex; flex-direction: column; gap: 0.25rem; margin-bottom: 0.7rem; min-width: 0; }
.settings-field > span { font-size: 0.78rem; color: var(--ink-soft); }
.settings-field input,
.settings-field textarea {
  font-family: inherit;
  font-size: 0.9rem;
  padding: 0.55rem 0.75rem;
  border-radius: 12px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink);
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
}
.settings-field-row { display: flex; gap: 0.6rem; }
.settings-field-row .settings-field { flex: 1 1 0; }
.settings-save-row { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.settings-save-row .lookup-status { margin: 0; }

.settings-heading {
  margin: 1.5rem 0 0.4rem;
  font-size: 0.95rem;
  color: var(--ink);
  border-top: 1px solid var(--grey-soft);
  padding-top: 1rem;
}

/* Light / dark: three states, all visible at once — a cycling icon button
   never told you what the other options were. */
.segmented {
  display: flex;
  gap: 0.25rem;
  background: var(--grey-soft);
  border-radius: 999px;
  padding: 0.25rem;
}
.segment-btn {
  flex: 1 1 0;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  border-radius: 999px;
  padding: 0.5rem 0.4rem;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  min-width: 0;
}
.segment-btn.active { background: var(--bg-card); color: var(--ink); box-shadow: var(--shadow); }

/* --- "I've read this" --- */
.markread-book { display: flex; align-items: center; gap: 0.7rem; margin: 0.8rem 0; }
.markread-book img { width: 44px; height: 64px; object-fit: cover; border-radius: 6px; flex: 0 0 auto; }
.markread-book .markread-title { font-weight: 700; overflow-wrap: anywhere; }
.markread-book .markread-author { font-size: 0.82rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.markread-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.6rem; }
.markread-actions .btn { flex: 1 1 auto; }
.rec-actions .rec-read-btn, .release-row-actions .btn { white-space: nowrap; }
.spotlight-actions, .card-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.6rem; }
.card-actions .btn, .rec-actions .btn { font-size: 0.78rem; padding: 0.4rem 0.7rem; }
.spotlight-actions .spotlight-add-btn { margin-top: 0; }

/* --- reader-defined tags --- */
.custom-tags { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.6rem 0 0.2rem; }
.custom-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--accent-soft);
  color: var(--ink);
  border-radius: 999px;
  padding: 0.25rem 0.6rem;
  font-size: 0.75rem;
  border: none;
  font-family: inherit;
  cursor: pointer;
}
.custom-tag .tag-remove {
  border: none;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1;
  padding: 0;
}
.tag-add-row { display: flex; gap: 0.4rem; margin-top: 0.4rem; }
.tag-add-row input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: inherit;
  font-size: 0.85rem;
  padding: 0.45rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink);
}
.tag-add-row .btn { flex: 0 0 auto; font-size: 0.8rem; padding: 0.45rem 0.9rem; }

/* --- cover photo capture --- */
.cover-preview { display: block; max-width: 180px; margin: 0.8rem auto 0; border-radius: 10px; }
.cover-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.8rem; }
.cover-actions .btn { flex: 1 1 auto; }
.detail-cover-actions { display: flex; justify-content: center; margin-top: 0.5rem; }
.detail-cover-actions .btn { font-size: 0.78rem; padding: 0.35rem 0.8rem; }

/* --- New & Upcoming --- */
.genre-releases-section { margin-bottom: 1.6rem; }
.genre-releases-section .section-subhead { margin-bottom: 0.3rem; }
.release-badge {
  align-self: flex-start;
  font-size: 0.68rem;
  font-weight: 700;
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
  margin-bottom: 0.25rem;
  white-space: nowrap;
}
.release-badge-coming { background: var(--accent-soft); color: var(--accent-deep); }
.release-badge-out { background: var(--green-soft); color: #3f6b46; }
.release-badge-undated { background: var(--grey-soft); color: var(--ink-soft); }
.release-card .book-info { gap: 0.15rem; }
.settings-field select {
  font-family: inherit;
  font-size: 0.9rem;
  padding: 0.55rem 0.7rem;
  border-radius: 12px;
  border: 1px solid var(--grey-soft);
  background: var(--bg-card);
  color: var(--ink);
  width: 100%;
  box-sizing: border-box;
}
