  /* ---------- tutorial ---------- */
  .tut-card{text-align:center;}
  .tut-card .tut-ico{font-size:46px; margin:8px 0 4px;}
  .tut-dots{display:flex; gap:6px; justify-content:center; margin:14px 0 4px;}
  .tut-dots span{width:8px; height:8px; border-radius:50%; background:var(--line);}
  .tut-dots span.on{background:var(--focus);}

  /* ---------- community ---------- */
  .rev-card{background:var(--card); border:1px solid var(--line); border-radius:14px;
    padding:12px 14px; margin-bottom:10px; box-shadow:var(--shadow); display:flex; gap:12px;}
  .rev-card .bd{flex:1; min-width:0;}
  .rev-meta{font-size:11.5px; color:var(--muted); margin-top:6px;}
  .rev-text{font-size:13.5px; margin-top:6px; line-height:1.5;}
  .divider{display:flex; align-items:center; gap:10px; color:var(--muted); font-size:12px; margin:14px 0;}
  .divider::before,.divider::after{content:""; flex:1; height:1px; background:var(--line);}
  .linklike{background:none; border:none; color:var(--accent-dark); font-size:13px;
    text-decoration:underline; cursor:pointer; font-family:var(--sans); padding:4px;}
  .fmt-list{display:flex; flex-direction:column; gap:6px;}
  .fmt-row{display:flex; gap:10px; align-items:baseline; font-size:12.5px; color:var(--muted);
    background:var(--accent-soft); border-radius:9px; padding:8px 11px;}
  .fmt-row b{color:var(--ink); font-family:var(--sans); flex:0 0 84px; font-size:12.5px;}
  .decor-pick{display:flex; flex-wrap:wrap; gap:8px;}
  .decor-pick button{font-size:24px; padding:8px 10px; border-radius:12px; border:2px solid var(--line);
    background:var(--card); cursor:pointer;}
  .decor-pick button.on{border-color:var(--accent); background:var(--accent-soft);}
  /* accessibility */
  :focus-visible{outline:3px solid var(--focus); outline-offset:2px; border-radius:6px;}
  /* --focus is an accent tuned against the PAGE surfaces; the header is the banner surface,
     which the user can set to any colour - including the accent itself, which made the ring on
     Settings/Sign in exactly 1:1 and invisible to keyboard users. --on-deep is already derived
     to clear 4.5:1 on whatever banner is in play, so it is a safe indicator here. */
  header :focus-visible{outline-color:var(--on-deep);}
  .mini{min-height:40px;}
  @media (prefers-reduced-motion: reduce){
    *, *::before, *::after{animation:none !important; transition:none !important;}
  }
  /* logo: books on a plate */
  /* logo mark: a machined tile (nested bezel — inset highlight over a warm well)
     instead of the old floating cream ellipse, which read as a dish in night mode */
  .logo{position:relative; display:inline-flex; align-items:center; justify-content:center;
    margin-right:10px; width:34px; height:34px; vertical-align:-9px; border-radius:10px;
    background:linear-gradient(150deg,#6b4a26,#3d250e);
    border:1px solid rgba(224,165,49,.35);
    box-shadow:inset 0 1px 0 rgba(255,235,205,.3), inset 0 -2px 4px rgba(0,0,0,.35), 0 2px 6px rgba(0,0,0,.3);}
  /* the plate under the books — it's called Bookplate — sitting inside the tile,
     books resting ON it rather than floating */
  .logo .pl{position:absolute; bottom:5px; left:50%; transform:translateX(-50%);
    width:24px; height:7px; border-radius:50%;
    background:radial-gradient(ellipse at 50% 30%, #fdf6e8, #c9ba9c);
    box-shadow:0 1px 2px rgba(0,0,0,.45);}
  .logo .bk{position:relative; z-index:1; font-size:16px; margin-bottom:3px;
    filter:drop-shadow(0 2px 2px rgba(0,0,0,.35));}
  .logo.big{display:flex; width:84px; height:84px; margin:4px auto 14px; border-radius:24px;}
  .logo.big .pl{width:56px; height:15px; bottom:12px;}
  .logo.big .bk{font-size:40px; margin-bottom:8px;}
  .reads-line{margin-top:7px; font-size:12px; color:var(--accent-dark); font-weight:600;}
  .mood-wrap{display:flex; flex-wrap:wrap; gap:7px;}
  .mood{border:1px solid var(--line); background:var(--card); border-radius:20px; padding:8px 13px;
    font-size:12.5px; cursor:pointer; font-weight:600; color:var(--muted); font-family:var(--sans);}
  .mood.on{background:var(--accent); color:#fff; border-color:var(--accent);}
  .why-line{margin-top:6px; font-size:11.5px; color:var(--accent-dark); font-weight:600;}

  /* social feed: friends' activity, each card tinted by its book (--tint) */
  .feed-card{position:relative; border:1px solid var(--line); border-radius:var(--r-card);
    padding:12px 14px; margin-bottom:10px; overflow:hidden;
    background:linear-gradient(180deg, var(--card), var(--surface-2));
    box-shadow:inset 0 1px 0 rgba(255,255,255,.5), var(--e1);}
  body.dark .feed-card{box-shadow:inset 0 1px 0 rgba(255,240,214,.05), var(--e1);}
  .feed-card::before{content:""; position:absolute; inset:0 auto 0 0; width:4px;
    background:var(--tint, var(--accent)); opacity:.75;}
  .feed-line{display:flex; align-items:center; flex-wrap:wrap; gap:6px; font-size:13px; color:var(--muted);}
  .feed-line b{color:var(--ink); font-weight:600;}
  .feed-ava{width:26px; height:26px; border-radius:50%; background:var(--accent-soft);
    color:var(--accent-dark); font-weight:700; font-size:13px; display:inline-flex;
    align-items:center; justify-content:center; text-transform:uppercase; flex:none;}
  .feed-when{margin-left:auto; font-size:11px; color:var(--faint);}
  .feed-body{display:flex; gap:12px; align-items:center; margin:8px 0 0 32px;}
  .feed-cov{width:40px; height:60px; object-fit:cover; border-radius:3px 6px 6px 3px;
    transform:perspective(400px) rotateY(-8deg);
    box-shadow:4px 5px 10px rgba(58,40,23,.28);}
  body.dark .feed-cov{box-shadow:4px 5px 12px rgba(0,0,0,.5);}
  .feed-auth{font-size:12px; color:var(--muted); margin-top:2px;}
  .feed-favs{display:flex; gap:8px; margin:8px 0 0 32px;}
  .feed-favs img,.feed-favspine{width:38px; height:57px; border-radius:3px 5px 5px 3px;
    object-fit:cover; box-shadow:3px 4px 8px rgba(58,40,23,.25), 0 0 0 1.5px var(--gold);}
  .feed-favspine{display:inline-flex; align-items:center; justify-content:center;
    background:linear-gradient(160deg,#dcc9ae,#ac8b66); font-weight:700; color:#fff; font-family:var(--serif);}

  /* Four Favorites: cover-forward hero tiles, gold-trimmed — the shrine row */
  .fav-row{display:grid; grid-template-columns:repeat(4, 1fr); gap:12px; margin-bottom:16px;}
  .fav-tile{cursor:pointer; text-align:center; padding:10px 6px 8px; border-radius:var(--r-card);
    background:linear-gradient(180deg, var(--card), var(--surface-2));
    border:1px solid var(--line);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.55), var(--e1);
    transition:transform var(--dur-micro) var(--ease-out), box-shadow var(--dur-micro) var(--ease-out);}
  body.dark .fav-tile{box-shadow:inset 0 1px 0 rgba(255,240,214,.06), var(--e1);}
  @media (hover:hover){
    .fav-tile:hover{transform:translateY(-3px); box-shadow:inset 0 1px 0 rgba(255,255,255,.55), var(--e2);}
    .fav-tile:hover .cov{transform:perspective(520px) rotateY(-3deg);}
  }
  .fav-tile .cov{width:64px; height:96px; margin:0 auto; font-size:26px;
    box-shadow:5px 7px 14px rgba(58,40,23,.28), inset -3px 0 6px rgba(0,0,0,.16), 0 0 0 2px var(--gold);}
  body.dark .fav-tile .cov{box-shadow:5px 7px 16px rgba(0,0,0,.5), inset -3px 0 6px rgba(0,0,0,.3), 0 0 0 2px var(--gold);}
  .fav-tile .fav-ttl{margin-top:8px; font-size:11px; font-weight:600; color:var(--muted);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .chip.love{background:#f6dfe3; color:#b0435a; font-weight:700;}
  body.dark .chip.love{background:#42232a; color:#e0919f;}
  @media (max-width:420px){ .fav-row{gap:8px;} .fav-tile .cov{width:52px; height:78px;} }

  /* cards: nested depth — a hairline shell, an inset top highlight (light catching
     the card's upper edge) and layered soft shadow, so the middle of the page reads
     as physical objects resting on the desk rather than flat rectangles */
  .card{background:linear-gradient(180deg, var(--card), var(--surface-2));
    border:1px solid var(--line); border-radius:16px;
    padding:12px; margin-bottom:11px; cursor:pointer;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.55), var(--e2);
    display:flex; gap:13px;
    transition:transform var(--dur-micro) var(--ease-out), box-shadow var(--dur-micro) var(--ease-out);}
  body.dark .card{box-shadow:inset 0 1px 0 rgba(255,240,214,.06), var(--e2);}
  @media (hover:hover){
    .card:hover{transform:translateY(-2px); box-shadow:inset 0 1px 0 rgba(255,255,255,.55), var(--e3);}
    body.dark .card:hover{box-shadow:inset 0 1px 0 rgba(255,240,214,.06), var(--e3);}
    .card:hover .cov{transform:perspective(520px) rotateY(-4deg);}
  }
  .card:active{transform:scale(.985);}
  /* covers stand like physical books: a slight page-side tilt, spine shading,
     and a cast shadow that lifts them off the card */
  .cov{width:54px; height:80px; flex:none; border-radius:4px 8px 8px 4px; overflow:hidden;
    background:linear-gradient(160deg,#dcc9ae,#ac8b66); display:flex; align-items:center;
    justify-content:center; font-size:22px;
    transform:perspective(520px) rotateY(-9deg);
    box-shadow:5px 7px 14px rgba(58,40,23,.28), inset -3px 0 6px rgba(0,0,0,.16);
    transition:transform var(--dur-enter) var(--ease-out);}
  body.dark .cov{box-shadow:5px 7px 16px rgba(0,0,0,.5), inset -3px 0 6px rgba(0,0,0,.3);}
  .cov img{width:100%; height:100%; object-fit:cover; display:block;}
  /* fast progress entry sheet (updateProgress) */
  .prog-now{font-family:var(--serif); font-weight:700; font-size:var(--fs-title); text-align:center; margin:8px 0 12px;}
  .prog-now .prog-pct{font-family:var(--sans); font-weight:600; font-size:var(--fs-small); color:var(--muted);}
  #ovProgress input[type=range]{width:100%; margin:6px 0 2px; accent-color:var(--accent);}
  .prog-incs{display:flex; gap:var(--s2); justify-content:center; margin:12px 0 14px;}
  .prog-incs .mini{flex:1; text-align:center; min-height:44px;}
  .prog-lbl{display:block; font-size:var(--fs-small); color:var(--muted); margin-bottom:4px;}
  /* one canonical signed-out CTA (signInPrompt) - tappable, opens the account sheet */
  .signin-cta{display:inline-flex; align-items:center; gap:7px; min-height:44px;
    padding:9px 16px; border:none; border-radius:var(--r-ctrl); cursor:pointer;
    font-family:var(--sans); font-size:var(--fs-body); font-weight:700; color:#fff;
    background:linear-gradient(160deg, var(--accent), var(--accent-dark)); box-shadow:var(--e1);}
  .signin-cta svg{width:16px; height:16px;}
  @media (hover:hover){ .signin-cta:hover{filter:brightness(1.05);} }
  .signin-cta:active{transform:translateY(1px);}

  /* onboarding wizard (identity.js: cup -> name -> import) */
  .ob-sheet h3{text-align:center;}
  .ob-dots{display:flex; gap:7px; justify-content:center; margin:2px 0 14px;}
  .ob-dots span{width:7px; height:7px; border-radius:50%; background:var(--line-strong);}
  .ob-dots span.on{background:var(--accent); transform:scale(1.15);}
  .ob-cup{height:190px; display:flex; align-items:center; justify-content:center; margin:4px 0 10px; position:relative;}
  .ob-cup .cup-wrap, .ob-cup canvas{max-height:190px;}
  .ob-swatches{display:flex; flex-wrap:wrap; gap:10px; justify-content:center; margin:0 0 16px;}
  .ob-swatches button{width:34px; height:34px; border-radius:50%; border:2px solid var(--line);
    cursor:pointer; padding:0; box-shadow:var(--e1);}
  .ob-swatches button.on{border-color:var(--ink); box-shadow:0 0 0 3px var(--accent-soft), var(--e1);}
  .ob-actions{display:flex; flex-direction:column; gap:10px; margin-bottom:14px;}
  /* guest-mode affordance (cloud sheet, signed out): honest, not a broken/empty state */
  .guest-note{display:flex; align-items:center; gap:8px; margin:0 0 12px; padding:9px 12px;
    background:var(--accent-soft); border-radius:var(--r-ctrl); color:var(--accent-dark);
    font-size:var(--fs-small); font-weight:600;}
  .guest-note svg{flex:none;}
  /* branded placeholder cover: title-on-spine (or book glyph) when a cover is missing
     or fails to load - never an empty box or a bare emoji */
  .cov-ph{padding:5px 4px; text-align:center; color:var(--accent-dark);
    background:linear-gradient(160deg, #e6d3b6, #b8946a);}
  body.dark .cov-ph{background:linear-gradient(160deg,#4a3a28,#2e2317); color:var(--gold);}
  .cov-ph .cov-ph-t{font-family:var(--serif); font-weight:600; font-size:9px; line-height:1.2;
    max-height:100%; overflow:hidden; display:-webkit-box; -webkit-line-clamp:5; -webkit-box-orient:vertical;}
  .cov-ph svg{width:22px; height:22px; opacity:.65;}
  .card .bd{flex:1; min-width:0;}
  .card .ttl{font-family:var(--serif); font-weight:600; font-size:16px; line-height:1.25;}
  /* The library card title is a real <button> (the card div must NOT be role=button: it
     contains interactive children, which that role forbids). Strip the UA button chrome;
     the global :focus-visible rule supplies the ring. */
  .card button.ttl{background:none; border:0; padding:0; margin:0; color:inherit;
    text-align:left; width:100%; cursor:pointer; display:block;}
  .card .auth{color:var(--muted); font-size:13px; margin-top:2px;}
  .card .meta{display:flex; flex-wrap:wrap; gap:5px 8px; margin-top:8px; font-size:12px;
    color:var(--muted); align-items:center;}
  .chip{background:var(--accent-soft); color:var(--accent-dark); border-radius:20px;
    padding:2.5px 10px; font-size:11px; font-weight:600;}
  .chip.g-light{background:#e6efdb; color:#456132;}
  .chip.g-medium{background:#f7ecd2; color:#82590e;}
  .chip.g-serious{background:#f3dfdf; color:var(--serious);}
  .chip.fmt{background:#eae4f2; color:#6b5b95;}
  .chip.untag{background:#eee9df; color:#a99a86; font-weight:500;}
  .stars{color:var(--gold); font-size:13.5px; letter-spacing:1.5px; white-space:nowrap;}
  .stars .num{color:var(--muted); font-size:12px; margin-left:4px; letter-spacing:0; font-weight:600;}
  .notes-line{margin-top:7px; font-size:12.5px; color:#77685a; font-style:italic; line-height:1.4;}

  .fab{position:fixed; right:18px; bottom:calc(92px + env(safe-area-inset-bottom)); z-index:15;
    width:56px; height:56px; border-radius:50%; border:none;
    background:linear-gradient(135deg,var(--accent),var(--accent-dark)); color:#fff;
    font-size:30px; line-height:1; box-shadow:0 6px 16px rgba(138,74,36,.45); cursor:pointer;}
  .fab:active{transform:scale(.93);}

  /* modal sheet */
  .overlay{display:none; position:fixed; inset:0; background:rgba(43,33,24,.5);
    z-index:30; backdrop-filter:blur(2px);}
  .overlay.open{display:block;}
  .sheet{position:fixed; left:0; right:0; bottom:0; max-height:92vh; overflow-y:auto;
    background:var(--bg); border-radius:22px 22px 0 0;
    padding:20px 18px calc(26px + env(safe-area-inset-bottom));
    z-index:31; max-width:640px; margin:0 auto; box-shadow:0 -8px 30px rgba(43,33,24,.3);
    animation:up .22s ease;}
  @keyframes up{from{transform:translateY(40px); opacity:.5;} to{transform:none; opacity:1;}}
  .sheet h3{font-family:var(--serif); margin:0 0 14px; font-size:var(--fs-h3); line-height:var(--lh-tight); font-weight:700;}
  .grabber{width:38px; height:4px; border-radius:2px; background:#d6c9b4; margin:-8px auto 12px;}

  .fld{margin-bottom:12px;}
  /* Field titles only. A checkbox caption is a sibling label, not a title, so it
     must be excluded explicitly — scoping to the direct child alone is not enough,
     because .checkline sits at the same level. */
  .fld > label:not(.checkline){display:block; font-size:11px; font-weight:700; color:var(--muted);
    margin-bottom:5px; text-transform:uppercase; letter-spacing:.6px;}
  /* Checkboxes are not text fields — width:100% + 11px padding made them look broken. */
  .fld input:not([type=checkbox]),.fld select,.fld textarea{width:100%; padding:11px 13px;
    border:1px solid var(--line); border-radius:11px; font-size:15px; background:var(--card);
    color:var(--ink); font-family:var(--sans);}
  .checkline{display:flex; align-items:flex-start; gap:9px; font-size:13.5px; line-height:1.45;
    color:var(--ink); cursor:pointer; text-transform:none; font-weight:400; letter-spacing:0;
    margin-bottom:0;}
  .checkline input[type=checkbox]{width:18px; height:18px; flex:0 0 18px; margin:1px 0 0;
    accent-color:var(--accent); cursor:pointer;}
  /* settings groups */
  .sgroup{border:1px solid var(--line); border-radius:13px; margin-bottom:9px; background:var(--card);
    overflow:hidden;}
  .sgroup > summary{list-style:none; cursor:pointer; padding:13px 14px; font-weight:700; font-size:13.5px;
    display:flex; align-items:center; gap:9px; user-select:none; color:var(--ink);}
  .sgroup > summary::-webkit-details-marker{display:none;}
  .sgroup > summary::after{content:"\203A"; margin-left:auto; font-size:19px; opacity:.45;
    transform:rotate(90deg); transition:transform .16s;}
  .sgroup[open] > summary::after{transform:rotate(-90deg);}
  .sgroup[open] > summary{border-bottom:1px solid var(--line);}
  .sbody{padding:14px 14px 4px;}
  .sbody .fld:last-child{margin-bottom:10px;}
  .ghint{font-size:11.5px; color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;}
  /* auth panel */
  .auth-h{margin:0 0 4px; font-family:var(--serif); font-size:var(--fs-h3); line-height:var(--lh-tight);}
  .auth-note{font-size:12px; color:var(--muted); background:var(--accent-soft); border-radius:9px;
    padding:9px 11px; margin-top:10px; line-height:1.45;}
  .auth-note.ok{color:var(--ink);}
  .auth-links{display:flex; justify-content:space-between; gap:10px; margin-top:12px;}
  .auth-links .linklike{width:auto; padding:4px 0;}
  .fld input:focus,.fld textarea:focus{outline:2px solid var(--accent-soft); border-color:var(--accent);}
  .fld textarea{min-height:70px; resize:vertical;}
  .row2{display:flex; gap:10px;} .row2 .fld{flex:1;}
  .seg{display:flex; border:1px solid var(--line); border-radius:11px; overflow:hidden; background:var(--card);}
  .seg button{flex:1; padding:10px 4px; border:none; background:none; font-size:12.5px;
    color:var(--muted); cursor:pointer; font-family:var(--sans); font-weight:500;}
  .seg button.on{background:var(--accent); color:#fff; font-weight:700;}
  .seg.wrap{flex-wrap:wrap;}
  .seg.wrap button{flex:1 1 42%; padding:11px 4px;}

  /* db search inside sheets */
  .dbsearch{background:var(--accent-soft); border:1px solid #e7cfb4; border-radius:14px;
    padding:12px; margin-bottom:16px;}
  .dbsearch .lbl{font-size:11px; font-weight:700; color:var(--accent-dark);
    text-transform:uppercase; letter-spacing:.6px; margin-bottom:7px;}
  /* wrap on narrow phones: with three controls (input + Search + Scan) a 320px
     viewport clipped the last button off-sheet (Codex, UX-1 review) */
  .dbsearch .row{display:flex; gap:8px; flex-wrap:wrap;}
  .dbsearch input{flex:1 1 140px; min-width:0; padding:10px 12px; border:1px solid #e0c8ab; border-radius:10px;
    font-size:14px; background:#fff; font-family:var(--sans);}
  .dbsearch .go{border:none; background:var(--accent); color:#fff; border-radius:10px;
    padding:0 16px; font-size:14px; font-weight:700; cursor:pointer; font-family:var(--sans);}
  .db-status{font-size:12.5px; color:var(--accent-dark); margin-top:8px;}
  .db-res{display:flex; gap:10px; align-items:center; background:#fff; border:1px solid #ecd9c2;
    border-radius:11px; padding:8px 10px; margin-top:8px; cursor:pointer;}
  .db-res:active{background:#faf3ea;}
  .db-res .rc{width:34px; height:50px; border-radius:4px; overflow:hidden; flex:none;
    background:linear-gradient(160deg,#dcc9ae,#ac8b66); display:flex; align-items:center;
    justify-content:center; font-size:15px;}
  .db-res .rc img{width:100%; height:100%; object-fit:cover;}
  .db-res .rt{font-size:13.5px; font-weight:600; font-family:var(--serif); line-height:1.2;}
  .db-res .rm{font-size:11.5px; color:var(--muted); margin-top:2px;}

  .star-input{display:flex; align-items:center; gap:2px; font-size:31px; user-select:none;}
  .star-input span{position:relative; cursor:pointer; color:#dfd3bf;}
  .star-input span .fill{position:absolute; left:0; top:0; overflow:hidden; color:var(--gold);
    pointer-events:none; width:0;}
  .star-input .val{font-size:15px; color:var(--muted); margin-left:8px; min-width:34px; font-weight:600;}

  .btnrow{display:flex; gap:9px; margin-top:16px;}
  .btn{flex:1; padding:13px; border-radius:13px; border:none; font-size:15px; font-weight:700;
    cursor:pointer; font-family:var(--sans);}
  .btn.primary{background:linear-gradient(135deg,var(--accent),var(--accent-dark)); color:#fff;
    box-shadow:0 3px 10px rgba(138,74,36,.3);}
  .btn.ghost{background:none; border:1.5px solid var(--line); color:var(--muted);}
  .btn.danger{background:none; border:1.5px solid #dcb6b6; color:var(--serious); flex:0 0 auto; padding:13px 15px;}
  .btn.move{background:#4c6741; color:#fff;}

  /* picker */
  .pick-grid{display:grid; grid-template-columns:1fr 1fr; gap:13px; margin-top:10px;}
  .pick-grid button{border:none; border-radius:18px; padding:28px 10px; font-size:17px;
    font-weight:700; cursor:pointer; color:#fff; font-family:var(--serif);
    box-shadow:0 5px 14px rgba(58,40,23,.22); transition:transform .1s;}
  .pick-grid button:active{transform:scale(.96);}
  .pick-grid .small{display:block; font-size:11.5px; font-weight:500; margin-top:6px;
    opacity:.9; font-family:var(--sans);}
  .pk-light{background:linear-gradient(135deg,#7fa268,#5c7f48);}
  .pk-medium{background:linear-gradient(135deg,#d9a032,#b47e18);}
  .pk-serious{background:linear-gradient(135deg,#b05959,#8c3d3d);}
  .pk-any{background:linear-gradient(135deg,#4a3421,#2b1d10);}
  .pick-result{margin-top:20px; text-align:center; display:none;
    background:linear-gradient(180deg, var(--card), var(--surface-2));
    border:1px solid var(--line); border-radius:var(--r-sheet); padding:24px 18px;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.5), var(--e2);
    animation:pop .3s cubic-bezier(.2,1.4,.5,1);}
  body.dark .pick-result{box-shadow:inset 0 1px 0 rgba(255,240,214,.06), var(--e2);}
  @keyframes pop{from{transform:scale(.85); opacity:0;} to{transform:scale(1); opacity:1;}}
  .pick-result .prcov{width:92px; height:138px; margin:0 auto 14px; border-radius:9px;
    overflow:hidden; background:linear-gradient(160deg,#dcc9ae,#ac8b66); display:none;
    align-items:center; justify-content:center; font-size:34px; box-shadow:0 6px 16px rgba(58,40,23,.3);}
  .pick-result .prcov img{width:100%; height:100%; object-fit:cover;}
  .pick-result .pr-ttl{font-family:var(--serif); font-size:22px; font-weight:700; line-height:1.2;}
  .pick-result .pr-auth{color:var(--muted); margin-top:5px; font-size:14px;}
  .pick-result .pr-note{font-style:italic; font-size:13px; color:#77685a; margin-top:9px;}
  .pick-result .btnrow{margin-top:20px;}

  /* stats */
  .stat-grid{display:grid; grid-template-columns:1fr 1fr; gap:11px;}
  .stat{background:var(--card); border:1px solid var(--line); border-radius:16px;
    padding:16px 12px; text-align:center; box-shadow:var(--shadow);}
  .stat .big{font-size:26px; font-weight:700; font-family:var(--serif); color:var(--accent-dark);}
  .stat .lbl{font-size:10.5px; color:var(--muted); margin-top:4px; text-transform:uppercase;
    letter-spacing:.6px; font-weight:600;}
  .bar-row{display:flex; align-items:center; gap:9px; margin-bottom:8px; font-size:13px;}
  .bar-row .bl{width:112px; color:var(--muted); text-align:right; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; font-weight:500;}
  .bar-row .bar{height:15px; background:linear-gradient(90deg,var(--accent),var(--accent-dark));
    border-radius:5px; min-width:3px;}
  .bar-row .bn{color:var(--muted); font-weight:600;}
  .empty{color:var(--muted); text-align:center; padding:36px 12px; font-size:14px; line-height:1.5;}
  .empty .big-em{font-size:34px; display:block; margin-bottom:8px;}

  /* composed empty state (emptyState() in icons.js): icon · heading · subtext · CTA,
     centered and breathing on mobile */
  .empty-state{display:flex; flex-direction:column; align-items:center; text-align:center;
    padding:var(--s8) var(--s5); gap:var(--s2);}
  .empty-state.compact{padding:var(--s4) var(--s3);}
  .empty-state .es-ico{color:var(--faint); line-height:0; margin-bottom:var(--s1);}
  .empty-state .es-ico svg{width:40px; height:40px;}
  .empty-state .es-title{font-family:var(--serif); font-weight:700; font-size:var(--fs-h3);
    line-height:var(--lh-tight); color:var(--ink);}
  .empty-state .es-text{font-size:var(--fs-small); line-height:var(--lh-body); color:var(--muted);
    max-width:32ch;}
  .empty-state .es-cta{margin-top:var(--s3); border:none; border-radius:var(--r-ctrl);
    padding:11px 20px; font-size:var(--fs-body); font-weight:700; font-family:var(--sans);
    color:#fff; background:linear-gradient(160deg, var(--accent), var(--accent-dark));
    box-shadow:var(--e1); cursor:pointer; min-height:44px;}
  @media (hover:hover){ .empty-state .es-cta:hover{filter:brightness(1.05);} }
  .empty-state .es-cta:active{transform:translateY(1px);}
  .section-card{background:var(--card); border:1px solid var(--line); border-radius:16px;
    padding:15px; margin-top:14px; box-shadow:var(--shadow);}
  .section-card h4{margin:0 0 11px; font-size:11.5px; text-transform:uppercase;
    letter-spacing:.7px; color:var(--muted); font-weight:700;}

  /* ---------- social layer 2: notifications · DMs · comments · visiting ---------- */
  .notif-badge{position:absolute; top:-5px; right:-5px; min-width:16px; height:16px;
    border-radius:8px; background:var(--serious); color:#fff; font-size:10px; font-weight:700;
    display:inline-flex; align-items:center; justify-content:center; padding:0 4px;}
  #notifBell{position:relative;}
  .notif-row{display:flex; align-items:center; gap:9px; padding:10px 11px; margin-bottom:7px;
    background:linear-gradient(180deg, var(--card), var(--surface-2));
    border:1px solid var(--line); border-radius:var(--r-card); font-size:13px; cursor:pointer;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.4), var(--e1);}
  body.dark .notif-row{box-shadow:inset 0 1px 0 rgba(255,240,214,.05), var(--e1);}
  .notif-row .nbody{flex:1; min-width:0;}
  .notif-row.read{opacity:.55;}
  .notif-row.done{opacity:.4; pointer-events:none;}

  .cmt{margin:10px 0 0 calc(var(--d, 0) * 16px); padding:10px 12px;
    border-left:3px solid var(--line-strong); border-radius:4px var(--r-ctrl) var(--r-ctrl) 4px;
    background:linear-gradient(180deg, var(--card), var(--surface-2));}
  .cmt-head{display:flex; align-items:center; gap:7px; font-size:12.5px; color:var(--muted);}
  .cmt-head b{color:var(--ink);}
  .cmt-head .feed-ava{width:22px; height:22px; font-size:11px;}
  .cmt-text{font-size:13.5px; line-height:1.5; margin:6px 0 4px; color:var(--ink);}
  .cmt-reply{font-size:11.5px; padding:0;}
  .cmt-compose{display:flex; gap:8px; margin-top:12px;}
  .cmt-compose.inline{margin:8px 0 4px;}
  .cmt-compose input{flex:1; padding:10px 13px; border:1px solid var(--line); border-radius:12px;
    background:var(--card); color:var(--ink); font-family:var(--sans); font-size:13.5px;}

  /* announcement banner (NOTIFY-1): in-flow strip under the header, pushes content
     down rather than overlaying it - the fixed visit-banner keeps z-order priority */
  .announce-banner{display:flex; gap:10px; align-items:center; justify-content:center;
    flex-wrap:wrap; padding:9px 14px; background:var(--accent-soft);
    border-bottom:1px solid var(--line); color:var(--ink); font-size:13.5px;
    text-align:center; line-height:1.45;}
  .announce-banner a{color:var(--accent-dark); font-weight:600;}
  .announce-banner .mini{flex:0 0 auto;}

  /* ESC-1: every ordinary sheet gets a visible named Close pinned to its top
     corner - phones have no Escape key and Done buttons sink below the fold.
     Sticky, not absolute: the sheet itself scrolls, and an absolute button
     rides its content out of view - sticky stays glued to the visible top. */
  .sheet-x{position:sticky; top:2px; float:right; margin:0 0 -34px;
    width:34px; height:34px; border-radius:50%; border:1px solid var(--line);
    background:var(--card); color:var(--muted); font-size:15px; line-height:1;
    cursor:pointer; z-index:5; box-shadow:var(--e1);}
  .sheet-x:hover{color:var(--ink); border-color:var(--line-strong);}

  .visit-banner{position:fixed; top:0; left:0; right:0; z-index:60; display:flex; gap:10px;
    align-items:center; justify-content:center; flex-wrap:wrap; padding:10px 14px;
    padding-top:calc(10px + env(safe-area-inset-top));
    background:linear-gradient(135deg, var(--gold), #8a5f14); color:#fff8ea;
    font-size:13.5px; font-weight:600; box-shadow:0 3px 14px rgba(0,0,0,.3);}
  .visit-banner .mini{background:rgba(255,255,255,.18); color:#fff;}
  .feed-actions{display:flex; gap:16px; margin:9px 0 0 32px;}
  .feed-actions .linklike{font-size:12px; padding:2px 0; text-decoration:none; font-weight:600;}
  .rev-card.clickable{cursor:pointer; transition:transform var(--dur-micro) var(--ease-out);}
  @media (hover:hover){ .rev-card.clickable:hover{transform:translateY(-1px);} }
  .star-input .starnum{width:64px; border:1px solid var(--line); border-radius:8px;
    background:var(--card); color:var(--ink); font-family:var(--sans); font-weight:700;
    font-size:14px; padding:6px 8px; text-align:center;}

  /* Compact circular FAB (Codex design ruling, Batch A #5): the labeled "+ Add book"
     pill duplicated the toolbar Add button and read as an accident. Reduce the FAB to
     an icon-only circular "+" — a persistent shortcut — while the labeled toolbar
     button stays the primary action. The base .fab above defines the 56px circle. */
  .fab{display:flex; align-items:center; justify-content:center;}
  .fab .fab-plus{font-size:30px; line-height:1;}
  .fab .fab-label{display:none;}

  /* cup designer: the preview sits at the top and SCROLLS with the options. It used to
     be sticky-pinned, but in this narrow sheet a pinned cup sat on top of whatever
     control row scrolled behind it — the middle Shape/Color buttons hid behind the cup.
     Scrolling it away keeps every option fully readable (the cup stays in view while you
     pick shape/color, which sit right beneath it). */
  #cupPreview{margin-bottom:6px;}

  /* shelf designer docks LEFT on wide screens so the real shelf (your live
     preview, on the right) stays in view while you design */
  @media (min-width:1180px){
    #ovShelf{background:rgba(43,33,24,.18);}
    #ovShelf .sheet{left:24px; right:auto; top:76px; bottom:auto; width:420px;
      max-height:calc(100vh - 110px); border-radius:var(--r-sheet);
      animation:fade .2s ease;}
  }

  /* ---------- friends & privacy (facelifted) ---------- */
  .id-card{display:flex; gap:12px; align-items:center; padding:12px 14px; margin-bottom:10px;
    background:linear-gradient(180deg, var(--card), var(--surface-2));
    border:1px solid var(--line); border-radius:var(--r-card);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.5), var(--e1);}
  body.dark .id-card{box-shadow:inset 0 1px 0 rgba(255,240,214,.05), var(--e1);}
  .id-ava{width:44px; height:44px; font-size:20px; border:2px solid var(--gold);}
  .id-info{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px;}
  .id-info > b{font-family:var(--serif); font-size:16px;}
  .id-user{font-size:13.5px; color:var(--accent-dark); font-weight:700;}
  .id-hint{font-size:11px; color:var(--faint);}
  .id-edit{display:flex; gap:6px; margin-top:2px;}
  .id-edit input{flex:1; min-width:0; padding:8px 11px; border:1px solid var(--line); border-radius:10px;
    background:var(--card); color:var(--ink); font-family:var(--sans);}
  .priv-note{font-size:var(--fs-small); color:var(--muted); margin:2px 2px 8px; line-height:var(--lh-snug);}
  /* safety (4B): report link on content */
  .rev-report{font-size:11px; color:var(--faint); text-decoration:underline; padding:0 2px;}
  /* read-only visited home (4C): hide every edit affordance while visiting a friend.
     Search + sort stay (reading their shelf); only mutating controls are removed. */
  body.visiting #tab-library .toolbar .autotag,
  body.visiting #tab-library .toolbar .mini,
  body.visiting #tab-tbr .toolbar .autotag,
  body.visiting #tab-tbr .toolbar .mini,
  /* The visiting rules originally covered only the library/TBR tabs, so mutating
     controls on OTHER tabs stayed visible while inside a friend's home (Explore's
     +TBR, the Stats goal editor, the taste quiz, the header name-edit). Cover them. */
  body.visiting #tab-explore .mini,
  body.visiting #tab-explore .autotag,
  body.visiting #tab-stats .goal-edit,
  body.visiting #tab-stats .section-card button,
  body.visiting #tasteBtn,
  body.visiting #appTitle,
  body.visiting #tab-library .card .mini-row,
  body.visiting #tab-tbr .card .mini-row,
  body.visiting .card .selc,
  body.visiting #fab { display:none !important; }
  .priv-card{border:1px solid var(--line); border-radius:var(--r-card); overflow:hidden; margin-bottom:10px;
    background:var(--card);}
  .switch-row{display:flex; align-items:center; justify-content:space-between; gap:12px;
    padding:11px 14px; cursor:pointer;}
  .switch-row + .switch-row{border-top:1px solid var(--line);}
  .sw-text{display:flex; flex-direction:column; gap:1px; font-size:13.5px;}
  .sw-text span{font-size:11.5px; color:var(--muted);}
  .switch{position:relative; flex:none; width:44px; height:26px;}
  .switch input{position:absolute; opacity:0; inset:0; margin:0; cursor:pointer;}
  .switch i{position:absolute; inset:0; border-radius:13px; background:var(--line-strong);
    transition:background var(--dur-micro) var(--ease-out);}
  .switch i::after{content:""; position:absolute; top:3px; left:3px; width:20px; height:20px;
    border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.3);
    transition:transform var(--dur-micro) var(--ease-out);}
  .switch input:checked + i{background:var(--accent);}
  .switch input:checked + i::after{transform:translateX(18px);}
  .add-row{display:flex; gap:7px; flex-wrap:wrap;}
  .add-row input{flex:1; min-width:150px; padding:9px 12px; border:1px solid var(--line);
    border-radius:10px; background:var(--card); color:var(--ink); font-family:var(--sans);}

  /* ---------- custom color chips ---------- */
  .colchips{display:flex; flex-wrap:wrap; gap:8px; align-items:stretch;}
  .colchip{display:flex; align-items:center; gap:8px; padding:8px 12px; cursor:pointer;
    border:1px solid var(--line); border-radius:12px;
    background:linear-gradient(180deg, var(--card), var(--surface-2));
    box-shadow:inset 0 1px 0 rgba(255,255,255,.5), var(--e1);}
  body.dark .colchip{box-shadow:inset 0 1px 0 rgba(255,240,214,.05), var(--e1);}
  .colchip .cc-ico{font-size:16px;}
  .colchip .cc-name{font-size:12px; font-weight:600; color:var(--muted);}
  .colchip input[type=color]{width:26px; height:26px; border:none; background:none; padding:0;
    border-radius:50%; overflow:hidden; cursor:pointer;}
  .colchip input[type=color]::-webkit-color-swatch-wrapper{padding:0;}
  .colchip input[type=color]::-webkit-color-swatch{border:2px solid var(--line-strong); border-radius:50%;}

  /* ---------- backdrop picker ---------- */
  .backdrop-pick{display:flex; flex-wrap:wrap; gap:8px;}
  .bd-chip{display:flex; align-items:center; gap:7px; padding:7px 12px 7px 8px; cursor:pointer;
    border:2px solid var(--line); border-radius:12px; background:var(--card);
    font-family:var(--sans); font-size:12.5px; font-weight:600; color:var(--muted);}
  .bd-chip.on{border-color:var(--accent); background:var(--accent-soft); color:var(--accent-dark);}
  .bd-prev{width:26px; height:26px; border-radius:8px; border:1px solid var(--line); background:var(--bg); flex:none;}
  .bd-dots{background-image:radial-gradient(rgba(58,40,23,.35) 1px, transparent 1px); background-size:6px 6px;}
  .bd-paper{background:#efe6d2;}
  .bd-linen{background-image:repeating-linear-gradient(0deg, rgba(58,40,23,.18) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, rgba(58,40,23,.18) 0 1px, transparent 1px 4px);}
  .bd-stripes{background-image:repeating-linear-gradient(90deg, rgba(176,95,46,.25) 0 5px, transparent 5px 10px);}
  .bd-stars{background:#241a10; background-image:radial-gradient(#e0a531 1px, transparent 1.5px); background-size:8px 8px;}
  .bd-rain{background-image:repeating-linear-gradient(100deg, rgba(79,142,178,.4) 0 1px, transparent 1px 7px);}
  .bd-fireflies{background:#241a10; background-image:radial-gradient(#ffdf70 1.5px, transparent 2.5px); background-size:11px 9px;}
  .bd-leaves{background:linear-gradient(140deg, #efe6d2, #dfc9a3);}
  .feed-group{margin-bottom:14px;}
  .feed-group-head{display:flex; align-items:center; gap:8px; margin:0 2px 8px;
    font-size:13.5px; color:var(--ink);}
  .feed-group-head b{font-family:var(--serif); font-size:14.5px;}
  .fg-count{font-size:11px; color:var(--faint); font-weight:600;}
  .fg-toggle{margin-left:auto; font-size:11.5px; text-decoration:none; font-weight:700;}
  /* flat canvas swaps into the pinned preview slot */
  /* notifications: unread = tinted row + dot (not faded reads) */
  .notif-row.unread{background:var(--surface-2); border-color:var(--line-strong);
    border-left:3px solid var(--focus);}
  .n-when{font-size:11px; color:var(--faint); font-weight:500;}
  .n-dot{width:8px; height:8px; border-radius:50%; background:var(--focus); flex:none;}

  /* cover carousels (trending / new releases): horizontal scroll, big covers */
  .cov-row{display:flex; gap:12px; overflow-x:auto; padding:4px 2px 10px;
    scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch;}
  .covtile{flex:none; width:96px; cursor:pointer; scroll-snap-align:start; text-align:center;}
  .covtile .ctimg{width:96px; height:144px; border-radius:5px 9px 9px 5px; overflow:hidden;
    background:linear-gradient(160deg,#dcc9ae,#ac8b66); display:flex; align-items:center;
    justify-content:center; font-size:30px;
    box-shadow:5px 7px 14px rgba(58,40,23,.3), inset -3px 0 6px rgba(0,0,0,.14);
    transition:transform var(--dur-micro) var(--ease-out);}
  body.dark .covtile .ctimg{box-shadow:5px 7px 16px rgba(0,0,0,.5), inset -3px 0 6px rgba(0,0,0,.3);}
  .covtile .ctimg img{width:100%; height:100%; object-fit:cover; display:block;}
  @media (hover:hover){ .covtile:hover .ctimg{transform:translateY(-3px);} }
  .covtile .ct-ttl{margin-top:6px; font-size:11px; font-weight:600; color:var(--muted);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}


  /* floating captions must stay legible over ANY backdrop or wallpaper */
  .fg-head b{color:var(--ink);}
  .fg-head .fg-count, .fg-head .fg-chevron{color:var(--muted);}

  /* adjustable sheets: floating = user-placed; native corner resize; ⟲ resets */
  .sheet .grabber{cursor:grab; width:72px; height:6px; touch-action:none;}
  .sheet .grabber:active{cursor:grabbing;}
  .sheet.floating{resize:both; overflow:auto; max-height:none; max-width:none;
    min-width:320px; min-height:240px; border-radius:var(--r-sheet); animation:none;}
  .sheet-reset{position:absolute; top:10px; right:14px; border:none; background:none;
    color:var(--faint); font-size:16px; cursor:pointer; padding:4px 7px; z-index:5;
    border-radius:8px;}
  .sheet-reset:hover{color:var(--accent-dark); background:var(--accent-soft);}


  /* the flat canvas opens WHILE the designer (ovCup) is open — both are .overlay at
     z-index 30, and ovFlat comes earlier in the DOM, so without this it opened behind
     the designer sheet and looked like it did nothing. Lift it above, and dim less so
     the 3D cup behind stays clearly visible + updating live as you draw. */
  #ovFlat{z-index:40; background:rgba(43,33,24,.28);}
  /* the flat canvas window: the drawing surface fills it edge to edge */
  #ovFlat #cupCanvas{display:block; width:100%; height:auto; background:#fff;
    border:1px solid var(--line); border-radius:12px; cursor:crosshair;
    touch-action:none; box-shadow:var(--e2);}

/* ---------- Share card modal ---------- */
.share-preview{ display:flex; justify-content:center; align-items:flex-start;
  background:var(--surface-2); border:1px solid var(--line); border-radius:14px;
  padding:12px; max-height:52vh; overflow:auto; }
.share-preview canvas{ display:block; width:auto; max-width:100%; max-height:calc(52vh - 24px);
  height:auto; border-radius:8px; box-shadow:var(--e2); background:var(--card); }
.share-status{ min-height:18px; margin:8px 2px 0; text-align:center;
  font-size:var(--fs-small); color:var(--muted); }

/* ---------- Reading personality card (4F) ---------- */
.rp-card{ text-align:left; }
.rp-head{ display:flex; align-items:center; gap:12px; }
.rp-emoji{ font-size:34px; line-height:1; flex:0 0 auto; }
.rp-kicker{ font-size:var(--fs-caption); letter-spacing:.08em; text-transform:uppercase;
  color:var(--accent); font-weight:700; }
.rp-type{ font-family:var(--serif); font-size:var(--fs-h2); font-weight:600; color:var(--ink); }
.rp-blurb{ margin:10px 0 12px; color:var(--muted); font-size:var(--fs-body); line-height:var(--lh-body); }
.rp-traits{ display:flex; flex-wrap:wrap; gap:6px; }
.rp-chip{ font-size:var(--fs-small); color:var(--faint); background:var(--surface-2);
  border:1px solid var(--line); border-radius:999px; padding:4px 10px; }

/* ---------- Barcode scanner (5A) ---------- */
.scan-stage{ position:relative; width:100%; aspect-ratio:4/3; background:#000;
  border-radius:14px; overflow:hidden; border:1px solid var(--line); }
.scan-stage video{ width:100%; height:100%; object-fit:cover; display:block; }
.scan-stage canvas#scanBox{ position:absolute; inset:0; width:100%; height:100%;
  pointer-events:none; }
/* Full-frame scanning (SCAN-1A): the WHOLE frame decodes, so no strip reticle and
   no vignette mask implying a target zone — just subtle corner ticks that read as
   "camera is live" without telling the user where to aim. */
.scan-corners{ position:absolute; inset:10px; pointer-events:none; opacity:.6;
  background-image:
    linear-gradient(#fff,#fff), linear-gradient(#fff,#fff),
    linear-gradient(#fff,#fff), linear-gradient(#fff,#fff),
    linear-gradient(#fff,#fff), linear-gradient(#fff,#fff),
    linear-gradient(#fff,#fff), linear-gradient(#fff,#fff);
  background-position: top left, top left, top right, top right,
    bottom left, bottom left, bottom right, bottom right;
  background-size: 18px 2px, 2px 18px, 18px 2px, 2px 18px,
    18px 2px, 2px 18px, 18px 2px, 2px 18px;
  background-repeat:no-repeat; }
/* Torch toggle (SCAN-1A): only shown when the live track reports the capability. */
.scan-torch{ position:absolute; right:8px; bottom:8px; z-index:2;
  background:rgba(0,0,0,.55); color:#fff; border:1px solid rgba(255,255,255,.4);
  border-radius:999px; padding:6px 12px; font-size:var(--fs-small); font-weight:600;
  cursor:pointer; }
  /* twin of .scan-torch on the other corner: the cover path is a peer of the
     barcode path, not a buried fallback. */
  .scan-cover-btn{position:absolute; left:10px; bottom:10px; z-index:2;
    background:rgba(0,0,0,.55); color:#fff; border:1px solid rgba(255,255,255,.35);
    border-radius:999px; padding:8px 12px; font-size:13px; cursor:pointer;}
  .scan-cover-btn:disabled{opacity:.6; cursor:default;}
  /* cover pick list: same row shape as a scanned result so both paths read alike */
  .scan-cover-hits .scan-hit{display:flex; gap:10px; align-items:center; width:100%;
    text-align:left; background:none; border:0; border-bottom:1px solid var(--line);
    padding:8px 2px; cursor:pointer; color:var(--ink); font-size:var(--fs-body);}
  .scan-cover-hits .scan-hit:hover, .scan-cover-hits .scan-hit:focus-visible{background:var(--surface-2);}
.scan-torch.on{ background:#fff; color:#1c1c1c; border-color:#fff; }
.scan-list{ margin-top:10px; max-height:34vh; overflow:auto; display:flex; flex-direction:column; gap:8px; }
.scan-empty{ color:var(--muted); font-size:var(--fs-small); text-align:center; padding:14px 6px; }
.scan-row{ display:flex; flex-direction:column; align-items:stretch; gap:8px; padding:8px;
  background:var(--surface-2); border:1px solid var(--line); border-radius:12px; }
.scan-cov{ width:34px; height:50px; object-fit:cover; border-radius:4px; flex:0 0 auto;
  background:var(--line); }
.scan-cov.ph{ background:var(--line-strong); }
.scan-bd{ flex:1; min-width:0; }
.scan-ttl{ font-weight:600; color:var(--ink); font-size:var(--fs-body);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.scan-meta{ color:var(--muted); font-size:var(--fs-small); }
.scan-x{ flex:0 0 auto; background:none; border:none; color:var(--muted); font-size:16px;
  cursor:pointer; padding:4px 8px; }

/* ---------- Scan duplicate badge (5B) ---------- */
.scan-dup{ display:inline-block; margin-left:6px; font-size:var(--fs-caption);
  font-weight:600; color:var(--accent-dark); background:var(--accent-soft);
  border-radius:999px; padding:2px 8px; }
.scan-row.is-dup{ border-color:var(--accent); }
.scan-dup.maybe{ color:var(--muted); background:var(--surface-2); border:1px solid var(--line); font-weight:500; }

/* ---------- Scan destination select (5C) ---------- */
.scan-main{ display:flex; align-items:center; gap:10px; }
.scan-dest{ display:flex; gap:4px; margin-top:8px; }
.scan-dest button{ flex:1; padding:6px 4px; font-size:var(--fs-small); font-weight:600;
  border:1px solid var(--line); background:var(--card); color:var(--muted);
  border-radius:8px; cursor:pointer; }
/* Selected: --accent-dark carries AA text in each theme. Light: #8a4a24 + white
   ~8.3:1. Night: --accent-dark is a lighter tint (#e2a06c), so use dark ink text
   ~6.8:1 instead of white (white on it was only ~3.1:1). */
.scan-dest button.on{ background:var(--accent-dark); border-color:var(--accent-dark); color:#fff; }
body.dark .scan-dest button.on{ color:#2b2118; }

/* ---------- Cosmetic packs / shop (6A) ---------- */
.decor-lock{ position:relative; opacity:.85; }
.decor-lock .dl-badge{ position:absolute; right:-2px; bottom:-2px; font-size:9px;
  line-height:1; filter:grayscale(.2); }
.decor-shop{ font-size:15px; }
.shop-hd{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-top:4px; }
.shop-name{ font-family:var(--serif); font-size:var(--fs-h2); font-weight:600; color:var(--ink); }
.shop-price{ font-weight:700; color:var(--accent-dark); }
.shop-blurb{ color:var(--muted); font-size:var(--fs-body); margin:6px 0 12px; }
.shop-items{ display:flex; flex-wrap:wrap; gap:10px; justify-content:center;
  background:var(--surface-2); border:1px solid var(--line); border-radius:14px; padding:16px; }
.shop-item{ font-size:30px; line-height:1; }
.shop-note{ font-size:var(--fs-small); color:var(--faint); margin:12px 2px; text-align:center; }

  /* Toast — transient, non-blocking confirmation, reachable from any tab.
     Sits above the visit banner (z 60) so it is never hidden while visiting, and clears
     the bottom nav, the bulk bar (bottom 62) and the FAB (bottom 92). Colours are tokens
     only, so dark.css themes it for free. */
  /* Centred with left+right+auto margins rather than left:50%+translateX(-50%): with only
     `left` set, shrink-to-fit gets just (viewport - 50%) to work with, so on a 375px phone
     the box capped at 188px and a normal block message wrapped to seven lines. */
  #toast{position:fixed; left:16px; right:16px; margin-left:auto; margin-right:auto;
    /* 156 = the FAB's 92px offset + its 56px height + an 8px gap, so the toast does not sit
       on top of the primary action. This is for VISIBILITY only - it is not what keeps taps
       working; see pointer-events below. */
    width:fit-content; bottom:calc(156px + env(safe-area-inset-bottom));
    transform:translateY(8px); z-index:70;
    max-width:min(420px, calc(100vw - 32px)); box-sizing:border-box;
    padding:11px 16px; border-radius:var(--r-ctrl);
    /* Inverse surface. On --card it was indistinguishable from a book card sitting directly
       above it and read as shelf content, not a message. Tokens are toast-specific on purpose
       (see base.css) so a custom banner colour cannot bleach it. */
    background:linear-gradient(135deg,var(--toast-bg1) 0%,var(--toast-bg2) 100%);
    color:var(--toast-fg); border:1px solid var(--toast-edge);
    box-shadow:var(--e3); font-family:var(--sans); font-size:var(--fs-body);
    line-height:var(--lh-snug); text-align:center;
    opacity:0;
    /* NEVER interactive, in either state. At z 70 the toast paints over everything, so any
       control it overlapped had its taps swallowed - measured with a modal open: it stole
       "+ Update progress", "Finish" and both date fields. Raising it dodged the FAB but not
       the class. pointer-events:none makes the whole class impossible instead of dodging
       each instance, at the cost of tap-to-dismiss; the timer dismisses it. */
    pointer-events:none;
    transition:opacity var(--dur-enter) var(--ease-out),
               transform var(--dur-enter) var(--ease-out);}
  #toast.show{opacity:1; transform:translateY(0);}
  @media (prefers-reduced-motion: reduce){
    #toast, #toast.show{transform:none; transition:opacity var(--dur-micro) linear;}
  }

  /* SEAM-2 guest-import sheet rows: real labelled checkboxes, generous tap targets */
  .import-row{display:flex; align-items:center; gap:10px; padding:10px 4px;
    font-size:var(--fs-body); cursor:pointer;}
  .import-row input[type=checkbox]{width:20px; height:20px; accent-color:var(--accent);}

