/* ---- design tokens -------------------------------------------------- */
:root {
  --bg: #f6f5f2;
  --surface: #ffffff;
  --surface-2: #efedea;
  --border: #e4e1db;
  --ink: #1c1a17;
  --muted: #74706a;
  --accent: #c0552f;
  --accent-hover: #a8492a;
  --accent-ink: #ffffff;
  --accent-weak: rgba(192, 85, 47, .10);
  --ok: #2f6b46;
  --err: #b23b2e;
  --warn-bg: #fbeecc;
  --warn-ink: #7a4f05;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.05);
  --shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.07);
  --radius: 16px;
  --radius-sm: 11px;
  --bar: rgba(255,255,255,.78);
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #17161a;
    --surface: #232127;
    --surface-2: #2b2930;
    --border: #38353d;
    --ink: #f0ede8;
    --muted: #a39e98;
    --accent: #e07a52;
    --accent-hover: #ec8a64;
    --accent-ink: #1a120d;
    --accent-weak: rgba(224, 122, 82, .16);
    --ok: #6fcf97;
    --err: #f08b7e;
    --warn-bg: #3a3320;
    --warn-ink: #f0d68a;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.3);
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.45);
    --bar: rgba(25,24,28,.72);
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }
h1 { letter-spacing: -.02em; }

/* ---- top bar -------------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .7rem clamp(1rem, 4vw, 1.5rem);
  padding-top: max(.7rem, env(safe-area-inset-top));
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.brand {
  display: inline-flex; align-items: center; gap: .5rem;
  color: var(--ink); font-weight: 700; font-size: 1.08rem;
  text-decoration: none; letter-spacing: -.01em;
}
.brand::before { content: "📚"; font-size: 1.15rem; }
.topbar nav { display: flex; align-items: center; gap: .35rem; }
.topbar nav a {
  color: var(--muted); text-decoration: none; font-size: .92rem; font-weight: 500;
  padding: .4rem .7rem; border-radius: 999px; transition: background .15s, color .15s;
}
.topbar nav a:hover { color: var(--ink); background: var(--surface-2); }
.topbar nav a.on { color: var(--accent); background: var(--accent-weak); }

main { max-width: 920px; margin: 0 auto; padding: clamp(1rem, 4vw, 1.6rem);
  padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }

/* Section headers for grouped sort (author / title / year). */
.group { margin: 1.5rem 0 .5rem; font-size: .8rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted); }
.group:first-of-type { margin-top: .25rem; }

/* Bottom icon nav (matches the other apps). */
.bottom-nav { position: fixed; bottom: 0; left: 0; right: 0; z-index: 20; display: flex;
  background: var(--surface); border-top: 1px solid var(--border);
  padding: 4px 4px env(safe-area-inset-bottom, 0px); }
.bottom-nav a { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; text-decoration: none; color: var(--muted); font-size: 11px; font-weight: 500;
  padding: 8px 4px; min-height: 54px; border-radius: var(--radius-sm); }
.bottom-nav a.active { color: var(--accent); }
.bottom-nav svg { width: 22px; height: 22px; }

/* ---- forms / cards -------------------------------------------------- */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1.2rem;
  display: flex; flex-direction: column; gap: .8rem;
  box-shadow: var(--shadow-sm);
}
label { display: flex; flex-direction: column; gap: .3rem; font-size: .8rem; font-weight: 500; color: var(--muted); }
input, select, textarea {
  font: inherit; color: var(--ink); width: 100%;
  padding: .6rem .7rem; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); transition: border-color .15s, box-shadow .15s;
}
input::placeholder { color: var(--muted); opacity: .8; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}
textarea { resize: vertical; }
.row { display: flex; gap: .8rem; }
.row > label { flex: 1; }

button, .btn {
  font: inherit; font-weight: 600; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  border: 1px solid transparent; border-radius: 999px;
  padding: .6rem 1.15rem; background: var(--surface-2); color: var(--ink);
  text-decoration: none; transition: background .15s, border-color .15s, transform .05s;
}
button:active, .btn:active { transform: translateY(1px); }
button.primary, button[type="submit"], .btn.primary {
  background: var(--accent); color: var(--accent-ink);
}
button.primary:hover, button[type="submit"]:hover, .btn.primary:hover { background: var(--accent-hover); }
button.ghost, .btn.ghost { background: transparent; border-color: var(--border); color: var(--ink); }
button.ghost:hover, .btn.ghost:hover { background: var(--surface-2); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }

.auth { max-width: 340px; margin: 12vh auto 0; }
.auth h1 { margin-top: 0; }
.err { color: var(--err); margin: 0; font-size: .9rem; }
.ok  { color: var(--ok); margin: 0; }
.warn { color: var(--warn-ink); background: var(--warn-bg); padding: .55rem .75rem; border-radius: var(--radius-sm); margin: 0; font-size: .9rem; }

/* ---- library: filters ---------------------------------------------- */
.filters { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; margin-bottom: 1.3rem; }
.search {
  flex: 1 1 13rem; display: flex; align-items: center; gap: .5rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 0 .85rem; transition: border-color .15s, box-shadow .15s;
}
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-weak); }
.search .search-icon { flex: 0 0 auto; color: var(--muted); display: flex; }
.search input[type="search"] {
  flex: 1; border: 0; background: transparent; padding: .58rem 0; min-width: 0;
}
.search input[type="search"]:focus { outline: none; box-shadow: none; }
.search input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.searchclear {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; border-radius: 999px;
  color: var(--muted); text-decoration: none; font-size: 1.2rem; line-height: 1;
}
.searchclear:hover { background: var(--surface-2); color: var(--ink); }
.filters select { width: auto; border-radius: 999px; padding-block: .55rem; }
.filters > button { width: auto; }

.count, .empty { color: var(--muted); font-size: .92rem; }
.count { margin: 0 0 1rem; }
.empty { text-align: center; padding: 4rem 1rem; }

/* ---- library: grid -------------------------------------------------- */
.grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1.3rem;
  grid-template-columns: repeat(auto-fill, minmax(135px, 1fr));
}
.book a { text-decoration: none; color: inherit; display: block; }
.cover {
  position: relative; display: block; aspect-ratio: 2/3;
  border-radius: 12px; overflow: hidden; background: var(--surface-2);
  box-shadow: var(--shadow); transition: transform .18s ease, box-shadow .18s ease;
}
.book a:hover .cover { transform: translateY(-4px); box-shadow: 0 12px 30px rgba(0,0,0,.16); }
.cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nocover {
  display: flex; align-items: center; justify-content: center; text-align: center;
  width: 100%; height: 100%; padding: .6rem; font-size: .82rem; font-weight: 600; color: var(--muted);
}
.copies {
  position: absolute; top: 8px; right: 8px;
  background: rgba(0,0,0,.65); color: #fff; font-size: .72rem; font-weight: 600;
  padding: .12rem .45rem; border-radius: 999px; backdrop-filter: blur(4px);
}
.book .meta { display: block; margin-top: .55rem; }
.book .t { display: block; font-size: .88rem; font-weight: 600; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.book .a { display: block; font-size: .79rem; color: var(--muted); margin-top: .1rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.book.read-read .cover::after {
  content: "✓"; position: absolute; top: 8px; left: 8px;
  width: 1.4rem; height: 1.4rem; display: flex; align-items: center; justify-content: center;
  background: var(--ok); color: #fff; border-radius: 999px; font-size: .8rem; font-weight: 700;
}

/* ---- scan ----------------------------------------------------------- */
.scanwrap { margin-bottom: 1.2rem; }
#scanner {
  position: relative; background: #000; border-radius: var(--radius);
  overflow: hidden; aspect-ratio: 3/4; max-height: 62vh; display: none;
  box-shadow: var(--shadow);
}
#scanner.live { display: block; }
#video { width: 100%; height: 100%; object-fit: cover; }
.reticle {
  position: absolute; inset: 26% 12%; border: 2px solid rgba(255,255,255,.9);
  border-radius: 12px; box-shadow: 0 0 0 100vmax rgba(0,0,0,.35);
}
.scanbar { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: .9rem; align-items: center; }
.manual { display: flex; gap: .5rem; flex: 1 1 14rem; }
.manual input { flex: 1; border-radius: 999px; }
.manual button { width: auto; }
.status { color: var(--muted); min-height: 1.4em; margin: .7rem 0 0; font-size: .9rem; }

.confirm .confirmhead { display: flex; gap: 1rem; }
.confirm .preview { width: 96px; height: 144px; flex: 0 0 96px;
  border-radius: 10px; overflow: hidden; background: var(--surface-2); box-shadow: var(--shadow-sm); }
.confirm .preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.confirm .cfields { flex: 1; display: flex; flex-direction: column; gap: .6rem; }
.isbnline { color: var(--muted); font-size: .82rem; margin: 0; }

/* ---- detail --------------------------------------------------------- */
.detail .ok { margin-bottom: 1rem; }
/* flex-start, not the default stretch: the cover box now takes its height from
   the image, and stretching would pad it out to match the facts column. */
.detailhead { display: flex; gap: 1.4rem; align-items: flex-start; }

/* The detail page shows the WHOLE cover.
   The grid keeps a fixed 2/3 crop, because a grid of uniform tiles is the point
   there. Here there is exactly one cover and no alignment to preserve, so
   forcing it into 2/3 only did one thing: cut the edges off every book that is
   not that shape — and almost none are. Paperbacks run nearer 2/3, hardbacks
   and art books are squarer, and the stored covers on the server range from
   0.61 to 0.73 wide-over-tall.
   No fixed ratio and no object-fit: the box takes the image's own proportions,
   so nothing is cropped and nothing is letterboxed either. */
/* `flex: 0 0 auto`, NOT `0 0 150px`. flex-basis sizes the MAIN axis, and the
   480px breakpoint below turns .detailhead into a column — at which point a
   basis of 150px stops meaning "150 wide" and starts meaning "150 TALL". With
   the width set to 160px there, the box came out 160x150: square, on the only
   device anybody reads this on. That, not the 2/3 ratio, is what was cropping
   the covers. With `auto` the basis defers to the width, and the height comes
   from the image in both directions. */
.cover.big { flex: 0 0 auto; width: 170px; aspect-ratio: auto; }
.cover.big img { width: 100%; height: auto; object-fit: contain; }
/* The no-cover placeholder has no image to take a shape from, so it keeps the
   book-ish default rather than collapsing to nothing. */
.cover.big .nocover { aspect-ratio: 2/3; height: auto; }
.facts h1 { margin: 0 0 .25rem; font-size: 1.4rem; line-height: 1.2; }
.facts .sub { margin: 0 0 .4rem; color: var(--muted); }
.facts .by { margin: 0 0 .7rem; font-weight: 600; }
.facts dl { display: grid; grid-template-columns: auto 1fr; gap: .25rem .9rem; margin: 0; font-size: .9rem; }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; }
.detail details { margin-top: 1.3rem; border-top: 1px solid var(--border); padding-top: .8rem; }
.detail summary { cursor: pointer; font-weight: 600; padding: .3rem 0; list-style: none; }
.detail summary::-webkit-details-marker { display: none; }
.detail summary::before { content: "▸ "; color: var(--muted); }
.detail details[open] summary::before { content: "▾ "; }
.desc p { color: var(--ink); }
.inlineform { margin-top: .9rem; }
.fetchhint { margin: -.2rem 0 0; }
button.small, .btn.small { padding: .4rem .8rem; font-size: .82rem; font-weight: 500; }
.coveredit { display: flex; gap: 1rem; align-items: flex-start; }
.coveredit .thumb { flex: 0 0 72px; width: 72px; height: 108px; border-radius: 8px; overflow: hidden; background: var(--surface-2); }
.coveredit .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.coveredit .coverctrls { flex: 1; display: flex; flex-direction: column; gap: .5rem; }
.coveredit input[type="file"] { font-size: .85rem; padding: .4rem; }
label.inline { flex-direction: row; align-items: center; gap: .45rem; font-size: .85rem; color: var(--ink); }
label.inline input { width: auto; }

.danger { margin-top: 1.5rem; border: 0; padding: 0; }
.danger button { background: transparent; color: var(--err); border: 1px solid var(--border); }
.danger button:hover { border-color: var(--err); background: var(--accent-weak); }

@media (max-width: 480px) {
  .detailhead { flex-direction: column; align-items: center; text-align: center; }
  /* 190px is chosen against the stored covers, not picked for looks: Google's
     scans are 575 px wide, which is exactly what a DPR 3 phone needs to draw
     190 CSS px sharply. Going wider would outrun the source. */
  .cover.big { width: 190px; }
  .facts dl { text-align: left; }
  .row { flex-direction: column; }
}
