/* ════════════════════════════════════════════════════════════════════════
   NOCTURNE — presentation layer (skin) over the existing app.
   Values are lifted verbatim from the canonical mockups:
     nocturne-final-clayrose.html · nocturne-three-tabs.html · nocturne-catalog-collect.html
   Behaviour is unchanged; this file only restyles + adds the candlelight ambient,
   the matte bouncy book, the Catalog collect flourishes, and the SightReadle page.
   Loaded LAST so it wins over the legacy game CSS (styles.css).
   All motion is disabled under prefers-reduced-motion (bottom of file).
   ════════════════════════════════════════════════════════════════════════ */

body { background: var(--app-bg); color: var(--text); }
.lib-title, .sr-heading, .cat-progress-title, .lib-empty h2, .modal h3, .auth-brand h1 {
  font-family: var(--font-display); letter-spacing: -.01em;
}

/* ════════════════════════════════════════════════════════════════════════
   Candlelight ambient system (verbatim from the mockups' .amb layers).
   Each layer is inset:0; the radial gradient positions the light itself.
   pointer-events:none; sits behind all content; disabled under reduced-motion.
   ════════════════════════════════════════════════════════════════════════ */
#ambient { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
#ambient .amb { position: absolute; inset: 0; pointer-events: none; will-change: opacity, transform; }
/* Lift ONLY the in-flow tab sections above the ambient (z-index:0). The appbar
   (z-index:500), reader (2000), auth sheet (4000), and gesture overlays already
   sit above the ambient with their own stacking — never force them here or they
   collapse out of their layer (the reader stops covering the screen). */
body > section.tab-view { position: relative; z-index: 1; }

.amb-warm   { background: radial-gradient(120% 92% at 50% 0%, rgba(122,72,32,.30), transparent 60%); animation: breathe 12s ease-in-out infinite; }
.amb-ember  { background: radial-gradient(40% 46% at 87% 96%, rgba(226,150,78,.24), rgba(180,100,50,.08) 45%, transparent 68%); animation: ember 7.3s ease-in-out infinite; }
.amb-night  { background: radial-gradient(40% 44% at 6% 4%, rgba(96,78,150,.06), transparent 66%); }
.amb-candle { background: radial-gradient(42% 42% at 50% 23%, rgba(240,182,96,.30), rgba(230,152,72,.10) 46%, transparent 72%); animation: candle 7.5s ease-in-out infinite; transform-origin: 50% 23%; }
.amb-core   { background: radial-gradient(19% 19% at 50% 21%, rgba(255,214,150,.32), transparent 66%); animation: core 4.2s ease-in-out infinite; }
.amb-tip    { background: radial-gradient(8% 10% at 50% 17.5%, rgba(255,140,58,.55), rgba(255,116,40,.14) 52%, transparent 74%); animation: tip 3.1s ease-in-out infinite; mix-blend-mode: screen; }
.amb-dim    { background: rgba(8,5,3,0); transition: background .8s ease; }
body.sr-active .amb-dim { background: rgba(8,5,3,.32); }
.amb-vig    { box-shadow: inset 0 0 170px 46px rgba(9,5,3,.62); }
.amb-grain  { opacity: .045; mix-blend-mode: overlay; background-image: 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='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
body.amb-paused #ambient .amb { animation-play-state: paused; }

@keyframes candle { 0%{opacity:.9;transform:scale(1)} 14%{opacity:1;transform:scale(1.018)} 30%{opacity:.94;transform:scale(1.008)} 46%{opacity:.99;transform:scale(1.02)} 60%{opacity:.9;transform:scale(1.004)} 74%{opacity:.98;transform:scale(1.016)} 88%{opacity:.93;transform:scale(1.008)} 100%{opacity:.9;transform:scale(1)} }
@keyframes core   { 0%{opacity:.82} 22%{opacity:.98} 44%{opacity:.86} 62%{opacity:.96} 82%{opacity:.84} 100%{opacity:.82} }
@keyframes tip    { 0%,100%{opacity:.7;transform:translateY(0)} 30%{opacity:1;transform:translateY(-1px)} 55%{opacity:.78} 80%{opacity:.95;transform:translateY(-1px)} }
@keyframes ember  { 0%,100%{opacity:.72} 40%{opacity:1} 68%{opacity:.82} }
@keyframes breathe{ 0%,100%{opacity:.9} 50%{opacity:1} }

/* The brand dot in the appbar becomes a glowing ember (mockup .brand .dot). */
.appbar-logo { filter: drop-shadow(0 0 6px rgba(236,178,94,.35)); }

/* ════════════════════════════════════════════════════════════════════════
   The matte bouncy book — shared Library + Catalog item (verbatim mockup .card/.b).
   Vertical card: note on top, bold title, small composer line. radius 24, chunky
   0 9px 0 bottom shadow, ~6% top-light (::before), bob idle + hover wobble + tap squash.
   ════════════════════════════════════════════════════════════════════════ */
.lib-card, .cat-card {
  cursor: pointer; position: relative; aspect-ratio: 1 / 1.4; border: none; border-radius: 24px;
  padding: 20px 16px 18px; overflow: visible;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  background: linear-gradient(165deg, var(--c1), var(--c2));
  box-shadow: 0 9px 0 var(--c3), 0 16px 26px rgba(0,0,0,.34);
  transition: transform .45s var(--ease-bounce), box-shadow .3s;
}
.lib-card::before, .cat-card::before {
  content: ""; position: absolute; inset: 0; border-radius: 24px; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,250,236,.06), transparent 32%);
}
.lib-card:hover, .cat-card:hover { transform: translateY(-8px) scale(1.045); box-shadow: 0 9px 0 var(--c3), 0 22px 34px rgba(0,0,0,.4); }
.lib-card:active, .cat-card:active { transform: translateY(-1px) scale(.965); transition: transform .12s ease; }
/* alternate the near-flat second tone so the shelf isn't uniform (mockup i%2) */
.lib-card:nth-child(2n), .cat-card:nth-child(2n) { background: linear-gradient(165deg, var(--c1), var(--c1)); }

.book-motif { margin-top: 6px; animation: bob 3s ease-in-out infinite; transform-origin: 50% 82%; filter: drop-shadow(0 2px 2px rgba(0,0,0,.16)); }
.lib-card:hover .book-motif, .cat-card:hover .book-motif { animation: wobble .6s var(--ease-wobble); }
.book-t { font-weight: 760; font-size: 15px; line-height: 1.22; letter-spacing: -.01em; color: var(--bink); margin-top: 14px; text-shadow: 0 1px 1px rgba(50,26,12,.16); }
.book-sub { font-size: 10.5px; font-weight: 600; color: var(--bink); opacity: .78; margin-top: 2px; }

@keyframes bob { 0%,100%{transform:translateY(0) rotate(-3deg)} 50%{transform:translateY(-3px) rotate(-2deg)} }
@keyframes wobble { 0%{transform:scale(1) rotate(-3deg)} 28%{transform:scale(1.18) rotate(6deg)} 55%{transform:scale(.9) rotate(-6deg)} 78%{transform:scale(1.07) rotate(2deg)} 100%{transform:scale(1) rotate(-3deg)} }

/* Library: edit/remove revealed on hover so the resting book stays clean (behaviour preserved). */
.book-tools { position: absolute; top: 10px; right: 10px; display: flex; gap: 4px; opacity: 0; transition: opacity .18s; z-index: 3; }
.lib-card:hover .book-tools, .lib-card:focus-within .book-tools { opacity: 1; }
.book-tools .icon-btn { width: 26px; height: 26px; border-radius: 8px; background: rgba(28,17,10,.34); color: var(--note); border: none; cursor: pointer; font-size: .8rem; }
.book-tools .icon-btn:hover { background: rgba(28,17,10,.55); color: var(--bink); }
.book-tools .icon-btn[data-remove]:hover { background: var(--danger-soft); }
/* A tiny playable dot, bottom-left, when the piece has scoring data (subtle). */
.book-playable { position: absolute; left: 12px; bottom: 12px; width: 7px; height: 7px; border-radius: 50%; background: var(--gilt); box-shadow: 0 0 6px var(--gilt); }

.lib-grid, .cat-grid { display: grid; gap: 30px 24px; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); }

/* ════════════════════════════════════════════════════════════════════════
   Catalog collect — progress bar, filter pills, add-burst, completion toast.
   (progress/pills/book/burst verbatim from catalog-collect.html; the pill ✓ and
   composer-completion toast are spec §3f, layered on top.)
   ════════════════════════════════════════════════════════════════════════ */
.cat-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
.cat-progress { min-width: 180px; text-align: right; }
.cat-progress-count { font-family: var(--font-mono); font-size: 11px; color: var(--muted); letter-spacing: .03em; }
.cat-progress-count b { color: var(--accent); font-weight: 700; }
.cat-progress-bar { margin-top: 6px; height: 8px; border-radius: 99px; background: rgba(255,220,180,.1); overflow: hidden; }
.cat-progress-fill { height: 100%; width: 0; border-radius: 99px; background: linear-gradient(90deg, var(--c1), var(--accent)); transition: width .55s cubic-bezier(.34,1.4,.64,1); }
.cat-progress-fill.pulse { animation: fillpulse .5s ease; }
@keyframes fillpulse { 50% { filter: brightness(1.35); } }

.cat-filter { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 18px; }
.cat-pill { cursor: pointer; font-size: 12px; font-weight: 650; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--border); background: transparent; color: var(--muted); transition: .2s; display: inline-flex; align-items: center; gap: 6px; }
.cat-pill:hover { border-color: rgba(236,178,94,.4); color: var(--text); }
.cat-pill.active { background: var(--accent); color: #241408; border-color: var(--accent); }
.cat-pill.done::after { content: "✓"; color: var(--good); font-weight: 800; }
.cat-pill.active.done::after { color: #1c5a12; }

/* Collect book extras */
.cat-card { animation: popin .5s var(--ease-wobble) backwards; }
@keyframes popin { 0%{opacity:0;transform:translateY(16px) scale(.92)} 100%{opacity:1;transform:none} }
.cat-card.added { animation: collect .55s cubic-bezier(.34,1.7,.5,1); }
@keyframes collect { 0%{transform:scale(1)} 30%{transform:scale(.9) translateY(3px)} 60%{transform:scale(1.12) translateY(-6px)} 100%{transform:scale(1)} }
.book-add { margin-top: auto; cursor: pointer; font-size: 11px; font-weight: 750; border: none; border-radius: 999px; padding: 7px 15px; background: var(--note); color: var(--c3); box-shadow: 0 3px 0 rgba(0,0,0,.2); transition: transform .14s, filter .14s; }
.book-add:hover { filter: brightness(1.04); }
.book-add:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(0,0,0,.2); }
.cat-card.owned { box-shadow: 0 9px 0 var(--c3), 0 0 0 2px rgba(127,190,110,.5), 0 16px 26px rgba(0,0,0,.34); }
.cat-card.owned .book-add { background: transparent; color: var(--good); box-shadow: none; pointer-events: none; font-weight: 700; }
.book-check { position: absolute; top: 11px; right: 11px; width: 22px; height: 22px; border-radius: 50%; background: var(--good); color: #fff; display: none; align-items: center; justify-content: center; font-size: 12px; box-shadow: 0 2px 6px rgba(0,0,0,.3); z-index: 3; }
.cat-card.owned .book-check { display: flex; animation: collect .5s cubic-bezier(.34,1.7,.5,1); }

/* Add-burst (verbatim geometry from catalog-collect.html) */
.ring { position: absolute; left: 50%; top: 42%; width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%; border: 2px solid var(--good); pointer-events: none; z-index: 4; animation: ring .55s ease-out forwards; }
@keyframes ring { 0%{transform:scale(.3);opacity:.9} 100%{transform:scale(2.6);opacity:0} }
.spark { position: absolute; left: 50%; top: 42%; width: 6px; height: 6px; border-radius: 50%; pointer-events: none; z-index: 4; animation: spark .62s ease-out forwards; }
@keyframes spark { 0%{transform:translate(0,0) scale(1);opacity:1} 100%{transform:translate(var(--dx),var(--dy)) scale(.3);opacity:0} }
.fp { position: absolute; left: 50%; top: 8px; transform: translateX(-50%); color: var(--good); font-size: 12px; font-weight: 800; pointer-events: none; z-index: 5; animation: fp-rise .95s forwards; }
@keyframes fp-rise { 0%{opacity:0;transform:translate(-50%,4px)} 20%{opacity:1} 100%{opacity:0;transform:translate(-50%,-22px)} }

/* Composer-completion toast (spec §3f + audible-variant look) */
#cat-toast { position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 20px); z-index: 3200;
  background: linear-gradient(165deg, #2a1c12, #20140c); border: 1px solid rgba(236,178,94,.4); border-radius: 14px;
  padding: 11px 20px; font-size: 13px; font-weight: 700; color: var(--accent); box-shadow: 0 12px 30px rgba(0,0,0,.5);
  opacity: 0; pointer-events: none; transition: .4s cubic-bezier(.34,1.4,.64,1); text-align: center; }
#cat-toast.show { opacity: 1; transform: translate(-50%, 0); }
#cat-toast .sm { display: block; font-size: 10.5px; font-weight: 500; color: var(--muted); margin-top: 2px; }

/* ════════════════════════════════════════════════════════════════════════
   Tab shell transitions (mockup .panel cross-fade + translateY)
   ════════════════════════════════════════════════════════════════════════ */
.tab-view.active { animation: tab-in var(--dur) var(--ease); }
@keyframes tab-in { 0% { opacity: 0; transform: translateY(12px); } 100% { opacity: 1; transform: none; } }

/* ════════════════════════════════════════════════════════════════════════
   SightReadle — dimmed room, warm cream page, crisp dark ink (three-tabs.html)
   ════════════════════════════════════════════════════════════════════════ */
.sr-stage .header { margin-bottom: 18px; }
.sr-streak { display: inline-flex; align-items: center; gap: 7px; margin: 0 auto 14px; font-size: 11.5px; font-weight: 600;
  color: var(--accent); background: rgba(236,178,94,.12); border: 1px solid rgba(236,178,94,.25); padding: 5px 12px; border-radius: 999px; }
.sr-streak-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--accent); }
.sr-heading { font-family: var(--font-display); color: var(--text); font-size: 26px; font-weight: 600; text-align: center; margin: 4px 0; letter-spacing: -.01em; }

/* The music page: a calm, DIMMED parchment — candlelight turned low. One smooth
   surface (no bright cream slab, no amber bloom, no inset seam). A gentle radial
   keeps the lighting even instead of glaring at the top; the sheet melts onto the
   paper via multiply blend so white areas disappear and only the dark ink remains. */
body.sr-active .challenge-card, #view-sightreadle .challenge-card {
  background: radial-gradient(135% 130% at 50% 32%, #E7D8BB 0%, #DECDAC 100%) !important;
  color: var(--ink); border-radius: 16px;
  border: 1px solid rgba(120,92,54,.26);
  box-shadow: 0 16px 40px rgba(0,0,0,.5);              /* soft dark drop only — no glow */
}
#view-sightreadle .challenge-title { color: var(--ink); font-family: var(--font-display); }
#view-sightreadle .challenge-meta, #view-sightreadle .selection-label { color: #6b573c; }
/* One continuous paper: the sheet sits directly on the card, no inset box or seam.
   multiply blend drops any white background into the parchment, keeping ink crisp. */
#view-sightreadle .music-container,
#view-sightreadle .osmd-container,
#view-sightreadle .music-sheet {
  background: transparent !important; border: none !important; box-shadow: none !important;
}
#view-sightreadle .music-container { margin: 16px 0; }
#view-sightreadle .osmd-container, #view-sightreadle .music-sheet { mix-blend-mode: multiply; }
#view-sightreadle .loading { color: #8a745a; mix-blend-mode: normal; }

/* Mode toggle → warm amber active (was legacy blue/white). */
#view-sightreadle .mode-btn { border: 1.5px solid var(--border-strong); background: var(--surface); color: var(--text); font-weight: 600; }
#view-sightreadle .mode-btn:hover { background: var(--accent-soft); border-color: var(--accent); }
#view-sightreadle .mode-btn.active { background: var(--accent); color: var(--text-on-accent); border-color: var(--accent); }

/* Chunky clay-rose Play (primary record action), matching the books (mockup .srplay). */
#view-sightreadle .btn-record, #view-sightreadle .btn-primary {
  background: linear-gradient(165deg, var(--c1), var(--c2)); color: var(--bink); border: none; border-radius: 16px;
  box-shadow: 0 7px 0 var(--c3), 0 12px 22px rgba(0,0,0,.4);
  transition: transform .4s var(--ease-wobble), box-shadow .2s;
}
#view-sightreadle .btn-record:hover, #view-sightreadle .btn-primary:hover { transform: translateY(-4px) scale(1.03); }
#view-sightreadle .btn-record:active, #view-sightreadle .btn-primary:active { transform: translateY(2px) scale(.98); box-shadow: 0 3px 0 var(--c3), 0 6px 14px rgba(0,0,0,.4); }

/* ════════════════════════════════════════════════════════════════════════
   Accessibility + reduced-motion
   ════════════════════════════════════════════════════════════════════════ */
.cat-pill:focus-visible, .book-add:focus-visible, .book-tools .icon-btn:focus-visible, .lib-card:focus-visible, .cat-card:focus-visible {
  outline: 2px solid var(--focus-ring); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  #ambient { display: none; }
  .lib-card, .cat-card, .book-motif, .cat-card.added, .cat-card.owned .book-check, .tab-view.active,
  .ring, .spark, .fp, #cat-toast, .cat-progress-fill, .cat-progress-fill.pulse,
  #view-sightreadle .btn-record, #view-sightreadle .btn-primary {
    animation: none !important; transition-duration: 1ms !important;
  }
  .lib-card:hover, .cat-card:hover { transform: none; }
}
