@import url('./native-feel.css');

/* =====================================================================
   GAMIFY · SKIN  —  single source of truth for the game UI
   ---------------------------------------------------------------------
   Every mechanic renderer in /app links this file:
       <link rel="stylesheet" href="skin.css">
   ...and then adds ONLY its mechanic-area CSS inline. Nothing visual is
   duplicated across renderers anymore — it lives here once.

   RESKIN THE WHOLE APP by editing :root below. Colors, corner radius and
   fonts are variables; the scaffold (HUD, cards, choices, win screen) and
   the juice (pop / shake / confetti / stars) read from them. A game can
   also override any variable locally for its own accent — that is exactly
   how the themed renderers vary their feel while sharing this scaffold.

   The ACTIVE theme below is the bright "sky / cloud" skin from the product
   mockups. The original dark "night" values are kept in the comment block
   at the bottom so you can flip back by swapping the :root values only.

   HARD RULE baked into the juice: there is NO fail state. "Wrong" is the
   .wrong / shake treatment only — a shake, a streak reset, a tiny penalty.
   Nothing in this file produces a game-over.
   ===================================================================== */

:root{
  /* ---- palette (ACTIVE = sky / cloud) ---- */
  --bg1:#3f97dd;           /* page gradient, deep sky (outer)   */
  --bg2:#8ecff5;           /* page gradient, light sky (top)    */
  --ink:#15324a;           /* primary text (dark on light)      */
  --muted:#2f536e;         /* secondary text (4.5:1 on the sky gradient's light end) */
  --accent:#ffce3a;        /* sunny highlight / primary          */
  --accent2:#ff9f43;       /* highlight gradient end (orange)    */
  --good:#34c06b;          /* correct (green)                   */
  --good-deep:#1f9e50;     /* correct gradient end              */
  --bad:#ff6a6a;           /* wrong (coral)                     */
  --bad-deep:#e0474f;      /* wrong gradient end                */

  /* ---- surfaces (light cards floating on the sky) ---- */
  --choice:#ffffff;                     /* choice / tile face      */
  --choice-edge:rgba(21,50,74,.14);     /* choice border           */
  --edge:rgba(21,50,74,.14);            /* generic hairline        */
  /* ONE SURFACE LANGUAGE on the light skin: nothing on a light screen is
     see-through, and every card shares the same corner. These four used to
     be overridden in web/css/app.css, which meant a renderer in an iframe
     drew on translucent surfaces inside a shell built on solid ones — two
     design languages in one screen. Night keeps the translucent values; its
     [data-theme] block below outranks this one. */
  --stage-bg:#ffffff;                   /* problem-card fill       */
  --stage-edge:rgba(21,50,74,.12);      /* problem-card border     */
  --pill-bg:#ffffff;                    /* HUD pill fill           */
  --pill-edge:rgba(21,50,74,.10);       /* HUD pill border         */
  --shadow:rgba(21,50,74,.16);          /* soft card lift          */

  /* ---- ink-on-color helpers (so text stays readable on light) ---- */
  --label:#966300;         /* uppercase instruction labels       */
  --gx-on-state:#0b2033;   /* text and glyph on a correct or wrong fill: dark on every skin's light green and coral */
  --btn-ink:#15324a;       /* text on the yellow button          */
  --back-btn-bg:rgba(255,255,255,.85);
  --back-btn-ink:#15324a;

  /* ---- shape ---- */
  --radius:14px;           /* choices, buttons, tiles  */
  --radius-lg:20px;        /* the stage / problem card */
  --radius-pill:999px;     /* HUD pills, back button   */

  /* ---- type ---- */
  --font:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
}

/* =====================================================================
   ALTERNATE THEME (live) — the original dark "night" skin, switchable at
   runtime: the shell's Settings toggle sets data-theme="night" on <html>
   (shell.js + bridge.js mirror it onto every page). Reskinning is still a
   one-file change — both palettes live here and nowhere else.
   ===================================================================== */
:root[data-theme="night"]{
  --bg1:#0f1123; --bg2:#23264d; --ink:#eef0ff; --muted:#9aa0d0;
  --accent:#ffd166; --accent2:#ff9f5a; --good:#22c197; --good-deep:#149174;
  --bad:#ff6b6b; --bad-deep:#b3323a;
  --choice:#2a2f52; --choice-edge:rgba(255,255,255,.14); --edge:rgba(255,255,255,.14);
  --stage-bg:rgba(255,255,255,.05); --stage-edge:rgba(255,255,255,.10);
  --pill-bg:rgba(255,255,255,.08); --pill-edge:rgba(255,255,255,.12); --shadow:rgba(0,0,0,.35);
  --label:#ffd166; --btn-ink:#1a1d3a;
  --back-btn-bg:rgba(0,0,0,.35); --back-btn-ink:#eef0ff;
}

/* ---- reset ---- */
*{box-sizing:border-box;margin:0;padding:0}

/* ---- page ---- */
body{
  font-family:var(--font);color:var(--ink);min-height:100vh;
  background:radial-gradient(120% 120% at 50% 0%,var(--bg2),var(--bg1) 70%);
  display:flex;flex-direction:column;align-items:center;padding:16px;
}
a.back{
  position:fixed;top:10px;left:12px;z-index:9999;color:var(--back-btn-ink);text-decoration:none;
  font-weight:600;font-size:14px;background:var(--back-btn-bg);border:1px solid var(--pill-edge);
  border-radius:var(--radius-pill);padding:6px 12px;box-shadow:0 2px 6px var(--shadow);
}
h1{font-size:1.5rem;margin-top:6px;text-align:center}
.sub{display:block;font-size:.85rem;color:var(--muted);font-weight:500;margin-top:4px}

/* ---- HUD (score / streak / counters) ---- */
.hud{display:flex;gap:10px;margin:12px 0}
.pill{
  background:var(--pill-bg);border:1px solid var(--pill-edge);border-radius:var(--radius-pill);
  padding:6px 14px;font-weight:700;font-size:.9rem;box-shadow:0 2px 6px var(--shadow);
}
.pill.bump{animation:scorePop .3s ease}      /* optional score count-up juice */
/* Pills lead with a line icon. It inherits stroke colour from the pill, which
   is the whole reason the set has no per-context variants. */
.pill{display:inline-flex;align-items:center;gap:7px}
.pill .p-ico{display:inline-flex;color:var(--muted)}
.pill .p-ico svg{display:block;width:15px;height:15px}

/* ---- progress pips (checkpoint dots) ---- */
.pips{display:flex;gap:6px;margin:4px 0 10px}
.pip{width:9px;height:9px;border-radius:50%;background:rgba(21,50,74,.18)}
.pip.done{background:var(--good)}
.pip.now{background:var(--accent);box-shadow:0 0 0 3px rgba(255,206,58,.30)}

/* ---- the stage / problem card ---- */
.stage{
  width:min(96vw,640px);border-radius:var(--radius-lg);padding:18px;
  border:1px solid var(--stage-edge);background:var(--stage-bg);box-shadow:0 12px 30px var(--shadow);
}
.instr{font-size:.8rem;text-transform:uppercase;letter-spacing:1px;color:var(--label);font-weight:800;margin-bottom:8px}
.prompt{font-size:1.15rem;line-height:1.4;margin-bottom:16px}

/* ---- checkpoint panel (multiple-choice) ---- */
.choices{display:flex;flex-direction:column;gap:12px}
.choice{
  position:relative;text-align:left;cursor:pointer;color:var(--ink);font-size:1rem;
  background:var(--choice);border:1px solid var(--choice-edge);border-radius:var(--radius);
  padding:14px 16px;box-shadow:0 3px 8px var(--shadow);
  transition:transform .1s,border-color .2s,background .2s,box-shadow .2s;
}
.choice:hover{border-color:var(--accent);transform:translateY(-1px);box-shadow:0 6px 14px var(--shadow)}
.choice.correct{background:var(--good);border-color:transparent;color:var(--gx-on-state);animation:pop .32s ease}
.choice.wrong{background:var(--bad);border-color:transparent;color:var(--gx-on-state);animation:shake .4s ease}
.choice.locked{pointer-events:none;opacity:.85}

/* ---- toast ---- */
.toast{min-height:22px;text-align:center;margin-top:12px;font-weight:700;font-size:.95rem;color:var(--muted)}

/* ---- win screen ---- */
.win{display:none;text-align:center;margin-top:22px}
.win.show{display:block}
/* Filled and empty are the same path at two opacities — see icons.js. */
.stars{display:flex;justify-content:center;gap:8px;color:var(--accent)}
.stars svg{display:block;width:34px;height:34px}
.stars .off{opacity:.28}
.stars.inline{display:inline-flex;gap:3px;vertical-align:-2px}
.stars.inline svg{width:14px;height:14px}
.win.show .stars{animation:starPop .5s ease}   /* win stars flourish */
.win h2{font-size:1.6rem;margin:6px 0}
.btn{
  margin-top:14px;border:0;border-radius:12px;cursor:pointer;padding:12px 18px;font-weight:800;
  background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--btn-ink);font-size:1rem;
  box-shadow:0 4px 12px var(--shadow);transition:transform .12s,box-shadow .2s,filter .2s;
}
.btn:hover{transform:translateY(-2px);box-shadow:0 8px 18px var(--shadow)}
.btn:active{transform:translateY(1px)}
.btn.ghost{background:transparent;border:1px solid var(--pill-edge);color:var(--ink);margin-left:10px;box-shadow:none}

/* ---- confetti ----
   Painted shapes, not emoji: an emoji particle is a different typeface on
   every device, and the one thing this layer is for is looking the same
   everywhere. Colours are the palette's own, so a reskin carries them. */
.confetti{position:fixed;top:-20px;width:10px;height:10px;border-radius:2px;
  animation:fall linear forwards;z-index:9998;pointer-events:none;background:var(--accent)}
.confetti.c1{background:var(--accent2)}
.confetti.c2{background:var(--good);border-radius:50%}
.confetti.c3{background:var(--bad);border-radius:50%}
.confetti.c4{background:var(--accent);width:7px;height:14px;border-radius:1px}

/* =====================================================================
   JUICE  —  the shared keyframes. Reused by every mechanic so "correct"
   and "wrong" feel identical across games. No keyframe here ends a game.
   ===================================================================== */
@keyframes pop{                                  /* correct-pop */
  0%{transform:scale(1)}45%{transform:scale(1.05)}100%{transform:scale(1)}
}
@keyframes shake{                                /* wrong-shake (no fail — just a shake) */
  0%,100%{transform:translateX(0)}
  20%{transform:translateX(-8px)}40%{transform:translateX(8px)}
  60%{transform:translateX(-5px)}80%{transform:translateX(5px)}
}
@keyframes fall{                                 /* confetti */
  to{transform:translateY(105vh) rotate(360deg);opacity:.9}
}
@keyframes scorePop{                             /* score count-up bump */
  0%{transform:scale(1)}40%{transform:scale(1.18)}100%{transform:scale(1)}
}
@keyframes starPop{                              /* win stars */
  0%{transform:scale(.4);opacity:0}
  60%{transform:scale(1.15);opacity:1}
  100%{transform:scale(1)}
}

/* =====================================================================
   ALTERNATE THEME — original dark "night" skin. To switch back, replace
   the :root palette/surface values above with these:

     --bg1:#0f1123; --bg2:#23264d; --ink:#eef0ff; --muted:#9aa0d0;
     --accent:#ffd166; --accent2:#ff9f5a; --good:#22c197; --good-deep:#149174;
     --bad:#ff6b6b; --bad-deep:#b3323a;
     --choice:#2a2f52; --choice-edge:rgba(255,255,255,.14); --edge:rgba(255,255,255,.14);
     --stage-bg:rgba(255,255,255,.05); --stage-edge:rgba(255,255,255,.10);
     --pill-bg:rgba(255,255,255,.08); --pill-edge:rgba(255,255,255,.12); --shadow:rgba(0,0,0,.35);
     --label:var(--accent); --btn-ink:#1a1d3a;
     --back-btn-bg:rgba(0,0,0,.35); --back-btn-ink:#eef0ff;
   ===================================================================== */

/* =====================================================================
   NARROW WIDTHS — reserve the back chip's row (o15)
   a.back is position:fixed, so it takes up no space in the flow and the
   centred h1 slides underneath it once the title is wide enough. Measured
   at 420px: the chip's right edge is 83, the title's left edge is 66.
   Which width it breaks at depends on how long the title is, so this
   reserves the chip a row of its own rather than nudging one element:
   below 460px everything starts under the chip instead of beside it.
   Lives here because a.back and h1 are shared by every renderer.
   ===================================================================== */
@media (max-width:460px){
  body{padding-top:46px}
  h1{margin-top:0}
}

/* =====================================================================
   SKINS + TABLE  (2026-10-01, games redesign)
   ---------------------------------------------------------------------
   The redesigned games are drawn as a card table. They read the tokens
   below, never a literal colour, so one game looks right in every skin.

   Four skins, picked in game (skins.js, the cards button top right):
     classic  the app's own palette. Follows the light / dark setting
              (data-theme="night"), exactly as before. Default.
     sky      Sky Deck: deep blue table, white cards
     neon     Neon Court: dark court, glowing cyan and magenta
     parlor   The Parlor: green felt, cream cards, brass, serif type
   skins.js sets data-skin on <html> ("classic" removes it).

   Why the skin blocks target `:root[data-skin] body` and not just :root:
   several renderers give themselves an accent on `body` (Sort Board's
   green, for one). In Classic that local accent still shows; a chosen skin
   must win over it, so its tokens sit one step more specific than `body`.

   Derived table tokens live on `body` for the same reason: `var(--accent)`
   there resolves against a renderer's own body accent.
   ===================================================================== */
body{
  --page-ink:var(--ink); --page-muted:var(--muted); --page-label:color-mix(in oklab,var(--label) 45%,var(--ink));
  --card-face:var(--choice); --card-ink:var(--ink); --card-edge:rgba(21,50,74,.10);
  --card-shadow:0 1px 1px rgba(21,50,74,.14),0 10px 20px rgba(21,50,74,.18);
  --card-lift:0 1px 1px rgba(21,50,74,.14),0 16px 28px rgba(21,50,74,.24);
  --panel-bg:var(--choice); --panel-ink:var(--ink); --panel-muted:var(--muted);
  --well-bg:rgba(255,255,255,.30); --well-edge:rgba(255,255,255,.65);
  --slot-bg:rgba(255,255,255,.22); --slot-edge:rgba(21,50,74,.26);
  --seg-off:rgba(21,50,74,.14); --seg-now:rgba(21,50,74,.36);
  --mark:#8aa0b4; --mark-hot:#ff8a2a; --medal-bg:rgba(255,255,255,.92); --medal-ink:#ffffff;
  --brass:var(--accent2);
  --pile-1:#1f9e50; --pile-2:#ff8a2a; --pile-3:#3d8ee6; --pile-4:#9b6ad9;
  --suit-1:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E"); --suit-2:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Ccircle cx='12' cy='12' r='4.2'/%3E%3Cpath d='M12 2.5v2.6M12 18.9v2.6M2.5 12h2.6M18.9 12h2.6M5.3 5.3l1.8 1.8M16.9 16.9l1.8 1.8M5.3 18.7l1.8-1.8M16.9 7.1l1.8-1.8' stroke='black' stroke-width='2.2' stroke-linecap='round' fill='none'/%3E%3C/g%3E%3C/svg%3E"); --suit-3:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M19 14.5A7.5 7.5 0 1 1 9.5 5a6 6 0 0 0 9.5 9.5z'/%3E%3C/g%3E%3C/svg%3E"); --suit-4:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3l7 9-7 9-7-9z'/%3E%3C/g%3E%3C/svg%3E");
  --mark-glyph:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E");
  --back-art:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='white'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E") center / 40% no-repeat;
  --back-fill:linear-gradient(135deg,color-mix(in oklab,var(--accent) 45%,var(--accent2)),var(--accent2) 85%);
  --back-edge:4px solid var(--choice);
  --back-shadow:inset 0 0 0 1px color-mix(in oklab,var(--accent2) 70%,black),0 1px 1px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.22);
  --g-radius:12px; --g-flip:380ms; --g-flip-ease:cubic-bezier(.2,.7,.3,1.3);
  --g-glow:none;
}
:root[data-theme="night"] body{
  --page-label:var(--label);
  --card-edge:rgba(255,255,255,.12);
  --card-shadow:0 1px 1px rgba(0,0,0,.3),0 10px 22px rgba(0,0,0,.38);
  --card-lift:0 1px 1px rgba(0,0,0,.3),0 16px 30px rgba(0,0,0,.45);
  --well-bg:rgba(255,255,255,.05); --well-edge:rgba(255,255,255,.12);
  --slot-bg:rgba(255,255,255,.05); --slot-edge:rgba(255,255,255,.30);
  --seg-off:rgba(255,255,255,.14); --seg-now:rgba(255,255,255,.50);
  --mark:#9aa0d0; --medal-bg:rgba(255,255,255,.10);
}

/* ---- Sky Deck: the light palette on a deep blue table ---------------- */
:root[data-skin="sky"],:root[data-skin="sky"] body{
  --bg1:#123f86; --bg2:#2a6fc4; --ink:#15324a; --muted:#3a5f7a;
  --accent:#ffce3a; --accent2:#ff9f43; --good:#34c06b; --good-deep:#1f9e50; --bad:#ff6a6a; --bad-deep:#e0474f;
  --choice:#ffffff; --choice-edge:rgba(21,50,74,.14); --edge:rgba(21,50,74,.14);
  --stage-bg:rgba(8,26,60,.30); --stage-edge:rgba(255,255,255,.28);
  --pill-bg:#ffffff; --pill-edge:rgba(21,50,74,.10); --shadow:rgba(8,26,60,.30);
  --label:#ffce3a; --btn-ink:#15324a; --back-btn-bg:rgba(255,255,255,.85); --back-btn-ink:#15324a;
  --font:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --page-ink:#ffffff; --page-muted:rgba(255,255,255,.82); --page-label:#ffce3a;
  --card-face:#ffffff; --card-ink:#15324a; --card-edge:rgba(0,0,0,.08);
  --card-shadow:0 1px 1px rgba(0,0,0,.18),0 2px 0 rgba(0,0,0,.06),0 14px 26px rgba(0,0,0,.28);
  --card-lift:0 1px 1px rgba(0,0,0,.18),0 2px 0 rgba(0,0,0,.06),0 20px 34px rgba(0,0,0,.34);
  --panel-bg:#ffffff; --panel-ink:#15324a; --panel-muted:#3a5f7a;
  --well-bg:rgba(255,255,255,.10); --well-edge:rgba(255,255,255,.30);
  --slot-bg:rgba(255,255,255,.10); --slot-edge:rgba(255,255,255,.45);
  --seg-off:rgba(255,255,255,.18); --seg-now:rgba(255,255,255,.55);
  --mark:#8aa0b4; --mark-hot:#ff8a2a; --medal-bg:rgba(255,255,255,.92); --medal-ink:#ffffff;
  --brass:#ff9f43;
  --pile-1:#1f9e50; --pile-2:#ff8a2a; --pile-3:#5aa9f0; --pile-4:#b06ad9;
  --suit-1:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E"); --suit-2:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Ccircle cx='12' cy='12' r='4.2'/%3E%3Cpath d='M12 2.5v2.6M12 18.9v2.6M2.5 12h2.6M18.9 12h2.6M5.3 5.3l1.8 1.8M16.9 16.9l1.8 1.8M5.3 18.7l1.8-1.8M16.9 7.1l1.8-1.8' stroke='black' stroke-width='2.2' stroke-linecap='round' fill='none'/%3E%3C/g%3E%3C/svg%3E"); --suit-3:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M19 14.5A7.5 7.5 0 1 1 9.5 5a6 6 0 0 0 9.5 9.5z'/%3E%3C/g%3E%3C/svg%3E"); --suit-4:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3l7 9-7 9-7-9z'/%3E%3C/g%3E%3C/svg%3E");
  --mark-glyph:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E");
  --back-art:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='white'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E") center / 40% no-repeat;
  --back-fill:linear-gradient(135deg,color-mix(in oklab,#ffce3a 45%,#ff9f43),#ff9f43 85%);
  --back-edge:4px solid #ffffff;
  --back-shadow:inset 0 0 0 1px color-mix(in oklab,#ff9f43 70%,black),0 1px 1px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.22);
  --g-radius:12px; --g-flip:380ms; --g-flip-ease:cubic-bezier(.2,.7,.3,1.3); --g-glow:none;
}

/* ---- Neon Court: dark court, cyan and magenta glow -------------------- */
:root[data-skin="neon"],:root[data-skin="neon"] body{
  --bg1:#0b1022; --bg2:#1d2552; --ink:#f2f5ff; --muted:#a9b3de;
  --accent:#3ee6ff; --accent2:#ff4fd8; --good:#2ee6a6; --good-deep:#12a97d; --bad:#ff7a8a; --bad-deep:#d9435c;
  --choice:#161d3d; --choice-edge:rgba(255,255,255,.14); --edge:rgba(255,255,255,.12);
  --stage-bg:rgba(255,255,255,.04); --stage-edge:rgba(255,255,255,.12);
  --pill-bg:rgba(255,255,255,.07); --pill-edge:rgba(255,255,255,.14); --shadow:rgba(0,0,0,.45);
  --label:#3ee6ff; --btn-ink:#0b1022; --back-btn-bg:rgba(255,255,255,.07); --back-btn-ink:#f2f5ff;
  --font:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --page-ink:#f2f5ff; --page-muted:#a9b3de; --page-label:#3ee6ff;
  --card-face:#141a38; --card-ink:#f2f5ff; --card-edge:var(--accent);
  --card-shadow:0 1px 1px rgba(0,0,0,.3),0 0 22px color-mix(in oklab,#3ee6ff 30%,transparent);
  --card-lift:0 1px 1px rgba(0,0,0,.3),0 0 30px color-mix(in oklab,#3ee6ff 45%,transparent);
  --panel-bg:#141a38; --panel-ink:#f2f5ff; --panel-muted:#a9b3de;
  --well-bg:rgba(255,255,255,.04); --well-edge:rgba(255,255,255,.14);
  --slot-bg:rgba(255,255,255,.04); --slot-edge:rgba(62,230,255,.45);
  --seg-off:rgba(255,255,255,.12); --seg-now:rgba(62,230,255,.55);
  --mark:#3ee6ff; --mark-hot:#3ee6ff; --medal-bg:rgba(11,16,34,.5); --medal-ink:#0b1022;
  --brass:#3ee6ff;
  --pile-1:#3ee6ff; --pile-2:#ff4fd8; --pile-3:#2ee6a6; --pile-4:#ffd166;
  --suit-1:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E"); --suit-2:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M19 14.5A7.5 7.5 0 1 1 9.5 5a6 6 0 0 0 9.5 9.5z'/%3E%3C/g%3E%3C/svg%3E"); --suit-3:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Ccircle cx='12' cy='12' r='4.2'/%3E%3Cpath d='M12 2.5v2.6M12 18.9v2.6M2.5 12h2.6M18.9 12h2.6M5.3 5.3l1.8 1.8M16.9 16.9l1.8 1.8M5.3 18.7l1.8-1.8M16.9 7.1l1.8-1.8' stroke='black' stroke-width='2.2' stroke-linecap='round' fill='none'/%3E%3C/g%3E%3C/svg%3E"); --suit-4:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3l7 9-7 9-7-9z'/%3E%3C/g%3E%3C/svg%3E");
  --mark-glyph:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E");
  --back-art:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cg fill='%23ffffff' fill-opacity='0.5'%3E%3Cpath transform='translate%281.1 1.1%29 scale%280.366667%29' d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3Cpath transform='translate%2812.1 12.1%29 scale%280.366667%29' d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 22px 22px;
  --back-fill:linear-gradient(150deg,#3ee6ff,#2a7dff);
  --back-edge:1px solid rgba(255,255,255,.3);
  --back-shadow:0 1px 1px rgba(0,0,0,.3),0 0 22px color-mix(in oklab,#3ee6ff 45%,transparent);
  --g-radius:12px; --g-flip:240ms; --g-flip-ease:cubic-bezier(.2,.8,.3,1);
  --g-glow:0 0 18px color-mix(in oklab,#3ee6ff 35%,transparent);
}

/* ---- The Parlor: green felt, cream cards, brass, serif ---------------- */
:root[data-skin="parlor"],:root[data-skin="parlor"] body{
  --bg1:#0f3326; --bg2:#235a45; --ink:#f4ecd9; --muted:#c3d3c6;
  --accent:#e2c06a; --accent2:#b8862f; --good:#5cc98a; --good-deep:#2f9a5e; --bad:#e8806e; --bad-deep:#b84a3a;
  --choice:#f4ecd9; --choice-edge:rgba(43,33,24,.18); --edge:rgba(244,236,217,.16);
  --stage-bg:rgba(0,0,0,.18); --stage-edge:rgba(244,236,217,.14);
  --pill-bg:rgba(0,0,0,.22); --pill-edge:rgba(244,236,217,.16); --shadow:rgba(0,0,0,.38);
  --label:#e2c06a; --btn-ink:#2b2118; --back-btn-bg:rgba(0,0,0,.25); --back-btn-ink:#f4ecd9;
  --font:Georgia,'Times New Roman',serif;
  --page-ink:#f4ecd9; --page-muted:#c3d3c6; --page-label:#e2c06a;
  --card-face:#f4ecd9; --card-ink:#2b2118; --card-edge:rgba(43,33,24,.18);
  --card-shadow:inset 0 0 0 1px #b08d3f,inset 0 0 0 4px #f4ecd9,inset 0 0 0 5px color-mix(in oklab,#b08d3f 45%,transparent),0 1px 1px rgba(0,0,0,.3),0 14px 26px rgba(0,0,0,.38);
  --card-lift:inset 0 0 0 1px #b08d3f,inset 0 0 0 4px #f4ecd9,inset 0 0 0 5px color-mix(in oklab,#b08d3f 45%,transparent),0 1px 1px rgba(0,0,0,.3),0 20px 34px rgba(0,0,0,.45);
  --panel-bg:#f4ecd9; --panel-ink:#2b2118; --panel-muted:#6b5a45;
  --well-bg:rgba(0,0,0,.16); --well-edge:rgba(176,141,63,.45);
  --slot-bg:rgba(0,0,0,.20); --slot-edge:rgba(176,141,63,.80);
  --seg-off:rgba(244,236,217,.16); --seg-now:rgba(226,192,106,.60);
  --mark:#b08d3f; --mark-hot:#7d2a2a; --medal-bg:rgba(0,0,0,.25); --medal-ink:#ecd08a;
  --brass:#b08d3f;
  --pile-1:#7d2a2a; --pile-2:#24365a; --pile-3:#2a6b52; --pile-4:#6b4a1e;
  --suit-1:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3C/g%3E%3C/svg%3E"); --suit-2:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z'/%3E%3C/g%3E%3C/svg%3E"); --suit-3:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3l7 9-7 9-7-9z'/%3E%3C/g%3E%3C/svg%3E"); --suit-4:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Ccircle cx='12' cy='7.6' r='3.6'/%3E%3Ccircle cx='7.6' cy='13' r='3.6'/%3E%3Ccircle cx='16.4' cy='13' r='3.6'/%3E%3Cpath d='M11 13h2l1.2 7.5h-4.4z'/%3E%3C/g%3E%3C/svg%3E");
  --mark-glyph:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3C/g%3E%3C/svg%3E");
  --back-art:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cg fill='%23b08d3f' fill-opacity='0.38'%3E%3Cpath transform='translate%281 1%29 scale%280.333333%29' d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3Cpath transform='translate%2811 11%29 scale%280.333333%29' d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 20px 20px;
  --back-fill:linear-gradient(160deg,#7d2a2a,#561b1b);
  --back-edge:0;
  --back-shadow:inset 0 0 0 4px #561b1b,inset 0 0 0 5px #b08d3f,0 1px 1px rgba(0,0,0,.3),0 8px 16px rgba(0,0,0,.38);
  --g-radius:9px; --g-flip:600ms; --g-flip-ease:cubic-bezier(.4,0,.2,1);
  --g-glow:none;
}
/* Every skin keeps the shell's page background rule. */
:root[data-skin] body{color:var(--page-ink)}

/* ---- shared surfaces that must read on every skin ---------------------- */
.choice{color:var(--card-ink);background:var(--card-face)}
.pill{color:var(--ink)}
h1,.sub{color:inherit}
.sub{color:var(--page-muted)}

/* ---- the skin button and sheet (skins.js) ------------------------------ */
.skin-btn{
  position:fixed;top:10px;right:12px;z-index:9999;width:44px;height:44px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;
  background:var(--back-btn-bg);color:var(--back-btn-ink);border:1px solid var(--pill-edge);
  box-shadow:0 2px 6px var(--shadow);font:inherit;transition:transform var(--flow-press,90ms)}
.skin-btn:active{transform:scale(.94)}
.skin-btn svg{width:20px;height:20px;display:block}
.skin-btn:focus-visible,.skin-opt:focus-visible,.skin-close:focus-visible{outline:3px solid var(--accent);outline-offset:2px}
.skin-veil{position:fixed;inset:0;z-index:10000;display:flex;align-items:flex-end;justify-content:center;
  background:color-mix(in oklab,var(--bg1) 55%,transparent);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  padding:0 0 env(safe-area-inset-bottom)}
.skin-sheet{width:min(100%,520px);background:var(--panel-bg);color:var(--panel-ink);border-radius:22px 22px 0 0;
  padding:16px 16px 20px;box-shadow:0 -10px 40px var(--shadow);animation:flowIn var(--flow-reveal,260ms) var(--flow-ease-out,ease-out) both;
  font-family:var(--font)}
.skin-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
.skin-head h2{font-size:1.1rem;margin:0}
.skin-head p{font-size:.8rem;color:var(--panel-muted);margin-top:2px}
.skin-close{min-width:44px;min-height:44px;border-radius:50%;border:1px solid var(--choice-edge);background:transparent;
  color:var(--panel-ink);font:inherit;font-size:1.2rem;cursor:pointer}
.skin-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.skin-opt{position:relative;display:flex;flex-direction:column;align-items:stretch;gap:8px;padding:8px;min-height:48px;
  border-radius:16px;border:2px solid var(--choice-edge);background:transparent;color:var(--panel-ink);font:inherit;
  cursor:pointer;text-align:left}
.skin-opt[aria-pressed="true"]{border-color:var(--accent2)}
.skin-opt[aria-pressed="true"]::after{content:"";position:absolute;top:12px;right:12px;width:22px;height:22px;border-radius:50%;
  background:var(--accent2) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M5 13l4 4L19 7'/></svg>") center/70% no-repeat}
.skin-swatch{position:relative;height:74px;border-radius:11px;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:6px}
.skin-swatch i{display:block;width:30px;height:42px;border-radius:5px}
.skin-name{font-weight:800;font-size:.95rem;line-height:1.2}
.skin-sub{font-size:.75rem;color:var(--panel-muted);line-height:1.3}
@media (hover:hover) and (pointer:fine){ .skin-opt:hover{border-color:var(--accent)} }

/* =====================================================================
   TABLE PIECES — shared by the redesigned games
   ===================================================================== */
.g-col{width:min(100%,480px);display:flex;flex-direction:column;align-items:stretch;gap:0}
.g-col .hud{justify-content:center;flex-wrap:wrap;gap:6px;margin:12px 0 10px}
.g-col .hud .pill{padding:6px 11px;font-size:.86rem;gap:6px;white-space:nowrap}
@media (max-width:360px){ .g-col .hud .pill{padding:5px 9px;font-size:.8rem} }
.g-col h1{font-size:1.25rem;letter-spacing:.3px}
.g-col .sub{font-size:.8rem}
/* progress: a row of segments rather than dots (same .pip / .done / .now classes) */
.pips.seg{display:flex;gap:4px;width:100%;margin:0 0 12px}
.pips.seg .pip{flex:1 1 0;width:auto;height:6px;border-radius:3px;background:var(--seg-off);transition:background 240ms ease}
.pips.seg .pip.done{background:linear-gradient(90deg,var(--accent),var(--accent2))}
.pips.seg .pip.now{background:var(--seg-now);box-shadow:none}
.pill .x{font-size:.72rem;color:var(--accent2);font-weight:800}
.g-row{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:24px}
.g-row .instr{margin:0;color:var(--page-label)}
.g-row .g-meta{font-size:.72rem;font-weight:800;letter-spacing:.5px;color:var(--page-muted);text-align:right}
.g-col > .toast,.g-col .toast{color:var(--page-ink)}
/* the felt: a translucent table area that holds a grid or a board */
.g-well{background:var(--well-bg);border:1px solid var(--well-edge);border-radius:calc(var(--g-radius) + 8px);padding:10px;
  box-shadow:inset 0 2px 12px rgba(0,0,0,.10)}
/* a card face: corner marks are the skin's own glyph, painted in --mark */
.g-face{position:relative;background:var(--card-face);color:var(--card-ink);border:1px solid var(--card-edge);
  border-radius:var(--g-radius);box-shadow:var(--card-shadow)}
:root[data-skin="neon"] .g-face{border-width:1.5px}
:root[data-skin="parlor"] .g-face{border-color:transparent}
.g-face.marks::before,.g-face.marks::after{content:"";position:absolute;width:11px;height:11px;background:var(--mark);
  -webkit-mask:var(--mark-glyph) center/contain no-repeat;mask:var(--mark-glyph) center/contain no-repeat;pointer-events:none}
.g-face.marks::before{top:7px;left:7px}
.g-face.marks::after{bottom:7px;right:7px;transform:rotate(180deg)}
.g-face.marks.hot::before,.g-face.marks.hot::after{background:var(--mark-hot)}
/* a card back */
.g-back{border-radius:var(--g-radius);background:var(--back-art),var(--back-fill);border:var(--back-edge);box-shadow:var(--back-shadow)}
/* a pile medal: the n-th suit of the skin on the n-th pile colour */
.g-medal{width:34px;height:34px;border-radius:50%;flex-shrink:0;position:relative;background:var(--pc,var(--pile-1));
  box-shadow:0 0 0 3px rgba(255,255,255,.9),0 4px 10px rgba(0,0,0,.2)}
.g-medal::after{content:"";position:absolute;inset:6px;background:var(--medal-ink);
  -webkit-mask:var(--sg,var(--suit-1)) center/contain no-repeat;mask:var(--sg,var(--suit-1)) center/contain no-repeat}
:root[data-skin="neon"] .g-medal{box-shadow:0 0 16px var(--pc,var(--pile-1))}
:root[data-skin="parlor"] .g-medal{box-shadow:0 0 0 2px var(--brass),0 3px 8px rgba(0,0,0,.35)}
:root[data-theme="night"]:not([data-skin]) .g-medal{box-shadow:0 0 0 2px rgba(255,255,255,.5),0 4px 10px rgba(0,0,0,.3)}
.g-suit{display:inline-block;width:12px;height:12px;flex-shrink:0;background:var(--pc,var(--pile-1));
  -webkit-mask:var(--sg,var(--suit-1)) center/contain no-repeat;mask:var(--sg,var(--suit-1)) center/contain no-repeat}
.g-k1{--pc:var(--pile-1);--sg:var(--suit-1)} .g-k2{--pc:var(--pile-2);--sg:var(--suit-2)}
.g-k3{--pc:var(--pile-3);--sg:var(--suit-3)} .g-k4{--pc:var(--pile-4);--sg:var(--suit-4)}
/* a dashed slot where something can land */
.g-slot{border:2px dashed var(--slot-edge);background:var(--slot-bg);border-radius:calc(var(--g-radius) + 2px)}
:root[data-skin="parlor"] .g-slot{border-width:1.5px}
/* big primary action under a board ("Check the order") */
.g-cta{display:block;margin:14px auto 0;min-height:48px}
/* the reward beat as an overlay panel on the table */
.win.g-win{position:fixed;inset:0;z-index:50;margin:0;display:none;align-items:center;justify-content:center;padding:18px;
  background:color-mix(in oklab,var(--bg1) 72%,transparent);backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);overflow:auto}
.win.g-win.show{display:flex}
.g-win .g-panel{--ink:var(--panel-ink);--muted:var(--panel-muted);--stage-bg:color-mix(in oklab,var(--panel-ink) 4%,transparent);
  --stage-edge:var(--choice-edge);--edge:var(--choice-edge);--pill-edge:var(--choice-edge);--card-ink:var(--panel-ink);
  width:min(100%,420px);margin:auto;background:var(--panel-bg);color:var(--panel-ink);border:1px solid var(--choice-edge);border-radius:20px;
  padding:22px 18px 18px;text-align:center;box-shadow:0 20px 60px var(--shadow)}
.g-win .g-panel h2{color:var(--panel-ink)}
.g-win .g-panel{--label:color-mix(in oklab,var(--accent2) 75%,var(--panel-ink))}
.g-win .stars svg path{fill:currentColor}
.g-win .stars span:nth-child(2){transform:translateY(-6px)}
.g-win .g-score{font-size:2rem;font-weight:800;color:var(--accent2);margin-top:2px}
.g-win .g-stats{font-size:.82rem;color:var(--panel-muted)}
.g-win .flow-answers{width:100%}
.g-win .g-btns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.g-win .g-btns .btn{margin-left:0;min-height:46px;display:inline-flex;align-items:center;text-decoration:none}
.g-win .btn.ghost{color:var(--panel-ink);border-color:var(--choice-edge)}
/* the shared flip: .g-flip holds .g-back and .g-front; add .up to show the front */
.g-flip{position:relative;perspective:900px}
.g-flip > .g-in{position:absolute;inset:0;transform-style:preserve-3d;transition:transform var(--g-flip) var(--g-flip-ease)}
.g-flip.up > .g-in{transform:rotateY(180deg)}
.g-flip .g-back,.g-flip .g-front{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.g-flip .g-front{transform:rotateY(180deg)}
/* table keyframes */
@keyframes gDeal{from{transform:translate(-150px,20px) rotate(-6deg) scale(.68)}to{transform:none}}
@keyframes gToss{to{transform:translate(var(--tx,0),var(--ty,-300px)) rotate(var(--rot,0deg)) scale(.34);opacity:.2}}
@keyframes gDrop{to{transform:translateY(70px) rotate(-7deg);opacity:0}}
@keyframes gLater{to{transform:translate(-150px,20px) rotate(-6deg) scale(.6);opacity:0}}
@keyframes gTab{from{opacity:0;transform:translateY(14px) scale(.9)}to{opacity:1}}
@keyframes gIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes gBlink{0%,100%{opacity:.45}50%{opacity:1}}
@keyframes gDraw{to{stroke-dashoffset:0}}
@keyframes gFlipIn{from{opacity:0;transform:rotateY(90deg) translateY(10px)}to{opacity:1;transform:none}}
@keyframes gFade{from{opacity:0}to{opacity:1}}
@keyframes gPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.14)}}
@keyframes gSnap{from{opacity:0;transform:translateY(16px) scale(.9)}}
@media (prefers-reduced-motion:reduce){
  .g-flip > .g-in{transition:none}
  .g-deal,.g-toss,.g-drop,.g-later,.g-tab{animation:none !important}
}

/* ---- two-sided cards (Card Match, Memory Grid): side A and side B each have
   their own back colour and glyph, so a face-down card already says which
   side it is. --tile-* is the back's pattern (none on Classic / Sky). ------ */
body{
  --side-a:var(--good); --side-a2:var(--good-deep); --side-b:var(--accent); --side-b2:var(--accent2);
  --back-ink-a:#ffffff; --back-ink-b:var(--btn-ink);
  --glyph-a:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E"); --glyph-b:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Ccircle cx='12' cy='12' r='4.2'/%3E%3Cpath d='M12 2.5v2.6M12 18.9v2.6M2.5 12h2.6M18.9 12h2.6M5.3 5.3l1.8 1.8M16.9 16.9l1.8 1.8M5.3 18.7l1.8-1.8M16.9 7.1l1.8-1.8' stroke='black' stroke-width='2.2' stroke-linecap='round' fill='none'/%3E%3C/g%3E%3C/svg%3E"); --tile-a:none; --tile-b:none;
}
:root[data-skin="neon"] body{
  --side-a:#3ee6ff; --side-a2:#2a7dff; --side-b:#ff4fd8; --side-b2:#8f4dff; --back-ink-a:#0b1022; --back-ink-b:#ffffff;
  --glyph-a:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E"); --glyph-b:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M19 14.5A7.5 7.5 0 1 1 9.5 5a6 6 0 0 0 9.5 9.5z'/%3E%3C/g%3E%3C/svg%3E"); --tile-a:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'%3E%3Cg fill='%23ffffff' fill-opacity='0.5'%3E%3Cpath transform='translate%281.1 1.1%29 scale%280.366667%29' d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3Cpath transform='translate%2812.1 12.1%29 scale%280.366667%29' d='M12 4l2.4 5 5.6.8-4 3.9 1 5.5-5-2.6-5 2.6 1-5.5-4-3.9 5.6-.8z'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 22px 22px; --tile-b:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='%23ffffff' fill-opacity='0.45'%3E%3Cpath transform='translate%281.2 1.2%29 scale%280.4%29' d='M19 14.5A7.5 7.5 0 1 1 9.5 5a6 6 0 0 0 9.5 9.5z'/%3E%3Cpath transform='translate%2813.2 13.2%29 scale%280.4%29' d='M19 14.5A7.5 7.5 0 1 1 9.5 5a6 6 0 0 0 9.5 9.5z'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 24px 24px;
}
:root[data-skin="parlor"] body{
  --side-a:#7d2a2a; --side-a2:#561b1b; --side-b:#24365a; --side-b2:#15213b; --back-ink-a:#ecd08a; --back-ink-b:#ecd08a;
  --glyph-a:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3C/g%3E%3C/svg%3E"); --glyph-b:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cpath d='M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z'/%3E%3C/g%3E%3C/svg%3E"); --tile-a:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cg fill='%23b08d3f' fill-opacity='0.38'%3E%3Cpath transform='translate%281 1%29 scale%280.333333%29' d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3Cpath transform='translate%2811 11%29 scale%280.333333%29' d='M12 3C9 7 5 9.5 5 13a3.5 3.5 0 0 0 6 2.4L10 20h4l-1-4.6A3.5 3.5 0 0 0 19 13c0-3.5-4-6-7-10z'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 20px 20px; --tile-b:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cg fill='%23b08d3f' fill-opacity='0.38'%3E%3Cpath transform='translate%281 1%29 scale%280.333333%29' d='M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z'/%3E%3Cpath transform='translate%2811 11%29 scale%280.333333%29' d='M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 20px 20px;
}

/* =====================================================================
   TWO-SIDED CARDS — Card Match and Memory Grid (2026-10-01 redesign)
   A .tcard is a <button> holding .cm-slot, .g-flip > .g-in > (.cm-back, .g-front)
   and a .turn badge. States: .flipped / .lifted / .matched (+ .settled or
   .cleared, by skin) / .correct / .wrong. .g-combo is Neon Court's combo meter,
   .g-tray the matched-pairs tray every other skin shows.
   ===================================================================== */
/* Neon Court: a combo meter instead of the tray */
.g-combo{display:none;align-items:center;gap:10px;width:100%;margin:-2px 0 10px}
:root[data-skin="neon"] .g-combo{display:flex}
.g-combo .k{font-size:11px;letter-spacing:1.5px;font-weight:800;color:var(--label)}
.g-combo .segs{flex:1;display:flex;gap:4px}
.g-combo .segs i{flex:1;height:8px;border-radius:4px;background:rgba(255,255,255,.1);transition:background 240ms ease,box-shadow 240ms ease}
.g-combo .segs i.on{background:linear-gradient(90deg,var(--accent),var(--accent2));box-shadow:0 0 10px color-mix(in oklab,var(--accent) 60%,transparent)}
.g-combo .m{font-size:12px;font-weight:800;color:var(--accent2)}

.tcard{position:relative;aspect-ratio:3/4;padding:0;border:0;background:transparent;font:inherit;color:inherit;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:transform 220ms cubic-bezier(.34,1.56,.64,1),opacity 300ms ease;z-index:1}
.tcard.side-a{--sc:var(--side-a);--sc2:var(--side-a2);--bink:var(--back-ink-a);--sg:var(--glyph-a);--tile:var(--tile-a)}
.tcard.side-b{--sc:var(--side-b);--sc2:var(--side-b2);--bink:var(--back-ink-b);--sg:var(--glyph-b);--tile:var(--tile-b)}
.tcard .g-flip{position:absolute;inset:0}
.tcard .g-in{transition:transform var(--g-flip) var(--g-flip-ease),opacity 360ms ease}
.tcard.flipped .g-flip > .g-in,.tcard.matched .g-flip > .g-in{transform:rotateY(180deg)}
.tcard.lifted .g-flip > .g-in{transform:rotateY(180deg) translateZ(18px)}
/* the back: side-coded */
.cm-back{display:flex;align-items:center;justify-content:center;border-radius:9px;
  background:linear-gradient(135deg,color-mix(in oklab,var(--accent) 45%,var(--accent2)),var(--accent2) 85%);
  border:4px solid var(--choice);
  box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--accent2) 70%,black),0 1px 1px rgba(0,0,0,.18),0 2px 0 rgba(0,0,0,.06),0 8px 16px rgba(0,0,0,.22)}
.cm-medal{width:42%;aspect-ratio:1;background:var(--btn-ink);-webkit-mask:var(--sg) center/contain no-repeat;mask:var(--sg) center/contain no-repeat}
:root[data-skin="neon"] .cm-back{border-radius:var(--g-radius);background:var(--tile),linear-gradient(150deg,var(--sc),var(--sc2));border:1px solid rgba(255,255,255,.3);
  box-shadow:0 1px 1px rgba(0,0,0,.3),0 0 22px color-mix(in oklab,var(--sc) 50%,transparent)}
:root[data-skin="neon"] .cm-medal{display:none}
:root[data-skin="parlor"] .cm-back{border-radius:var(--g-radius);border:0;background:var(--tile),linear-gradient(160deg,var(--sc),var(--sc2));
  box-shadow:inset 0 0 0 4px var(--sc2),inset 0 0 0 5px var(--brass),0 1px 1px rgba(0,0,0,.3),0 8px 16px var(--shadow)}
:root[data-skin="parlor"] .cm-medal{width:44%;border-radius:50%;background:var(--sc2);border:1px solid var(--brass);box-shadow:0 0 0 4px var(--sc2);
  -webkit-mask:none;mask:none;position:relative}
:root[data-skin="parlor"] .cm-medal::after{content:"";position:absolute;inset:22%;background:var(--brass);-webkit-mask:var(--sg) center/contain no-repeat;mask:var(--sg) center/contain no-repeat}
/* the face */
.tcard .g-front{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:16px 5px;text-align:center;border-radius:9px;
  --mark-glyph:var(--sg);--mark:var(--sc)}
:root[data-skin] .tcard .g-front{border-radius:var(--g-radius)}
:root[data-skin="neon"] .tcard .g-front{border:1.5px solid var(--sc);box-shadow:0 1px 1px rgba(0,0,0,.3),0 0 16px color-mix(in oklab,var(--sc) 40%,transparent)}
.expr{font-size:.9rem;font-weight:800;line-height:1.1;color:var(--card-ink);text-wrap:balance;overflow-wrap:anywhere;hyphens:auto}
.side-b .expr{font-size:.74rem;font-weight:700;line-height:1.25}
.expr.mid{font-size:.8rem}
.expr.small{font-size:.68rem;font-weight:700;line-height:1.25}
:root[data-skin="parlor"] .side-a .expr{font-weight:700}
.tag{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}   /* side name: for screen readers; the back and glyph say it on screen */
/* states */
.tcard.lifted{transform:translateY(-7px) rotate(-1deg);z-index:2}
:root:not([data-skin]) .tcard.lifted,:root[data-skin="sky"] .tcard.lifted{outline:3px solid var(--accent);outline-offset:2px;border-radius:11px}
:root[data-skin="neon"] .tcard.lifted .g-front{box-shadow:0 0 0 1px var(--sc),0 0 30px color-mix(in oklab,var(--sc) 65%,transparent)}
:root[data-skin="parlor"] .tcard.lifted{transform:translateY(-8px) rotate(-2deg)}
:root[data-skin="parlor"] .tcard.lifted .g-front{box-shadow:var(--card-lift),0 0 0 2px var(--accent)}
.tcard.correct .g-front{box-shadow:0 0 0 3px var(--good),0 12px 24px var(--shadow)}
:root[data-skin="neon"] .tcard.correct .g-front{border-color:var(--good);box-shadow:0 0 0 1px var(--good),0 0 28px color-mix(in oklab,var(--good) 60%,transparent)}
.tcard.wrong .g-front{box-shadow:0 0 0 3px var(--bad),0 8px 18px var(--shadow)}
:root[data-skin="neon"] .tcard.wrong .g-front{border-color:var(--bad);box-shadow:0 0 22px color-mix(in oklab,var(--bad) 55%,transparent)}
/* Classic and Sky Deck: a matched pair stays, dimmed, so the board keeps its shape */
.tcard.matched{cursor:default}
:root:not([data-skin]) .tcard.matched.settled,:root[data-skin="sky"] .tcard.matched.settled{opacity:.45;transform:scale(.93)}
:root:not([data-skin]) .tcard.matched.settled .g-front,:root[data-skin="sky"] .tcard.matched.settled .g-front{box-shadow:none}
/* Neon and Parlor: a matched pair clears off the table and leaves its slot */
.cm-slot{position:absolute;inset:0;border-radius:var(--g-radius);opacity:0;transition:opacity 360ms ease;
  background:rgba(0,0,0,.16);box-shadow:inset 0 2px 8px rgba(0,0,0,.3);border:1px solid rgba(255,255,255,.06)}
:root[data-skin="neon"] .cm-slot{background:none;box-shadow:none;border:1.5px dashed rgba(255,255,255,.16)}
.tcard.cleared .cm-slot{opacity:1}
.tcard.cleared .g-in{opacity:0}
/* Pop and shake come from skin.css (.flow-mark on the card). The painted
   check / cross is the corner badge, so colour is never the only signal. */
.tcard.flow-mark.correct::after,.tcard.flow-mark.wrong::after{
  right:-7px;top:-7px;margin-top:0;width:24px;height:24px;border-radius:50%;z-index:3;box-shadow:0 2px 6px var(--shadow);background-size:60%}
.tcard.flow-mark.correct::after{background-color:var(--good-deep)}
.tcard.flow-mark.wrong::after{background-color:var(--bad-deep)}
.tcard.matched.settled.flow-mark.correct::after,.tcard.cleared.flow-mark.correct::after{display:none}
.tcard.flow-hint{outline-offset:-3px;border-radius:11px}
/* tap a face-up card again to turn it back: the little badge says so */
.turn{position:absolute;bottom:-9px;left:50%;margin-left:-15px;width:30px;height:30px;border-radius:50%;z-index:3;display:none;
  align-items:center;justify-content:center;background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--btn-ink);box-shadow:0 3px 8px var(--shadow)}
.turn svg{width:16px;height:16px}
.tcard.lifted .turn{display:flex;animation:flowIn var(--flow-reveal) var(--flow-ease-out) both}
/* the tray: matched pairs land here */
.g-tray{display:flex;flex-direction:column;gap:6px;width:100%;margin-top:auto;padding:12px 14px;border-radius:16px;
  background:var(--well-bg);border:1px solid var(--well-edge);backdrop-filter:blur(14px) saturate(150%);-webkit-backdrop-filter:blur(14px) saturate(150%)}
:root[data-skin="neon"] .g-tray{display:none}
.g-tray .head{display:flex;justify-content:space-between;font-size:11px;letter-spacing:1.5px;font-weight:800;color:var(--page-label);text-transform:uppercase}
.g-tray .list{display:flex;gap:6px;flex-wrap:wrap}
.g-tray .empty{font-size:12px;color:var(--page-muted)}
.g-tray .pr{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:700;padding:5px 9px;border-radius:999px;
  background:var(--card-face);color:var(--card-ink);border:1px solid var(--choice-edge);animation:gIn 300ms ease-out both}
:root[data-skin="parlor"] .g-tray .pr{font-style:italic}
.g-tray .pr i{width:7px;height:7px;border-radius:50%;background:var(--side-a)}
.g-tray .pr i + span + i{background:var(--side-b)}
@media (prefers-reduced-motion:reduce){ .tcard,.tcard .g-in,.cm-slot{transition:none} .g-tray .pr{animation:none} }
/* One back for every card (Memory Grid): the side still shows in the face's corner glyph. */
.same-backs .tcard .cm-back{--sc:var(--side-a);--sc2:var(--side-a2);--sg:var(--glyph-a);--tile:var(--tile-a)}
/* Flip-down wave after a preview: each card waits its turn (set --w on the card). */
.tcard.wave .g-in{transition-delay:calc(var(--w,0) * 45ms)}

/* =====================================================================
   PLAY AND POLISH (2026-10-14) — shared feel tokens. One press physics,
   one streak and reward colour, tabular digits so counters never jitter.
   Reduced motion is already covered globally in native-feel.css.
   ===================================================================== */
:root{
  --press-scale:.96;           /* how far a pressed thing sinks          */
  --press-ms:100ms;            /* press feedback lands inside 100ms      */
  --streak:#ff8a3d;            /* streak flame                           */
  --reward:#ffce3a;            /* stars, +N chips, gain                  */
  --fs-min:11px;               /* nothing the player reads goes below it */
}
:root[data-theme="night"],body.shell[data-bg="night"]{--streak:#ff9f5a;--reward:#ffd166}
.pill,.g-score,.g-combo,.hud span,#score,#streak{font-variant-numeric:tabular-nums}
.choice,.btn,.aid{transition-property:transform,box-shadow,border-color,background,filter;transition-duration:var(--press-ms),.2s,.2s,.2s,.2s}
.choice:active{transform:scale(var(--press-scale))}
.btn:active{transform:scale(var(--press-scale))}

/* =====================================================================
   FLOW  —  the one animation flow every mechanic shares (2026-09-25)
   ---------------------------------------------------------------------
   Spec: docs/animation-flow-spec.md. Behaviour: flow.js (window.GamifyFlow).
   This block is only tokens, looks and keyframes, so retiming the whole app
   is a change to the tokens below.

   Placed at the end of the file on purpose: everything here is namespaced
   flow-* (nothing redefines an existing class, keyframe or token) so it can
   sit beside the motion-pass layer (.lifted / .armed / .flipping / .deal-in)
   without either one knowing about the other.

   Reduced motion is handled in this block, class by class, and NOT with a
   blanket "every animation lasts 1ms" rule. A chip that flies up and fades
   would vanish instantly under that rule and take its information with it;
   flow.js keeps such chips still and readable instead (see reduced()).
   ===================================================================== */
:root{
  --flow-ease-out:cubic-bezier(.2,.8,.3,1);
  --flow-ease-in:cubic-bezier(.4,0,1,1);
  --flow-ease-io:cubic-bezier(.4,0,.2,1);
  --flow-spring:cubic-bezier(.34,1.56,.64,1);
  --flow-press:90ms;
  --flow-fast:160ms;
  --flow-reveal:260ms;
  --flow-pop:320ms;
  --flow-shake:400ms;
  --flow-chip:760ms;
  --flow-streak:640ms;
  --flow-star:500ms;
  --flow-answer:420ms;
  --flow-stagger:60ms;
}

/* ---- 1. intro: heading first, then the rest, staggered ------------------
   No opacity:0 in the base rule: `both` holds the first keyframe during the
   delay, and if the animation never runs (reduced motion, or flow.js removing
   the class) nothing is left invisible. */
.flow-in{animation:flowIn var(--flow-reveal) var(--flow-ease-out) both;animation-delay:calc(var(--i,0) * var(--flow-stagger))}
.flow-in.flow-head{animation-name:flowHead}
.flow-swap{animation:flowSwap var(--flow-reveal) var(--flow-ease-out) both}
@keyframes flowIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes flowHead{from{opacity:0;letter-spacing:.14em;transform:translateY(4px)}to{opacity:1;letter-spacing:1px;transform:none}}
@keyframes flowSwap{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ---- 2 + 3. correct / wrong: pop and shake keep their keyframes, gain a
   second channel (a painted glyph) so color is never the only signal ------- */
.choice.correct,.flow-mark.correct{animation:pop var(--flow-pop) var(--flow-spring)}
.choice.wrong,.flow-mark.wrong{animation:shake var(--flow-shake) ease}
.choice.correct,.choice.wrong{padding-right:44px}
:is(.choice,.flow-mark).correct::after,:is(.choice,.flow-mark).wrong::after{
  content:"";position:absolute;right:12px;top:50%;width:22px;height:22px;margin-top:-11px;
  background:center/contain no-repeat;pointer-events:none}
:is(.choice,.flow-mark).correct::after{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M5 13l4 4L19 7'/></svg>")}
:is(.choice,.flow-mark).wrong::after{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M7 7l10 10M17 7L7 17'/></svg>")}
/* correct and wrong choices: dark glyph in the same ink as the text, so the answer reads by colour, glyph and shape */
.choice.correct::after,.choice.wrong::after{
  background:var(--gx-on-state);
  -webkit-mask:center/contain no-repeat;mask:center/contain no-repeat}
.choice.correct::after{
  -webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><path d='M5 13l4 4L19 7'/></svg>");
          mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><path d='M5 13l4 4L19 7'/></svg>")}
.choice.wrong::after{
  -webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><path d='M6 6l12 12M18 6L6 18'/></svg>");
          mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.8' stroke-linecap='round' stroke-linejoin='round'><path d='M6 6l12 12M18 6L6 18'/></svg>")}

/* ---- chips: +N, -N, xN, "Costs 1 star". Position is set by flow.js; the
   transform below centres each on that point. Decorative (aria-hidden): the
   same information is in the toast. */
.flow-chip{
  position:fixed;left:0;top:0;z-index:9997;pointer-events:none;white-space:nowrap;
  font-weight:800;font-size:1rem;line-height:1;padding:6px 12px;border-radius:var(--radius-pill);
  box-shadow:0 4px 12px var(--shadow);transform:translate(-50%,-50%);
  animation:flowChip var(--flow-chip) var(--flow-ease-out) forwards;
}
.flow-chip.good{background:linear-gradient(180deg,var(--good),var(--good-deep));color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.25)}
.flow-chip.soft{background:var(--pill-bg);border:1px solid var(--pill-edge);color:var(--muted)}
.flow-chip.cost{background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--btn-ink);
  animation:flowStreak var(--flow-streak) var(--flow-spring) forwards}   /* a label, not a delta: pops, holds, fades; flow.js stretches it */
.flow-chip.streak{background:linear-gradient(90deg,var(--accent),var(--accent2));color:var(--btn-ink);
  animation:flowStreak var(--flow-streak) var(--flow-spring) forwards}
@keyframes flowChip{
  0%{opacity:0;transform:translate(-50%,-30%) scale(.8)}
  20%{opacity:1;transform:translate(-50%,-70%) scale(1.06)}
  100%{opacity:0;transform:translate(-50%,-160%) scale(1)}
}
@keyframes flowStreak{
  0%{opacity:0;transform:translate(-50%,0) scale(.5)}
  31%{opacity:1;transform:translate(-50%,-6px) scale(1.18)}
  45%{opacity:1;transform:translate(-50%,-6px) scale(1)}
  78%{opacity:1;transform:translate(-50%,-6px) scale(1)}
  100%{opacity:0;transform:translate(-50%,-14px) scale(1)}
}
/* streak of 5: one painted ring expands from the pill */
.flow-ring{
  position:fixed;left:0;top:0;z-index:9996;pointer-events:none;width:44px;height:44px;border-radius:50%;
  border:3px solid var(--accent);transform:translate(-50%,-50%);animation:flowRing 520ms var(--flow-ease-out) forwards;
}
@keyframes flowRing{from{opacity:.9;transform:translate(-50%,-50%) scale(.6)}to{opacity:0;transform:translate(-50%,-50%) scale(2.2)}}

/* streak pill states: warm while a streak runs, a soft dip when it resets */
.pill.hot .p-ico{color:var(--accent2)}
.pill.reset{animation:flowReset 300ms var(--flow-ease-io)}
@keyframes flowReset{0%,100%{opacity:1}40%{opacity:.45}}

/* ---- 5. hint: a ring that breathes twice; ruled-out choices fade + strike */
.flow-hint{outline:3px solid var(--accent);outline-offset:2px;animation:flowHint 600ms var(--flow-ease-io) 2}
@keyframes flowHint{0%,100%{outline-offset:2px}50%{outline-offset:7px}}
.flow-out{opacity:.35;text-decoration:line-through;pointer-events:none;transition:opacity var(--flow-reveal) var(--flow-ease-out)}
/* .choice.locked (opacity .85) would otherwise out-rank .flow-out and un-fade a ruled-out choice the moment the player answers */
.choice.flow-out{opacity:.35}
/* the shell's lever (play.html): depresses, springs back */
.aid.lever-pull{animation:flowLever 320ms var(--flow-spring)}
@keyframes flowLever{0%{transform:translateY(0)}35%{transform:translateY(3px) scale(.96)}100%{transform:none}}

/* ---- toast: fades in; flow.js also marks it aria-live -------------------- */
.toast.flow-toast-in{animation:flowToast var(--flow-fast) var(--flow-ease-out)}
@keyframes flowToast{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}

/* ---- coach mark: first play of a mechanic only. A painted hand and a tap
   ripple over the first valid target; gone on the first tap. ------------- */
.flow-coach{position:fixed;left:0;top:0;z-index:9996;pointer-events:none;width:64px;height:64px;margin:-22px 0 0 -22px;color:var(--accent)}
.flow-coach::before{content:"";position:absolute;left:8px;top:8px;width:28px;height:28px;border-radius:50%;
  border:3px solid currentColor;animation:flowRipple 1200ms var(--flow-ease-out) infinite}
.flow-coach svg{position:absolute;left:16px;top:16px;width:34px;height:34px;color:var(--ink);
  filter:drop-shadow(0 2px 3px var(--shadow));animation:flowTapHand 1200ms var(--flow-ease-io) infinite}
@keyframes flowRipple{0%{opacity:.85;transform:scale(.6)}70%,100%{opacity:0;transform:scale(1.6)}}
@keyframes flowTapHand{0%,100%{transform:translate(0,0)}35%{transform:translate(-4px,-5px)}55%{transform:translate(0,0)}}

/* ---- 6. reward beat: stars one at a time, then the answers card ---------- */
.flow-reward-run .stars{animation:none}
.flow-reward-run .stars > span{display:inline-flex;animation:starPop var(--flow-star) var(--flow-spring) both;animation-delay:calc(var(--i,0) * 140ms)}
.flow-answers{
  width:min(92vw,520px);margin:14px auto 0;text-align:left;padding:12px 14px;
  background:var(--stage-bg);border:1px solid var(--stage-edge);border-radius:var(--radius);box-shadow:0 3px 8px var(--shadow);
  animation:flowAnswer var(--flow-answer) var(--flow-ease-out) both;animation-delay:700ms;
}
.flow-answers .flow-ans-head{font-size:.8rem;text-transform:uppercase;letter-spacing:1px;color:var(--label);font-weight:800;margin-bottom:4px}
.flow-ans{padding:8px 0;border-top:1px solid var(--edge)}
.flow-ans-head + .flow-ans{border-top:0}
.flow-ans .q{font-size:.9rem;color:var(--muted);line-height:1.35}
.flow-ans .a{font-size:1rem;font-weight:800;line-height:1.35;margin-top:2px}
.flow-ans .k{font-size:.72rem;text-transform:uppercase;letter-spacing:1px;color:var(--label);font-weight:800;margin-right:8px}
.flow-ans .w,.flow-ans .why{font-size:.85rem;color:var(--muted);margin-top:2px;line-height:1.35}
.flow-ans-more{font-size:.85rem;color:var(--muted);padding-top:6px;border-top:1px solid var(--edge)}
@keyframes flowAnswer{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
/* a tap on the panel skips the sequence to its end state */
.flow-skip .stars > span,.flow-skip .flow-answers{animation-delay:0ms;animation-duration:1ms}

/* ---- reduced motion: swap movement for opacity or color, keep the info --- */
@media (prefers-reduced-motion:reduce){
  .flow-in,.flow-in.flow-head,.flow-swap,.flow-hint,.flow-ring,.toast.flow-toast-in,.aid.lever-pull,
  .pill.reset,.flow-reward-run .stars > span,.flow-answers,.flow-coach::before,.flow-coach svg,
  .choice.correct,.choice.wrong,.flow-mark.correct,.flow-mark.wrong,.pill.bump{animation:none}
  .flow-ring{display:none}
  /* chips sit still, in place, and flow.js removes them after 1.4s */
  .flow-chip,.flow-chip.streak,.flow-chip.cost{animation:none;opacity:1;transform:translate(-50%,-110%)}
  /* the hint ring and coach ripple stay as a still ring: they carry information */
  .flow-coach::before{opacity:.85;transform:none}
  .flow-out{transition:none}
}


