/* ============================================================================
   THE OBSERVATORY · album.css — the night-sky album styling, on the Curioso
   brand tokens (brand.css loads first). Fonts vendored from the core dir by
   absolute path (the album ships to /space/, the core to /play/core/v1/).

   The star anatomy (built by album-app.js):
     .star > .dot > .halo    soft rarity-tinted bloom, breathing
                    .spikes  4-point diffraction cross, shimmering
                    .spikes2 45° secondary glint (legendary only)
                    .core    the hot jewel centre, gently winking
                    .burst   one-shot ignite ring (freshly collected)
            > .slabel        the star's name
   Every infinite animation is desynced per star via --twd/--twp (negative
   delays, golden-ratio phase spread, set inline by album-app.js) so the sky
   never pulses in lock-step. Rarity tints via --halo-rgb/--mid/--deep/--lab:
   gold legendary · violet rare · cream common.
   One-shot ceremonies (entry cascade, link draw-in, ignite) live inside
   @media (prefers-reduced-motion: no-preference); the reduce block at the
   bottom stills every loop while keeping the sky beautiful.
   ========================================================================== */
@font-face{font-family:'Fraunces';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/play/core/v1/vendor/fonts/fraunces-900.woff2') format('woff2')}
@font-face{font-family:'Anton';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/play/core/v1/vendor/fonts/anton.woff2') format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:600;font-display:swap;
  src:url('/play/core/v1/vendor/fonts/hanken-600.woff2') format('woff2')}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:800;font-display:swap;
  src:url('/play/core/v1/vendor/fonts/hanken-800.woff2') format('woff2')}

:root{
  --f-title:'Fraunces',Georgia,serif;
  --f-caps:'Anton',-apple-system,system-ui,sans-serif;
  --f-body:'Hanken Grotesk',-apple-system,system-ui,sans-serif;
  --ink:var(--text-100);
  --sub:var(--text-400);
  --gold:var(--gold-400);
  --gold2:var(--gold-300);
  --violet:var(--violet-400);
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%;height:100dvh;
  touch-action:manipulation;overscroll-behavior:none;-webkit-touch-callout:none}
body{
  /* rich static fallback (also the context-loss backdrop): nebula spots baked in CSS */
  background:
    radial-gradient(90% 62% at 68% 28%, rgba(86,52,142,.34) 0%, rgba(86,52,142,0) 62%),
    radial-gradient(74% 52% at 20% 66%, rgba(40,46,116,.30) 0%, rgba(40,46,116,0) 66%),
    radial-gradient(120% 90% at 50% 8%, #171233 0%, #0d0a1e 46%, #06050e 100%);
  color:var(--ink);font-family:var(--f-body);font-weight:600;
  overflow:hidden;position:fixed;inset:0;
  -webkit-user-select:none;user-select:none;
  -webkit-font-smoothing:antialiased;
}
#app{position:fixed;inset:0}

/* the WebGL night-sky backdrop fills the screen */
#sky{position:fixed;inset:0;width:100%;height:100%;display:block;z-index:0;touch-action:none}

/* ---- shooting stars (DOM layer under the constellation lines) ---- */
#meteors{position:fixed;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.meteor{
  position:absolute;width:160px;height:2px;pointer-events:none;opacity:0;
  background:linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,244,214,.10) 45%,
    rgba(255,244,214,.85) 90%, #fff 100%);
  border-radius:2px;
  filter:drop-shadow(0 0 5px rgba(255,240,200,.7));
  animation:meteorfly var(--mdur,1.2s) ease-out forwards;
}
@keyframes meteorfly{
  0%{opacity:0;transform:rotate(var(--ang,152deg)) translateX(0)}
  10%{opacity:.95}
  100%{opacity:0;transform:rotate(var(--ang,152deg)) translateX(300px)}
}

/* ---- constellation filaments (under the stars) ---- */
#links{position:fixed;inset:0;z-index:1;pointer-events:none}
#links .clink-glow{stroke:rgba(255,223,138,.14);stroke-width:6;stroke-linecap:round}
#links .clink{
  stroke:#ffdf8a;stroke-width:1.4;stroke-linecap:round;opacity:.85;
  filter:drop-shadow(0 0 5px rgba(255,223,138,.6));
}
#links .clink-flow{
  stroke:#fff;stroke-width:2.2;stroke-linecap:round;opacity:.9;
  stroke-dasharray:16 220;
  filter:drop-shadow(0 0 6px rgba(255,231,166,.9));
  animation:clinkflow 3.8s linear infinite;
}
@keyframes clinkflow{to{stroke-dashoffset:-236}}

/* ---- header: the hero moment ---- */
#obshead{
  position:fixed;top:0;left:0;right:0;z-index:3;
  padding:calc(env(safe-area-inset-top,0px) + 18px) 20px 14px;
  text-align:center;pointer-events:none;
  background:linear-gradient(180deg, rgba(6,5,14,.78) 0%, rgba(6,5,14,.36) 58%, rgba(6,5,14,0) 100%);
}
#obshead .kicker{
  display:flex;align-items:center;justify-content:center;gap:12px;
  font-family:var(--f-caps);font-weight:800;font-size:10.5px;letter-spacing:.30em;
  color:rgba(255,223,138,.72);text-transform:uppercase;
}
#obshead .kicker::before,#obshead .kicker::after{
  content:'';height:1px;width:36px;flex:none;
  background:linear-gradient(90deg, rgba(255,223,138,0), rgba(255,223,138,.5));
}
#obshead .kicker::after{background:linear-gradient(90deg, rgba(255,223,138,.5), rgba(255,223,138,0))}
#obstitle{
  margin:6px 0 0;font-family:var(--f-title);font-weight:900;font-size:27px;line-height:1.04;
  letter-spacing:.005em;color:var(--ink);
  text-shadow:0 2px 26px rgba(139,107,240,.55), 0 0 80px rgba(139,107,240,.30), 0 1px 2px rgba(0,0,0,.55);
}
/* the progress jewel: a glassy pill + a thin gold meter */
#progress{
  display:inline-flex;flex-direction:column;align-items:center;gap:7px;margin-top:12px;
  padding:9px 20px 12px;border-radius:var(--radius-pill);
  background:rgba(19,14,40,.55);border:1px solid rgba(245,198,91,.26);
  box-shadow:0 10px 30px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.06), 0 0 30px rgba(139,107,240,.12);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
}
#progress .ptext{
  font-family:var(--f-caps);font-weight:800;font-size:14px;letter-spacing:.08em;
  color:var(--gold2);text-transform:uppercase;
}
#progress b{color:#fff;font-weight:800;font-size:15px}
#progress .pstar{
  display:inline-block;color:var(--gold);
  filter:drop-shadow(0 0 7px rgba(245,198,91,.85));
  animation:pwink 3.2s ease-in-out infinite;
}
#progress .pbar{
  display:block;width:170px;max-width:46vw;height:3px;border-radius:2px;
  background:rgba(255,255,255,.13);overflow:hidden;
}
#progress .pfill{
  display:block;height:100%;border-radius:2px;background:var(--grad-gold-flat);
  box-shadow:0 0 10px rgba(245,198,91,.9);
  transition:width .6s var(--ease-out);
}
@keyframes pwink{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}

/* ---- the star field ---- */
#field{position:fixed;inset:0;z-index:2}

.star{
  position:absolute;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:5px;
  min-width:44px;min-height:44px;
  padding:6px 4px;border:0;background:none;color:inherit;font:inherit;
  cursor:default;text-align:center;
  /* size + rarity tokens (rarity/state blocks override) */
  --dotpx:13px;--boost:1;--hx:7.2;--spx:4.8;
  --halo-rgb:246,240,222;--mid:#fdf3d3;--deep:#d9c9a8;--lab:#f3ecd8;   /* common: cream */
}
.star[data-rarity="rare"]{--halo-rgb:166,140,245;--mid:#e6dbff;--deep:#8b6bf0;--lab:#cfc0f7}
.star[data-rarity="legendary"]{--halo-rgb:245,198,91;--mid:#ffe9a8;--deep:#e8a92e;--lab:#ffdf8a}
.star[data-ui]{cursor:pointer}

.star .dot{
  --mag:1;
  position:relative;display:block;
  width:calc(var(--dotpx) * var(--mag) * var(--boost));
  height:calc(var(--dotpx) * var(--mag) * var(--boost));
  transition:transform .2s var(--ease-out);
}
.star .dot > span{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);pointer-events:none}
.star .halo{
  width:calc(var(--dotpx) * var(--mag) * var(--hx));
  height:calc(var(--dotpx) * var(--mag) * var(--hx));
  border-radius:50%;opacity:0;
  background:radial-gradient(circle, rgba(var(--halo-rgb),.40) 0%, rgba(var(--halo-rgb),.13) 38%, rgba(var(--halo-rgb),0) 70%);
}
.star .spikes,.star .spikes2{
  width:calc(var(--dotpx) * var(--mag) * var(--spx));
  height:calc(var(--dotpx) * var(--mag) * var(--spx));
  opacity:0;
}
.star .spikes::before,.star .spikes2::before{
  content:'';position:absolute;left:0;right:0;top:50%;height:1.6px;margin-top:-.8px;
  background:linear-gradient(90deg, rgba(var(--halo-rgb),0), rgba(255,255,255,.95) 50%, rgba(var(--halo-rgb),0));
}
.star .spikes::after,.star .spikes2::after{
  content:'';position:absolute;top:0;bottom:0;left:50%;width:1.6px;margin-left:-.8px;
  background:linear-gradient(180deg, rgba(var(--halo-rgb),0), rgba(255,255,255,.95) 50%, rgba(var(--halo-rgb),0));
}
.star .spikes2{display:none;width:calc(var(--dotpx) * var(--mag) * 3.2);height:calc(var(--dotpx) * var(--mag) * 3.2)}
.star .dot .core{
  position:absolute;left:0;top:0;right:0;bottom:0;transform:none;
  border-radius:50%;
  background:radial-gradient(circle at 38% 32%, #fff 0%, #cfc9ee 42%, #6b5ea6 100%);
  box-shadow:0 0 0 1px rgba(255,255,255,.10);
}
.star .burst{
  width:calc(var(--dotpx) * var(--mag) * 2);
  height:calc(var(--dotpx) * var(--mag) * 2);
  border:2px solid rgba(var(--halo-rgb),.9);border-radius:50%;opacity:0;
}
.star .slabel{
  font-family:var(--f-caps);font-weight:800;font-size:11px;letter-spacing:.08em;
  line-height:1.05;color:var(--sub);text-transform:uppercase;
  max-width:104px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  text-shadow:0 1px 8px rgba(0,0,0,.95), 0 0 2px rgba(0,0,0,.8);
  position:relative;z-index:1;
}

/* --- UNOWNED: an elegant waiting point — thin ring + centre mote + reticle
       ticks + a whisper of shimmer. Named desire, never sad, never nagging. */
.star[data-state="unowned"]{--boost:.94;--halo-rgb:198,190,234}
.star[data-state="unowned"] .core{
  background:radial-gradient(circle, rgba(216,210,246,.85) 0%, rgba(216,210,246,.16) 18%, rgba(216,210,246,0) 24%);
  border:1px solid rgba(198,190,234,.36);
  box-shadow:none;
  animation:whisper var(--twp2,8s) ease-in-out var(--twd,0s) infinite;
}
.star[data-state="unowned"] .spikes{
  --spx:3.1;opacity:.5;
  animation:whisper var(--twp2,8s) ease-in-out var(--twd2,0s) infinite;
}
.star[data-state="unowned"] .spikes::before{
  height:1px;margin-top:-.5px;
  background:linear-gradient(90deg, rgba(198,190,234,.55) 0, rgba(198,190,234,.55) 4px,
    transparent 4px, transparent calc(100% - 4px), rgba(198,190,234,.55) calc(100% - 4px));
}
.star[data-state="unowned"] .spikes::after{
  width:1px;margin-left:-.5px;
  background:linear-gradient(180deg, rgba(198,190,234,.55) 0, rgba(198,190,234,.55) 4px,
    transparent 4px, transparent calc(100% - 4px), rgba(198,190,234,.55) calc(100% - 4px));
}
.star[data-state="unowned"] .halo{
  --hx:5;opacity:.07;
  animation:wisp var(--twp2,8s) ease-in-out var(--twd,0s) infinite;
}
.star[data-state="unowned"] .slabel{
  font-size:10px;letter-spacing:.13em;max-width:96px;
  color:rgba(176,170,208,.55);
}

/* --- SEEN / PLAYED: a dim violet ember — a promise, tappable to resume --- */
.star[data-state="seen"],.star[data-state="played"]{--halo-rgb:139,107,240}
.star[data-state="seen"] .core,
.star[data-state="played"] .core{
  background:radial-gradient(circle at 38% 32%, #fff 0%, #d9d3f4 46%, #8b6bf0 100%);
  box-shadow:0 0 9px 2px rgba(139,107,240,.55);
}
.star[data-state="seen"] .halo,
.star[data-state="played"] .halo{--hx:5.4;opacity:.22;animation:breathe var(--twp2,8s) ease-in-out var(--twd,0s) infinite}
.star[data-state="seen"] .spikes,
.star[data-state="played"] .spikes{opacity:.16}
.star[data-state="seen"] .slabel,
.star[data-state="played"] .slabel{color:#cfc9ee}

/* --- COLLECTED: a jewel of light — hot core, breathing bloom, shimmering
       diffraction spikes; rarity tints the whole lightform. Earned. --- */
.star[data-state="collected"]{--boost:1.16}
.star[data-state="collected"] .core{
  background:radial-gradient(circle at 38% 32%, #fff 0%, var(--mid) 45%, var(--deep) 100%);
  box-shadow:0 0 10px 2px rgba(var(--halo-rgb),.9), 0 0 26px 6px rgba(var(--halo-rgb),.35);
  animation:corewink var(--twp,4.6s) ease-in-out var(--twd2,0s) infinite;
}
.star[data-state="collected"] .halo{
  opacity:.5;
  animation:breathe var(--twp2,7s) ease-in-out var(--twd,0s) infinite;
}
.star[data-state="collected"] .spikes{
  opacity:.75;
  animation:glimmer var(--twp,4.6s) ease-in-out var(--twd,0s) infinite;
}
.star[data-state="collected"][data-rarity="legendary"]{--spx:6.2;--hx:8.6}
.star[data-state="collected"][data-rarity="legendary"] .spikes2{
  display:block;opacity:0;
  animation:glimmer45 var(--twp2,7s) ease-in-out var(--twd2,0s) infinite;
}
.star[data-state="collected"] .slabel{
  font-size:11.5px;color:var(--lab);
  text-shadow:0 1px 8px rgba(0,0,0,.9), 0 0 12px rgba(var(--halo-rgb),.5);
}

/* the living rhythms (per-star desync via --twp/--twd, set inline) */
@keyframes breathe{
  0%,100%{opacity:.40;transform:translate(-50%,-50%) scale(1)}
  50%{opacity:.68;transform:translate(-50%,-50%) scale(1.16)}
}
@keyframes glimmer{
  0%,100%{opacity:.55;transform:translate(-50%,-50%) scale(1)}
  50%{opacity:1;transform:translate(-50%,-50%) scale(1.10)}
}
@keyframes glimmer45{
  0%,100%{opacity:0;transform:translate(-50%,-50%) rotate(45deg) scale(.9)}
  50%{opacity:.8;transform:translate(-50%,-50%) rotate(45deg) scale(1.05)}
}
@keyframes corewink{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}
@keyframes whisper{0%,100%{opacity:.42}50%{opacity:.85}}
@keyframes wisp{
  0%,100%{opacity:.05;transform:translate(-50%,-50%) scale(1)}
  50%{opacity:.13;transform:translate(-50%,-50%) scale(1.12)}
}

/* keyboard / focus ring (brand) */
.star[data-ui]:focus-visible{outline:none;border-radius:12px;box-shadow:var(--focus-ring)}

/* press feedback */
.star[data-ui]:active .dot{transform:scale(.86)}

/* ---- THE DOORS BAND (#obsfoot keeps its id — scripts/e2e target it): the
       two explore-doors now sit at the TOP, directly under the progress
       jewel, above the constellation. Two unmistakable side-by-side BUTTONS
       a 7-year-old parses instantly. The band itself passes pointer events
       through; only the doors are interactive. ---- */
#obsfoot{
  position:fixed;left:0;right:0;z-index:3;
  top:calc(env(safe-area-inset-top,0px) + 146px);
  padding:0 16px;
  text-align:center;pointer-events:none;
}
/* the two-door row: side-by-side half-width on phones, a centred pair wider up */
.obsfoot-row{
  display:flex;align-items:stretch;justify-content:center;gap:10px;
}
.arcpanel,.storypanel{pointer-events:auto}
/* the arcade door: five game medallions (a coin-stack on phones), the big
   STAR ARCADE title, the game count, one big PLAY chip. Built games glow;
   future games sit as dim silhouettes (the unowned-star grammar). The whole
   door is the tap target. Both doors are TREASURE-DOORS: a breathing violet
   halo (::before, opacity/transform only), a bright rim, a one-shot ignite
   sheen on arrival (::after, ~1.2s, the two doors desynced), and a PLAY/READ
   action chip. Locked stays visibly quieter than unlocked — desire, never
   frustration. */
.arcpanel{
  position:relative;
  display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  min-height:44px;min-width:0;flex:1 1 0;max-width:206px;padding:13px 10px 12px;
  border-radius:22px;cursor:pointer;
  background:linear-gradient(180deg, rgba(46,38,90,.82), rgba(23,18,50,.86));
  border:1px solid rgba(168,142,250,.55);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 10px 28px rgba(0,0,0,.45),
    0 0 26px rgba(139,107,240,.28);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  transition:transform .16s var(--ease-out), box-shadow .25s, border-color .25s;
}
.arcpanel[disabled]{
  cursor:default;
  border-color:rgba(139,107,240,.28);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 8px 26px rgba(0,0,0,.4);
}
/* the breathing door-halo: a soft violet bloom behind each panel, animating
   ONLY opacity/transform (negative delays — the two doors never pulse in
   lock-step). Locked arcade: still, faint — quieter than the open doors. */
.arcpanel::before,.storypanel::before{
  content:'';position:absolute;inset:-18px;border-radius:40px;z-index:-1;pointer-events:none;
  background:radial-gradient(closest-side, rgba(150,118,246,.38), rgba(139,107,240,.14) 58%, rgba(139,107,240,0) 100%);
  opacity:.7;
}
.arcpanel[disabled]::before{opacity:.2}
/* the one-shot IGNITE sheen: a soft light band sweeps each door once on
   arrival (opacity + background-position only — safe everywhere) */
.arcpanel::after,.storypanel::after{
  content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:2;
  background:linear-gradient(115deg, rgba(255,255,255,0) 38%, rgba(238,230,255,.34) 50%, rgba(255,255,255,0) 62%);
  background-size:280% 100%;background-position:135% 0;background-repeat:no-repeat;
  opacity:0;
}
@media (prefers-reduced-motion:no-preference){
  .arcpanel:not([disabled])::before{animation:doorBreathe 3.6s ease-in-out -1.3s infinite}
  .storypanel::before{animation:doorBreathe 3.6s ease-in-out -2.7s infinite}
  .arcpanel::after{animation:doorIgnite 1.2s cubic-bezier(.3,.6,.3,1) .35s both}
  .storypanel::after{animation:doorIgnite 1.2s cubic-bezier(.3,.6,.3,1) .85s both}
}
@keyframes doorBreathe{
  0%,100%{opacity:.55;transform:scale(1)}
  50%{opacity:1;transform:scale(1.05)}
}
@keyframes doorIgnite{
  0%{opacity:0;background-position:135% 0}
  20%{opacity:1}
  80%{opacity:1}
  100%{opacity:0;background-position:-35% 0}
}
/* the action chips: big friendly BUTTONS in the album's caps/violet-glass
   grammar (gold stays reserved for the NEW pip + the ready-glow) */
.arc-foot{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;max-width:100%}
.arc-cta,.story-cta{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  font-family:var(--f-caps);font-weight:800;font-size:13px;letter-spacing:.18em;
  text-transform:uppercase;color:#f5f1ff;
  min-width:96px;padding:8px 18px 7px 21px;border-radius:999px;
  background:linear-gradient(180deg, rgba(148,116,248,.62), rgba(99,72,196,.46));
  border:1px solid rgba(206,190,255,.7);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 4px 12px rgba(0,0,0,.4), 0 0 16px rgba(139,107,240,.35);
}
/* locked arcade: the chip drops to the unowned-star grammar — named desire */
.arcpanel[disabled] .arc-cta{
  color:rgba(198,190,234,.5);
  background:rgba(216,210,246,.05);
  border:1px dashed rgba(198,190,234,.35);
  box-shadow:none;
}
.arcpanel:not([disabled]):active{transform:scale(.97)}
.arcpanel:focus-visible{outline:none;box-shadow:var(--focus-ring)}
@media (hover:hover){
  .arcpanel:not([disabled]):hover{transform:translateY(-2px);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.16), 0 12px 32px rgba(0,0,0,.5), 0 0 34px rgba(245,198,91,.22)}
}
.arc-tiles{display:flex;align-items:center;gap:10px}
.arc-tile{
  width:41px;height:41px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
}
.arc-tile svg{width:21px;height:21px}
/* a BUILT, playable game: a lit gold jewel */
.arc-tile.live{
  color:#1a1330;
  background:radial-gradient(circle at 38% 30%, #fff2cf, var(--gold-400) 62%, #d9a53a);
  border:1.5px solid rgba(255,240,200,.85);
  box-shadow:0 3px 10px rgba(0,0,0,.4), 0 0 12px rgba(245,198,91,.45), inset 0 1px 0 rgba(255,255,255,.6);
}
/* a built game still gated by the collection: violet glass, quietly waiting */
.arc-tile.locked{
  color:#a99ee0;
  background:radial-gradient(circle at 38% 30%, rgba(90,72,150,.85), rgba(38,30,74,.9) 70%);
  border:1.5px solid rgba(139,107,240,.45);
  box-shadow:0 3px 8px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.12);
}
/* a designed-but-future game: the dim silhouette (named desire) */
.arc-tile.soon{
  color:rgba(176,170,208,.5);
  background:rgba(216,210,246,.05);
  border:1.5px dashed rgba(198,190,234,.3);
}
.arc-label{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  font-family:var(--f-caps);font-weight:800;text-transform:uppercase;white-space:nowrap;
}
.arc-title{font-size:17px;letter-spacing:.10em;color:#e9e3ff}
.arc-count{font-size:10.5px;letter-spacing:.16em;color:var(--sub)}
.arc-count::before{content:'·';margin-right:8px;color:rgba(139,107,240,.7)}
/* the READY state: the panel warms gold and breathes (still under reduce) */
.arcpanel.ready{border-color:rgba(245,198,91,.55)}
.arcpanel.ready .arc-title{color:var(--gold-300)}
.arcpanel[disabled] .arc-title{color:rgba(178,172,212,.75)}
.arcpanel[disabled] .arc-tile.live{filter:saturate(.35) brightness(.75)}
@media (prefers-reduced-motion:no-preference){
  .arcpanel.ready{animation:arcReady 2.8s ease-in-out infinite}
}
@keyframes arcReady{
  0%,100%{box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 10px 28px rgba(0,0,0,.45), 0 0 20px rgba(245,198,91,.18)}
  50%{box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 10px 30px rgba(0,0,0,.45), 0 0 34px rgba(245,198,91,.45)}
}
.hintline{
  margin-top:9px;font-family:var(--f-body);font-weight:600;font-size:12.5px;
  color:rgba(178,172,212,.8);letter-spacing:.02em;
}

/* ---- THE STORYBOOK PANEL: a cover thumb + kicker + title, same glass grammar
       as the arcade. Never gated, never disabled — the deck's free gift. A
       quiet gold NEW pip sits until the first open (album-app.js removes it). */
.storypanel{
  position:relative;display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  min-height:44px;min-width:0;flex:1 1 0;max-width:206px;padding:13px 10px 12px;
  border-radius:22px;cursor:pointer;
  background:linear-gradient(180deg, rgba(46,38,90,.82), rgba(23,18,50,.86));
  border:1px solid rgba(168,142,250,.55);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14), 0 10px 28px rgba(0,0,0,.45),
    0 0 26px rgba(139,107,240,.28);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  transition:transform .16s var(--ease-out), box-shadow .25s, border-color .25s;
}
.storypanel:active{transform:scale(.97)}
.storypanel:focus-visible{outline:none;box-shadow:var(--focus-ring)}
@media (hover:hover){
  .storypanel:hover{transform:translateY(-2px);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.16), 0 12px 32px rgba(0,0,0,.5), 0 0 34px rgba(245,198,91,.22)}
}
/* the cover thumb: rounded, gold hairline. A real cover.webp when present;
   a graceful gradient + star glyph fallback while the art is missing. */
.story-thumb{
  flex:0 0 auto;width:52px;height:66px;border-radius:11px;overflow:hidden;
  background:
    radial-gradient(120% 90% at 50% 20%, rgba(139,107,240,.5), rgba(12,10,28,.9) 70%),
    linear-gradient(180deg, #1a1440, #0b0a1e);
  background-size:cover;background-position:50% 40%;
  border:1px solid rgba(245,198,91,.42);
  box-shadow:0 3px 10px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.08);
  display:flex;align-items:center;justify-content:center;position:relative;
}
/* the fallback star glyph — hidden once a cover image loads (.has-art) */
.story-thumb::after{
  content:'';position:absolute;left:50%;top:50%;width:16px;height:16px;
  transform:translate(-50%,-50%);
  color:var(--gold-300);opacity:.85;
  background:var(--gold-300);
  -webkit-mask:radial-gradient(circle,#000 60%,transparent 61%);
  /* a simple 4-point star via clip is complex; use a small gold spark dot */
  border-radius:50%;
  box-shadow:0 0 8px rgba(245,198,91,.7);
}
.story-thumb.has-art{background-color:#0b0a1e}
.story-thumb.has-art::after{display:none}
.story-label{display:flex;flex-direction:column;align-items:center;gap:3px;text-align:center}
.story-kick{
  font-family:var(--f-caps);font-weight:800;font-size:10px;letter-spacing:.20em;
  text-transform:uppercase;color:var(--sub);
}
.story-title{
  font-family:var(--f-title);font-weight:800;font-size:17px;line-height:1.05;
  color:var(--gold-300);text-shadow:0 1px 8px rgba(0,0,0,.6);white-space:nowrap;
}
.story-cta{margin-left:0}
/* the quiet gold NEW pip (removed by album-app.js after the first open) */
.story-pip{
  position:absolute;top:-6px;right:-4px;
  font-family:var(--f-caps);font-weight:800;font-size:8px;letter-spacing:.14em;
  text-transform:uppercase;color:#1a1330;
  padding:2px 7px;border-radius:999px;
  background:linear-gradient(180deg, var(--gold-300), var(--gold-400));
  border:1px solid rgba(255,240,200,.7);
  box-shadow:0 3px 10px rgba(0,0,0,.4), 0 0 12px rgba(245,198,91,.4);
}
.storypanel.opened .story-pip{display:none}
@media (prefers-reduced-motion:no-preference){
  .storypanel .story-pip{animation:storyPip 2.8s ease-in-out infinite}
}
@keyframes storyPip{
  0%,100%{box-shadow:0 3px 10px rgba(0,0,0,.4), 0 0 10px rgba(245,198,91,.3)}
  50%{box-shadow:0 3px 10px rgba(0,0,0,.4), 0 0 18px rgba(245,198,91,.7)}
}

/* ---- desktop / large screens: bigger type, roomier ---- */
@media (min-width:900px){
  #obshead .kicker{font-size:11.5px}
  #obstitle{font-size:38px}
  #progress .ptext{font-size:15px}
  #progress b{font-size:16px}
  #progress .pbar{width:220px}
  .star{--dotpx:15px}
  .star .slabel{font-size:12.5px;max-width:140px}
  .star[data-state="collected"] .slabel{font-size:13px}
  .arcpanel,.storypanel{max-width:252px;padding:15px 16px 14px;gap:10px}
  #obsfoot{top:calc(env(safe-area-inset-top,0px) + 208px)}
  /* coin-stack the 5 medallions so the row fits inside the door (was 5×46+4×10
     =270px overflowing a 252px door by 9px/side — learning #109) */
  .arc-tiles{gap:0}
  .arc-tile{width:46px;height:46px}
  .arc-tile:not(:first-child){margin-left:-10px}
  .arc-tile svg{width:23px;height:23px}
  .arc-title{font-size:19px}
  .arc-count{font-size:11.5px}
  .arc-cta,.story-cta{font-size:11px;padding:6px 15px 5px 17px}
  .hintline{font-size:13px}
  .storypanel{padding:12px 22px 12px 14px;gap:15px}
  .story-thumb{width:58px;height:74px;border-radius:12px}
  .story-title{font-size:20px}
  .story-kick{font-size:11px}
}
@media (min-width:1300px){
  #obstitle{font-size:44px}
}

/* ---- narrow phones (<620px): the row wraps — two full-width stacked DOORS,
       not two shrunken pills. Label left, chip right: door grammar. ---- */
@media (max-width:619px){
  .arc-tiles{gap:0}
  .arc-tile{width:36px;height:36px}
  .arc-tile svg{width:18px;height:18px}
  .arc-tile:not(:first-child){margin-left:-8px}
}

/* ---- short viewports (landscape phones): compact the chrome so the sky
       keeps its breathing room; must come after the width queries ---- */
@media (max-height:520px){
  #obsfoot{top:calc(env(safe-area-inset-top,0px) + 92px);padding:0 12px}
  #obshead{padding-top:calc(env(safe-area-inset-top,0px) + 10px);padding-bottom:8px}
  #obshead .kicker{font-size:9px;letter-spacing:.24em}
  #obstitle{font-size:20px}
  #progress{margin-top:6px;padding:6px 14px 8px;gap:4px}
  #progress .ptext{font-size:11.5px}
  #progress b{font-size:12.5px}
  #progress .pbar{width:130px;height:2px}
  .star{--dotpx:11px}
  .star .slabel{font-size:9.5px;max-width:88px}
  .star[data-state="collected"] .slabel{font-size:10px}
  #obsfoot{padding:6px 20px calc(env(safe-area-inset-bottom,0px) + 6px)}
  .arcpanel{flex-direction:row;gap:12px;min-width:0;width:auto;padding:8px 18px;border-radius:999px}
  .arcpanel::before,.storypanel::before{inset:-10px;border-radius:999px}
  .arc-cta,.story-cta{display:none}
  .arc-foot{width:auto}
  .arc-tile{width:26px;height:26px}
  .arc-tile svg{width:14px;height:14px}
  .arc-title{font-size:11px}
  .arc-count{font-size:9.5px}
  .hintline{display:none}
  .obsfoot-row{gap:9px}
  .storypanel{width:auto;padding:7px 14px 7px 8px;gap:8px;border-radius:999px}
  .story-thumb{width:26px;height:33px;border-radius:6px}
  .story-title{font-size:12px}
  .story-kick{font-size:8.5px;letter-spacing:.14em}
  .story-pip{font-size:7px;padding:1px 5px;top:-5px}
}
/* very narrow phones (≤380px): trim the door padding so the stacked full-width
   doors never overflow or crowd the sky's footer reserve */
@media (max-width:380px){
  .obsfoot-row{gap:10px}
  .arcpanel{min-width:0;padding:12px 16px 11px}
  .storypanel{padding:10px 14px 10px 10px;gap:10px}
  .arc-tile{width:32px;height:32px}
  .arc-tile svg{width:19px;height:19px}
  .story-thumb{width:48px;height:61px}
}

/* ---- one-shot ceremonies: only when motion is welcome ---- */
@media (prefers-reduced-motion:no-preference){
  /* arrival: the sky settles in, star by star */
  .star{animation:settle .45s var(--ed,0s) cubic-bezier(.18,.7,.3,1.15) both}
  /* ignite: the freshly-collected star arrives with a small ceremony */
  .star.ignite .dot{animation:ignitepop .9s .5s cubic-bezier(.34,1.56,.44,1) backwards}
  .star.ignite .burst{animation:burst 1s .5s cubic-bezier(.2,.7,.2,1) both}
  /* constellation filament draws itself between the two lit stars */
  #links .clink,#links .clink-glow{
    stroke-dasharray:var(--len,600px);stroke-dashoffset:var(--len,600px);
    animation:drawin .7s cubic-bezier(.3,.7,.2,1) forwards;
  }
  #links .clink-flow{
    opacity:0;
    animation:flowin .5s .55s both, clinkflow 3.8s .55s linear infinite;
  }
}
@keyframes settle{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.5)}
  100%{opacity:1;transform:translate(-50%,-50%) scale(1)}
}
@keyframes ignitepop{
  0%{transform:scale(.4);filter:brightness(2.2)}
  60%{transform:scale(1.35)}
  100%{transform:scale(1);filter:brightness(1)}
}
@keyframes burst{
  0%{opacity:.95;transform:translate(-50%,-50%) scale(.4);border-width:3px}
  100%{opacity:0;transform:translate(-50%,-50%) scale(5.2);border-width:1px}
}
@keyframes drawin{to{stroke-dashoffset:0}}
@keyframes flowin{from{opacity:0}to{opacity:.9}}

/* ---- reduced motion: still the loops, keep the beauty ---- */
@media (prefers-reduced-motion:reduce){
  .star .halo,.star .spikes,.star .spikes2,.star .core,#progress .pstar{animation:none!important}
  #links .clink,#links .clink-glow{animation:none!important}
  #links .clink-flow,.meteor,.star .burst{display:none}
  .star .dot{transition:none}
  #progress .pfill{transition:none}
}

/* ========================================================================
   THE ARCADE MODAL — the shared mini-game shell (ARCADE-DESIGN.md §1).
   The hub panel opens a card-shaped night pocket: first the game MENU,
   then the chosen engine mounts into the same stage; a result card ends
   every round. (Class names keep the legacy dbf- prefix — same shell.)
   ==================================================================== */
body.dbf-lock{overflow:hidden}

/* the modal shell */
.dbf{
  position:fixed;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;
  padding:calc(env(safe-area-inset-top,0px) + 14px) 12px calc(env(safe-area-inset-bottom,0px) + 14px);
  opacity:0;visibility:hidden;transition:opacity .28s ease, visibility .28s;
}
.dbf.on{opacity:1;visibility:visible}
.dbf-scrim{
  position:absolute;inset:0;background:rgba(6,5,14,.62);
  -webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);cursor:pointer;
}
/* the card-shaped stage the engine fills — its own pocket of night sky:
   a baked starfield + a violet aurora crown, arriving on a springy rise */
.dbf-card{
  position:relative;z-index:1;width:min(94vw,460px);height:min(90vh,780px);
  display:flex;flex-direction:column;border-radius:26px;overflow:hidden;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(40,32,78,.62), rgba(12,10,28,.72) 66%),
    linear-gradient(180deg, rgba(23,19,49,.86), rgba(10,9,22,.9));
  border:1px solid rgba(139,107,240,.28);
  box-shadow:0 40px 90px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.07);
  transform:translateY(26px) scale(.955);transition:transform .44s cubic-bezier(.22,1.35,.36,1);
}
.dbf.on .dbf-card{transform:none}
.dbf-card::before{             /* the tiled micro-starfield */
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.8;
  background-image:
    radial-gradient(circle at 18% 22%, rgba(255,255,255,.55) .8px, transparent 1.7px),
    radial-gradient(circle at 72% 12%, rgba(255,255,255,.4) 1px, transparent 1.9px),
    radial-gradient(circle at 46% 38%, rgba(255,223,138,.5) .7px, transparent 1.5px),
    radial-gradient(circle at 88% 52%, rgba(255,255,255,.35) .9px, transparent 1.8px),
    radial-gradient(circle at 8% 64%, rgba(195,178,249,.45) 1px, transparent 1.9px),
    radial-gradient(circle at 33% 82%, rgba(255,255,255,.3) .8px, transparent 1.6px),
    radial-gradient(circle at 64% 71%, rgba(255,255,255,.4) .7px, transparent 1.4px),
    radial-gradient(circle at 92% 88%, rgba(255,223,138,.35) .8px, transparent 1.6px);
  background-size:210px 210px;
}
.dbf-card::after{              /* the violet aurora crowning the prompt */
  content:"";position:absolute;left:-15%;right:-15%;top:-24%;height:52%;z-index:0;pointer-events:none;
  background:radial-gradient(52% 62% at 50% 34%, rgba(139,107,240,.26), transparent 72%);
}
.dbf-stage{position:relative;z-index:1;flex:1 1 auto;min-height:0}
/* the album owns close (top-right) + back (top-left) — keep every engine's
   centred prompt clear of them (cards have neither, so this is modal-scoped) */
#dbf .msort-head,#dbf .qz-head,#dbf .lnup-head,#dbf .oo-head,#dbf .tb-head{padding-left:48px;padding-right:48px}
#dbf .msort-q{max-width:20em}
.dbf-close,.dbf-back{
  position:absolute;top:8px;z-index:12;width:44px;height:44px;padding:0;
  display:flex;align-items:center;justify-content:center;line-height:1;
  color:#cfc7ef;background:rgba(20,16,42,.5);border:1px solid rgba(255,255,255,.14);
  border-radius:50%;cursor:pointer;transition:transform .16s, background .2s, color .2s;
}
.dbf-close{right:8px}
.dbf-back{left:8px;display:none}
.dbf-back.show{display:flex}
.dbf-close svg,.dbf-back svg{width:17px;height:17px}
.dbf-close:hover,.dbf-back:hover{background:rgba(40,32,78,.7);color:#fff}
.dbf-close:active,.dbf-back:active{transform:scale(.9)}
.dbf-close:focus-visible,.dbf-back:focus-visible{outline:2.5px solid var(--gold-400);outline-offset:2px}

/* ---- the game MENU: one inviting row per mechanic ---- */
/* centred as a group; the auto margins collapse when content overflows, so a
   short viewport scrolls from the top instead of clipping the header */
.arc-menu{
  position:absolute;inset:0;display:flex;flex-direction:column;
  padding:14px 16px 16px;overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.arc-mhead{flex:0 0 auto;text-align:center;margin:auto 0 16px;padding:0 44px}
.arc-mkick{
  font-family:var(--f-caps);font-weight:800;font-size:10.5px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--gold-300);opacity:.9;
}
.arc-mtitle{
  margin:5px 0 0;font-family:var(--f-title);font-weight:800;font-size:24px;line-height:1.1;
  color:var(--ink);text-shadow:0 1px 10px rgba(0,0,0,.5);
}
.arc-msub{
  margin-top:6px;font-family:var(--f-body);font-weight:600;font-size:12.5px;line-height:1.4;
  color:var(--sub);
}
.arc-list{flex:0 0 auto;display:flex;flex-direction:column;gap:10px;padding:2px 0;margin-bottom:auto}
.arc-game{
  display:flex;align-items:center;gap:12px;min-height:64px;padding:10px 14px;
  border-radius:18px;text-align:left;cursor:pointer;width:100%;
  font-family:var(--f-body);color:var(--ink);
  background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.04));
  border:1.5px solid rgba(255,255,255,.18);
  box-shadow:0 4px 14px rgba(0,0,0,.35), inset 0 1.5px 0 rgba(255,255,255,.14);
  transition:transform .16s var(--ease-out), box-shadow .2s, border-color .2s;
}
@media (hover:hover){
  .arc-game:not([disabled]):hover{transform:translateY(-2px);border-color:rgba(245,198,91,.55);
    box-shadow:0 7px 20px rgba(0,0,0,.4), 0 0 18px rgba(245,198,91,.18), inset 0 1.5px 0 rgba(255,255,255,.16)}
}
.arc-game:not([disabled]):active{transform:scale(.985)}
.arc-game:focus-visible{outline:2.5px solid var(--gold-400);outline-offset:2px}
.arc-gico{
  width:46px;height:46px;border-radius:15px;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;color:var(--gold-300);
  background:linear-gradient(180deg, rgba(245,198,91,.16), rgba(245,198,91,.05));
  border:1px solid rgba(245,198,91,.3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.12);
}
.arc-gico svg{width:24px;height:24px}
.arc-gtxt{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px}
.arc-gtitle{
  font-family:var(--f-body);font-weight:800;font-size:17px;line-height:1.12;color:var(--ink);
  display:flex;align-items:center;gap:8px;
}
.arc-gtag{font-weight:600;font-size:13px;line-height:1.3;color:var(--sub)}
.arc-gplay{
  width:38px;height:38px;border-radius:50%;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;color:#1a1330;
  background:radial-gradient(circle at 38% 30%, #fff2cf, var(--gold-400) 62%, #d9a53a);
  border:1.5px solid rgba(255,240,200,.85);
  box-shadow:0 3px 10px rgba(0,0,0,.4), 0 0 12px rgba(245,198,91,.4), inset 0 1px 0 rgba(255,255,255,.6);
}
.arc-gplay svg{width:15px;height:15px;margin-left:2px}
.arc-badge{
  flex:0 0 auto;padding:3px 8px;border-radius:999px;
  font-family:var(--f-caps);font-weight:800;font-size:8.5px;letter-spacing:.18em;text-transform:uppercase;
  color:rgba(198,190,234,.75);border:1px dashed rgba(198,190,234,.4);
}
/* a built game still gated by the collection: readable, quiet, honest */
.arc-game.off{cursor:default;opacity:.72}
.arc-game.off .arc-gico{color:#a99ee0;border-color:rgba(139,107,240,.4);
  background:linear-gradient(180deg, rgba(139,107,240,.14), rgba(139,107,240,.05))}
/* a future game: the dim silhouette row (named desire, never nagging) */
.arc-game.soon{cursor:default;opacity:.5;border-style:dashed;box-shadow:none;background:rgba(216,210,246,.04)}
.arc-game.soon .arc-gico{color:rgba(176,170,208,.6);border:1px dashed rgba(198,190,234,.35);background:rgba(216,210,246,.05)}
@media (min-width:900px){
  .arc-mtitle{font-size:28px}
  .arc-msub{font-size:14px}
  .arc-list{gap:12px}
  .arc-game{min-height:72px;padding:12px 18px}
  .arc-gico{width:52px;height:52px}.arc-gico svg{width:28px;height:28px}
  .arc-gtitle{font-size:18.5px}
  .arc-gtag{font-size:13.5px}
}
@media (max-height:560px){
  .arc-mhead{margin:auto 0 8px}
  .arc-mtitle{font-size:20px}
  .arc-list{gap:7px}
  .arc-game{min-height:52px;padding:7px 12px}
  .arc-gico{width:38px;height:38px}.arc-gico svg{width:20px;height:20px}
}

/* the result card that slides over the finished sort — a genuine reward:
   slow gold rays wheel behind a haloed medal, then the pieces arrive one
   beat after another (medal → headline → line → streak → actions) */
.dbf-result{
  position:absolute;inset:0;z-index:9;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;gap:6px;padding:26px 22px;
  background:
    radial-gradient(95% 58% at 50% 20%, rgba(86,52,142,.5), rgba(10,9,22,0) 64%),
    linear-gradient(180deg, rgba(14,11,32,.96), rgba(8,7,18,.97));
  opacity:0;transition:opacity .3s ease;overflow:hidden;
}
.dbf-result.on{opacity:1}
@keyframes dbfRays{from{transform:rotate(0)}to{transform:rotate(360deg)}}
/* the staggered arrival — each piece rises on the pop curve, one beat apart */
.dbf-result>*{opacity:0;transform:translateY(14px);
  transition:opacity .5s ease, transform .55s cubic-bezier(.25,1.45,.4,1)}
.dbf-result>.dbf-medal{transform:scale(.2) rotate(-24deg)}
.dbf-result.on>*{opacity:1;transform:none}
.dbf-result.on>*:nth-child(1){transition-delay:.06s}
.dbf-result.on>*:nth-child(2){transition-delay:.18s}
.dbf-result.on>*:nth-child(3){transition-delay:.28s}
.dbf-result.on>*:nth-child(4){transition-delay:.38s}
.dbf-result.on>*:nth-child(5){transition-delay:.5s}
.dbf-medal{
  position:relative;font-size:56px;line-height:1;margin-bottom:4px;color:var(--gold-300,#ffd98a);
  text-shadow:0 0 26px rgba(245,198,91,.65);
  display:flex;align-items:center;justify-content:center;
}
.dbf-medal svg{width:56px;height:56px;filter:drop-shadow(0 0 20px rgba(245,198,91,.65))}
.dbf-medal::before{            /* the halo disc behind the medal */
  content:"";position:absolute;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;
  z-index:-1;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle, rgba(245,198,91,.3), rgba(245,198,91,.06) 55%, transparent 70%);
}
.dbf-medal::after{             /* the reward rays, wheeling slowly around the medal */
  content:"";position:absolute;left:50%;top:50%;width:540px;height:540px;margin:-270px 0 0 -270px;
  z-index:-2;pointer-events:none;border-radius:50%;
  background:repeating-conic-gradient(rgba(245,198,91,.085) 0 11deg, rgba(245,198,91,0) 11deg 30deg);
  -webkit-mask-image:radial-gradient(closest-side, rgba(0,0,0,.9), transparent 70%);
  mask-image:radial-gradient(closest-side, rgba(0,0,0,.9), transparent 70%);
  animation:dbfRays 30s linear infinite;
}
@media (prefers-reduced-motion:no-preference){
  .dbf-result.on .dbf-medal{animation:dbfMedalFloat 3.6s ease-in-out 1s infinite}
}
@keyframes dbfMedalFloat{0%,100%{transform:none}50%{transform:translateY(-5px)}}
.dbf-h{
  margin:0;font-family:var(--f-title);font-weight:800;font-size:28px;color:var(--ink);
  text-shadow:0 2px 14px rgba(0,0,0,.5);
}
.dbf-p{margin:0;font-family:var(--f-body);font-weight:600;font-size:14.5px;color:var(--sub);max-width:20em}
/* the streak, promoted to a proper badge — a warm gold-glass keepsake pill */
.dbf-streak{
  display:flex;flex-direction:column;align-items:center;gap:2px;margin:14px 0 4px;
  padding:13px 30px 11px;border-radius:20px;
  background:linear-gradient(180deg, rgba(245,198,91,.1), rgba(245,198,91,.03));
  border:1px solid rgba(245,198,91,.3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 0 30px rgba(245,198,91,.12);
}
.dbf-streak-n{font-family:var(--f-num,var(--f-title));font-weight:800;font-size:40px;line-height:1;
  background:var(--grad-gold-flat,linear-gradient(90deg,#ffe08a,#f5c65b));
  -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 12px rgba(245,198,91,.35))}
/* the "/ N" of a score: its own fill (opacity/child-compositing would break
   the parent's background-clip:text and render it invisible) */
.dbf-streak-n .dbf-of{font-size:22px;color:var(--gold-400);-webkit-text-fill-color:var(--gold-400)}
.dbf-streak-l{font-family:var(--f-caps);font-weight:800;font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--sub)}
.dbf-actions{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:14px}
.dbf-btn{
  min-height:48px;min-width:132px;padding:0 20px;
  font-family:var(--f-caps);font-weight:800;font-size:12.5px;letter-spacing:.08em;text-transform:uppercase;
  color:#cfc7ef;background:linear-gradient(180deg, rgba(40,33,78,.8), rgba(23,18,48,.8));
  border:1px solid rgba(139,107,240,.34);border-radius:var(--radius-pill,999px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.08), 0 6px 20px rgba(0,0,0,.4);cursor:pointer;
  transition:transform .16s, box-shadow .2s;
}
.dbf-btn:active{transform:scale(.96)}
.dbf-btn:focus-visible{outline:2.5px solid var(--gold-400);outline-offset:2px}
.dbf-primary{
  color:#1a1330;background:linear-gradient(180deg, var(--gold-300,#ffd98a), var(--gold-400,#f5c65b));
  border-color:rgba(245,198,91,.7);box-shadow:inset 0 1px 0 rgba(255,255,255,.4), 0 6px 22px rgba(245,198,91,.3);
}
@media (hover:hover){
  .dbf-btn:hover{transform:translateY(-1px)}
  .dbf-primary:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.4), 0 8px 28px rgba(245,198,91,.45)}
}
@media (min-width:900px){
  .dbf-h{font-size:32px}.dbf-p{font-size:16px}.dbf-medal{font-size:64px}
  .dbf-medal::before{width:180px;height:180px;margin:-90px 0 0 -90px}
  .dbf-streak-n{font-size:46px}
}
@media (prefers-reduced-motion:reduce){
  .dbf,.dbf-card,.dbf-result{transition:opacity .12s !important;transform:none !important}
  .dbf-result>*{transition:opacity .12s !important;transform:none !important}
  .dbf-medal::after{animation:none}
  .arcpanel.ready{animation:none}
  .arcpanel,.arc-game,.storypanel{transition:none}
  .storypanel .story-pip{animation:none}
}

/* ========================================================================
   CONSTELLATION VIGNETTES — a tappable ▶ at each lit link's midpoint + the
   caption band Vela narrates into (§5.3). A lit-but-unheard link pulses gold.
   ==================================================================== */
/* the caption band Vela narrates into (DS.Say toggles .on — used by the arcade) */
.vcap{
  position:fixed;left:50%;transform:translateX(-50%) translateY(10px);
  bottom:calc(env(safe-area-inset-bottom,0px) + 96px);
  z-index:6;width:min(92vw,540px);padding:13px 18px;box-sizing:border-box;text-align:center;
  border-radius:18px;pointer-events:none;
  background:linear-gradient(180deg, rgba(28,22,58,.88), rgba(14,11,30,.92));
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  border:1px solid rgba(139,107,240,.34);
  box-shadow:0 18px 44px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.07);
  opacity:0;visibility:hidden;transition:opacity .3s ease, transform .3s cubic-bezier(.2,.9,.3,1.1), visibility .3s;
}
.vcap.on{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
.vcap-title{
  font-family:var(--f-caps);font-weight:800;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--gold-300,#ffd98a);margin-bottom:5px;
}
.vcap-title:empty{display:none}
.vcap-text{font-family:var(--f-body);font-weight:600;font-size:14.5px;line-height:1.42;color:var(--ink)}
@media (min-width:900px){
  .vcap{bottom:calc(env(safe-area-inset-bottom,0px) + 104px);padding:15px 22px}
  .vcap-text{font-size:16.5px}.vcap-title{font-size:12px}
}
@media (max-height:520px){
  .vcap{bottom:calc(env(safe-area-inset-bottom,0px) + 74px);padding:10px 15px}
  .vcap-text{font-size:13px}
}
@media (prefers-reduced-motion:reduce){
  .vcap{transition:opacity .12s !important;transform:translateX(-50%) !important}
}

/* partner-preview badge (?demo=1) — subtle, honest, out of the way */
#demopill{
  position:fixed;left:50%;transform:translateX(-50%);
  top:calc(env(safe-area-inset-top,0px) + 4px);z-index:14;pointer-events:none;
  font-family:var(--f-caps);font-weight:800;font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,223,138,.85);background:rgba(19,14,40,.6);
  padding:4px 12px;border-radius:999px;border:1px solid rgba(245,198,91,.28);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  box-shadow:0 4px 14px rgba(0,0,0,.35);
}
@media (max-width:520px){ #demopill{font-size:8.5px;letter-spacing:.12em;padding:3px 9px} }
