/* display font: Anaktoria by George Douros (UFAS). It has one thin weight, so the display style
   thickens it with an outline and sets it lowercase with the letters touching */
@font-face { font-family: "Anaktoria"; src: url("assets/fonts/Anaktoria.ttf") format("truetype"); font-display: swap; }

:root {
  /* palette: Cappuccino Foam · Transparent Yellow · Green Eyes · Powder Blue · 4625 C brown */
  --foam: #f6f3e8;
  --butter: #f4ecc2;
  --sage: #7d8c67;
  --powder: #94b0c4;
  --cocoa: #4f2c1d;

  /* the panel itself stays near-neutral; foam is only a hint */
  --surface: rgba(247, 246, 241, 0.97);
  --surface-solid: #f7f6f1;
  --card: #fcfbf8;
  --ink: var(--cocoa);          /* 11:1 on foam */
  --ink-2: #6b5244;             /* 6.5:1 */
  --ink-3: #786353;             /* 5.1:1 */
  --line: #e7e3d8;
  --accent: var(--sage);
  --chip: #edeae1;
  --chip-active: var(--cocoa);
  --radius-panel: 22px;
  --radius-cover: 4px;
  --shadow-panel: 0 30px 80px rgba(30, 40, 30, 0.22);
  --shadow-cover: 0 1px 2px rgba(0,0,0,.08), 0 8px 18px rgba(0,0,0,.12);
  --shadow-cover-hover: 0 2px 4px rgba(0,0,0,.1), 0 18px 34px rgba(0,0,0,.18);
  --ease: cubic-bezier(.2, .7, .2, 1);
  /* faint paper grain laid over every cover */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .22 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* Latin in Jost (a free stand-in for Kollektif), Thai falls through to Bai Jamjuree */
  --font: "Jost", "Bai Jamjuree", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-brand: "Anaktoria", "Bai Jamjuree", Georgia, serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; }
html { height: 100%; overflow: hidden; background: var(--powder); } /* also behind the phone's notch and overscroll */
body {
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--powder);
  height: 100dvh;
  overflow: hidden; /* the page itself never scrolls — only the book area does */
  -webkit-font-smoothing: antialiased;
}

/* a printed two-colour halftone: deep blue dots on Powder Blue, thick in some clouds and gone in others.
   ::before is a soft dot grid over grey clouds (white = no dots), pushed to hard edges by contrast and turned 45deg
   like a print screen; multiply lets the blue through the white, and lighten turns the black dots deep blue */
.backdrop { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: var(--powder); }
.backdrop::before {
  /* a square wide enough to cover every corner of any screen shape once it's turned */
  content: ""; position: absolute; left: 50%; top: 50%; width: 150vmax; height: 150vmax; transform: translate(-50%, -50%) rotate(45deg); mix-blend-mode: multiply;
  background:
    radial-gradient(circle, #000, #fff) 0 0 / 7px 7px,
    radial-gradient(14% 22% at 50% 76%, #4d4d4d, transparent),
    radial-gradient(22% 12% at 76% 50%, #5a5a5a, transparent),
    radial-gradient(12% 20% at 50% 24%, #e8e8e8, transparent),
    radial-gradient(18% 12% at 24% 50%, #ededed, transparent),
    #a8a8a8;
  background-blend-mode: overlay, normal, normal, normal, normal, normal;
  filter: contrast(24);
}
.backdrop::after { content: ""; position: absolute; inset: 0; background: #7593ab; mix-blend-mode: lighten; } /* the dots: a deeper blue */

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; flex: none; }

/* ---------- panel ---------- */
.panel {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 64px minmax(0, 1fr); grid-template-rows: minmax(0, 1fr);
  height: calc(100dvh - 48px);
  margin: 24px; /* always the full screen, with the same 24px of backdrop on every side */
  /* solid, except the bottom-right corner, which thins out so the halftone shows through, sharp, with no blur */
  background: radial-gradient(52% 58% at 100% 100%, rgba(247, 246, 241, .62), rgba(247, 246, 241, .98));
  border-radius: var(--radius-panel);
  box-shadow: var(--shadow-panel);
  overflow: hidden;
}

.rail {
  display: flex; flex-direction: column; align-items: center; justify-content: space-between;
  padding: 28px 0 24px;
  border-right: 1px solid var(--line);
}
.brand {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  color: var(--ink-2); text-decoration: none;
  font-family: var(--font-brand); font-size: 19px; font-weight: 400;
}
.brand-mark { width: 26px; height: 26px; stroke: #7593ab; stroke-width: 1.5; } /* noook: three ovals in blue line, the first punched with a star */
.brand-mark .brand-star { fill: #7593ab; stroke: none; }
/* refresh: pull the latest from Notion */
.rail-foot { display: flex; flex-direction: column; align-items: center; gap: 8px; }
@keyframes spin { to { transform: rotate(360deg); } }

.rail { grid-column: 1; grid-row: 1; }
.content {
  grid-column: 2; grid-row: 1;
  isolation: isolate; /* keep the sticky bar's z-index inside the book area, under the series page */
  padding: 0 32px 40px; min-width: 0;
  overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: #d6cdb3 transparent;
}
.content::-webkit-scrollbar { width: 8px; }
.content::-webkit-scrollbar-thumb { background: #d6cdb3; border-radius: 8px; }

/* header + filters stay pinned while scrolling */
.stick-sentinel { height: 1px; }
.sticky-head {
  position: sticky; top: 0; z-index: 5;
  margin: -1px -32px 0; padding: 22px 32px 0;
  background: var(--surface-solid);
  transition: box-shadow .2s var(--ease);
}
.sticky-head.is-stuck {
  box-shadow: 0 10px 18px -14px rgba(30, 28, 24, .35);
}

/* ---------- toolbar: mode · genres · tools, all on one line ---------- */
/* Shelf | Wishlist — a segmented switch where the space label used to be */
.mode-switch { display: inline-flex; flex: none; padding: 3px; border-radius: 999px; background: var(--chip); }
.mode {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px; padding: 0 14px; border: 0; border-radius: 999px; cursor: pointer;
  background: none; color: var(--ink-2); font: inherit; font-size: 13px; font-weight: 500;
  transition: background .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease);
}
.mode:hover { color: var(--ink); }
.mode[aria-pressed="true"] { background: var(--card); color: var(--ink); box-shadow: 0 1px 3px rgba(0,0,0,.1); }
.mode .n { font-size: 11px; font-weight: 400; color: var(--ink-3); }
.mode:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.toolbar {
  container-type: inline-size;
  display: flex; align-items: center; gap: 16px;
  padding: 0 0 14px; border-bottom: 1px solid var(--line);
}
.tools { flex: none; margin-left: auto; display: flex; align-items: center; gap: 4px; }

/* quiet round tool buttons; they grow a label only when it carries information */
.tool-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 36px; height: 36px; padding: 0 9px;
  border: 1px solid transparent; border-radius: 999px; background: none; cursor: pointer;
  color: var(--ink-2); font: inherit; font-size: 13px;
  transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.tool-btn svg { flex: none; width: 18px; height: 18px; stroke-width: 1.8; }
.tool-btn:hover { color: var(--ink); background: var(--chip); }
button.tool-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* status: plain words, the picked one underlined; the line sits on the toolbar's rule and slides */
.status-tabs { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; justify-content: flex-start; gap: 2px; margin-left: -8px; } /* the switch moved to the rail, so the tabs lead the bar */
.tab {
  padding: 8px 12px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 14px; color: var(--ink-3); white-space: nowrap;
  transition: color .2s var(--ease);
}
.tab:hover { color: var(--ink); }
.tab[aria-pressed="true"] { color: var(--ink); font-weight: 500; }
.tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 8px; }
.tab-ink {
  position: absolute; left: 0; bottom: -15px; height: 2px; width: 0;
  border-radius: 2px; background: var(--accent);
  transition: transform .3s var(--ease), width .3s var(--ease);
}

/* genre: a small menu; the button shows the picked one */
.filter { position: relative; }
.filter-label { display: none; }
#genre-btn.is-on .filter-label { display: inline; }
.filter-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 6;
  animation: fade .14s var(--ease);
}
.menu-sheet {
  display: flex; flex-direction: column; width: 288px; max-height: min(72dvh, 560px); overflow: hidden;
  background: var(--card); border-radius: 16px;
  box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 14px 32px -8px rgba(30, 28, 24, .28);
}
.menu-sheet.is-short { width: 220px; }
.menu-sheet.is-short .menu-top { padding-bottom: 4px; }
.menu-top { flex: none; padding: 12px 14px 0; border-bottom: 1px solid var(--line); }
.menu-title { display: flex; justify-content: space-between; align-items: center; min-height: 44px; }
.menu-title h2 { margin: 0; font-size: 17px; font-weight: 500; color: var(--ink); }
.menu-close { display: grid; place-items: center; width: 44px; height: 44px; margin-right: -10px; padding: 0; border: 0; background: none; color: var(--ink-2); cursor: pointer; }
.menu-tabs { display: flex; gap: 18px; }
.menu-tabs button { min-height: 44px; padding: 0; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--ink-2); font: inherit; font-size: 15px; cursor: pointer; }
.menu-tabs button[aria-pressed="true"] { border-bottom-color: var(--accent); color: var(--ink); font-weight: 500; }
.menu-tabs button:focus-visible, .menu-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.menu-list { flex: 1; min-height: 0; overflow-y: auto; padding: 6px 6px 10px; overscroll-behavior: contain; }
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 44px; padding: 0 8px; border: 0; border-radius: 9px; background: none; cursor: pointer;
  font: inherit; font-size: 15px; color: var(--ink-2); text-align: left;
}
.menu-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.menu-check { flex: none; width: 18px; height: 18px; stroke-width: 2; visibility: hidden; }
.menu-item:hover { background: var(--chip); color: var(--ink); }
.menu-item[aria-pressed="true"] { color: var(--ink); font-weight: 500; }
.menu-item[aria-pressed="true"] .menu-check { visibility: visible; }
.menu-item .n { font-size: 13px; font-weight: 400; color: var(--ink-3); }
.menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (max-width: 760px) {
  /* phone: rises from the bottom like the add form, with the thumb's reach */
  .filter-menu { position: fixed; inset: 0; z-index: 50; display: flex; align-items: flex-end; background: rgba(30, 28, 24, .32); }
  .filter-menu[hidden] { display: none; }
  .menu-sheet { width: 100%; max-height: 78dvh; padding-bottom: env(safe-area-inset-bottom); border-radius: 20px 20px 0 0; }
  .menu-sheet.is-short { width: 100%; }
  .menu-top { padding: 8px 18px 0; }
  .menu-list { padding: 6px 10px 12px; }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 760px) {
  .menu-sheet { animation: menu-rise .22s var(--ease); }
}
@keyframes menu-rise { from { transform: translateY(32px); } }

/* search: an icon until you use it, then it opens over the genre row */
.search { gap: 0; cursor: pointer; transition: width .22s var(--ease); }
.search input { width: 0; padding: 0; opacity: 0; border: 0; outline: 0; background: none; font: inherit; font-size: 15px; color: var(--ink); }
/* opens to ~40% of the row; the status tabs stay in view */
.toolbar.searching .search, .search:focus-within { width: 40cqi; gap: 8px; background: var(--card); border-color: var(--line); justify-content: flex-start; padding: 0 14px; cursor: text; }
.toolbar.searching .search input, .search:focus-within input { width: 100%; opacity: 1; }
.search:focus-within { border-color: #cbbf9f; }


/* ---------- grid ---------- */
.grid {
  list-style: none;  padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 32px 22px; align-items: start;
  margin: 28px 0 0;
}
/* wide screens: always 8 to a row */
@media (min-width: 1100px) { .grid { grid-template-columns: repeat(8, minmax(0, 1fr)); } }
.book { margin: 0; }
/* Wishlist sections: a heading across the whole row, with more room above the later ones */
/* a section starts with a bookmark rising out of the line, in the colours of its status */
.grid-head { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 4px 12px; margin: 0 0 -6px; border-bottom: 1px solid var(--line); }
.grid-head:not(:first-child) { margin-top: 20px; }
/* desktop wishlist: the first heading sits in the top row, its tab standing on the row's line */
.toolbar:has(.toolbar-head) { align-items: flex-end; padding-bottom: 0; }
.toolbar:has(.toolbar-head) .tools { margin-bottom: 8px; }
.toolbar:has(.toolbar-head) .status-tabs { display: none; }
.toolbar-head { flex: 1; min-width: 0; margin: 0; border-bottom: 0; }
.grid-head h2 {
  margin: 0 auto 0 0; padding: 8px 20px 5px; border-radius: 7px 7px 0 0;
  font-family: var(--font-brand); font-weight: 400; font-size: clamp(25px, 2.5vw, 30px); line-height: 1.1; color: var(--bm-ink);
  background: radial-gradient(circle, var(--bm-dot) .65px, transparent 1px) 0 0 / 3px 3px, var(--b0);
}
.is-soon { --b0: var(--butter); --bm-ink: var(--cocoa); --bm-dot: rgba(79,44,29,.32); }  /* next */
.is-later { --b0: var(--powder); --bm-ink: var(--cocoa); --bm-dot: rgba(79,44,29,.42); } /* someday, still wanted */
.is-sage { --b0: var(--sage); --bm-ink: var(--cocoa); --bm-dot: rgba(79,44,29,.32); }
.is-pile { --b0: var(--cocoa); --bm-ink: var(--foam); --bm-dot: rgba(246,243,232,.3); }  /* pile */
.grid-count { margin: 0 0 8px; font-size: 14px; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.grid-count b { font-weight: 600; color: var(--ink); }
.grid-note { margin-bottom: 8px; font-size: 13px; color: var(--ink-3); }
.book-btn {
  display: block; width: 100%; padding: 0; border: 0; background: none; cursor: pointer;
  text-align: center; color: inherit; font: inherit;
}
.cover {
  position: relative; display: block; aspect-ratio: 2 / 3; width: 100%;
  border-radius: var(--radius-cover); overflow: hidden;
  background: #e4dcc4;
  box-shadow: var(--shadow-cover);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cover::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--grain);
}
.book-btn:hover .cover, .book-btn:focus-visible .cover { transform: translateY(-4px); box-shadow: var(--shadow-cover-hover); }
.book-btn:focus-visible { outline: none; }
.book-btn:focus-visible .cover { outline: 2px solid var(--accent); outline-offset: 4px; }

/* wishlist tile: which volume you're after, under the title */
.caption-vol { display: block; margin-top: 2px; font-size: 12.5px; color: var(--ink-3); }

/* ---------- series pile ---------- */
.stack { position: relative; display: block; }
.stack .cover { z-index: 2; }
.layer {
  position: absolute; inset: 0; z-index: 0;
  border-radius: var(--radius-cover);
  background-color: #e4dcc4; background-size: cover; background-position: center;
  box-shadow: var(--shadow-cover);
  box-shadow: 0 1px 2px rgba(0,0,0,.1);
  transition: transform .25s var(--ease);
}
/* small offset peek — just enough to read as "more than one" */
/* each sheet further back fades lighter */
.layer-1 { z-index: 1; transform: translate(3px, -3px); filter: saturate(.7) brightness(1.06); opacity: .7; }
.layer-2 { transform: translate(6px, -6px); filter: saturate(.5) brightness(1.12); opacity: .4; }
.book-btn:hover .layer-1, .book-btn:focus-visible .layer-1 { transform: translate(4px, -8px); }
.book-btn:hover .layer-2, .book-btn:focus-visible .layer-2 { transform: translate(8px, -12px); }
.vol-count {
  position: absolute; z-index: 3; right: 6px; bottom: 6px;
  min-width: 22px; padding: 1px 7px; border-radius: 999px;
  background: rgba(255, 255, 255, .7); color: var(--ink);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  font-size: 11px; font-weight: 600; line-height: 1.7; text-align: center;
  font-variant-numeric: tabular-nums;
}

.caption {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  margin-top: 12px; font-size: 13px; line-height: 1.45; color: var(--ink-2);
}

/* typographic placeholder covers */
.cover.typo { display: flex; flex-direction: column; justify-content: space-between; padding: 14% 12% 12%; text-align: left; }
.cover.typo::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 7%; background: rgba(0,0,0,.1); }
.typo-title { display: block; }
.typo-title { font-family: var(--font-brand); font-weight: 400; font-size: clamp(15px, 1.2vw, 18px); line-height: 1.15; }
.typo-author { font-size: 11px; letter-spacing: .04em; text-transform: uppercase; opacity: .85; }
/* default covers: the palette colours as they are; type colour picked per background for contrast */
.g-manga { background: var(--powder); color: var(--cocoa); }        /* 5.4:1 */
.g-light-novel { background: var(--powder); color: var(--cocoa); }
.g-literature { background: var(--sage); color: #fff; }              /* 3.6:1, fine for the large title */
.g-thriller { background: var(--cocoa); color: var(--foam); }        /* 11:1 */
.g-psychology { background: var(--butter); color: var(--cocoa); }    /* 10:1 */
.g-art, .g-design { background: var(--foam); color: var(--cocoa); }  /* 11:1 */
.g-self-help, .g-philosophy { background: var(--butter); color: var(--cocoa); }
.g-sci-fi, .g-horror { background: var(--cocoa); color: var(--foam); }
.g-memoir { background: var(--sage); color: #fff; }

.empty { text-align: center; padding: 60px 0; color: var(--ink-3); }
.link-btn { border: 0; background: none; color: var(--accent); font: inherit; cursor: pointer; text-decoration: underline; padding: 8px; }

.stars { color: var(--cocoa); letter-spacing: 2px; font-size: 18px; }
.stars .off { color: #ddd3b8; }
.progress { height: 6px; border-radius: 99px; background: var(--chip); overflow: hidden; }
.progress > span { display: block; height: 100%; background: var(--ink); border-radius: 99px; }
.link-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* quiet icon button (the edit pencil); 28px hit area */
.action-icon {
  display: inline-grid; place-items: center; vertical-align: middle;
  width: 28px; height: 28px; margin: -4px 0 -4px 6px; border-radius: 8px;
  color: var(--ink-3);
  transition: color .2s var(--ease), background .2s var(--ease);
}
.action-icon svg { width: 15px; height: 15px; fill: currentColor; stroke: none; }
.action-icon:hover { color: var(--ink); background: var(--chip); }
.edit-icon { display: none; border: 0; background: none; padding: 0; cursor: pointer; }
.edit-icon svg { fill: none; stroke: currentColor; stroke-width: 1.7; }
.can-edit .edit-icon { display: inline-grid; }
.action-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- series shelf (volumes fanned out) ---------- */
/* sits in the same grid cell as .content and covers it; .content keeps its scroll position underneath */
.shelf {
  grid-column: 2; grid-row: 1; z-index: 4; min-width: 0;
  display: flex; flex-direction: column;
  background: var(--surface-solid);
  overflow: hidden;
  animation: fade .2s var(--ease);
}
.shelf.closing { animation: fade-out .16s var(--ease) forwards; }
.shelf-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 22px 20px 18px 32px; border-bottom: 1px solid var(--line);
}
.shelf-info { min-width: 0; }
.shelf-info h2 { margin: 0; font-size: 22px; line-height: 1.3; font-weight: 600; }
.shelf-info h2:focus { outline: none; }
.shelf-info .sub { margin: 2px 0 0; color: var(--ink-2); font-size: 15px; }
/* author · progress · owned/total · edit, all on one line */
.shelf-info .by {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  margin: 10px 0 0; font-size: 14px; color: var(--ink-2);
}
/* bar, count and edit stay together when the line wraps */
.shelf-info .by .have { display: inline-flex; align-items: center; gap: 10px; }
.shelf-info .by .progress { width: 120px; }
.shelf-info .by .count { font-variant-numeric: tabular-nums; color: var(--ink-3); }
.shelf-info .by .action-icon { margin: -4px 0 -4px -4px; }

/* round icon close, shared by the series page and the lifted book */
.icon-close {
  flex: none; display: grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  border: 0; border-radius: 999px; cursor: pointer;
  background: var(--chip); color: var(--ink-2);
  transition: background .2s var(--ease), color .2s var(--ease);
}
.icon-close svg { width: 18px; height: 18px; stroke-width: 1.8; }
.icon-close:hover { background: #e4dcc0; color: var(--ink); }
.icon-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.shelf-grid {
  list-style: none; margin: 0; padding: 28px 32px 40px;
  overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 28px 20px; align-content: start;
}
.vol-tile { text-align: center; }
.vol-tile .cover { box-shadow: var(--shadow-cover); transition: transform .25s var(--ease), box-shadow .25s var(--ease); }
.vol-btn { display: block; width: 100%; padding: 0; border: 0; background: none; font: inherit; cursor: pointer; text-align: center; }
.cover-wrap { position: relative; display: block; }
.vol-btn:hover .cover, .vol-btn:focus-visible .cover { transform: translateY(-4px); box-shadow: var(--shadow-cover-hover); }
.vol-btn:focus-visible { outline: none; }
.vol-btn:focus-visible .cover { outline: 2px solid var(--accent); outline-offset: 4px; }
.vol-label { display: block; margin-top: 10px; font-size: 13px; color: var(--ink-2); }

/* missing volume: an empty slot on the shelf */
.slot {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  aspect-ratio: 2 / 3; border-radius: var(--radius-cover);
  border: 1.5px dashed #cbbf9f;
  background: repeating-linear-gradient(135deg, transparent 0 9px, rgba(120, 108, 90, .045) 9px 10px);
  color: var(--ink-2);
}
.slot-no { font-size: 34px; line-height: 1; color: #b8a98c; }
.slot-text { font-size: 12px; }
.vol-tile.missing .vol-label { color: var(--ink-3); }

/* ---------- lift: a book picked up off the shelf ---------- */
.lift {
  position: fixed; inset: 0; z-index: 20;
  display: grid; place-items: center; padding: 24px;
  /* keep the blur, but wash it out more — brightest where the title sits */
  background: radial-gradient(ellipse 60% 70% at 50% 55%, rgba(249, 248, 244, .9), rgba(247, 246, 241, .74) 70%);
  -webkit-backdrop-filter: blur(22px) saturate(.6);
          backdrop-filter: blur(22px) saturate(.6);
  overflow-y: auto; overscroll-behavior: contain;
}
.lift-close { position: fixed; top: 20px; right: 20px; background: rgba(255,255,255,.8); box-shadow: 0 1px 3px rgba(0,0,0,.1); }
/* edit: a plain icon beside the close button, no frame even on hover */
.lift-actions { position: fixed; top: 22px; right: 72px; display: flex; gap: 6px; }
.lift-actions .action-icon { width: 36px; height: 36px; margin: 0; color: var(--ink-2); background: none; }
.lift-actions .action-icon:hover { color: var(--ink); background: none; }
.lift-actions .action-icon svg { width: 19px; height: 19px; }
.lift-meta:empty { display: none; }
.lift-stage { display: flex; flex-direction: column; align-items: center; gap: 22px; }
.lift-book { position: relative; margin: 0; }
.lift-cover { width: min(calc(68dvh * 2 / 3), 380px, 70vw); transform-origin: 0 0; }
.lift-cover .cover {
  border-radius: 3px 6px 6px 3px;
  box-shadow: 0 2px 6px rgba(0,0,0,.12), 0 30px 60px rgba(30, 30, 20, .3);
}
/* semi-3D: the book turns a little so its page block shows on the right */
.lift-cover { perspective: 1600px; }
.book3d {
  --thick: calc(34px * var(--page-k, 1)); /* --page-k: the book's pages against a 300-page book, set in app.js */
  --tilt: 16deg;
  position: relative; transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(calc(var(--tilt) * -1 + var(--ry, 0deg))); /* --rx/--ry: dragged by hand */
  animation: tilt-in .5s var(--ease) .12s backwards; /* lifts flat, then turns */
  transition: transform .2s var(--ease);
}
.lift[data-closing] .book3d { transform: none; } /* flat again before it lands on the shelf */
@keyframes tilt-in { from { transform: none; } }
.book-pages {
  position: absolute; left: 100%; top: 1.2%; bottom: 1.2%; width: var(--thick);
  transform-origin: left center; transform: rotateY(90deg);
  background:
    repeating-linear-gradient(90deg, rgba(120, 100, 70, .12) 0 1px, transparent 1px 3px),
    linear-gradient(90deg, #d9cdb4, #f3ecdd 30%, #ebe2cf 75%, #cdbfa3);
  box-shadow: inset 0 0 0 1px rgba(90, 70, 40, .12), inset -6px 0 10px -6px rgba(60, 40, 20, .35);
}
/* spine crease and a soft sheen across the cover */
.lift-cover .cover::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(0,0,0,.28) 0, rgba(255,255,255,.18) 2.2%, rgba(0,0,0,.1) 3.8%, transparent 7%),
    linear-gradient(105deg, transparent 40%, rgba(255,255,255,.12) 55%, transparent 70%),
    var(--grain);
}
.lift-cover .typo .typo-title { font-size: clamp(24px, 3vw, 34px); }
.lift-cover { position: relative; z-index: 1; touch-action: none; cursor: grab; } /* drag to turn the book */
.lift-cover:active { cursor: grabbing; }
/* the cover is only for turning: its title text can't be selected, its photo can't be dragged out */
.lift-cover .cover, .lift-cover .cover * { user-select: none; -webkit-user-select: none; -webkit-user-drag: none; -webkit-touch-callout: none; }
.lift-cover .cover img { pointer-events: none; }
/* the review: a slip slid in between the pages (it lives inside the 3D book, halfway
   through the page block), so only the bit past the page edge shows; tap pulls it out in front */
.postit {
  --overlap: 64px; /* how far it sits over the cover once pulled out */
  --peek: 36px;    /* how much sticks out past the page edge while tucked */
  --z-in: calc(var(--thick) / -2);
  --tuck: translate3d(calc(var(--peek) + var(--overlap) - 100%), 0, var(--z-in)) rotate(2deg);
  --clear: translate3d(calc(var(--overlap) + 24px), 0, var(--z-in)) rotate(5deg);     /* pulled clear of the pages */
  --lifted: translate3d(calc(var(--overlap) + 24px), 0, 40px) rotate(5deg);           /* raised above the cover */
  --read: translate3d(0, 0, 40px) rotateY(var(--tilt)) rotate(-2deg);               /* facing you, over the cover */
  position: absolute; left: calc(100% - var(--overlap)); top: 18%;
  width: 180px; aspect-ratio: 1; padding: 12px; overflow: hidden;
  display: flex; flex-direction: column; align-items: stretch; /* write from the top, not centred like a button */
  border: 0; cursor: pointer; text-align: left;
  background: linear-gradient(180deg, #f8f1d1 0%, var(--butter) 100%);
  color: var(--cocoa); font-family: "Sriracha", var(--font); font-size: 13.5px; line-height: 1.6;
  overflow-wrap: anywhere;
  transform: var(--tuck);
  box-shadow: 0 1px 1px rgba(0,0,0,.06), 0 12px 22px -6px rgba(60, 50, 10, .35);
  border-bottom-right-radius: 18px 6px; /* a slightly lifted corner */
  transition: transform .2s var(--ease);
}
.postit:not(.is-open):hover { transform: translate3d(calc(var(--peek) + 10px + var(--overlap) - 100%), 0, var(--z-in)) rotate(3deg); }
.postit-date { margin-top: auto; padding-top: 6px; text-align: right; font-size: .85em; opacity: .65; font-variant-numeric: tabular-nums; }
.postit:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.postit.is-open { transform: var(--read); animation: note-out .55s var(--ease); }
.postit.is-tucking { animation: note-in .45s var(--ease); }
/* out of the pages, up over the cover, then across to read — and the reverse */
@keyframes note-out {
  0%   { transform: var(--tuck); }
  40%  { transform: var(--clear); }
  60%  { transform: var(--lifted); }
  100% { transform: var(--read); }
}
@keyframes note-in {
  0%   { transform: var(--read); }
  40%  { transform: var(--lifted); }
  60%  { transform: var(--clear); }
  100% { transform: var(--tuck); }
}
.lift-info { text-align: center; max-width: 34ch; }
.lift-info h2 { margin: 0; font-size: 20px; line-height: 1.35; font-weight: 600; color: var(--ink); }
.lift-info h2:focus { outline: none; }
.lift-info .sub { margin: 2px 0 0; font-size: 14px; color: var(--ink-2); }
.lift-info .sub:empty { display: none; }
.lift-meta { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 8px 0 0; }
.lift-credits { margin: 6px 0 0; font-size: 14px; color: var(--ink-2); }
.lift-meta:not(:empty) { margin-top: 10px; }
.star { fill: currentColor; stroke: currentColor; stroke-width: 3; stroke-linejoin: round; }
/* rating: one dark star + the score */
.rating { display: inline-flex; align-items: center; gap: 5px; font-size: 14px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.rating svg { width: 15px; height: 15px; }
.rating.is-empty { font-weight: 400; color: var(--ink-3); }

/* ---------- edit in place (book view) ---------- */
#lift-title.editable { cursor: text; border-radius: 6px; padding: 0 6px; margin: 0 -6px; }
#lift-title.editable:hover { background: var(--chip); }
.title-edit { display: flex; flex-direction: column; gap: 6px; width: min(320px, 80vw); }
.title-edit input {
  min-height: 40px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--card); color: var(--ink); font: inherit; font-size: 16px; text-align: center;
}
.title-edit input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.title-edit input[name="en"] { font-weight: 600; font-size: 18px; }

/* stars you tap */
.rate { display: inline-flex; }
.rate button {
  display: inline-grid; place-items: center;
  width: 30px; height: 32px; padding: 0; border: 0; background: none; cursor: pointer;
  color: #d6ceb9; transition: color .15s var(--ease), transform .15s var(--ease);
}
.rate .star { width: 21px; height: 21px; }
.rate button.on { color: var(--cocoa); }
.rate:hover button { color: var(--cocoa); }
.rate button:hover ~ button { color: #d6ceb9; }
.rate button:active { transform: scale(.9); }
.rate button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }

/* status bookmark: slid in between the pages with its top showing; tap pulls it out over the cover.
   printed look: one palette colour under a halftone dot screen, the status word in the display font,
   and a solid bar at the foot */
.bookmark {
  --z-in: calc(var(--thick) / -2);
  --peek: 54px;
  --tuck: translate3d(0, calc(var(--peek) * -1), var(--z-in));
  --clear: translate3d(0, calc(-100% - 8px), var(--z-in));   /* pulled up out of the pages */
  --lifted: translate3d(-14%, calc(-100% - 8px), 2px);        /* brought in front of the cover */
  --read: translate3d(0, 0, 2px) rotate(-5deg); /* with bm-out's place: exactly the deck's front card */
  position: absolute; left: 9%; top: 0; z-index: 1;
  width: 24%; height: 62%; min-width: 64px;
  display: flex; flex-direction: column; align-items: stretch; overflow: hidden;
  container-type: inline-size; /* the word is sized against the bookmark's width */
  color: var(--bm-ink);
  background: radial-gradient(circle, var(--bm-dot) .65px, transparent 1px) 0 0 / 3px 3px, var(--b0);
  border-radius: 6px 6px 2px 2px;
  filter: drop-shadow(0 6px 10px rgba(40, 30, 15, .28));
  transform: var(--tuck); transition: transform .2s var(--ease);
  touch-action: pan-y; user-select: none; -webkit-user-select: none;
}
.bookmark[data-s="0"], .bm-card[data-s="0"] { --b0: #d08a6b; --bm-ink: var(--foam); --bm-dot: rgba(246,243,232,.35); } /* wish */
.bookmark[data-s="1"], .bm-card[data-s="1"] { --b0: var(--butter); --bm-ink: var(--cocoa); --bm-dot: rgba(79,44,29,.32); } /* next */
.bookmark[data-s="2"], .bm-card[data-s="2"] { --b0: var(--cocoa); --bm-ink: var(--foam); --bm-dot: rgba(246,243,232,.3); } /* pile */
.bookmark[data-s="3"], .bm-card[data-s="3"] { --b0: var(--sage); --bm-ink: var(--foam); --bm-dot: rgba(79,44,29,.42); } /* read */
.bm-bar {
  flex: none; padding: 7px 4px; text-align: center; font-family: "Archivo Black", sans-serif; font-size: 10px; line-height: 1.1; letter-spacing: .02em;
  background: var(--bm-ink); color: var(--b0);
}
.bm-tab {
  display: block; width: 100%; min-height: var(--peek); padding: 5px 0 0 6px; border: 0; background: none; color: inherit;
  text-align: left; white-space: nowrap; cursor: pointer;
}
.bm-word { display: inline-block; font-family: var(--font-brand); font-size: 46cqi; line-height: 1; /* app.js fits it to the width */ }
span.bm-tab { cursor: default; }
.bm-tab:focus-visible { outline: 2px solid currentColor; outline-offset: -4px; border-radius: 6px; }
.can-edit .bookmark:not(.is-open):hover { transform: translate3d(0, calc(var(--peek) * -1 - 8px), var(--z-in)); }
.bookmark.is-open { left: -16%; top: -4%; transform: var(--read); animation: bm-out .6s var(--ease); opacity: 0; pointer-events: none; }
.bookmark .bm-bar { margin-top: auto; }
.bookmark.is-still { animation: none; }
/* the deck: smaller than the book, so the cover still shows below it */
.bm-deck { position: absolute; inset: 0; z-index: 4; transform: translateZ(4px); transform-style: preserve-3d; visibility: hidden; pointer-events: none; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.bookmark.is-open ~ .bm-deck { visibility: visible; pointer-events: auto; transition: visibility 0s .6s; }
.bm-card {
  position: absolute; left: -16%; top: -4%; width: 24%; height: 62%; min-width: 64px; padding: 0; border: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: stretch; container-type: inline-size; text-align: left;
  color: var(--bm-ink); background: radial-gradient(circle, var(--bm-dot) .65px, transparent 1px) 0 0 / 3px 3px, var(--b0);
  border-radius: 6px 6px 2px 2px; box-shadow: 0 6px 10px rgba(40, 30, 15, .28); cursor: grab;
  transform: rotate(-5deg);
}
.bm-card .bm-word { align-self: flex-start; margin: 5px 0 0 6px; }
.bm-card .bm-bar { margin-top: auto; }
.bm-card.is-side { cursor: pointer; transition: transform .34s var(--ease) .6s; }
.bm-card.is-side::after { content: ""; position: absolute; inset: 0; background: rgba(255, 255, 255, .46); } /* faded back: not the one chosen */
.bookmark.is-open ~ .bm-deck .is-behind1 { transform: translate3d(-38%, 10%, -8px) rotate(-9deg); }
.bookmark.is-open ~ .bm-deck .is-behind2 { transform: translate3d(-56%, 16%, -10px) rotate(-13deg); }
.bookmark.is-still ~ .bm-deck, .bookmark.is-still ~ .bm-deck .bm-card { transition: none; }
.bm-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bookmark.is-tucking { animation: bm-in .45s var(--ease); }
/* one bookmark, one size: tucked, pulled out, and the deck's front card are the same shape */
@keyframes bm-out {
  0%   { transform: var(--tuck); left: 9%; top: 0; opacity: 1; }
  35%  { transform: var(--clear); left: 9%; top: 0; opacity: 1; }
  50%  { transform: var(--lifted); left: 9%; top: 0; opacity: 1; }
  99.9% { transform: var(--read); left: -16%; top: -4%; opacity: 1; }
  100% { transform: var(--read); left: -16%; top: -4%; opacity: 0; }
}
@keyframes bm-in {
  0%   { transform: var(--read); left: -16%; top: -4%; }
  50%  { transform: var(--lifted); left: 9%; top: 0; }
  65%  { transform: var(--clear); left: 9%; top: 0; }
  100% { transform: var(--tuck); left: 9%; top: 0; }
}

/* ---------- shrink-wrap: a book you don't have yet ---------- */
/* barely there: one soft diagonal glint and a clear edge */
.shrink {
  /* cling film: a sheet a little bigger than the book, crumpled at the edge, with soft glossy streaks */
  position: absolute; inset: -9px 0 -9px -10px; pointer-events: none; /* runs to the right edge, then bends round (.shrink-side) */
  background: url("assets/film.svg") center / 100% 100% no-repeat;
  transform: translateZ(1px);
  transition: opacity .45s var(--ease), transform .6s cubic-bezier(.5,0,.7,.4);
}
/* light comes from the top-left. Turning the book (app.js sets --tx/--ty, -1…1) slides the glare across the
   film and the sticker the other way, and tipping toward the light makes it brighter */
.book3d {
  --glare: linear-gradient(125deg, transparent 38%, rgba(255,255,255,.34) 47%, rgba(255,255,255,.1) 52%, transparent 60%);
  --glare-pos: calc(30% - var(--tx, 0) * 45%) calc(28% - var(--ty, 0) * 45%);
  --glare-on: calc(.75 - var(--tx, 0) * .3 - var(--ty, 0) * .3);
}
.shrink::after {
  content: ""; position: absolute; inset: 9px 0 9px 10px; /* the book itself, not the overhang */
  background: var(--glare) var(--glare-pos) / 300% 300% no-repeat; opacity: var(--glare-on);
  transition: background-position .6s cubic-bezier(.3,1.5,.5,1), opacity .6s var(--ease);
}
.is-turning .shrink::after, .is-turning .st-face::after, .is-turning .shrink-side { transition: none; }
/* a paper price tag on a string, hung over the top edge. It swings from the top of the string:
   it settles when the book opens, then sways a little; turning the book pushes it the other way and it springs back */
.price-tag {
  --tag-bg: var(--butter); --tag-ink: var(--cocoa);
  position: absolute; right: 8%; top: -1.5%; width: 15%; min-width: 46px; pointer-events: none;
  transform-origin: 50% 0; transform: translateZ(3px) rotate(calc(var(--tx, 0) * -16deg));
  transition: transform .9s cubic-bezier(.25,1.8,.45,.9), opacity .35s var(--ease);
}
.pt-swing {
  display: block; transform-origin: 50% 0;
  filter: drop-shadow(calc(2px + var(--tx, 0) * 4px) 5px 4px rgba(30, 20, 10, .38));
  animation: tag-settle 1.7s ease-out, tag-sway 3.6s ease-in-out 1.7s infinite alternate;
}
.price-tag svg { display: block; width: 100%; height: auto; overflow: visible; stroke: none; }
.pt-string { fill: none; stroke: #c4ad84; stroke-width: 1.2; stroke-linecap: round; } /* twine: shows on dark and pale covers alike */
.pt-paper { fill: var(--tag-bg); }
.pt-line { fill: none; stroke: var(--tag-ink); stroke-width: .6; }
.pt-price { font-family: "Jost", sans-serif; font-size: 16px; font-weight: 600; letter-spacing: .01em; fill: var(--tag-ink); }
@keyframes tag-settle {
  0% { transform: rotate(14deg); } 22% { transform: rotate(-9deg); } 44% { transform: rotate(6deg); }
  64% { transform: rotate(-3.500deg); } 82% { transform: rotate(1.500deg); } 100% { transform: rotate(-2deg); }
}
@keyframes tag-sway { from { transform: rotate(-2deg); } to { transform: rotate(2deg); } }
.price-tag.is-off { opacity: 0; }
.is-turning .price-tag { transition: none; }
/* the same film pulled round the page edge, crumpled where it's sealed past the top and bottom */
.shrink-side {
  position: absolute; left: 100%; top: calc(1.2% - 9px); bottom: calc(1.2% - 9px); width: var(--thick); pointer-events: none;
  transform-origin: left center; transform: rotateY(90deg) translateZ(1px);
  background: url("assets/film-side.svg") center / 100% 100% no-repeat;
  opacity: calc(.85 - var(--tx, 0) * .35); /* the page edge faces away from the light; turned toward you it catches more */
  transition: opacity .35s var(--ease);
}
.shrink-side.is-off { opacity: 0; }
.shrink.is-off { opacity: 0; transform: translate3d(36px, 28px, 1px) rotate(5deg) scale(1.04); }
/* the sticker: --c is the fold line (x + y = c, in px); its face shows on one side, its paper back folds over the other */
.sticker {
  --c: 999;
  /* where a barcode would be: bottom-right, inside the cover, with a small shadow so it reads as stuck on */
  position: absolute; right: 5%; bottom: 4%; width: 38%; min-width: 88px; aspect-ratio: 120 / 68;
  padding: 0; border: 0; background: none; cursor: grab; touch-action: none;
  filter: drop-shadow(0 1px 1.5px rgba(30, 20, 10, .3));
  transform: translateZ(2px) rotate(-8deg);
  transition: transform .5s cubic-bezier(.4,0,.6,1), opacity .35s var(--ease);
}
span.sticker { cursor: default; }
.st-face, .st-back { position: absolute; inset: 0; }
.st-face svg, .st-back svg { display: block; width: 100%; height: 100%; overflow: visible; stroke: none; } /* not an icon: no outlines */
.st-face { clip-path: polygon(0 0, calc(var(--c) * 1px) 0, 0 calc(var(--c) * 1px)); }
/* a glossy sticker: a fixed soft sheen plus the same moving glare as the film, kept inside the zigzag */
.st-face::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  -webkit-mask: url("assets/sticker-mask.svg") center / 100% 100% no-repeat; mask: url("assets/sticker-mask.svg") center / 100% 100% no-repeat;
  background:
    var(--glare) var(--glare-pos) / 300% 300% no-repeat,
    linear-gradient(160deg, rgba(255,255,255,.22), transparent 45%);
  opacity: var(--glare-on);
  transition: background-position .6s cubic-bezier(.3,1.5,.5,1), opacity .6s var(--ease);
}
.st-back {
  clip-path: polygon(calc(var(--c) * 1px) 0, 400px 0, 400px 400px, 0 400px, 0 calc(var(--c) * 1px));
  transform-origin: 0 0; transform: matrix(0, -1, -1, 0, var(--c), var(--c)); /* mirrored across the fold */
  filter: drop-shadow(1px 2px 2px rgba(60, 40, 20, .35));
}
.st-back ellipse { fill: #fbf8ef; }
.st-word { font-size: 23px; }
.sticker:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 50%; }
.sticker.is-gone { transform: translateZ(2px) rotate(-24deg) translate(-50px, -80px) scale(.7); opacity: 0; }
/* on the shelf: wishlist covers get the same faint wrap */
.is-wrapped .cover::before {
  content: ""; position: absolute; inset: 0; width: auto; z-index: 1; pointer-events: none; border-radius: inherit;
  background: url("assets/film-tile.svg") center / 100% 100% no-repeat;
}
/* default covers draw their spine shade on ::before too; keep it under the film */
.is-wrapped .cover.typo::before {
  background: url("assets/film-tile.svg") center / 100% 100% no-repeat, linear-gradient(90deg, rgba(0,0,0,.1) 7%, transparent 7%);
}

/* the note you write on */
.postit-text[contenteditable="plaintext-only"], .postit-text[contenteditable="true"] { outline: none; cursor: text; min-height: 3em; }
.postit-text:empty::before { content: attr(data-placeholder); color: #a8977b; }
.postit.is-blank:not(.is-open) .postit-text::before { content: ""; }

/* Saved · Undo */
.toast {
  /* a bottom corner: the top has the bookmark, the bottom centre has the stars */
  position: fixed; right: 116px; bottom: max(54px, env(safe-area-inset-bottom)); z-index: 40; /* beside the floating + */
  max-width: calc(100vw - 32px); white-space: nowrap;
  display: flex; align-items: center; gap: 14px; padding: 10px 10px 10px 18px; border-radius: 999px;
  background: var(--cocoa); color: var(--foam); font-size: 14px; box-shadow: var(--shadow-panel);
  animation: fade .2s var(--ease);
}
.toast button { min-height: 32px; padding: 0 12px; border: 0; border-radius: 999px; background: rgba(255,255,255,.14); color: var(--foam); font: inherit; font-size: 13px; cursor: pointer; }

/* ---------- add a book ---------- */
.add-sheet {
  width: min(780px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); padding: 0; overflow: hidden;
  border: 0; border-radius: 20px; background: var(--surface-solid); color: var(--ink);
  box-shadow: var(--shadow-panel);
}
.add-sheet::backdrop { background: rgba(30, 28, 24, .32); backdrop-filter: blur(6px); }
.add-sheet[open] { animation: sheet-in .28s var(--ease); }
@keyframes sheet-in { from { opacity: 0; transform: translateY(14px); } }
#add-form { display: flex; flex-direction: column; max-height: calc(100dvh - 48px); }
.add-head { flex: none; display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 8px 8px 8px 18px; border-bottom: 1px solid var(--line); }
.add-close { flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--ink-2); cursor: pointer; }
.add-close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.add-foot { flex: none; padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); background: var(--surface-solid); }
.add-foot .btn-main { display: block; width: 100%; min-height: 48px; }
#add-kind { grid-template-columns: 1fr 1fr; }
.add-head h2 { margin: 0; font-size: 16px; font-weight: 600; }
.add-body { flex: 1; min-height: 0; overflow-y: auto; display: grid; grid-template-columns: 250px minmax(0, 1fr); align-items: start; }
.add-stage { position: sticky; top: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 30px 22px; }
.add-preview { position: relative; display: block; width: 180px; padding: 0; border: 0; background: none; cursor: pointer; perspective: 900px; color: inherit; font: inherit; text-align: left; transition: scale .15s var(--ease); }
.add-preview:active { scale: .98; }
.add-preview:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 6px; }
.add-preview .book-btn { display: block; transform: rotateY(-9deg); transform-origin: 40% 50%; }
.add-preview .cover { box-shadow: 0 2px 6px rgba(0,0,0,.12), 0 18px 34px rgba(30, 30, 20, .28); transition: background .25s var(--ease); }
.add-preview .sticker { right: 6%; bottom: 5%; width: 44%; min-width: 0; transform: rotate(-8deg); }
.have-list { display: flex; flex-direction: column; gap: 2px; margin: 8px 0 0; padding: 0; list-style: none; }
.have-row { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; padding: 6px; border: 0; border-radius: 9px; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.have-row:hover { background: rgba(79, 44, 29, .06); }
.have-row img, .have-blank { flex: none; width: 30px; height: 45px; border-radius: 2px; object-fit: cover; background: var(--chip); }
.have-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 500; line-height: 1.25; overflow-wrap: anywhere; }
.have-name small { display: block; font-size: 12px; font-weight: 400; color: var(--ink-3); }
.have-tag { flex: none; max-width: 45%; padding: 3px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; line-height: 1.3; text-align: center; }
.have-tag.is-have { background: #dfe6d2; color: #3f4e2c; }
.have-tag.is-lack { background: var(--butter); color: var(--cocoa); }
.have-tag.is-wish { background: #d8e4ec; color: #2f5068; }
.have-none { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px; font-size: 14px; color: var(--ink-2); }
.offline-pill { position: fixed; z-index: 20; left: 50%; top: 12px; transform: translateX(-50%); padding: 6px 14px; border-radius: 999px; background: var(--cocoa); color: var(--foam); font-size: 13px; white-space: nowrap; box-shadow: 0 4px 12px rgba(40, 30, 15, .25); }
.menu-seg { display: grid; grid-template-columns: repeat(3, 1fr); margin-bottom: 6px; padding: 3px; border-radius: 999px; background: var(--chip); }
.menu-seg button { min-height: 32px; padding: 0 6px; border: 0; border-radius: 999px; background: none; color: var(--ink-2); font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap; }
.menu-seg button[aria-pressed="true"] { background: var(--surface-solid); color: var(--ink); font-weight: 500; box-shadow: 0 1px 3px rgba(40, 30, 15, .2); }
.filter-row { grid-column: 1 / -1; }
.filter-clear { display: inline-flex; gap: 6px; align-items: center; max-width: 100%; min-height: 30px; padding: 3px 10px; border: 0; border-radius: 999px; background: var(--cocoa); color: var(--foam); font: inherit; font-size: 12px; cursor: pointer; }
.filter-clear span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.credit { padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px; transition: text-decoration-color .15s; }
.credit:hover, .credit:focus-visible { text-decoration-color: currentColor; }
.ask-note {
  position: absolute; z-index: 5; left: 50%; top: 50%; width: min(290px, calc(100vw - 48px)); padding: 16px 16px 12px; transform: translate(-50%, -56%) rotate(1.6deg);
  background: #fbf3b4; color: var(--cocoa); box-shadow: 0 10px 22px rgba(40, 30, 15, .28);
  font-family: "Sriracha", var(--font-body, sans-serif); animation: ask-in .5s cubic-bezier(.2, .9, .3, 1.2);
}
@keyframes ask-in { from { opacity: 0; transform: translate(-50%, -30%) rotate(-5deg) scale(.9); } }
.ask-q { margin: 0 0 6px; font-size: 19px; line-height: 1.3; }
.ask-stars { display: flex; gap: 2px; margin-bottom: 6px; }
.ask-stars button { display: grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 0; background: none; color: #d8c98a; cursor: pointer; }
.ask-stars button.on { color: var(--cocoa); }
.ask-stars .star { width: 26px; height: 26px; }
.ask-note textarea { display: block; width: 100%; padding: 6px 0; border: 0; border-bottom: 1.5px dashed #b7a56a; outline: 0; background: none; color: inherit; font: inherit; font-size: 16px; resize: none; }
.ask-note textarea::placeholder { color: #937f4f; }
.ask-date { display: flex; gap: 6px; align-items: center; margin-top: 8px; font-size: 14px; }
.ask-date input { min-width: 0; border: 0; background: none; color: inherit; font: inherit; font-size: 14px; }
.ask-acts { display: flex; justify-content: space-between; margin-top: 8px; }
.ask-acts button { min-height: 44px; padding: 0 8px; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: 15px; cursor: pointer; }
.ask-acts [data-ask="stick"] { color: var(--cocoa); font-size: 17px; text-decoration: underline; text-underline-offset: 3px; }
.paid-note {
  padding: 18px 16px 14px; background: var(--card); box-shadow: none; filter: drop-shadow(0 10px 18px rgba(40, 30, 15, .28));
  font-family: ui-monospace, "SF Mono", Menlo, var(--font); font-size: 13px; line-height: 1.5;
}
.paid-note::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 7px; background: linear-gradient(135deg, var(--card) 50%, transparent 50%) 0 0 / 12px 7px repeat-x, linear-gradient(225deg, var(--card) 50%, transparent 50%) 0 0 / 12px 7px repeat-x; }
.paid-close { position: absolute; right: 4px; top: 4px; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; background: none; color: var(--ink-2); cursor: pointer; }
.paid-head { margin: 0; font: 400 38px/1.1 var(--font-brand); letter-spacing: -.05em; text-align: center; }
.paid-date { margin: 2px 0 10px; padding-bottom: 10px; border-bottom: 1px dashed var(--cocoa); font-size: 12px; text-align: center; }
.paid-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.paid-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.paid-off { display: flex; gap: 6px; margin: 10px 0; }
.paid-off button { flex: 1; min-height: 44px; padding: 0; border: 1px dashed var(--cocoa); border-radius: 4px; background: none; color: inherit; font: inherit; cursor: pointer; }
.paid-off button[aria-pressed="true"] { border-style: solid; background: var(--cocoa); color: var(--foam); }
.paid-total { padding-top: 8px; border-top: 1px dashed var(--cocoa); font-size: 16px; font-weight: 600; }
.paid-price { display: flex; align-items: baseline; gap: 4px; }
.paid-price input { width: 96px; padding: 2px 0; border: 0; border-bottom: 1px solid var(--line); outline: 0; background: none; color: inherit; font: inherit; font-size: 22px; text-align: right; }
.paid-price input:focus { border-bottom-color: var(--cocoa); }
.paid-price input[aria-invalid] { border-bottom: 2px solid var(--cocoa); }
.paid-save { display: block; width: 100%; min-height: 44px; margin-top: 12px; border: 0; border-radius: 999px; background: var(--cocoa); color: var(--foam); font: 500 15px var(--font); cursor: pointer; }
.paid-bars { display: block; height: 26px; margin-top: 12px; background: repeating-linear-gradient(90deg, var(--cocoa) 0 2px, transparent 2px 4px, var(--cocoa) 4px 5px, transparent 5px 9px); }
.blind-book { position: relative; display: block; width: 100%; aspect-ratio: 2 / 3; filter: drop-shadow(0 3px 5px rgba(40, 30, 15, .28)); }
.blind-book::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(#f0e6cf, #f0e6cf) center / 3px 100% no-repeat, linear-gradient(#f0e6cf, #f0e6cf) 0 42% / 100% 3px no-repeat, url(assets/kraft.svg) center / cover, #c8a877;
  /* a hand-wrapped outline, not a clean rectangle */
  clip-path: polygon(0 .6%, 14% 0, 31% .9%, 52% .2%, 73% 1%, 88% .1%, 100% .7%, 99.2% 19%, 100% 38%, 98.9% 57%, 99.8% 78%, 99% 100%, 82% 99.2%, 61% 100%, 40% 99.1%, 21% 99.9%, .6% 99.3%, 1.1% 79%, 0 60%, .9% 39%, .2% 20%);
}
.blind-book .draw-mark { z-index: 1; }
.draw-mark { position: absolute; right: 8%; bottom: 3%; font: 400 clamp(38px, 12cqi, 72px)/1 var(--font-brand); color: rgba(79, 44, 29, .62); }
.draw { user-select: none; -webkit-user-select: none; width: 100vw; max-width: none; height: 100dvh; max-height: none; margin: 0; padding: 24px; border: 0; background: rgba(247, 246, 241, .94); color: var(--ink); }
.draw[open] { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; }
.draw::backdrop { background: rgba(30, 28, 24, .3); backdrop-filter: blur(10px); }
.draw-close { position: absolute; top: 12px; right: 12px; }
.draw-book { position: relative; width: min(58vw, 34dvh, 260px); aspect-ratio: 2 / 3; }
.draw-cover .cover { display: block; width: 100%; height: 100%; }
.draw-cover .cover img { width: 100%; height: 100%; object-fit: cover; }
.draw-paper { position: absolute; inset: 0; cursor: grab; touch-action: none; --pull: 0; --open: 0; }
/* two flaps of crumpled paper, folded back from the seam down the middle */
.draw-flap {
  position: absolute; top: -1%; bottom: -1%; width: 56%; backface-visibility: visible;
  background: url(assets/kraft.svg) left center / 179% 100%, #c8a877;
  opacity: calc(1.5 - var(--open) * 1.5);
}
.draw-flap::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(60, 35, 10, calc(var(--open) * .45)), transparent 55%); }
.draw-flap.is-left { left: -.5%; transform-origin: 0 50%; transform: perspective(600px) translateX(calc(var(--open) * -10%)) rotateY(calc(var(--open) * -118deg)) rotate(calc(var(--open) * -7deg)) scale(calc(1 - var(--open) * .22)); }
.draw-flap.is-right { right: -.5%; transform-origin: 100% 50%; transform: perspective(600px) translateX(calc(var(--open) * 10%)) rotateY(calc(var(--open) * 118deg)) rotate(calc(var(--open) * 9deg)) scale(calc(1 - var(--open) * .18)); background-position: right center; }
.draw-flap.is-right::after { background: linear-gradient(-90deg, rgba(60, 35, 10, calc(var(--open) * .45)), transparent 55%); }
/* the string comes away first: across slides off to the right, down drops out of the bottom */
.draw-string { position: absolute; background: #f0e6cf; box-shadow: 0 1px 1px rgba(60, 40, 15, .35); opacity: calc(1.6 - var(--pull) * 1.6); }
.draw-string.is-across { left: -3%; right: -3%; top: 42%; height: 4px; transform: translateX(calc(var(--pull) * 90%)) rotate(calc(var(--pull) * 7deg)); }
.draw-string.is-down { top: -3%; bottom: -3%; left: calc(50% - 2px); width: 4px; transform: translateY(calc(var(--pull) * 80%)) rotate(calc(var(--pull) * -6deg)); }
.draw-label { position: absolute; left: 50%; top: 30%; transform: translate(-50%, calc(var(--pull) * 240%)) rotate(calc(-3deg + var(--pull) * 24deg)); opacity: calc(1.4 - var(--pull) * 1.4); padding: 6px 12px; background: var(--foam); box-shadow: 0 1px 3px rgba(0, 0, 0, .25); font: 14px/1.35 "Sriracha", sans-serif; text-align: center; white-space: nowrap; }
.draw-ask, .draw-wrapped, .draw-open { display: none; flex-direction: column; align-items: center; gap: 8px; width: min(280px, 100%); text-align: center; }
.draw[data-state="ask"] .draw-ask, .draw[data-state="wrapped"] .draw-wrapped, .draw[data-state="open"] .draw-open { display: flex; }
.draw[data-state="ask"] .draw-book { display: none; }
.draw-ask h2 { margin: 0 0 12px; font: 400 30px/1.15 var(--font-brand); letter-spacing: -.03em; outline: 0; }
.draw-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; }
.draw-pick { min-height: 96px; padding: 8px; border: 1.5px dashed var(--cocoa); border-radius: 10px; background: none; color: var(--ink); font: 400 20px/1.2 "Sriracha", sans-serif; cursor: pointer; }
.draw-pick:active { background: var(--cocoa); color: var(--foam); }
.draw-wrapped .btn-main, .draw-open .btn-main { width: 100%; min-height: 46px; }
.draw-hint { margin: 0; font-size: 13px; color: var(--ink-3); }
.draw-open h2 { margin: 0; font-size: 20px; font-weight: 600; outline: 0; }
.draw-by { margin: 0 0 6px; font-size: 14px; color: var(--ink-2); }
.vol-series { justify-self: start; margin-top: 4px; }
.write-review { min-height: 32px; margin-left: 12px; padding: 2px 0; border: 0; border-bottom: 1px dashed currentColor; background: none; color: var(--ink-2); font: inherit; font-size: 13px; cursor: pointer; }
.cover-field { width: 100%; }
.add-preview-hint { margin: 0; font-size: 12px; color: var(--ink-3); text-align: center; }
.add-fields { display: flex; flex-direction: column; gap: 14px; padding: 20px 22px 26px 4px; min-width: 0; }
.field.naiin-field { padding: 12px; border-radius: 12px; background: var(--chip); }
.naiin-field > label { font-size: 13px; font-weight: 500; color: var(--ink-2); }
.naiin-row { display: flex; gap: 6px; }
.naiin-row input { flex: 1; min-width: 0; }
.naiin-field .field-note { padding: 0; align-self: start; }
.naiin-field .field-note:empty { display: none; }
.series-fields:not([hidden]) { display: grid; gap: 14px; }
.owned-head { display: flex; justify-content: space-between; align-items: center; width: 100%; }
.owned-all { min-height: 32px; padding: 0 4px; border: 0; background: none; color: var(--ink-2); font: inherit; font-size: 13px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.owned-pick .pick-item span { justify-content: center; min-width: 44px; min-height: 44px; padding: 0 8px; border-radius: 10px; }
.scan-btn { flex: none; display: grid; place-items: center; width: 42px; min-height: 42px; padding: 0; border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--cocoa); cursor: pointer; }
.scan-btn svg { width: 22px; height: 22px; }
.scan-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.share-btn svg { width: 19px; height: 19px; }
.share-sheet { width: min(460px, 100vw); }
.share-sheet[open] { display: flex; flex-direction: column; }
.share-step { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto; }
.share-step[hidden] { display: none; }
.share-sources { display: flex; flex-wrap: wrap; gap: 6px; padding: 14px 18px 0; }
.share-source { min-height: 40px; padding: 0 14px; border: 0; border-radius: 999px; background: var(--chip); color: var(--ink-2); font: inherit; font-size: 14px; cursor: pointer; }
.share-source[aria-pressed="true"] { background: var(--chip-active); color: var(--foam); }
.share-source:focus-visible, .share-date { padding: 12px 18px 0; }
.share-count { display: flex; justify-content: space-between; align-items: center; min-height: 44px; padding: 6px 18px 0; font-size: 14px; color: var(--ink-2); }
.share-count p { margin: 0; }
.share-books { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; flex: 1; align-content: start; margin: 0; padding: 6px 18px 16px; list-style: none; }
.share-book { position: relative; display: block; width: 100%; aspect-ratio: 2 / 3; padding: 0; overflow: hidden; border: 0; border-radius: var(--radius-cover); background: var(--chip); color: var(--ink-2); font: inherit; font-size: 11px; cursor: pointer; }
.share-book img { display: block; width: 100%; height: 100%; object-fit: cover; }
.share-book-name { display: block; padding: 6px; }
.share-book[aria-pressed="false"] img { opacity: .3; }
.share-tick { position: absolute; right: 4px; top: 4px; width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--foam); background: rgba(40, 30, 15, .35); }
.share-book[aria-pressed="true"] .share-tick { background: var(--cocoa) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f6f3e8' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.500 4.500 4.500L19 7.500'/%3E%3C/svg%3E") center / 14px no-repeat; }
.share-foot { position: sticky; bottom: 0; display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px calc(12px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); background: var(--surface-solid); }
.share-foot .btn-main { flex: 1; min-height: 48px; }
.share-foot .btn-main:disabled { opacity: .5; cursor: default; }
.share-preview { display: flex; justify-content: center; padding: 14px 18px 0; }
.share-preview canvas { display: block; height: min(46dvh, 460px); width: auto; border-radius: 10px; box-shadow: 0 8px 22px rgba(40, 30, 15, .22); }
.share-options { display: grid; gap: 12px; padding: 14px 18px; }
.scan-view { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--cocoa); }
.scan-view video { display: block; width: 100%; height: 100%; object-fit: cover; }
.scan-line { position: absolute; left: 10%; right: 10%; top: 50%; height: 2px; background: var(--butter); box-shadow: 0 0 8px var(--butter); }
.scan-note { margin: 0; padding: 14px 18px 18px; font-size: 14px; color: var(--ink-2); text-align: center; }
.pin-sheet { width: min(320px, calc(100vw - 32px)); padding: 22px; border: 0; border-radius: var(--radius-panel); background: var(--surface-solid); color: var(--ink); box-shadow: var(--shadow-panel); }
.pin-sheet::backdrop { background: rgba(30, 28, 24, .32); backdrop-filter: blur(6px); }
.pin-sheet h2 { margin: 0; font-size: 18px; font-weight: 500; }
.pin-note { margin: 4px 0 14px; font-size: 13px; color: var(--ink-3); }
.pin-input { box-sizing: border-box; width: 100%; min-height: 48px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--ink); font: inherit; font-size: 20px; letter-spacing: .3em; text-align: center; }
.pin-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.pin-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.pin-acts button { min-height: 44px; padding: 0 18px; }
.btn-soft { flex: none; min-height: 40px; padding: 0 14px; border: 0; border-radius: 10px; background: var(--cocoa); color: var(--foam); font: inherit; font-size: 14px; font-weight: 500; cursor: pointer; }
.btn-soft:disabled { opacity: .6; cursor: progress; }
.btn-soft:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.check[hidden], .field[hidden] { display: none; }
/* status: one row, like a switch */
.pick.pick-seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; padding: 3px; border-radius: 999px; background: var(--chip); }
.pick.pick-seg .pick-item span { display: block; min-height: 34px; line-height: 34px; padding: 0; text-align: center; border-radius: 999px; background: none; color: var(--ink-2); }
.pick.pick-seg .pick-item input:checked + span { background: var(--surface-solid); color: var(--ink); font-weight: 500; box-shadow: 0 1px 3px rgba(40, 30, 15, .2); }
/* search-and-pick */
.combo { position: relative; min-width: 0; }
.combo-box {
  display: flex; flex-wrap: wrap; align-items: center; gap: 5px; min-height: 42px; padding: 4px 8px; cursor: text;
  border: 1px solid var(--line); border-radius: 10px; background: var(--card);
}
.combo-box:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.combo-chips { display: contents; }
.combo-chip { display: inline-flex; align-items: center; gap: 2px; max-width: 100%; padding: 2px 3px 2px 10px; border-radius: 999px; background: var(--chip); font-size: 13px; overflow-wrap: anywhere; }
.combo-chip button { width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--ink-2); font: inherit; font-size: 15px; line-height: 1; cursor: pointer; }
.combo-chip button:hover { background: rgba(79, 44, 29, .12); }
.field .combo-box input { flex: 1; min-width: 60px; min-height: 32px; padding: 0 2px; border: 0; background: none; outline: none; color: var(--ink); font: inherit; font-size: 16px; border-radius: 0; }
.field .combo-box input:focus { outline: none; }
.combo-list {
  position: absolute; z-index: 5; left: 0; right: 0; top: calc(100% + 5px); max-height: 230px; overflow-y: auto; margin: 0; padding: 5px; list-style: none;
  border-radius: 12px; background: var(--surface-solid); box-shadow: 0 1px 2px rgba(40, 30, 15, .14), 0 12px 28px rgba(40, 30, 15, .22);
  animation: fade .12s var(--ease);
}
.combo-list[hidden] { display: none; }
.combo-list li { padding: 9px 10px; border-radius: 8px; font-size: 14px; cursor: pointer; overflow-wrap: anywhere; }
.combo-list li:hover, .combo-list li.is-active { background: var(--chip); }
.combo-list li.is-add { color: var(--accent); font-weight: 500; }
.combo-list .combo-empty { color: var(--ink-3); cursor: default; background: none; }
/* the add button floats over the shelf */
.fab {
  position: fixed; z-index: 6; right: 48px; bottom: 48px;
  display: grid; place-items: center; width: 54px; height: 54px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--powder); color: #fff; box-shadow: 0 2px 4px rgba(40, 30, 15, .25), 0 10px 24px rgba(40, 30, 15, .32);
  transition: scale .15s var(--ease), box-shadow .15s var(--ease);
}
.fab[hidden] { display: none; }
.fab svg { width: 30px; height: 30px; stroke-width: 1.7; overflow: visible; }
.fab-dot { fill: currentColor; stroke: none; }
.fab-plus { stroke: var(--powder); }
.fab:hover { scale: 1.05; }
.fab:active { scale: .94; }
.fab:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.field { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; border: 0; min-width: 0; }
.field > span, .field > legend { font-size: 13px; font-weight: 500; color: var(--ink-2); padding: 0; }
.field small, .check small { font-weight: 400; color: var(--ink-3); }
.field input {
  min-height: 42px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--card); color: var(--ink); font: inherit; font-size: 16px; /* 16px: no zoom on iOS */
}
.field input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
.field input[type="number"]::-webkit-inner-spin-button, .field input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.field input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.pick { display: flex; flex-wrap: wrap; gap: 6px; }
.pick-item { position: relative; }
.pick-item input { position: absolute; opacity: 0; pointer-events: none; }
.pick-item span {
  display: inline-flex; align-items: center; min-height: 34px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  background: var(--chip); color: var(--ink-2); font-size: 14px;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.pick-item input:checked + span { background: var(--chip-active); color: var(--foam); }
.pick-item input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.check { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--ink-2); cursor: pointer; }
.check input { width: 18px; height: 18px; accent-color: var(--cocoa); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.field textarea {
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; resize: vertical;
  background: var(--card); color: var(--ink); font: inherit; font-size: 16px; line-height: 1.5;
}
.field textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.field-note { margin: 0; align-self: end; padding-bottom: 10px; font-size: 13px; color: var(--ink-3); }
.after-fields { display: flex; flex-direction: column; gap: 14px; }
.form-error { margin: 0; min-height: 1.2em; font-size: 13px; color: #a2401f; }
.btn-main, .btn-quiet { min-height: 42px; padding: 0 20px; border: 0; border-radius: 999px; font: inherit; font-size: 15px; cursor: pointer; }
.btn-main { background: var(--cocoa); color: var(--foam); font-weight: 500; }
.btn-main:disabled { opacity: .6; cursor: progress; }
.btn-quiet { background: none; color: var(--ink-2); }
.btn-quiet:hover { background: var(--chip); }
.btn-main:focus-visible, .btn-quiet:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@keyframes fade { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; transform: scale(.98); } }

/* ---------- responsive ---------- */
@media (max-width: 760px) {
  .grid-note { order: 3; width: 100%; text-align: right; }
  .panel { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); margin: 8px 0; height: calc(100dvh - 16px); border-radius: 26px 26px 44px 44px; } /* phones: full width; the bottom corners follow the iPhone's own rounded screen */
  .rail { flex-direction: row; padding: 14px 18px; border-right: 0; border-bottom: 1px solid var(--line); }
  .brand { flex-direction: row; }
  .rail-foot { flex-direction: row-reverse; }
    .content { grid-column: 1; grid-row: 2; padding: 0 16px 116px; } /* room to scroll past the floating switch and the raised + */
  .sticky-head { margin: -1px -16px 0; padding: 6px 16px 0; }
  /* phone: one thin row, tabs on the left and tools on the right; Shelf/Wishlist floats at the bottom, by the thumb */
  .toolbar { container-type: normal; gap: 8px; padding-top: 2px; padding-bottom: 6px; } /* containment would trap the floating switch */
  /* phone: the main menu is a bar along the bottom of the panel, the + at its right end */
  .rail .mode-switch {
    position: fixed; z-index: 6; left: 0; right: 0; bottom: 8px; margin: 0;
    flex-direction: row; justify-content: space-around; gap: 0;
    padding: 6px 80px calc(10px + env(safe-area-inset-bottom)) 22px; border-radius: 0 0 44px 44px;
    border-top: 1px solid var(--line); background: var(--surface-solid);
  }
  .rail .mode { flex: 1; }
  .tools { margin-left: auto; }
  /* phone: the add form rises from the bottom */
  .add-sheet { width: 100vw; max-width: none; margin: auto 0 0; border-radius: 20px 20px 0 0; max-height: 94dvh; }
  #add-form { max-height: 94dvh; }
  .add-body { display: block; }
  .add-stage { position: static; padding: 20px 16px 8px; gap: 8px; }
  .add-preview { width: 128px; }
  .add-fields { padding: 12px 16px 28px; }
  /* phones: the + floats up over the bar's top edge */
  .fab { right: 22px; bottom: calc(42px + env(safe-area-inset-bottom)); width: 56px; height: 56px; box-shadow: 0 6px 14px rgba(40, 30, 15, .28); }
  .fab svg { width: 26px; height: 26px; }
  .status-tabs { justify-content: flex-start; margin-left: -8px; gap: 0; }
  .status-tabs:empty { display: none; }
  .tab { padding: 8px 8px; font-size: 14px; }
  .tab-ink { bottom: -7px; }
  /* the tabs and tools moved up: nothing left in this bar but the floating switch */
  .sticky-head { padding: 0; margin: 0; border: 0; background: none; box-shadow: none; }
  .toolbar { padding: 0; border: 0; min-height: 0; }
  .rail .tool-btn .filter-label { display: none !important; } /* the name shows on its own row above the books */
  /* phone: the tools live in the top row, beside refresh; search takes that row while it's open */
  .rail { position: relative; z-index: 7; }
  .rail-foot { gap: 4px; }
  .rail { gap: 10px; }
  .rail .status-tabs { flex: 1; min-width: 0; margin: 0 auto 0 0; }
  .rail.searching .brand, .rail.searching .status-tabs { display: none; }
  .rail.searching .rail-foot, .rail.searching .tools { flex: 1; min-width: 0; }
  .rail.searching .search, .rail .search:focus-within { flex: 1; width: auto; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 24px 14px; }
  .caption { font-size: 12.5px; }
  .shelf { grid-column: 1; grid-row: 1 / -1; z-index: 8; } /* a series page takes the whole panel, over the top row */
  .shelf-grid { padding-bottom: 116px; } /* scroll past the bottom bar */
  /* a series page covers the top row, but the bottom bar stays on top and tappable */
  body.has-shelf .rail { z-index: 9; pointer-events: none; border-bottom-color: transparent; }
  body.has-shelf .rail > :not(.mode-switch) { visibility: hidden; }
  body.has-shelf .rail .mode-switch { pointer-events: auto; }
  .shelf-head { padding: 14px 12px 14px 16px; gap: 10px; }
  .lift { padding: 72px 16px; place-items: center; } /* equal top and bottom, so the book and its title sit dead centre */
  .lift-close { top: 14px; right: 14px; }
  .lift-actions { top: 16px; right: 66px; }
  .lift-cover { width: min(62vw, calc(52dvh * 2 / 3)); }
  .book3d { --thick: calc(22px * var(--page-k, 1)); }
  /* phone: less room at the side, so it peeks less and comes further over the cover */
  .postit { --overlap: 130px; --peek: 24px; width: min(46vw, 170px); font-size: 13px; padding: 10px; }
  .shelf-info h2 { font-size: 19px; }
  .shelf-grid { padding: 20px 16px 32px; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 20px 12px; }
  .slot-no { font-size: 26px; }
}

@media (max-width: 720px) {
  .offline-pill { top: auto; bottom: calc(72px + env(safe-area-inset-bottom)); } /* phones: clear of the tabs, above the floating switch */
  .toast { right: auto; left: 50%; transform: translateX(-50%); bottom: calc(92px + env(safe-area-inset-bottom)); } /* phones: above the floating switch */
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* the display style: one weight and one spacing everywhere this font appears, set in em so they scale with the type.
   Thai falls back to Bai Jamjuree, which keeps its normal spacing and weight (.is-thai) */
:root { --display-track: -.075em; --display-stroke: .02em; }
.grid-head h2, .typo-title, .slot-no, .bm-word, .st-word {
  font-family: var(--font-brand); font-weight: 400; text-transform: lowercase;
  letter-spacing: var(--display-track); -webkit-text-stroke: var(--display-stroke) currentColor; paint-order: stroke fill;
}
.st-word { color: var(--cocoa); stroke: currentColor; stroke-width: var(--display-stroke); -webkit-text-stroke: 0; }
.typo-title.is-thai { letter-spacing: 0; -webkit-text-stroke: 0; font-style: italic; font-size: .86em; }

/* ---------- main menu: a column in the rail on a desktop (a bar along the bottom on a phone) ---------- */
.rail .mode { flex-direction: column; gap: 3px; min-height: 0; padding: 7px 6px; border-radius: 12px; font-size: 11px; font-weight: 400; }
@media (min-width: 761px) { .rail .mode-switch { flex-direction: column; gap: 6px; margin: 32px 0 auto; padding: 0; border-radius: 0; background: none; } }
.rail .mode svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.rail .mode[aria-pressed="true"] { background: var(--chip); box-shadow: none; font-weight: 500; }
body.is-reading .tools, body.is-reading .status-tabs { display: none; }
body.is-reading .sticky-head { display: none; } /* Reading has no tools: no empty top row, the desk starts at the top */
/* Reading: the desk is the whole page, edge to edge, top to bottom */
body.is-reading .content { padding: 0; }
body.is-reading .reading { display: flex; flex-direction: column; max-width: none; min-height: calc(100% - 1px); /* minus the 1px scroll marker above it, so a page that fits never scrolls */ margin: 0; padding: 0; }
body.is-reading .reading[hidden] { display: none; }
body.is-reading .desk { flex: 1; border-radius: 0; }
.bookmark[data-s="4"], .bm-card[data-s="4"], .desk-mark[data-s="4"] { --b0: var(--powder); --bm-ink: var(--cocoa); --bm-dot: rgba(79,44,29,.42); } /* reading */

/* ---------- reading: the open book lies on a desk, turned a little; the month below ---------- */
.reading { max-width: 560px; margin: 0 auto; padding: 16px 0 24px; }
.reading[hidden] { display: none; }
/* the desk: dark wood with a strip of fabric along the top (a sage band, cream polka dots, a scalloped coral trim);
   the book, its bookmark and the page note sit on it */
.desk {
  position: relative; padding: 0 16px 22px; border-radius: 16px; overflow: hidden;
  background:
    repeating-linear-gradient(178deg, rgba(0, 0, 0, .09) 0 2px, transparent 2px 13px),
    repeating-linear-gradient(181deg, rgba(255, 255, 255, .045) 0 1px, transparent 1px 7px),
    #6e4b32;
}
.desk::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 78px;
  background:
    linear-gradient(var(--sage), var(--sage)) top / 100% 22px no-repeat,
    radial-gradient(circle, rgba(255, 255, 255, .4) 1.2px, transparent 1.8px) 0 3px / 7px 8px repeat-x,
    radial-gradient(circle, rgba(255, 255, 255, .4) 1.2px, transparent 1.8px) 3.5px 10px / 7px 8px repeat-x,
    radial-gradient(circle, var(--powder) 2.6px, transparent 3.2px) 0 14px / 18px 18px,
    radial-gradient(circle, var(--powder) 2.6px, transparent 3.2px) 9px 23px / 18px 18px,
    #f7f1dc;
}
/* green lace under the sage band, then a white scalloped lace hanging onto the wood */
.desk::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 90px; pointer-events: none;
  background:
    radial-gradient(circle at 50% 0, var(--sage) 4px, transparent 4.6px) 0 22px / 10px 6px repeat-x,
    radial-gradient(circle, #e3dccd 1.3px, transparent 1.9px) 6px 73px / 12px 5px repeat-x,
    linear-gradient(#fff, #fff) 0 70px / 100% 9px no-repeat,
    radial-gradient(circle at 50% 0, #fff 6px, transparent 6.6px) 0 79px / 12px 8px repeat-x;
  filter: drop-shadow(0 2px 2px rgba(20, 10, 4, .25));
}
/* the page's heading: a cream label sewn onto the left of the fabric, stitched all round */
.desk-head {
  position: absolute; z-index: 3; left: 16px; top: 28px; margin: 0; padding: 2px 16px 4px;
  background: #fffdf6; border: 1.5px dashed #b98a68; outline: 3px solid #fffdf6;
  box-shadow: 0 3px 5px rgba(60, 40, 20, .25); transform: rotate(-2deg);
  font-family: var(--font-brand); font-weight: 400; font-size: 28px; line-height: 36px; text-transform: lowercase;
  letter-spacing: var(--display-track); -webkit-text-stroke: var(--display-stroke) currentColor; paint-order: stroke fill;
  color: var(--cocoa);
}
.desk-top { position: relative; display: grid; place-items: center; height: clamp(400px, 62dvh, 520px); padding: 124px 0 44px; box-sizing: border-box; }
.desk-spot.is-empty { height: clamp(260px, 44dvh, 380px); padding: 88px 0 0; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 12px; color: #f7f1dc; }
.desk-spot.is-empty p { margin: 0; }
.desk-cal { position: relative; margin-top: 8px; }
/* every open book is the same size, in one row; --off is its place from the middle (0 = the chosen one) */
.desk-book {
  --step: calc(100% + 26px);
  grid-area: 1 / 1; position: relative; z-index: 2; width: min(58%, 240px); padding: 0; border: 0; background: none; cursor: pointer;
  transform: translateX(calc(var(--off, 0) * var(--step))) rotate(-6deg); transition: transform .38s var(--ease);
}
.desk-book:not(.is-side):hover { transform: rotate(-4deg) translateY(-3px); }
.desk-book.is-side { z-index: 0; transform: translateX(calc(var(--off) * var(--step))) rotate(3deg); }
.desk-book.is-side:hover { transform: translateX(calc(var(--off) * var(--step))) rotate(1deg) translateY(-3px); }
.desk.is-sliding .desk-book { transform: translateX(calc(var(--off) * var(--step))) rotate(-2deg); }
.desk.is-sliding .desk-note { opacity: 0; transition: opacity .15s; }
.desk-cover { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: pointer; }
.desk-book .cover { display: block; border-radius: 2px 4px 4px 2px; box-shadow: 6px 12px 22px rgba(20, 10, 4, .5), 1px 2px 3px rgba(20, 10, 4, .3); }
.desk-book .cover img { display: block; width: 100%; }
/* the bookmark: the same printed one as in the book view, tucked in the same place with its top showing */
.desk-mark {
  position: absolute; z-index: -1; left: 9%; top: 0; width: 28%; height: 62%;
  display: flex; flex-direction: column; overflow: hidden; container-type: inline-size;
  color: var(--bm-ink); background: radial-gradient(circle, var(--bm-dot) .65px, transparent 1px) 0 0 / 3px 3px, var(--b0);
  border-radius: 4px 4px 2px 2px; transform: translateY(-34px);
}
.desk-mark .bm-word { align-self: flex-start; margin: 4px 0 0 4px; white-space: nowrap; }
/* the page note: a square sticky note, low on the right, tucked under the book with its number showing */
.desk-note {
  position: absolute; z-index: -1; right: -12%; bottom: -48px; width: 88px; height: 88px; padding: 0 7px 5px 0;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-end;
  border: 0; border-radius: 1px; background: var(--butter); color: var(--cocoa);
  font: 19px/1.15 "Sriracha", sans-serif; text-align: center; cursor: pointer;
  box-shadow: 1px 4px 8px rgba(20, 10, 4, .3); transform: rotate(10deg); transition: transform .2s var(--ease);
}
.desk-note b { display: block; font-weight: 400; }
.desk-note small { display: block; font-size: 13px; color: #7a6650; }
button.desk-note:hover { transform: rotate(11deg) translate(2px, 2px); }
/* tapped: it comes out from under the book and over it, big enough to write on, like the review note */
.desk-note.is-writing {
  z-index: 3; right: auto; bottom: auto; left: 50%; top: 50%; width: 170px; height: 170px; padding: 0 12px; gap: 4px; justify-content: center; align-items: stretch;
  font-size: 26px; cursor: auto; box-shadow: 0 1px 1px rgba(0,0,0,.06), 0 18px 30px -6px rgba(20, 10, 4, .5);
  transform: translate(-50%, -50%) rotate(4deg); animation: desk-note-out .45s var(--ease);
}
.desk-note.is-writing small { font-size: 16px; }
.desk-note.is-tucking { animation: desk-note-in .35s var(--ease); }
@keyframes desk-note-out { from { transform: translate(-50%, -50%) translate(70%, 60%) scale(.5) rotate(14deg); } }
@keyframes desk-note-in { from { transform: translate(-120%, -110%) scale(1.9) rotate(4deg); } }
.desk-note label { display: flex; align-items: baseline; justify-content: center; gap: 2px; }
.desk-note input { width: 80px; padding: 0 2px; border: 0; border-bottom: 1.5px solid var(--cocoa); background: transparent; color: var(--cocoa); font: inherit; font-size: 26px; text-align: center; -moz-appearance: textfield; }
.desk-note input::-webkit-inner-spin-button { -webkit-appearance: none; }
.desk-note input:focus { outline: none; border-bottom-color: var(--accent); }
.note-save { align-self: center; margin-top: 8px; padding: 5px 16px; border: 0; border-radius: 999px; background: var(--cocoa); color: #fff; font: 500 13px/1.4 var(--font); cursor: pointer; }
/* the month: a planner page, lined, with each book as a strip of washi tape across its days */
.timeline { margin-top: 0; }
.cal-page {
  position: relative; isolation: isolate; margin-top: 30px; padding: 26px 12px 16px; border-radius: 4px; background: #fffdf6;
  box-shadow: 0 2px 3px rgba(20, 10, 4, .25), 0 12px 24px rgba(20, 10, 4, .35);
}
/* the spiral binding along the top: thin silver coils, each through a punched hole */
.cal-rings { position: absolute; left: 18px; right: 18px; top: -13px; display: flex; justify-content: space-between; pointer-events: none; }
.cal-rings i {
  position: relative; width: 4px; height: 24px; border-radius: 3px;
  background: linear-gradient(90deg, #8d9196, #f4f5f6 45%, #c3c7cc 70%, #7c8085);
  box-shadow: 0 2px 2px rgba(60, 40, 20, .25);
}
.cal-rings i::before { content: ""; position: absolute; z-index: -1; left: -2px; bottom: 3px; width: 8px; height: 8px; border-radius: 50%; background: #4a3a2a; } /* the hole */
.tl-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding-left: 4px; }
.tl-head h2 {
  margin: 0; font-family: var(--font-brand); font-weight: 400; font-size: 30px; line-height: 1.1; color: var(--cocoa);
  letter-spacing: var(--display-track); -webkit-text-stroke: var(--display-stroke) currentColor; paint-order: stroke fill;
}
.tl-nav { display: flex; gap: 2px; }
.tl-head .tool-btn:disabled { opacity: .3; cursor: default; }
.cal-dow, .cal-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-dow { margin-top: 8px; padding-bottom: 4px; }
.cal-dow span { text-align: center; font-size: 11px; font-weight: 500; color: #a8977b; }
.cal-week { position: relative; border-top: 1px solid #efe5cf; }
.cal-day { position: relative; padding: 3px 4px; }
.cal-day + .cal-day { border-left: 1px dashed #f3ead6; }
.cal-day i { font-style: normal; font-size: 12px; color: #7a6650; font-variant-numeric: tabular-nums; }
.cal-day.is-today i { display: inline-block; margin: -2px -5px; padding: 1px 5px; border: 1.5px solid #d0306c; border-radius: 50%; color: var(--cocoa); }
.cal-tape {
  position: absolute; height: 16px; padding: 0 6px; box-sizing: border-box; overflow: hidden;
  font: 11.5px/16px "Sriracha", sans-serif; color: var(--cocoa); white-space: nowrap; text-overflow: ellipsis;
  background: repeating-linear-gradient(45deg, rgba(255, 255, 255, .32) 0 4px, transparent 4px 8px), var(--tape);
  clip-path: polygon(0 0, 100% 5%, 98.5% 50%, 100% 100%, 0 95%, 1.5% 50%); /* torn ends */
  opacity: .92; transform: rotate(-.6deg);
}
.cal-tape b { position: relative; font-weight: 400; }
.cal-tape.is-powder { --tape: var(--powder); } .cal-tape.is-sage { --tape: #a5b18f; } .cal-tape.is-coral { --tape: #e3a98f; } .cal-tape.is-butter { --tape: #ecd98a; }
.tl-empty { margin: 10px 0 0; text-align: center; font: 14px "Sriracha", sans-serif; color: #a8977b; }
/* tap a day: what was read that day, on a little note over the page */
button.cal-day { display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; /* number at the top, like the other days */ width: 100%; margin: 0; border: 0; border-radius: 0; background: none; font: inherit; text-align: left; cursor: pointer; }
button.cal-day i { text-decoration: underline dotted #c9b48f; text-underline-offset: 3px; }
button.cal-day[aria-expanded="true"] { background: rgba(236, 217, 138, .35); }
button.cal-tape { border: 0; margin: 0; cursor: pointer; z-index: 1; }
button.cal-tape:focus-visible, button.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cal-day.is-today.is-due i { border-style: dashed; } /* today is still waiting for a page */
.day-note {
  position: absolute; z-index: 4; top: 26px; min-width: 150px; max-width: 220px; padding: 8px 10px; box-sizing: border-box;
  background: #fffaf0; color: var(--cocoa); font: 13px/1.35 "Sriracha", sans-serif;
  box-shadow: 0 2px 3px rgba(20, 10, 4, .18), 0 8px 18px rgba(20, 10, 4, .22); transform: rotate(-1.5deg);
  animation: day-note-in .18s var(--ease);
}
.day-note p { margin: 0; } .day-note p + p { margin-top: 6px; }
.day-note em { display: inline-block; margin-bottom: 1px; font-style: normal; font-family: var(--font-brand); font-size: 17px; letter-spacing: var(--display-track); -webkit-text-stroke: var(--display-stroke) currentColor; } /* the title, in the same hand as "reading" */
.day-note b { font-weight: 400; color: #7593ab; } .day-note small { color: #8aa37a; font-size: 12px; }
@keyframes day-note-in { from { opacity: 0; transform: translateY(-4px) rotate(-1.5deg); } }
/* the day a book was finished: a little ink stamp in its square */
.cal-stamp {
  position: absolute; right: 3px; top: 2px; padding: 0 4px; border: 1.5px solid #c56b4c; border-radius: 999px;
  font: 10px/14px "Sriracha", sans-serif; color: #c56b4c; transform: rotate(-12deg); opacity: .85; pointer-events: none;
}
/* a week read every single day gets a big stamp at its end */
.week-stamp {
  position: absolute; z-index: 2; right: 4px; top: 50%; width: 40px; height: 40px; margin-top: -20px; border: 2px double #c56b4c; border-radius: 50%;
  display: grid; place-items: center; font: 14px "Sriracha", sans-serif; color: #c56b4c; transform: rotate(-14deg); opacity: .8; pointer-events: none;
}

/* this week's punch card: powder blue card stock, a big hand-lettered title running off its edges,
   seven cream ovals (one per day) and an eighth for the prize; a day read gets a star punched through */
.punch-card {
  position: relative; width: 200px; margin: 22px 0 0 auto; padding: 0 10px 10px; box-sizing: border-box;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .25  0 0 0 0 .2  0 0 0 0 .15  0 0 0 .55 -.12'/%3E%3C/filter%3E%3Crect width='100%' height='100%' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 140px, #a9c0d0; border-radius: 8px; /* card stock: a fine paper grain over the blue */
  box-shadow: 0 2px 3px rgba(20, 10, 4, .25), 0 10px 18px rgba(20, 10, 4, .3); --tilt: 3deg; transform: rotate(var(--tilt)); color: #fffaf0;
}
button.punch-card { display: block; border: 0; font: inherit; text-align: left; cursor: pointer; zoom: .9; } /* the card on the desk is 10% smaller; tap to pick it up */
button.punch-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.punch-title { /* cut off by the card's edges, like lettering printed past the trim */
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  margin: 0 -10px 4px; height: 38px; overflow: hidden; border-radius: 8px 8px 0 0; white-space: nowrap;
}
.punch-title span { font-family: var(--font-brand); font-size: 40px; line-height: 40px; margin: 0 -5px; letter-spacing: var(--display-track); }
.punch-holes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px 7px; }
.punch-day, .punch-prize { position: relative; display: grid; place-items: center; height: 21px; --star: polygon(50.0% 0.0%, 61.0% 30.9%, 89.8% 27.0%, 72.0% 50.0%, 93.3% 75.0%, 61.0% 69.1%, 50.0% 97.0%, 39.0% 69.1%, 7.6% 74.5%, 28.0% 50.0%, 11.0% 27.5%, 39.0% 30.9%); }
.punch-day b {
  grid-area: 1 / 1; display: grid; place-items: center; width: 100%; height: 100%; box-sizing: border-box;
  border: 1.5px solid #4a3a2a; border-radius: 50%; background: #fffaf0;
  font: 400 12px/1 "Sriracha", sans-serif; color: #4a3a2a;
}
.punch-day.is-today b { border: 1.5px dashed #c56b4c; color: #c56b4c; } /* today's oval, waiting for its punch */
.punch-day i { grid-area: 1 / 1; width: 27px; height: 27px; clip-path: var(--star); background: linear-gradient(160deg, #36241a, #5a3d28); visibility: hidden; } /* the hole: the desk shows through */
.punch-day.is-punched i { visibility: visible; }
.punch-prize { border: 1.5px dashed #fffaf0; border-radius: 50%; box-sizing: border-box; font: 11px "Sriracha", sans-serif; color: #fffaf0; }
.punch-prize.is-won { border: 2px double #c56b4c; background: #fffaf0; color: #c56b4c; transform: rotate(-8deg); } /* a full week: the prize slot gets its stamp */
@media (prefers-reduced-motion: no-preference) {
  /* punch: the hole snaps open and its paper circle drops onto the desk */
  .punch-day.is-new i { animation: punch .32s cubic-bezier(.3, 1.6, .5, 1) .25s backwards; }
  .punch-day.is-new::after { /* the star cut out of the oval, tumbling onto the desk */
    content: ""; position: absolute; left: calc(50% - 13.5px); top: -3px; width: 27px; height: 27px; clip-path: var(--star); background: #fffaf0;
    animation: chad 1.1s cubic-bezier(.4, 0, .7, 1) .25s both;
  }
  .punch-card:has(.is-new) { animation: card-jolt .3s ease-out .25s; }
  .punch-prize.is-new { animation: stamp-down .5s cubic-bezier(.3, 1.4, .5, 1) .9s backwards; }
}
@keyframes punch { from { transform: scale(0) rotate(-40deg); } }
@keyframes chad { 0% { transform: none; opacity: 1; } 70% { opacity: 1; } 100% { transform: translate(26px, 120px) rotate(200deg) scale(.9); opacity: 0; } }
@keyframes card-jolt { 30% { transform: rotate(var(--tilt)) translateY(3px) scale(.98); } }
@keyframes stamp-down { 0% { transform: scale(2.4) rotate(-40deg); opacity: 0; } 60% { transform: scale(.9) rotate(-10deg); opacity: .9; } }

/* desktop: the book on the left, the planner on the right, sharing one centre line;
   this week's punch card is tucked behind the planner, peeking out over its top-right edge */
@media (min-width: 761px) {
  .reading { max-width: 1040px; }
  .desk { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: 0 28px; padding: 100px 28px 40px; } /* the card may overlap the fabric; book and planner stay centred on the desk */ /* room at the top for the card peeking over the planner */
  .desk-cal { position: relative; } /* the card sticks out above it without taking space, so book and planner stay centred together */
  .desk-cal .cal-page { position: relative; z-index: 3; margin-top: 0; } /* in front of the card; its rings too */
  .punch-card { position: absolute; z-index: 2; top: -114px; right: 28px; margin: 0; padding-bottom: 24px; --tilt: 3deg; } /* blank strip at the bottom: the part tucked behind the planner */
  .desk-top { height: auto; padding: 45px 0 35px; } /* even above and below, so the cover's centre is the column's centre: level with the planner's */
  .desk-book { width: min(72%, 290px, calc((100dvh - 290px) / 1.5)); } /* shorter screens: a smaller book, still no scrolling */
  .desk-book { --step: calc(-100% - 26px); }
  .desk-book.is-side, .desk-book.is-side:hover, .desk.is-sliding .desk-book { transform: translateX(calc(var(--d) * var(--step))) rotate(3deg); } /* others line up to its left */
  .desk-book.is-side ~ .desk-book:not(.is-side) { margin-left: 40%; } /* with others beside it, it moves over to make room */
}

/* the full-width desk: room under the phone's bottom bar; on wide screens its contents stay a readable width */
/* short desktop windows: a little less desk around the edges, so it still fits without scrolling */
@media (min-width: 761px) and (max-height: 700px) { body.is-reading .desk { padding-top: 88px; padding-bottom: 24px; } .desk-cal { zoom: .85; } } /* the planner and its card shrink a little too */
@media (max-width: 760px) { body.is-reading .desk { padding-bottom: 116px; } }
/* phone: the card sits centred just above the planner, its bottom edge tucked behind the planner's page */
@media (max-width: 760px) {
  .desk-cal { display: flex; flex-direction: column; }
  .desk-cal .cal-page { z-index: 1; }
  .punch-card { order: -1; z-index: 0; margin: 18px auto -36px; padding-bottom: 32px; }
}
@media (min-width: 761px) { body.is-reading .desk { padding-inline: max(28px, calc((100% - 1040px) / 2)); } }
@media (min-width: 761px) { body.is-reading .desk-head { left: max(28px, calc((100% - 1040px) / 2)); } } /* lines up with the desk's contents */
/* picked up to look at: the whole book leaves the desk, bookmark and page note too */
.desk-book.is-lifted .desk-mark, .desk-book.is-lifted .desk-note { visibility: hidden; }

/* the card picked up: centred over a dim desk, bigger and straight; tap anywhere to put it back */
.card-view {
  position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  background: rgba(30, 22, 14, .55); cursor: pointer; animation: fade .2s var(--ease);
}
.card-view:focus { outline: none; }
.card-view.is-closing { animation: fade-out .16s var(--ease) forwards; }
.card-view-card { zoom: 1.6; }
.card-view .punch-card { position: relative; inset: auto; order: 0; margin: 0; padding-bottom: 12px; --tilt: -2deg; animation: card-pick .3s cubic-bezier(.2, .8, .2, 1); }
.card-view-note { margin: 0; font: 18px "Sriracha", sans-serif; color: #fffaf0; }
@keyframes card-pick { from { transform: rotate(4deg) scale(.6); opacity: 0; } }
@media (max-width: 380px) { .card-view-card { zoom: 1.4; } }
