/* Interval Bingo — Beat Kitchen brand palette (teal/blue, Roboto) */
:root{
  --bg:#0d2027; --panel:#123039; --panel2:#17414c; --line:#255a66;
  --ink:#eef4f5; --dim:#9fb6bd;
  --accent:#2dacb3;        /* BKS teal */
  --accent-ink:#04262b;
  --accent2:#7fd6db;       /* light teal */
  --blue:#124e68;          /* deep brand blue */
  --good:#3ecf7a; --bad:#ff6b6b; --free:#255a66;
}
*{box-sizing:border-box}
/* behave like a native app on iOS: no long-press magnifier / callout, no accidental text selection (everywhere) */
*{-webkit-touch-callout:none !important;-webkit-user-select:none;user-select:none}
svg,svg *,img{-webkit-touch-callout:none !important;-webkit-user-select:none !important;pointer-events:auto}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{margin:0;font-family:"Roboto",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
     background:var(--bg);color:var(--ink);-webkit-font-smoothing:antialiased;
     touch-action:manipulation;-webkit-tap-highlight-color:transparent;overscroll-behavior:none}
/* let text in the events banner still be selectable if needed */
.ib-events,.ib-events *{-webkit-user-select:text;user-select:text}

/* brand header — always clear the notch / Dynamic Island (env is 0 on non-notch devices) */
.brandbar{display:flex;align-items:center;gap:12px;max-width:1140px;margin:0 auto;
  position:sticky;top:0;z-index:20;background:var(--bg);   /* PINNED top bar — brand/back + nav stay put while the board scrolls under it */
  /* status bar is hidden in-game, so most of the inset is wasted. Logo + buttons live BESIDE the centered
     cutout, so they can ride up near the top; we keep ~28px less than the full inset. Tunable if it clips. */
  padding:max(env(safe-area-inset-top, 0px) - 6px, 8px) max(20px, env(safe-area-inset-right, 0px) + 6px) 8px max(20px, env(safe-area-inset-left, 0px) + 6px)}

/* web-only site nav — shown only in a normal browser tab (body.web); mirrors the main site header so the
   game reads as part of the site. Hidden in the iOS app + installed PWA (standalone). White like the real header. */
.site-nav{display:none}
body.web .site-nav{display:flex;align-items:center;gap:16px;flex-wrap:nowrap;
  position:sticky;top:0;z-index:30;box-sizing:border-box;height:44px;
  background:#fff;border-bottom:1px solid #e6e6e6;padding:0 16px}
body.web .site-nav .sn-logo{display:flex;align-items:center;flex:0 0 auto}
body.web .site-nav .sn-logo img{height:24px;width:auto;display:block}
body.web .site-nav .sn-links{display:flex;align-items:center;gap:18px;flex:1 1 auto;min-width:0;
  overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch;scrollbar-width:none}
body.web .site-nav .sn-links::-webkit-scrollbar{display:none}
body.web .site-nav .sn-links a{color:#111;text-decoration:none;font-size:14px;font-weight:500;
  padding:2px 0;border-bottom:2px solid transparent;transition:color .15s,border-color .15s}
body.web .site-nav .sn-links a:hover{color:var(--accent)}
body.web .site-nav .sn-links a.active{color:#111;border-bottom-color:var(--accent)}
body.web .brandbar{top:44px}   /* stick below the site-nav bar */
.brandbar img{height:30px;width:auto;display:block}
.brandbar .wm{font-weight:500;letter-spacing:.3px;color:var(--dim);font-size:15px}
/* in-game: logo-only top bar — hide the centered wordmark so nothing hits the island, and ride higher */
.ingame .brandbar .wm{display:none}
.ingame .brandbar{padding-top:max(env(safe-area-inset-top, 0px) - 34px, 8px)}
.brandbar:hover .wm b{color:var(--accent2)}
.brandbar .wm b{color:var(--ink);font-weight:700}
.brandbar .navbtn{background:var(--panel2);border:1px solid var(--line);color:var(--accent2);
  width:38px;height:38px;border-radius:50%;font-size:18px;line-height:1;cursor:pointer;flex:0 0 auto}
.brandbar .navbtn:first-of-type{margin-left:auto}
.brandbar .navbtn:active{background:var(--panel)}
/* The chorDLE brand mark IS the return-to-menu (tap it → main screen); a little taller for presence. A left
   chevron sits by the wordmark on every non-menu screen to read as "back". On the menu both are hidden (the big
   hero logo is right below) — see body.at-menu. */
.brandbar .brand-mark{height:34px;cursor:pointer}
.brandbar .back-arrow{font-size:30px;line-height:1;color:var(--accent2);cursor:pointer;margin-left:-2px;margin-right:1px;font-weight:600}
body.at-menu .brandbar .back-arrow,body.at-menu .brandbar .brand-mark{display:none}

#app{max-width:1140px;margin:0 auto;padding:6px 18px 70px}
h1{font-size:26px;margin:0 0 6px;font-weight:700}
h2{font-size:20px;margin:6px 0 14px;font-weight:500}
h3{font-size:13px;letter-spacing:.5px;text-transform:uppercase;color:var(--dim);margin:20px 0 10px;font-weight:500}
.sub{color:var(--dim);font-size:14px;line-height:1.55;margin:0 0 18px;max-width:640px}
.mono{font-family:"Roboto Mono",ui-monospace,Menlo,monospace}
.muted{color:var(--dim);font-size:13px}
.hint{color:var(--dim);font-size:12px;line-height:1.5}
button{font:inherit;cursor:pointer}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:22px}

.choose{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:8px}
@media(max-width:720px){.choose{grid-template-columns:1fr}}
/* menu = one evenly-spaced vertical list; every game button carries the same weight */
.gamelist{display:flex;flex-direction:column;gap:12px;margin-top:8px}
.gamelist>.big{margin:0}
/* Multiplayer group — gold-bordered, both games full weight (no diagonal split) */
.mpgroup{border:1px solid #e8c14a;border-radius:14px;padding:10px;display:flex;flex-direction:column;gap:10px;background:rgba(232,193,74,.05)}
.mplabel{font-size:11px;letter-spacing:1.5px;text-transform:uppercase;color:#e8c14a;font-weight:800;margin:0 2px}
.mpgroup .big.mp{border-color:#e8c14a}
.mpgroup .big.mp:hover{border-color:#ffdd6a}
.big{width:100%;box-sizing:border-box;background:var(--panel2);border:1px solid var(--line);color:var(--ink);border-radius:12px;
     padding:22px 16px;font-size:17px;font-weight:600;display:flex;flex-direction:column;gap:8px;text-align:left}
.big small{font-weight:400;color:var(--dim);font-size:13px}
.big:hover{border-color:var(--accent)}
.big:focus{outline:none}   /* a stray focus ring reads as a 'pre-selected' button; a tap navigates instantly, so suppress it */
/* Per-game color identity — a colored band + soft tint so the flagship Solo practice (and each game) isn't a plain box.
   Daily quiz keeps its own full-border treatment below to stay differentiated. Custom icons to come. */
.big.g-solo{border-color:#3ecf7a;background:rgba(62,207,122,.09)}
.big.g-chordle{border-color:#c58af0;background:rgba(197,138,240,.09)}
.big.g-sing{border-color:#ff8f6b;background:rgba(255,143,107,.09)}
.big.g-hear{border-color:#5aa0ff;background:rgba(90,160,255,.09)}
.big.g-solo:hover{border-color:#3ecf7a;background:rgba(62,207,122,.16)}
.big.g-chordle:hover{border-color:#c58af0;background:rgba(197,138,240,.16)}
.big.g-sing:hover{border-color:#ff8f6b;background:rgba(255,143,107,.16)}
.big.g-hear:hover{border-color:#5aa0ff;background:rgba(90,160,255,.16)}
.g-title{font-weight:700;font-size:18px}
.big.resume{border-color:var(--accent);background:#123039;grid-column:1/-1}
.big.newbie{border-color:var(--accent2);background:#123a44;margin-bottom:14px}
/* landing easy-mode — clear space from the buttons above, full-width row (no awkward wrap) */
.landing-easy{display:flex;justify-content:flex-start;align-items:center;gap:7px;flex-wrap:nowrap;white-space:nowrap;margin:34px 0 6px;font-size:13.5px}
/* top-players board on the landing (the space the old footer links used) */
.landboard{margin-top:22px;border-top:1px solid var(--line);padding-top:16px}
.landboard-h{font-size:12px;letter-spacing:.5px;text-transform:uppercase;color:var(--accent2);font-weight:600;margin-bottom:10px}
.introsteps{display:flex;flex-direction:column;gap:12px;margin:14px 0 18px}
.introstep{display:flex;gap:12px;align-items:flex-start;background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.introstep .ic{font-size:24px;line-height:1;flex:0 0 auto}
.introstep b{color:var(--ink)}
.introstep p{margin:3px 0 0;color:var(--dim);font-size:14px;line-height:1.45}

.primary{background:var(--accent);color:var(--accent-ink);border:0;border-radius:9px;padding:11px 18px;font-weight:600}
.primary:hover{background:var(--accent2)}
.danger{background:transparent;color:var(--accent2);border:1px solid var(--accent2);border-radius:9px;padding:10px 16px;font-weight:600}
.ghost{background:var(--panel2);color:var(--ink);border:1px solid var(--line);border-radius:8px;padding:9px 13px}
.ghost:hover{border-color:var(--accent)}
.link{background:none;border:0;color:var(--dim);text-decoration:underline;padding:4px 0}
.back{display:block;margin-bottom:8px}

.cfg{display:flex;gap:14px;flex-wrap:wrap;margin:10px 0 18px;align-items:flex-end}
.cfg label{display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--dim)}
.cfg select,.cfg input,.panel input{background:#0a1a20;border:1px solid var(--line);color:var(--ink);
     border-radius:8px;padding:9px 11px;font-size:15px;min-width:120px}
/* aligned two-column setup form */
.setup{display:grid;grid-template-columns:max-content minmax(200px,340px);gap:12px 16px;align-items:center;margin:14px 0 20px}
.setup label{justify-self:end;text-align:right;color:var(--dim);font-size:13px}
.setup select{width:100%;background:#0a1a20;border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:9px 11px;font-size:15px}
.setup input[type=checkbox]{justify-self:start;width:18px;height:18px}
.setup .lvlshow{color:var(--ink);font-size:15px}
.setup .lvlshow small{color:var(--dim);font-size:12px}
.lvlpick{display:flex;gap:8px;align-items:center}
.lvlpick select{flex:1}
.lvlpick .mini{flex:0 0 auto;min-width:84px;padding:8px 10px}
/* advanced foldable settings */
details.advanced{margin:6px 0 16px;border:1px solid var(--line);border-radius:10px;background:var(--panel2)}
details.advanced>summary{cursor:pointer;padding:11px 14px;font-size:13px;font-weight:600;color:var(--accent2);
  letter-spacing:.3px;list-style:none;user-select:none}
details.advanced>summary::-webkit-details-marker{display:none}
details.advanced>summary::before{content:"▸ ";color:var(--dim)}
details.advanced[open]>summary::before{content:"▾ "}
details.advanced .setup{margin:0;padding:4px 14px 14px}
details.advanced .settingsrow{padding:4px 14px 14px}
@media(max-width:560px){.setup{grid-template-columns:1fr;gap:4px 0}.setup label{justify-self:start;text-align:left;margin-top:8px}}

/* STACKED header: title alone, pills in a full-width row, progress bar spanning the full column width
   (5 pills + title can't share one line on a 375px phone, so they get their own row) */
.hostbar{display:flex;flex-direction:column;align-items:stretch;gap:7px;
         background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:9px 14px;margin-bottom:10px}
.hostbar small{display:block;color:var(--dim);font-size:12px;margin-top:2px}
.hb-title{min-width:0;display:flex;flex-direction:column;gap:1px}
.hb-title b{line-height:1.2}
.hb-lvl{color:var(--dim);font-size:12px;line-height:1.25}   /* second line — wraps, never truncated */
.hb-right{display:flex;align-items:center;gap:6px;flex-wrap:wrap}   /* pills — their own full-width row */
.cluehd{color:var(--dim);font-size:12px;margin:0 0 5px}
.scorechip{background:var(--panel2);border:1px solid var(--accent);color:var(--accent2);font-weight:700;font-size:13px;padding:3px 9px;border-radius:20px;font-variant-numeric:tabular-nums}
.scorechip[data-tip]{cursor:pointer}   /* tappable info pills — tap to learn what they mean */
.pilltip{position:fixed;left:50%;top:66px;transform:translateX(-50%) translateY(-8px);background:var(--panel2);border:1px solid var(--accent2);color:#fff;padding:8px 14px;border-radius:16px;font-size:13px;font-weight:600;z-index:80;opacity:0;transition:opacity .25s ease,transform .25s ease;pointer-events:none;max-width:88vw;text-align:center;box-shadow:0 6px 20px rgba(0,0,0,.55)}
.pilltip.show{opacity:1;transform:translateX(-50%) translateY(0)}
.about-links{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.about-legal{margin-top:14px;text-align:center;font-size:13px}
.about-legal a{color:var(--accent2)}
.about-copy{margin-top:14px;font-size:12px;color:var(--dim);text-align:center;line-height:1.6}
.rp-desc{width:100%;box-sizing:border-box;margin:8px 0;background:var(--panel2);border:1px solid var(--line);border-radius:8px;color:#fff;padding:10px;font-size:15px;font-family:inherit;resize:vertical}
/* gambit forfeit — quick shake of the free square */
@keyframes gmshake{0%,100%{transform:translateX(0)}18%{transform:translateX(-4px)}38%{transform:translateX(4px)}58%{transform:translateX(-3px)}78%{transform:translateX(2px)}}
.cell.gm-shake{animation:gmshake .44s ease-in-out}
/* progress meter — full width of the column */
.hb-meter{display:block;height:6px;width:100%;border-radius:3px;background:rgba(255,255,255,.13);overflow:hidden}
.hb-meter>i{display:block;height:100%;background:var(--accent2);border-radius:3px;transition:width .3s ease}
/* clue-card badge row: "Clue N" + speaker (tap-to-hear affordance, replaces the "listen…" text) */
.cc-badgerow{display:flex;align-items:center;gap:6px}
.cc-spk{color:var(--accent2);flex:0 0 auto;opacity:.9}
/* clue-tile achievement icons in the SIDE column: ✓ = all notes; 🏆 = all intervals (wild-square win, pulses). Small. */
.cc-chk{color:var(--good);font-weight:900;font-size:12px;margin-right:1px}
.cc-ach{display:inline-flex;align-items:center;vertical-align:middle;margin-right:2px}
.cc-ach svg{display:block}
.cc-ach.pulse{animation:achpulse 1.15s ease-in-out infinite;transform-origin:center}
@keyframes achpulse{0%,100%{transform:scale(1);filter:drop-shadow(0 0 1px rgba(232,193,74,.5))}50%{transform:scale(1.35);filter:drop-shadow(0 0 7px #e8c14a)}}
/* leaderboard name — clean standard field (16px avoids iOS zoom-on-focus) */
.nameinput{-webkit-appearance:none;appearance:none;width:100%;background:#0a1a20;border:1px solid var(--line);
  color:var(--ink);border-radius:10px;padding:12px 14px;font-size:16px;margin:14px 0;display:block}
.nameinput::placeholder{color:var(--dim)}
.nameinput:focus{outline:none;border-color:var(--accent)}
.trophy .tr-score{font-size:14px;font-weight:700;margin-top:4px}
.trophy .tr-btns{display:flex;gap:10px;margin-top:10px}
.trophy .tr-btns .big{margin:0;padding:14px;font-size:16px;text-align:center;align-items:center}
.trophy .tr-btns .ghost{flex:0 0 auto;padding:14px 16px}
.trophy .tr-cta{margin-top:10px;font-size:13px}
.trophy .tr-cta a{color:#0a3540;font-weight:800;text-decoration:underline}
.trophy .tr-score .link{color:#0a3540;font-weight:700;text-decoration:underline}
.primary.sm{padding:7px 12px;font-size:13px;border-radius:8px}
.code{font-size:24px;font-weight:700;letter-spacing:4px;color:var(--accent2)}
.phasepill{font-size:12px;text-transform:uppercase;letter-spacing:1px;padding:5px 11px;border-radius:20px;
           border:1px solid var(--line);color:var(--dim)}
.phasepill.playing{color:var(--accent);border-color:var(--accent)}
.phasepill.ended{color:var(--good);border-color:var(--good)}

.hostcols{display:grid;grid-template-columns:1fr 1fr;gap:22px}
@media(max-width:820px){.hostcols{grid-template-columns:1fr}}
.col{min-width:0}
.builder-row{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.builder-row input{flex:1;min-width:140px;background:#0a1a20;border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:9px 11px}
.builder-row select{background:#0a1a20;border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:9px 11px;font-size:14px}
.flash{margin-top:10px;color:var(--bad);font-size:13px}

.pianobox{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:8px}
.piano{display:block;touch-action:none;user-select:none}
.wkey{fill:#f3f6f6;stroke:#b9c6c9;stroke-width:1}
.wkey.on{fill:#E74C3C}      /* branded eraser red for active notes (not blue) */
.bkey{fill:#0e2830;stroke:#000;stroke-width:1}
.bkey.on{fill:#ff7a6a}
.minikb{margin-top:8px;background:#f3f6f6;border-radius:6px;padding:3px}

.chordlist{display:flex;flex-direction:column;gap:9px}
.chordrow{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px 12px}
.cr-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cr-notes{color:var(--ink);font-weight:600}
.cr-ivs{color:var(--dim);font-size:12px;margin:4px 0}
.cr-guessers{font-size:12px;margin:2px 0 4px;display:flex;gap:10px;flex-wrap:wrap}
.cr-guessers .gg.ok{color:var(--good)}
.cr-guessers .gg.bad{color:var(--bad)}
.cr-guessers.muted{color:var(--dim);font-style:italic}
.cr-actions{display:flex;gap:7px;flex-wrap:wrap;margin-top:6px}
.cr-top{display:flex;align-items:center;gap:8px}
.cr-top .eraser{margin-left:auto}
.cr-toggles{display:flex;flex-direction:column;gap:6px;margin-top:8px}
.cr-toggles .tgl{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}
.cr-toggles .tgl small{color:var(--dim);font-weight:400}
.cr-toggles .tgl input{width:16px;height:16px;flex:0 0 auto}
.num{color:var(--accent2);font-weight:700}
.badge{font-size:11px;padding:2px 8px;border-radius:12px;border:1px solid var(--line);color:var(--dim)}
.badge.rev{color:var(--good);border-color:var(--good)}
.badge.open{color:var(--accent);border-color:var(--accent)}
.badge.hid{color:var(--dim)}
.badge.bad{color:var(--bad);border-color:var(--bad)}

.playerlist{display:flex;flex-direction:column;gap:7px}
.prow{display:flex;align-items:center;gap:10px;background:var(--panel2);border:1px solid var(--line);border-radius:9px;padding:8px 12px;cursor:pointer}
.prow .pn{font-weight:500}
.prow .pscore{color:var(--good);font-size:12px;font-variant-numeric:tabular-nums}
.prow .spybtn{margin-left:auto}
.prow.watching{border-color:var(--accent);background:#0f2a33}

/* spectate a player's live card (Band Leader) */
.spypanel{margin-top:12px;background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:12px}
.spypanel h4{margin:0 0 10px}
.spygrid .cell{min-height:auto;padding:6px}
.spygrid .cell .iv{font-size:13px}

/* room roster / leaderboard (player view) */
.roompanel{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px 12px;margin:12px 0}
.roompanel h4{margin:0 0 8px}
.lb{display:flex;flex-direction:column;gap:5px}
.lbrow{display:flex;align-items:center;gap:9px;font-size:14px;padding:3px 4px;border-radius:7px}
.lbrow.me{background:#0f2a33}
.lbrow .rank{width:20px;text-align:center;color:var(--dim);font-variant-numeric:tabular-nums}
.lbrow .lbname{flex:1}
.lbrow .lblevel{color:var(--accent2);font-size:11px;font-weight:600;background:#123039;border:1px solid var(--line);border-radius:8px;padding:1px 7px}
.lbrow .lbscore{color:var(--good);font-size:12px;font-variant-numeric:tabular-nums;min-width:34px;text-align:right}
.landboard-h .mylevel{display:block;text-transform:none;letter-spacing:0;color:var(--dim);font-weight:400;font-size:12px;margin-top:2px}
/* My ears — per-interval accuracy bars */
.eartotals{color:var(--dim);font-size:13px;margin:6px 0 14px}
/* My Progress dashboard */
.prog-hero{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:6px 0 10px}
.pcard{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px 6px;text-align:center}
.pcard .pnum{font-size:20px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.1}
.pcard .plabel{font-size:11px;color:var(--dim);margin-top:3px}
@media(max-width:420px){.pcard .pnum{font-size:17px}}
.psec{font-size:14px;margin:18px 0 8px;color:var(--accent2)}
.psec .muted{font-weight:400;font-size:12px}
.spark{width:100%;height:56px;display:block}
.spark polyline{fill:none;stroke:var(--accent2);stroke-width:2;vector-effect:non-scaling-stroke}
.spark circle{fill:var(--accent)}
.spark .sparkbase{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.sparkcap{display:flex;justify-content:space-between;font-size:11px;color:var(--dim);margin-top:2px}
.conflist{display:flex;flex-direction:column;gap:6px}
.confrow{display:flex;align-items:center;gap:8px;background:var(--panel2);border:1px solid var(--line);border-radius:8px;padding:7px 10px;font-size:14px}
.confrow b{color:var(--ink)}
.confrow .wrongtint{color:var(--bad)}
.confrow .confarrow{color:var(--dim);font-size:12px}
.confrow .muted{margin-left:auto;font-size:12px}
.needswork{margin-top:16px;padding:10px 12px;border-radius:10px;background:#14283a;border:1px solid var(--accent2);color:var(--ink);font-size:13px}
.trajhdr{display:flex;align-items:baseline;gap:12px;margin-bottom:8px;flex-wrap:wrap}
.trajdelta{font-size:30px;font-weight:800;font-variant-numeric:tabular-nums}
.trajdelta.up{color:var(--good)} .trajdelta.down{color:var(--bad)} .trajdelta.flat{color:var(--dim)}
.trajmsg{font-size:14px;color:var(--ink)}
.pstats-tabs{margin-bottom:14px}
/* glowing interval constellation (galaxy / harmony-wheel aesthetic) */
.constellation{width:100%;max-width:440px;height:auto;display:block;margin:6px auto 2px}
.constellation .cst-ring{stroke:rgba(126,214,219,.14);stroke-width:1}
.constellation .cst-core{fill:var(--accent2);filter:drop-shadow(0 0 7px var(--accent2));animation:cstpulse 2.4s ease-in-out infinite}
@keyframes cstpulse{0%,100%{opacity:.55}50%{opacity:1}}
.constellation .cst-lbl{fill:#cfe3e6;font-size:13px;text-anchor:middle;font-weight:700}
.cst-key{display:flex;gap:14px;justify-content:center;font-size:11px;color:var(--dim);margin:2px 0 4px}
.cst-key .k::before{content:'';display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;vertical-align:middle}
.cst-key .good::before{background:#3ecf7a}.cst-key .mid::before{background:#e8b04a}.cst-key .weak::before{background:#ff6b6b}.cst-key .none::before{background:#33465a}
/* swipeable chart carousel */
.pchart-dots{display:flex;flex-wrap:wrap;gap:7px;justify-content:center;margin:2px 0 12px}
.pchart-dots .cardot{width:24px;height:24px;font-size:11px}
.pchart-scroll{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:0;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.pchart-scroll::-webkit-scrollbar{display:none}
.pchart-slide{flex:0 0 100%;scroll-snap-align:center;padding:0 2px;box-sizing:border-box}
.pchart{background:var(--panel2);border:1px solid var(--line);border-top:3px solid var(--cc,var(--accent2));border-radius:14px;padding:15px 14px;min-height:300px;display:flex;flex-direction:column;box-shadow:0 0 22px -14px var(--cc,transparent)}
.pchart-t{font-size:15px;color:var(--cc,var(--accent2));margin:0 0 12px;font-weight:800}
.pchart .chart-note{font-size:13px;color:var(--dim);line-height:1.5;margin:12px 0 0}
.pchart .chart-note b{color:var(--ink)}
.pchart-fix{margin-top:auto;width:100%}
.pchart .earbars,.pchart .conflist{margin-top:2px}
/* practice calendar (galaxy heat) */
.calgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;max-width:260px;margin:8px auto 0}
.calcell{aspect-ratio:1;border-radius:5px;background:#1a2836}
.calcell.l1{background:#5a2a30;box-shadow:0 0 5px #ff6b6b55}
.calcell.l2{background:#6b5a24;box-shadow:0 0 6px #e8b04a66}
.calcell.l3{background:#1f5a3a;box-shadow:0 0 8px #3ecf7a88}
.calcap{text-align:center;margin-top:8px;font-size:11px}
.calstreak{text-align:center;font-size:16px;font-weight:800;color:#ff9d3c;margin-bottom:8px}
.pchart-fix{text-align:center}
.constellation .cst-spoke{stroke:rgba(126,214,219,.09);stroke-width:1}
/* clearer, color-coded chart dots */
.pchart-dots .cardot{border-color:var(--cc,var(--line));color:var(--dim);transition:all .15s}
.pchart-dots .cardot.cur{background:var(--cc,var(--accent2));border-color:var(--cc,var(--accent2));color:#04222a;transform:scale(1.3);box-shadow:0 0 12px var(--cc,var(--accent2))}
.constellation .cst-ringc{fill:none;stroke:rgba(126,214,219,.14);stroke-width:1}
.scatter{width:100%;max-width:320px;height:auto;display:block;margin:4px auto 0}
.scatter .axis{stroke:var(--line);stroke-width:1}
.scatax{display:flex;justify-content:space-between;max-width:320px;margin:2px auto 0;font-size:11px;color:var(--dim)}
/* iPad/desktop: divider between the clue cards and the grid */
.clue-divider{display:flex;align-items:center;gap:12px;margin:18px 0 14px}
.clue-divider::before,.clue-divider::after{content:'';flex:1;height:1px;background:var(--line)}
.clue-divider span{font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--dim)}
/* iPad / desktop landscape: a pinned title bar across the top, then clues (left, independent scroll) + grid (right,
   aligned to the top of the clue list). The progress line under the header acts as the divider. */
@media(min-width:820px){   /* match JS "wide" threshold so iPad 11" portrait (834px) gets two columns */ 
  body.ingame #app{padding-bottom:8px}
  /* Two columns · two rows. Row 1: [Solo-practice badge (with its own progress meter)] | [coaching message].
     Row 2: [clue strip, scrolls] | [a big SQUARE grid that grows to fill the space]. The full-width progress
     divider is gone (meter lives in the badge), which frees the top-right for messaging and lets the grid grow. */
  .solo-wrap{display:grid;grid-template-columns:388px minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);column-gap:30px;row-gap:10px;align-items:start}
  .solo-wrap.play>.hostbar,.solo-wrap>.hostbar{grid-column:1;grid-row:1;margin:0;max-width:none;align-items:stretch}
  .solo-wrap>.gridmsg{grid-column:2;grid-row:1;align-self:center;margin:0;min-height:40px;display:block;position:static}   /* messaging ABOVE the grid (block so spaces around <b> survive) */
  /* GRID grows to a large square (no scrolling to see it), centered in the right column. 250px ≈ brandbar + badge + controls. */
  .solo-wrap.play>.grid,.solo-wrap>.grid{grid-column:2;grid-row:2;justify-self:center;align-self:center;width:min(100%,calc(100vh - 250px));max-width:none;aspect-ratio:1;margin:0}
  .solo-wrap>*:not(.grid):not(.hostbar):not(.gridmsg){grid-column:1}                   /* clues + controls in the left column */
  /* strip scrolls INDEPENDENTLY of the grid — a FIXED height cap (matching the grid square) is what makes overflow
     actually engage; height:100% of a content-sized row never scrolls. Few clues fit; many scroll, grid stays put. */
  .solo-wrap.play>.strip,.solo-wrap>.strip{grid-column:1;grid-row:2;display:flex;flex-direction:column;gap:12px;max-height:calc(100vh - 250px);min-height:0;overflow-y:auto;padding:34px 8px 0 0;margin:0;max-width:none}   /* padding-top so the popped '1' handle isn't clipped by overflow */
  .solo-wrap>.strip .chordcard{width:100%;max-width:none;margin:0;flex:0 0 auto}
  .solo-wrap>.clue-divider{display:none}
  .solo-wrap>.playbar,.solo-wrap>.foot{grid-column:1}
}
/* "you made a mistake on this clue" indicator */
.cc-wrong{color:var(--bad);font-size:10px;font-weight:700;margin-left:auto;white-space:nowrap}
.chordcard.had-wrong{border-color:rgba(255,107,107,.45)}
/* difficulty level rows with replay */
.lvlchart{display:flex;flex-direction:column;gap:9px}
.lvlrow{display:flex;align-items:center;gap:9px}
.lvlrow .lvlname{width:108px;font-size:12px;font-weight:700;color:var(--ink);flex:0 0 auto}
.lvlrow .lvlname small{display:block;color:var(--dim);font-weight:400;font-size:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lvlrow .earbar{flex:1;height:18px;border-radius:9px}
.lvlrow .earbar span{transition:width .4s ease}
.lvlrow .earbar.good span{box-shadow:0 0 8px var(--good)}
.lvlrow .earbar.none{border-style:dashed;opacity:.6}
.lvlrow .earpct{width:34px}
.lvlrow .lvlreplay{flex:0 0 auto;padding:7px 15px;font-size:15px;line-height:1}
/* school CTA on the consistency screen */
.school-cta{margin-top:16px;padding:12px 13px;border-radius:10px;background:linear-gradient(150deg,#14283a,#122c26);border:1px solid var(--accent2);font-size:12.5px;line-height:1.5;color:var(--dim)}
.school-cta b{color:var(--ink)}
.school-cta-btn{display:inline-block;margin-top:9px;color:var(--accent2);font-weight:700;text-decoration:none}
.earbars{display:flex;flex-direction:column;gap:8px}
.earrow{display:flex;align-items:center;gap:10px}
.earrow .eariv{width:44px;font-weight:700;color:var(--ink);font-size:14px}
.earrow .earbar{flex:1;height:12px;border-radius:6px;background:var(--panel2);border:1px solid var(--line);overflow:hidden}
.earrow .earbar span{display:block;height:100%}
.earrow .earbar.good span{background:var(--good)}
.earrow .earbar.mid span{background:#e8b04a}
.earrow .earbar.weak span{background:var(--bad)}
.earrow .earpct{width:38px;text-align:right;font-size:12px;font-variant-numeric:tabular-nums;color:var(--dim)}
.earrow .earseen{width:34px;text-align:right;font-size:11px;color:var(--dim)}
.lbrow .youtag{display:inline-block;background:var(--accent);color:var(--accent-ink);font-size:10px;font-weight:800;
  padding:1px 6px;border-radius:8px;margin-left:6px;letter-spacing:.03em;vertical-align:middle}
.lbcta{display:flex;gap:12px;margin-top:18px}
.lbcta .primary,.lbcta .ghost{flex:1}
.lbrow .lbdots{margin-left:auto;color:var(--good);letter-spacing:1px;font-size:11px}

.claim{border-radius:12px;padding:12px 16px;margin-bottom:14px;font-size:15px}
.claim.good{background:#123a2a;border:1px solid var(--good)}
.claim.bad{background:#3a1c1c;border:1px solid var(--bad)}

.hintbox{display:inline-flex;gap:7px;align-items:center;color:var(--dim);font-size:13px;margin:0 0 10px;cursor:pointer}
.settingsrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px 22px;align-items:center;
  margin:4px 0 18px;padding:14px 16px;background:var(--panel);border:1px solid var(--line);border-radius:12px}
.settingsrow .hintbox{margin:0;justify-content:flex-start}
.settingsrow select{background:#0a1a20;border:1px solid var(--line);color:var(--ink);border-radius:6px;padding:5px 7px;margin-left:auto}
.minikb{max-width:320px}
.cnum{position:absolute;top:4px;left:5px;min-width:16px;height:16px;border-radius:8px;padding:0 4px;
      font-size:11px;font-weight:700;color:#08252b;display:flex;align-items:center;justify-content:center}
.cbadge{display:inline-flex;height:19px;border-radius:9px;padding:0 9px;letter-spacing:.02em;
      font-size:11.5px;font-weight:800;color:#08252b;align-items:center;justify-content:center;white-space:nowrap}
.btnrow{display:flex;gap:4px;width:100%;margin-top:6px}
.mini{flex:1;border-radius:6px;padding:5px 4px;font-size:12px;font-weight:600;cursor:pointer;
      background:var(--panel);border:1px solid var(--line)}
.cc-top .mini{flex:0 0 auto;padding:9px 14px;font-size:13px}   /* give-up: a comfortable tap target on the card */
.mini.go{color:var(--accent2);border-color:var(--accent2)}      /* neutral teal — not "right" green */
.mini.go:hover{background:rgba(45,172,179,.15)}
.mini.cancel{color:var(--dim)}
.mini.cancel:hover{border-color:var(--dim)}
.cell.committed input{opacity:.65}
/* NYC-subway-style guess bullets */
.bullets{display:flex;justify-content:center;gap:0;margin:3px 0 0;padding:0 4px;flex-wrap:nowrap}   /* small flow deck in the gap between description & keyboard — no overlap, keyboard stays bottom-anchored */
.cell .bul{width:16px;height:16px;font-size:10px;border:2px solid #eef2f2;box-shadow:0 1px 2px rgba(0,0,0,.35);position:relative}
.cell .bullets .bul+.bul{margin-left:-7px}   /* fanned-deck overlap (like cards) — packs many clue numbers into one row */
.bul{position:relative;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
     font-size:14px;font-weight:800;color:#08252b;cursor:pointer;border:2px solid rgba(0,0,0,.25);user-select:none}
/* wrong guess: dim the number and strike a clear white ✕ through it so it reads as WRONG, not just red */
.bul.bad{color:rgba(255,255,255,.55);border-color:#ff6b6b}
.bul.bad::after{content:"";position:absolute;left:50%;top:50%;width:150%;height:3px;background:#fff;border-radius:2px;
     transform:translate(-50%,-50%) rotate(-45deg);box-shadow:0 0 0 1px rgba(0,0,0,.35)}
.bul.confirm{outline:3px solid #ffd76a;outline-offset:1px;animation:bulconfirm .6s ease-in-out infinite}
@keyframes bulconfirm{0%,100%{transform:scale(1)}50%{transform:scale(1.15)}}
.bul.dim{filter:saturate(.62) brightness(.82)}   /* dim WITHOUT opacity so overlapping circles stay solid (no bleed-through) */
.bul:hover{filter:brightness(1.12)}
.status.warn{color:var(--accent)}
.mini.go.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.wildtag{margin-top:6px;font-size:11px;font-weight:700;letter-spacing:1px;color:#e8c14a}
.bonusbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:14px;max-width:560px;
          background:rgba(232,193,74,.08);border:1px solid rgba(232,193,74,.4);border-radius:10px;padding:8px 12px;
          animation:bonusglow 1.7s ease-in-out infinite}   /* a banked mulligan glows — it's the high point */
@keyframes bonusglow{0%,100%{box-shadow:0 0 0 0 rgba(232,193,74,0);border-color:rgba(232,193,74,.4)}50%{box-shadow:0 0 18px 2px rgba(232,193,74,.45);border-color:#e8c14a}}
/* shimmer the tiles a banked mulligan can bring back — advertise the reward before you even spend it */
.cell.mull-shimmer{animation:mullshimmer 2.6s ease-in-out infinite}
.cell.mull-shimmer:nth-child(3n){animation-delay:.55s} .cell.mull-shimmer:nth-child(3n+1){animation-delay:1s}
@keyframes mullshimmer{0%,100%{box-shadow:inset 0 0 0 1.5px rgba(232,193,74,.5)}50%{box-shadow:inset 0 0 0 1.5px rgba(232,193,74,.85)}}
.btok{color:#e8c14a;font-weight:700}
.bonusbar .mini{flex:0 0 auto;min-width:110px}
.listen{touch-action:none;user-select:none}
.strip{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;max-width:560px}  /* uniform grid; lone card doesn't stretch */
/* HORIZONTAL clue card: [Clue N badge + status] column · full keyboard · give-up overlaid top-right of the keyboard.
   Height is driven by the keyboard (width-fit), so every key is fully visible + TAPPABLE — nothing clipped. */
.chordcard{background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:24px 10px 10px;min-width:0;box-sizing:border-box;overflow:visible;cursor:pointer;display:flex;flex-direction:row;align-items:center;gap:11px;position:relative}
/* badge/label at the TOP of the card; status below it, leaving room for per-clue messaging as the game progresses */
/* LAYOUT B: left column = stats stack (top) + give-up (pinned bottom); Clue N pill overlays the keyboard center. */
.cc-side{flex:0 0 auto;align-self:stretch;width:78px;display:flex;flex-direction:column;gap:4px;align-items:flex-start;padding-top:2px}
.cc-statwrap{display:flex;flex-direction:column;gap:4px;align-items:flex-start;min-height:0}
.give-side{margin-top:auto;align-self:stretch;padding:5px 6px;font-size:11px;font-weight:600;border-radius:7px;background:var(--panel);border:1px solid var(--line);color:var(--dim);white-space:nowrap;cursor:pointer;text-align:center}
.give-side.confirm{background:var(--bad);border-color:var(--bad);color:#fff;font-weight:700}
.cc-playbtns{margin-top:auto;align-self:stretch;display:flex;flex-direction:column;gap:4px}
.cc-pb{padding:5px 4px;font-size:10.5px;font-weight:700;border-radius:6px;background:var(--panel);border:1px solid var(--accent2);color:var(--accent2);cursor:pointer;text-align:center;white-space:nowrap}
@media(hover:hover){ .cc-pb:hover{background:rgba(45,172,179,.15)} }
.cc-pb:active{background:var(--panel2)}
@media(hover:hover){ .give-side:hover{border-color:var(--bad);color:#fff} }
/* The clue label is now a NUMBERED STATUS CIRCLE (was a "Clue N" pill): chord-colored, pops above the keyboard,
   and inherits status (green ring = solved/all-notes, red = locked/off-card) — same language as the carousel dots. */
.cc-cluelbl{position:absolute;top:-30px;left:50%;transform:translateX(-50%);z-index:3;display:inline-flex;align-items:center;justify-content:center;text-align:center;font-variant-numeric:tabular-nums;width:38px;height:38px;padding:0;border-radius:50%;font-size:19px;font-weight:800;color:#08252b;box-shadow:0 4px 10px rgba(0,0,0,.45);border:3px solid rgba(255,255,255,.7);background:var(--cc)}
.cc-cluelbl.st-solved,.cc-cluelbl.st-allnotes{border-color:var(--good);box-shadow:0 0 0 2px var(--good),0 4px 10px rgba(0,0,0,.45)}
.cc-cluelbl.st-failed,.cc-cluelbl.st-cleared{background:var(--bad);color:#fff}
.cc-status{font-size:11.5px;font-weight:700;color:var(--ink);line-height:1.2}
.cc-status.dim{color:var(--dim);font-weight:600}
.cc-status.ok{color:var(--good)} .cc-status.mid{color:var(--accent2)} .cc-status.bad{color:var(--bad)}
.cc-ans{font-size:10px;color:var(--accent2);font-weight:700;line-height:1.15}
.cc-kbwrap{position:relative;flex:1;min-width:0;display:flex;align-items:center}
.cc-kbwrap .minikb{width:100%;margin:0;background:#f3f6f6;border-radius:6px;padding:3px;box-sizing:border-box}
/* HERO clue card = STACK vertically so the keyboard goes FULL-WIDTH (it was squeezed to a ~36px strip beside the
   78px side column, which killed the note markers at wide levels). Applies to EVERY carousel card (phone shows
   one at a time — active OR revealed/locked) and to the ACTIVE card in the iPad strip (others stay compact).
   Controls drop to a compact row UNDER the keyboard; the Clue-N slide handle pops up centered above it. */
.carslide .chordcard{flex-direction:column;align-items:stretch;gap:9px;padding:30px 12px 12px}
.carslide .chordcard .cc-kbwrap{order:1;width:100%}
.carslide .chordcard .cc-side{order:2;flex-direction:row;width:auto;align-self:stretch;align-items:center;gap:10px;padding-top:0;flex-wrap:wrap}
.carslide .chordcard .cc-statwrap{flex-direction:row;align-items:center;gap:8px;min-height:0;flex-wrap:wrap}
.carslide .chordcard .give-side{margin-top:0;margin-left:auto;align-self:center;flex:0 0 auto;padding:6px 14px}
.carslide .chordcard .cc-playbtns{margin-top:0;flex-direction:row;align-self:center}
/* Keyboard sized by WIDTH (fills the wrap) so all keys top-to-bottom are visible/tappable — never clipped. The
   viewBox ratio sets the height; a generous cap keeps any one card from getting too tall. Range is C-aligned +
   >=2 octaves (set in app.js) so it's always cut on C, never mid-key, with room on the sides. */
.minikb svg,.minikb .piano{display:block;width:100%;height:auto;max-height:158px}
.give-ov{position:absolute;top:6px;right:6px;z-index:3;padding:4px 9px;font-size:11px;font-weight:600;border-radius:7px;
         background:rgba(8,20,24,.72);border:1px solid rgba(255,255,255,.2);color:#e3f0f2;white-space:nowrap;cursor:pointer}
.give-ov.confirm{background:var(--bad);border-color:var(--bad);color:#fff;font-weight:700}
@media(hover:hover){ .give-ov:hover{border-color:var(--bad);color:#fff} }
.cc-count{font-size:12px;color:var(--dim);font-weight:600}
.card-solved{border-color:var(--good)!important}
.card-solved .cbadge{box-shadow:0 0 0 2px var(--good)}
.card-allnotes{border-color:#e8c14a!important}
.card-failed{opacity:.75;border-color:#7a3b3b!important}
.card-cleared{opacity:.8;border-color:var(--good)!important}
.badge.mid{background:#3a2f12;border:1px solid #e8c14a;color:#ffdd8a}
/* SELECTED clue — must be unmistakable (playtest: "hardly looks different"). Bold ring + heavy glow + tint + a pop. */
.chordcard.active{border-color:var(--accent2);box-shadow:0 0 0 3px var(--accent2),0 0 26px 4px rgba(45,172,179,.6);background:rgba(45,172,179,.16);transform:scale(1.02);z-index:2}
/* (removed the left teal accent bar — redundant now that the active card has a full accent border + glow, and
   in the centered carousel it read as an odd floating stripe on the card's left edge) */
.chordcard.active .cbadge{outline:2px solid #fff;outline-offset:1px}
.chordcard{position:relative;transition:transform .12s ease,box-shadow .12s ease}
/* when placing, invite a tap (crosshair) and pulse ONLY the tiles already holding the selected chord
   (NOT empty tiles — that wrongly implied the answer was limited to them) */
.grid.placing [data-assign]{cursor:crosshair}
.cell.activehere{animation:placepulse 2.4s ease-in-out infinite}
@keyframes placepulse{0%,100%{box-shadow:inset 0 0 0 2px rgba(45,172,179,.5)}50%{box-shadow:inset 0 0 0 2px rgba(45,172,179,.95)}}
.cell.activemine{animation:minepulse 2.2s ease-in-out infinite}   /* selected chord's placed tiles pulse in ITS color */
@keyframes minepulse{0%,100%{box-shadow:inset 0 0 0 2px var(--pc)}50%{box-shadow:inset 0 0 0 2px var(--pc),0 0 7px var(--pc)}}
/* a clear banner while a chord is selected */
.placebar{display:flex;align-items:center;gap:8px;background:#123039;border:1px solid var(--accent2);border-radius:10px;padding:8px 12px;margin:6px 0 10px;font-weight:600;color:var(--accent2)}
/* persistent status line — always present (min-height) so messages never shift the layout below */
.statusbar{height:58px;box-sizing:border-box;display:flex;align-items:center;gap:8px;padding:9px 12px;margin:6px 0 12px;border-radius:10px;font-size:14px;line-height:1.3;overflow:hidden}   /* FIXED height — message changes never shift anything below */
.statusbar.act{background:#123039;border:1px solid var(--accent2);color:var(--accent2);font-weight:600}
.statusbar.warn{background:#3a2a12;border:1px solid #e8b04a;color:#ffd98a;font-weight:600}
.statusbar.dim{background:var(--panel2);border:1px solid var(--line);color:var(--dim)}
.pchip{width:22px;height:22px;flex:0 0 auto;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:#04262b;font-weight:800;font-size:13px}
.chordcard:hover{filter:brightness(1.08)}
.cc-top{display:flex;gap:8px;align-items:center;margin-bottom:8px;min-width:0}
.cc-top .cbadge{flex:0 0 auto}
.cc-top .give{flex:0 0 auto;margin-left:auto;padding:4px 8px;font-size:11px;white-space:nowrap;color:var(--dim);border-color:var(--line);background:transparent}
/* hover only on hover-capable devices — otherwise the red state sticks after a tap on touchscreens */
@media(hover:hover){ .cc-top .give:hover{color:var(--bad);border-color:var(--bad)} }
.cc-top .give:active{color:var(--bad);border-color:var(--bad)}
.cc-top .give.confirm{color:#fff;background:var(--bad);border-color:var(--bad);font-weight:700}
.cc-ivs{font-size:12px;color:var(--accent2);margin-top:3px;font-weight:600}
/* obvious "play the chord" affordance on the clue card (the whole card is tappable, this makes it clear) */
.cc-play{margin:10px 0 6px;padding:10px;text-align:center;border-radius:9px;background:#12333c;border:1px solid var(--accent);color:var(--accent2);font-weight:700;font-size:15px}
.chordcard:active .cc-play{background:#164450}
/* high-stakes gambit button + outcomes */
.mini.gambit{border-color:#e8a04a;color:#ffcf8a;margin-left:6px}
.mini.gambit.confirm{background:#4a2a12;border-color:#ff6b6b;color:#ffd98a}
/* gamble control + its dismissible confirm modal */
.gamblewrap{margin:2px 0 10px;text-align:center}
.gamblebtn{width:100%;padding:11px;border-radius:10px;background:#2a1c0a;border:1px solid #e8a04a;color:#ffcf8a;font-weight:700;font-size:14px;cursor:pointer}
.gamblebtn:active{background:#3a2610}
.modal-ov{position:fixed;inset:0;z-index:400;background:rgba(4,14,18,.72);display:flex;align-items:center;justify-content:center;padding:20px}
.modal{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:18px;max-width:360px;width:100%;box-shadow:0 20px 60px rgba(0,0,0,.6)}
.modal h3{margin:0 0 8px}
.modal p{margin:6px 0;font-size:14px;color:var(--ink)}
.modal .modal-win{color:var(--good)}
.modal .modal-lose{color:#ff9a6a}
.iv-picker{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:12px 0}
.iv-pick{padding:11px 4px;border-radius:9px;background:var(--panel2);border:1px solid var(--line);color:var(--ink);font-weight:700;font-size:15px;cursor:pointer}
.iv-pick:hover{border-color:var(--accent2);color:var(--accent2)}
.iv-pick:active{background:var(--panel)}
/* gambit dialog: bigger surface + GOLD to match the FREE/gambit square; every interval shows its full name */
.gambit-modal{max-width:560px;border-color:#e8c14a;box-shadow:0 20px 60px rgba(0,0,0,.6),0 0 0 1px rgba(232,193,74,.4)}
.gambit-modal h3{color:#e8c14a}
.iv-picker.big{grid-template-columns:repeat(auto-fill,minmax(94px,1fr));gap:10px;max-height:54vh;overflow-y:auto;padding-right:4px}
.iv-picker.big .iv-pick{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:12px 6px;min-height:58px}
.iv-pick b{font-size:17px;line-height:1}
.iv-pick small{font-size:10px;color:var(--dim);font-weight:600;line-height:1.1;text-align:center;white-space:normal}
.iv-picker.big .iv-pick:hover{border-color:#e8c14a;color:#e8c14a}
.iv-picker.big .iv-pick:hover small{color:#e8c14a}
.modal-btns{display:flex;gap:10px;margin-top:14px}
.modal-btns button{flex:1;padding:11px;border-radius:9px;font-weight:700;cursor:pointer}
.villain-face{width:46px;height:46px;border-radius:50%;background:#2a1c0a;border:2px solid #e8c14a;color:#e8c14a;font-size:26px;font-weight:900;display:flex;align-items:center;justify-content:center;margin:0 auto 8px}
/* the gambit taunt: "?"s pop in at random angles, fill the free square, then all fade — with a long pause between */
.qm-field{position:absolute;inset:-6px;pointer-events:none;overflow:visible}   /* scatter a little AROUND the tile too */
.qm-field .qm{position:absolute;font-weight:900;color:#e8c14a;opacity:0;transform-origin:center;
  animation:qmPop 8s ease-in-out calc(4.5s + var(--d)) infinite}   /* ~4.5s searching, then fill/fade with a long gap */
@keyframes qmPop{
  0%,58%,100%{opacity:0;transform:scale(.2) rotate(var(--r))}
  8%{opacity:.95;transform:scale(1.15) rotate(var(--r))}
  16%{opacity:.9;transform:scale(1) rotate(var(--r))}
  44%{opacity:.9;transform:scale(1) rotate(var(--r))}
  52%{opacity:0;transform:scale(.5) rotate(var(--r))} }
.cell.free[data-freegambit]{cursor:pointer;animation:freeGlow 8s ease-in-out 4.5s infinite}   /* glow pulses in sync with the ?s */
.cell.free[data-freegambit]:hover{border-color:#e8c14a}
.cell.free .iv{position:relative;z-index:1}
@keyframes freeGlow{ 0%,55%,100%{box-shadow:none;border-color:var(--line)} 20%,40%{box-shadow:0 0 0 2px #e8c14a,0 0 18px rgba(232,193,74,.55);border-color:#e8c14a} }
/* cartoon speech-bubble caption pointing at the free square */
.gambit-cap{position:absolute;transform:translate(-50%,-118%);z-index:30;width:210px;max-width:62vw}
.gambit-cap.below{transform:translate(-50%,55%)}
.gambit-bubble{background:#e8c14a;color:#26200f;font-size:12px;font-weight:600;line-height:1.35;padding:9px 11px;border-radius:11px;box-shadow:0 10px 26px rgba(0,0,0,.5);position:relative}
.gambit-bubble .mini{margin-top:8px;width:100%;background:#26200f;color:#ffd98a;border-color:#26200f}
.gambit-bubble::after{content:'';position:absolute;left:50%;transform:translateX(-50%);border:9px solid transparent}
.gambit-cap:not(.below) .gambit-bubble::after{bottom:-9px;border-top-color:#e8c14a;border-bottom:0}
.gambit-cap.below .gambit-bubble::after{top:-9px;border-bottom-color:#e8c14a;border-top:0}
/* slim progress line (replaces the old clues block) */
/* above-grid coaching message (which square to work / wild prompts / bingo win) */
.gridmsg{font-size:13.5px;color:var(--dim);line-height:1.5;margin:2px 0 10px;min-height:42px;display:block;position:sticky;top:calc(max(env(safe-area-inset-top,0px) - 34px, 8px) + 42px);z-index:6;background:var(--bg);padding:5px 2px;border-radius:8px}   /* block (NOT flex) so spaces around <b> words survive — flex trims inter-item whitespace → "PlacingClue1" */
.gridmsg b{color:var(--ink)}
.gridmsg.act{color:var(--accent2)} .gridmsg.act b{color:var(--accent2)}
.gridmsg.win{color:var(--good);font-weight:700;font-size:15px} .gridmsg.win b{color:var(--good)}
.cluebar-thin{height:4px;background:var(--panel2);border:1px solid var(--line);border-radius:3px;overflow:hidden;margin:0 0 10px}
.cluebar-thin span{display:block;height:100%;background:var(--accent)}
.gambit-tip{display:flex;gap:10px;align-items:center;margin:10px 0;padding:10px 12px;border-radius:10px;
  background:#2a1c0a;border:1px solid #e8a04a;color:#ffe0b0;font-size:13px;line-height:1.35}
.gambit-tip .mini{flex:0 0 auto}
.chordcard.cleared{opacity:.72;border-color:var(--good)!important}
.cell.gambit-why{border-color:#7fd6db!important;box-shadow:0 0 0 2px #7fd6db,0 0 14px rgba(127,214,219,.6)}   /* "here's the interval that WAS on your grid" after a failed gambit */
.cell.bonusfree{border-color:#e8c14a}
.cell.bonusfree .iv{color:#e8c14a}   /* a converted (won-gambit) free square — distinct from the built-in one */
.cell.swapped{position:relative}
.cell.swapped::after{content:"⇄";position:absolute;top:2px;left:3px;font-size:11px;line-height:1;color:#e8c14a;opacity:.85;pointer-events:none}   /* replay marker: this tile came from a won-gambit exchange */
.cell.freelocked{border-color:#ff6b6b!important;background:#2a1418}
.cell.freelocked .iv{opacity:.5;text-decoration:line-through}
.cell.freelocked .freelock{font-size:9px;color:#ff6b6b;font-weight:800;letter-spacing:.5px;margin-top:2px}
.clues h3{margin-bottom:6px}
.cluebar{height:6px;border-radius:4px;background:var(--panel2);border:1px solid var(--line);overflow:hidden;margin:0 0 8px}
.cluebar span{display:block;height:100%;background:var(--good);transition:width .3s ease}
/* solved-clue keyboard IS playable (only the chord notes sound; scrub across them); tile diagrams never playable */
.sqkb{pointer-events:none}
.cell .sqkb,.cell .sqkb svg,.cell .sqkb svg *{pointer-events:none!important}   /* the grid keyboard must NOT eat taps (svg{pointer-events:auto} was re-enabling it) — the whole open tile places */
.chordcard .ghost{width:100%}
.chordcard.playable{user-select:none;touch-action:none}
.cc-play{text-align:center;color:var(--dim);font-size:12px;padding:10px 4px;border:1px dashed var(--line);border-radius:8px}
.chordcard:hover .cc-play{color:var(--ink);border-color:var(--accent)}
.cc-notes{margin-top:6px;font-weight:600;text-align:center}
.chordcard.inert{opacity:.4;filter:grayscale(.55);cursor:default}
/* phone carousel: status dots + one active clue card (iPad keeps the full .strip) */
.carousel{margin:6px 0 12px}
.cardots{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;margin-bottom:12px;touch-action:manipulation}
/* Numberless STATUS PIPS: small dots spread across the full width — a purely visual count of how many puzzles
   there are + each one's state. open = chord-color ring · solved = filled · wrong = red · revealed = dashed. */
.cardots{gap:6px;justify-content:space-between;padding:0 4px;max-width:340px;margin-left:auto;margin-right:auto;width:100%;box-sizing:border-box}
.cardot{width:12px;height:12px;border-radius:50%;border:2px solid var(--line);background:transparent;font-size:0;line-height:0;padding:0;cursor:pointer;flex:0 0 auto;opacity:.72;transition:opacity .15s,transform .15s,box-shadow .15s}   /* off-focus dots dimmed but status still reads; the current one pops */
/* Legible-at-11px status language (dashes didn't read): HOLLOW ring = still to solve · SOLID = resolved.
   Colour says how it resolved — chord-colour = solved, red = wrong lock, grey = revealed/given up. */
.cardot.open{border-color:var(--dc);background:transparent}
.cardot.solved{background:var(--dc);border-color:var(--dc);opacity:.95}
.cardot.wrong{background:#ff6b6b;border-color:#ff6b6b;opacity:.95}
.cardot.revealed{background:transparent;border-color:var(--dim);opacity:.5}
/* current = a bright, larger ring with a halo; pops even though the others are dimmed AND keeps its status fill */
.cardots .cardot.cur{opacity:1;transform:scale(1.4);box-shadow:0 0 0 2px var(--bg),0 0 0 4px var(--dc)}
.carstage{display:flex;align-items:center;gap:6px;justify-content:center}
.carscroll{flex:1 1 auto;min-width:0;display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding:2px 0}
.carscroll::-webkit-scrollbar{display:none}
.carscroll::before,.carscroll::after{content:'';flex:0 0 8%}   /* breathing room so clue 1 (and the last clue) can CENTER instead of sitting flush at the scroll edge */
.carslide{flex:0 0 84%;scroll-snap-align:center;scroll-snap-stop:always;opacity:.45;transform:scale(.93);transition:opacity .2s,transform .2s}   /* next card peeks; non-centered fade back; snap-stop:always = ONE card per swipe (no skipping) */
.carslide.cur{opacity:1;transform:none}
.carslide .chordcard{margin:0}
.carscroll{touch-action:pan-x}
.carslide .chordcard.playable{touch-action:pan-x}   /* let a horizontal swipe scroll the carousel (tap still plays) */
.carslide:not(.cur){cursor:pointer}   /* tap a peeking card to bring it into view */
.chordcard .minikb{touch-action:none;cursor:pointer}   /* the PIANO is the play target — sound is intentional */
/* robber reward: reclaim a locked tile */
.cell.unlockhere{animation:unlockpulse 1s ease-in-out infinite}
@keyframes unlockpulse{0%,100%{box-shadow:0 0 0 2px #3ecf7a inset,0 0 8px #3ecf7a44}50%{box-shadow:0 0 0 3px #3ecf7a inset,0 0 18px #3ecf7a99}}
.convert-banner{margin-top:10px;padding:9px 12px;border-radius:10px;background:#123028;border:1px solid #3ecf7a66;color:#bff0d6;font-size:13px;text-align:center;line-height:1.35}
.convert-banner b{color:#7ef0b4}
.winpop{position:fixed;left:50%;top:37%;z-index:9999;pointer-events:none;white-space:nowrap;
  font-weight:800;font-size:22px;color:#3ecf7a;background:rgba(8,20,24,.94);border:1px solid rgba(62,207,122,.55);border-radius:14px;padding:12px 22px;box-shadow:0 12px 44px rgba(0,0,0,.55),0 0 24px rgba(62,207,122,.22);text-shadow:0 1px 6px #0009;transform:translate(-50%,-50%) scale(.6);animation:winpopin .28s cubic-bezier(.2,1.5,.4,1) forwards}
.winpop.out{animation:winpopout .3s ease forwards}
@keyframes winpopin{to{transform:translate(-50%,-50%) scale(1)}}
@keyframes winpopout{to{opacity:0;transform:translate(-50%,-58%) scale(1.05)}}
.carnav{flex:0 0 auto;width:34px;height:128px;border-radius:11px;border:1px solid var(--line);background:var(--panel2);color:var(--accent2);font-size:24px;line-height:1;cursor:pointer;padding:0}
.carnav:active{background:var(--panel)}
@media(hover:none){.carnav{display:none}}   /* touch devices swipe; arrows are for mouse */
.tally{font-size:11px;margin-top:6px;text-align:center;line-height:1.4}
.tally .tc{color:var(--good);font-weight:700}
.tally .tw{color:var(--bad);font-weight:700}
.tally .tm{color:var(--accent)}
.tally .tdone{color:#7fd6db;font-weight:700}
.tally .tall{color:#e8c14a;font-weight:800}
.sqkb{margin-top:6px;background:#f3f6f6;border-radius:4px;padding:2px;width:100%}
/* grid mini-keyboards: same consistent-aspect fix as the clue cards — drive by a definite height so keys keep
   their natural proportion (no tall/stubby mismatch between a 2-key and a wide tile), width auto + meet-fit. */
.sqkb svg,.sqkb .piano{display:block;width:100%;height:auto;max-height:70px}   /* fit by width → C-aligned keyboard never clipped on the sides */

.grid{display:grid;gap:8px;max-width:560px;width:100%;position:relative}
.strikeline{position:absolute;height:6px;margin-top:-3px;transform-origin:left center;border-radius:3px;pointer-events:none;z-index:6;
  background:linear-gradient(90deg,#e8c14a,#fff3c0,#e8c14a);box-shadow:0 0 12px rgba(232,193,74,.9)}
.cell.winline{border-color:#e8c14a!important;box-shadow:0 0 14px rgba(232,193,74,.7)!important}
/* BINGO banner floats as a fixed TOP toast — overlays the top of the screen (visible immediately), never
   pushes the grid/strikethrough down. */
.trophy{position:fixed;left:12px;right:12px;top:calc(10px + env(safe-area-inset-top));z-index:200;
  text-align:center;font-weight:800;letter-spacing:1px;color:#08252b;border-radius:12px;padding:12px;
  font-size:18px;max-width:560px;margin:0 auto;box-shadow:0 10px 30px rgba(0,0,0,.55);
  background:linear-gradient(90deg,#e8c14a,#ffe08a,#e8c14a);animation:trPop .35s ease}
@keyframes trPop{from{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:none}}
.trophy .tr-main{font-size:20px;font-weight:800;letter-spacing:1px}
.trophy .tr-sub{font-size:13px;font-weight:600;letter-spacing:.2px;margin-top:4px;opacity:.85}
.trophy .winchords{display:inline-flex;gap:6px;vertical-align:middle;margin-left:6px}
.trophy .winchords .bul{border-color:rgba(0,0,0,.35)}
.cell{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:8px 6px;
      display:flex;flex-direction:column;align-items:center;justify-content:space-between;
      aspect-ratio:1;min-height:0;overflow:hidden;text-align:center;position:relative}   /* always a fixed square — placing a guess never grows it */
.cell .iv{font-size:clamp(15px,2.4vw,20px);font-weight:700;line-height:1}
.cell .lg{font-size:10px;color:var(--dim);margin-top:3px;line-height:1.1}
.cell input{width:100%;margin-top:6px;background:#0a1a20;border:1px solid var(--line);color:var(--ink);
      border-radius:7px;text-align:center;font-size:15px;padding:5px 2px;outline:none}
.cell input:focus{border-color:var(--accent)}
.cell input:disabled{opacity:.6}
.cell.free{background:var(--free);justify-content:center}
.cell.free .iv{color:var(--accent2)}
.cell.ok{border-color:var(--good);box-shadow:inset 0 0 0 1px var(--good)}
/* a wrong answer makes the tile ineligible for bingo — tint it red + faint diagonal hatch so that reads clearly */
.cell.err{border-color:var(--bad);box-shadow:inset 0 0 0 1px var(--bad);
  background-image:linear-gradient(135deg,rgba(255,107,107,.13) 0 25%,transparent 25% 50%,rgba(255,107,107,.13) 50% 75%,transparent 75%);
  background-size:14px 14px}
.cell.pop{animation:cellpop .36s ease-out}
@keyframes cellpop{0%{transform:scale(1)}30%{transform:scale(1.09);box-shadow:inset 0 0 0 2px var(--good),0 0 14px rgba(62,207,122,.55)}100%{transform:scale(1)}}
.cell.dead{opacity:.6;cursor:not-allowed;background:#2a1a1c}
.cell.dead::after{content:"locked";position:absolute;bottom:3px;right:5px;font-size:9px;letter-spacing:.04em;text-transform:uppercase;color:var(--bad);font-weight:700}
.cell{position:relative}
.cell.bonus{border-color:#e8c14a!important;animation:bonuspulse 1.4s ease-in-out infinite}
@keyframes bonuspulse{
  0%,100%{box-shadow:inset 0 0 0 2px #e8c14a,0 0 5px rgba(232,193,74,.3)}
  50%{box-shadow:inset 0 0 0 2px #e8c14a,0 0 16px rgba(232,193,74,.8)}
}
.sparkfx{position:fixed;pointer-events:none;font-weight:700;z-index:9999;will-change:transform,opacity;animation:sparkle 1000ms ease-out forwards}
@keyframes sparkle{0%{opacity:0;transform:translate(0,0) scale(.4)}15%{opacity:1}100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(1.25)}}
.mark{position:absolute;top:4px;right:6px;font-size:13px;font-weight:700}
.mark.ok{color:var(--good)} .mark.err{color:var(--bad)}

.playbar{display:flex;align-items:center;gap:14px;margin-top:16px;flex-wrap:wrap}
.status{color:var(--dim);font-size:13px}
/* footers: wrap as WHOLE links (never break a label mid-phrase; the "·" separator rides with the next
   link so it never dangles at a line end) */
.foot{margin-top:22px;display:flex;flex-wrap:wrap;align-items:center;gap:6px 0}
.link{white-space:nowrap}
.foot .link ~ .link::before{content:"·";margin:0 10px;color:var(--dim)}
.cta-block{max-width:1140px;margin:26px auto 40px;padding:16px 18px;border-top:1px solid var(--line);
  color:var(--dim);font-size:14px;line-height:1.6}
.cta-block b{color:var(--accent2)}
.cta-about{color:#999;font-size:13px;line-height:1.5;margin:16px 0 4px}
.cta-about b{color:var(--accent2)}
.cta-links{display:flex;gap:18px;flex-wrap:wrap;margin-top:10px}
.cta-block a{color:var(--accent);text-decoration:none;font-weight:600}
.cta-block a:hover{text-decoration:underline}
@media(max-width:600px){.cta-links{display:flex;margin:8px 0 0}}

/* live "Now Playing" + next-up events banner (shared /js/upcoming-events.js, dark-themed for this page) */
.ib-events{margin:12px 0}
.ib-events:empty{display:none}
.ib-events-h{font-size:12px;letter-spacing:.5px;text-transform:uppercase;color:var(--accent2);font-weight:600;margin-bottom:8px}
/* site-wide standard: a clean VERTICAL LIST — headshot · title+times · countdown, hairline dividers (matches the Harmony Wheel) */
.ib-events .upcoming-events-cards{display:flex;flex-direction:column;gap:0;margin:0}
.ib-events .upcoming-event-card{display:flex;align-items:center;gap:12px;
  background:none;border:none;border-radius:0;padding:11px 2px;
  text-decoration:none;color:#ccc;transition:background .15s}
.ib-events .upcoming-event-card + .upcoming-event-card{border-top:1px solid rgba(255,255,255,0.1)}
.ib-events .upcoming-event-card:hover{background:rgba(255,255,255,0.05)}
.ib-events .upcoming-event-card.upcoming-event-live{background:rgba(45,172,179,0.08)}
.ib-events .instructor-headshot-sm{width:46px;height:46px;border-radius:50%;object-fit:cover;flex:0 0 auto}
/* CTA face cluster — real instructor headshots (window.BKS_INSTRUCTOR_PHOTOS), overlapping row */
.cta-faces{display:flex;justify-content:center;align-items:center;margin:0 0 10px;padding-left:9px}
.cta-faces .instructor-headshot-sm{width:38px;height:38px;border-radius:50%;object-fit:cover;margin-left:-9px;border:2px solid rgba(18,22,28,.92);box-shadow:0 1px 3px rgba(0,0,0,.45)}
.ib-events .upcoming-event-text{flex:1;min-width:0;font-size:14px;line-height:1.4}
.ib-events .upcoming-event-title{font-weight:700;color:#fff}
.ib-events .upcoming-instructor{color:#2DACB3;font-size:13px}
.ib-events .upcoming-meta{display:block;color:#999;font-size:12.5px;margin-top:2px}
.ib-events .upcoming-countdown{flex:0 0 auto;margin-left:auto;color:#2DACB3;font-size:13px;font-weight:700;
  font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.ib-events .upcoming-countdown--soon{color:#e8b04a}
.ib-events .upcoming-countdown--live{color:var(--bad)}
.ib-events .upcoming-today{display:inline-block;background:#e8862a;color:#fff;font-size:10px;font-weight:700;
  padding:1px 5px;border-radius:3px;letter-spacing:.04em;vertical-align:middle;margin-right:4px}
.ib-events .upcoming-live-badge{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;
  text-transform:uppercase;letter-spacing:.04em;color:var(--bad);margin-right:4px}
.ib-events .upcoming-live-badge .live-dot{width:8px;height:8px;border-radius:50%;background:var(--bad);
  display:inline-block;animation:ib-live-blink 1.2s ease-in-out infinite}
.ib-events .upcoming-join{color:var(--accent);font-weight:600;font-size:12px}
@keyframes ib-live-blink{0%,100%{opacity:1}50%{opacity:.2}}

/* ---- promo rotator (one cycling card slot: classes / events / products) ---- */
.pr-h{display:flex;align-items:center;gap:8px}
.pr-dots{display:flex;gap:5px;margin-left:auto}
.pr-dots i{width:6px;height:6px;border-radius:50%;background:var(--line);display:block;cursor:pointer;transition:background .2s}
.pr-dots i.on{background:var(--accent)}
.pr-slot{margin-top:2px}
.pr-row{display:flex;gap:10px;align-items:stretch}
.pr-card{flex:1 1 0;min-width:0;display:flex;gap:12px;align-items:stretch;background:var(--panel);border:1px solid var(--line);
  border-radius:14px;overflow:hidden;min-height:80px;text-decoration:none;color:var(--ink);
  transition:border-color .15s,background .15s}
.pr-card:hover{background:var(--panel2)}
.pr-media{width:80px;flex:0 0 80px;background-size:cover;background-position:center;
  display:flex;align-items:center;justify-content:center}
.pr-media .pr-icon{width:54px;height:54px;border-radius:14px;display:block}
.pr-media .pr-head{width:52px;height:52px;border-radius:50%;object-fit:cover;display:block}
.pr-body{flex:1;min-width:0;padding:10px 13px 10px 0;display:flex;flex-direction:column;justify-content:center}
.pr-tag{font-size:9.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;margin-bottom:3px;color:var(--accent2)}
.pr-title{font-size:15.5px;font-weight:800;color:#fff;line-height:1.13}
.pr-sub{font-size:12.5px;color:var(--dim);margin-top:1px}
.pr-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:7px}
.pr-meta{font-size:12px;color:var(--accent2)}
.pr-btn{background:var(--accent);color:var(--accent-ink);border-radius:7px;padding:6px 12px;
  font-size:12.5px;font-weight:700;white-space:nowrap;flex:0 0 auto}
/* per-type accents */
.pr-class .pr-media{border-left:3px solid #F08640} .pr-class .pr-tag{color:#F08640}
.pr-event .pr-media{border-left:3px solid var(--accent)}
.pr-live{background:rgba(45,172,179,0.08)} .pr-live .pr-tag{color:var(--accent)}
.pr-product .pr-media{border-left:3px solid var(--accent2)} .pr-product .pr-tag{color:var(--accent2)}
.pr-msg .pr-media{border-left:3px solid #e8b04a} .pr-msg .pr-tag{color:#e8b04a}

/* "N playing now" live indicator on the leaderboard header */
.lb-online{font-size:12px;font-weight:600;color:var(--accent2);vertical-align:middle;margin-left:8px;white-space:nowrap}
.lb-online:empty{display:none}
.lb-online .lbdot{display:inline-block;width:8px;height:8px;border-radius:50%;background:#2ecc71;margin-right:5px;vertical-align:middle;animation:lbpulse 2s infinite}
.lb-online.refreshing{opacity:.45}
.nudge-future{font-size:12.5px;color:var(--dim);font-style:italic;margin-top:-4px}
@keyframes lbpulse{0%{box-shadow:0 0 0 0 rgba(46,204,113,.55)}70%{box-shadow:0 0 0 6px rgba(46,204,113,0)}100%{box-shadow:0 0 0 0 rgba(46,204,113,0)}}

/* ---- mobile ---- */
@media(max-width:600px){
  .brandbar{padding:12px 12px 0}
  .brandbar img{height:24px}
  .brandbar .wm{font-size:13px}
  #app{padding:12px 12px 60px}
  .hostbar{flex-wrap:nowrap;gap:8px}   /* keep score/badge on the SAME line as the title, right-aligned */
  .code{font-size:20px}
  .strip{gap:8px}
  .chordcard{flex:1 1 116px;padding:11px}
  .chordcard .listen{padding:8px 6px}
  .grid{gap:6px}
  .cell{min-height:74px;padding:7px 4px}
  .cell .iv{font-size:17px}
  .cell .lg{font-size:10px;margin-top:2px}
  .cell input{font-size:15px;padding:4px 3px;margin-top:4px}
  .cnum{top:2px;left:3px;min-width:16px;height:16px;font-size:11px}
  .mark{font-size:12px;top:2px;right:4px}
  .btnrow{gap:3px;margin-top:4px}
  .mini{padding:7px 6px;font-size:13px}
  .cfg{gap:10px}
  /* bigger tap targets — checkboxes, bullets, buttons read as too small on iPhone */
  input[type=checkbox]{width:22px;height:22px}
  .setup input[type=checkbox]{width:22px;height:22px}
  .bul{width:30px;height:30px;font-size:14px}
  .hintbox,.tgl{font-size:14px}
  .settingsrow{gap:10px}
  .btn,.ghost,.primary,.danger{padding:11px 14px;font-size:15px}
  .big{padding:18px 14px;font-size:16px}
  .sub{font-size:14px}
  h3{font-size:12px}
}
/* landscape phones: give the grid more room, keep it app-like */
@media(max-width:900px) and (orientation:landscape){
  #app{padding:10px 14px 50px}
  .cell{min-height:56px}
}
/* installed / standalone (Add-to-Home-Screen or the native wrapper): edge-to-edge, respect the notch,
   drop the panel chrome so it reads like a native app */
/* wide screens / iPad / desktop — keep the card comfortable, don't stretch it edge-to-edge */
@media(min-width:820px){
  .play .grid, .play .strip{max-width:640px;margin-left:auto;margin-right:auto}
  .play .cell{min-height:92px}
  .play .cell .iv{font-size:22px}
  .play h3, .play .clues, .play .placebar, .play .playbar, .play .bonusbar, .play .foot, .play .hostbar{max-width:900px;margin-left:auto;margin-right:auto}
  .panel{max-width:720px;margin-left:auto;margin-right:auto}
}
@media all and (display-mode: standalone){
  #app{padding-left:max(10px, env(safe-area-inset-left));padding-right:max(10px, env(safe-area-inset-right));padding-bottom:calc(60px + env(safe-area-inset-bottom))}
  .panel{border-left:none;border-right:none;border-radius:0;padding-left:12px;padding-right:12px}
  .cta-block{border-top-color:transparent}
}

/* ── Sign-in with Discord (landing) ── reuses the portal's OAuth; Discord blurple accent ── */
.authrow{margin:0 0 14px}
.authbtn{width:100%;box-sizing:border-box;display:flex;flex-direction:column;gap:2px;text-align:left;
  background:#5865F2;border:1px solid #4752c4;color:#fff;border-radius:12px;padding:12px 14px;
  font-size:15px;font-weight:600;cursor:pointer}
.authbtn small{font-weight:400;color:#dfe2fb;font-size:12.5px}
.authbtn:hover{background:#4752f0}
.authpill{display:flex;align-items:center;justify-content:space-between;gap:10px;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:10px 14px}
.authpill.signedin{border-color:var(--accent)}
.authwho{color:var(--ink);font-size:14px}
.authwho b{color:var(--accent2)}
.authtier{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:9px;background:var(--accent);
  color:var(--accent-ink);font-size:11px;font-weight:700;text-transform:capitalize;vertical-align:middle}
.authpill .link{white-space:nowrap}

/* ── Daily quiz button (landing) ── */
.big.daily{border-color:var(--accent);background:#12333c;margin-bottom:14px}
.big.daily small{color:var(--accent2)}

/* ── Interval palette (click-to-hear) ── */
.palette{display:grid;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:8px;margin-top:6px}
.palchip{display:flex;flex-direction:column;align-items:center;gap:2px;padding:12px 6px;cursor:pointer;
  background:var(--panel2);border:1px solid var(--line);border-radius:12px;color:var(--ink);transition:border-color .12s,transform .08s}
.palchip b{font-size:18px;font-weight:700}
.palchip span{font-size:11px;color:var(--dim);text-align:center;line-height:1.15}
.palchip:hover{border-color:var(--accent)}
.palchip.ring{border-color:var(--accent);background:#154049;transform:scale(1.04)}

/* ── Daily quiz screen ── */
.dqhead{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}
.dqmeta{color:var(--dim);font-size:13px;font-variant-numeric:tabular-nums}
.big.dqplay{margin:6px 0 12px;border-color:var(--accent);background:#12333c;text-align:center}
.dqopts{display:grid;gap:10px}
.dqopt{display:flex;flex-direction:column;align-items:center;gap:2px;padding:16px 8px;cursor:pointer;
  background:var(--panel2);border:1px solid var(--line);border-radius:12px;color:var(--ink);transition:border-color .12s}
.dqopt b{font-size:22px;font-weight:700}
.dqopt span{font-size:12px;color:var(--dim)}
.dqopt:hover:not(:disabled){border-color:var(--accent)}
.dqopt:focus:not(:disabled){outline:none}   /* a focus ring on load reads as a pre-selected answer — suppress it */
.singdone{display:block;margin:14px auto 0;min-width:200px}
.setacct{font-size:14px;color:var(--ink);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.setacct b{color:var(--accent2)}
button.working{opacity:.85;animation:btnworking 1s ease-in-out infinite}
@keyframes btnworking{0%,100%{opacity:.85}50%{opacity:.55}}
/* sing result: group the "listen again" ghost buttons, then a clear gap before the single move-on button */
.singlisten{flex-wrap:wrap;justify-content:center;gap:8px}
.singnext{margin-top:30px}   /* big gap so nobody taps Next meaning "hear again" */
.dqopt:disabled{cursor:default;opacity:.92}
.dqopt.right{border-color:var(--good);background:#123a2a}
.dqopt.right b{color:var(--good)}
.dqopt.wrong{border-color:var(--bad);background:#3a1a1e}
.dqopt.wrong b{color:var(--bad)}
.dqfeed{min-height:22px;margin-top:10px;text-align:center;font-size:15px;color:var(--ink)}
.dqresult{text-align:center;margin:18px 0}
.dqscore{font-size:52px;font-weight:800;color:var(--accent2);line-height:1}
.dqsub{color:var(--dim);font-size:14px;margin-top:4px}

/* ── Leaderboard mode tabs ── */
.lbtabs{display:flex;gap:8px;margin:4px 0 10px}
.lbtab{flex:1;padding:9px 0;background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  border-radius:9px;cursor:pointer;font-size:14px;font-weight:600}
.lbtab.on{border-color:var(--accent);color:var(--ink);background:#12333c}

/* ── Sing the interval ── */
.singstage{display:flex;flex-direction:column;align-items:center;gap:10px;margin:14px 0;padding:18px;
  background:var(--panel2);border:1px solid var(--line);border-radius:14px}
.singstep{font-size:16px;color:var(--ink);min-height:22px;text-align:center}
.singmeter{font-size:44px;font-weight:800;color:var(--accent2);font-variant-numeric:tabular-nums;line-height:1;min-height:46px}
.singresult{text-align:center;font-size:20px;font-weight:700;margin:14px 0 4px}
.singresult.good{color:var(--good)}
.singresult.bad{color:var(--bad)}

/* Sign in with Apple — native iOS only (guideline 4.8). Apple-logo glyph renders on Apple devices. */
.authbtn.apple{background:#000;border-color:#000;margin-top:8px}
.authbtn.apple small{color:#c9c9c9}
.authbtn.apple:hover{background:#161616}

/* ── Palette play-mode toggle (ascending / descending / together) ── */
.pmodes{display:flex;gap:8px;margin:2px 0 12px}
.pmode{flex:1;padding:9px 0;background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  border-radius:9px;cursor:pointer;font-size:13px;font-weight:600}
.pmode.on{border-color:var(--accent);color:var(--ink);background:#12333c}
/* shared sound (timbre) selector — same control everywhere */
.tbrow{margin:2px 0 10px}
.tbrow .pmode.on{border-color:var(--accent2);box-shadow:0 0 0 1px var(--accent2) inset}
.tbwrap{margin:2px 0 4px}
.setup .tbrow{margin:0}
.cntreveal{margin-top:12px;min-height:196px}   /* reserve space so the answer/Next don't bounce the layout (keeps the CTA steady) */
.cntreveal .scblk{margin:0 auto;max-width:300px}
.cntreveal.fading{opacity:0;transition:opacity .6s ease}
.minikb{margin-left:auto;margin-right:auto}   /* reveal keyboards are centered everywhere */
/* long-press "hold to hear" must never pop the iOS text-selection / callout menu */
.dqplay,.cntopt,.cntopts,.cntreveal,.minikb,.scblk,.singkb,.palchip,.dqopt,.chordcard,.cardot,.carnav{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}

/* Daily quiz option = a PICTURE of the interval (mini keyboard at the round's real pitches) */
.dqkb{width:100%;max-width:150px;margin:0 auto 6px;pointer-events:none}
.dqkb svg{width:100%;height:auto;display:block;border-radius:6px}
.dqopt{padding:12px 8px}

/* Sing mode — mic input picker */
.micpick{display:flex;align-items:center;gap:8px;margin:6px 0 12px;color:var(--dim);font-size:14px}
.micpick select{flex:1;background:#0a1a20;border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:8px 10px;font-size:14px}

/* Sing mode — live tuner keyboard: light the pitch class you're singing (teal), distinct from eraser red */
.singkb{max-width:300px;margin:10px auto 0}
.singkb .piano{filter:none}
.wkey.lit{fill:#2dacb3}     /* BKS teal — "you are here" */
.bkey.lit{fill:#7fd6db}

/* Sing manual-capture + palette keyboards + daily speed badge */
.singcap{text-align:center;color:var(--dim);font-size:15px;margin:10px 0}
.singcap b{color:var(--ink)}
.dqspeed{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:9px;background:var(--accent);color:var(--accent-ink);font-size:12px;font-weight:700}
.palette{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.palkb{width:100%;margin:0 auto 6px;pointer-events:none}
.palkb svg{width:100%;height:auto;display:block;border-radius:5px}

/* Sing hands-free fill meter + result compare */
.singbar{width:100%;max-width:300px;height:16px;margin:8px auto;background:#0a1a20;border:1px solid var(--line);border-radius:9px;overflow:hidden}
.singbar>span{display:block;height:100%;width:0%;background:var(--accent);border-radius:9px;transition:width .08s linear}
.singbar>span.near{background:var(--good)}
.singcompare{display:flex;gap:12px;justify-content:center;margin:10px 0}
.scblk{flex:1;max-width:220px;text-align:center}
.scblk .singkb{margin-top:0}
.sclabel{font-size:12px;color:var(--dim);margin-bottom:4px}

/* Close-X (top-right of a panel) + intro "don't show again" */
.panel{position:relative}
.closeX{position:absolute;top:10px;right:12px;width:34px;height:34px;border-radius:50%;
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);font-size:16px;line-height:1;cursor:pointer;z-index:2}
.closeX:hover{color:var(--ink);border-color:var(--accent)}
.introdont{margin-top:14px;justify-content:center}

/* Combined "Overall" leaderboard columns */
.lbcol{width:40px;text-align:center;color:var(--dim);font-size:13px;font-variant-numeric:tabular-nums;flex:none}
.lbrow.lbhead{background:transparent;border:none;color:var(--dim);font-size:11px;text-transform:uppercase;letter-spacing:.04em;padding-bottom:2px}
.lbrow.lbhead .lbname,.lbrow.lbhead .lbscore{color:var(--dim);font-weight:600}

/* Compact clue cards so the grid is visible alongside them (esp. cards with no keyboard graphic) */
.strip{grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:8px}
.chordcard{min-height:auto;padding:8px 10px}
.cc-top{margin-bottom:4px}

/* Leveled sing mode — level tag, per-note breakdown */
.singlvl{text-align:center;color:var(--accent2);font-size:13px;font-weight:600;margin-bottom:4px}
.singnotes{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:10px 0}
.singnote{padding:5px 11px;border-radius:10px;font-size:14px;font-weight:600;border:1px solid var(--line)}
.singnote.good{color:var(--good);border-color:var(--good);background:#123a2a}
.singnote.bad{color:var(--bad);border-color:var(--bad);background:#3a1a1e}
.singnote.sang{color:var(--accent2);border-color:var(--accent2);background:transparent}
.singnotes .rowtag{align-self:center;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--dim);min-width:58px;text-align:right}
.singresult.mid{color:var(--accent2)}
.singcap .cur{color:var(--accent2)}

/* How many notes? — number-choice tiles */
.cntopts{display:grid;grid-template-columns:repeat(auto-fit,minmax(64px,1fr));gap:10px;margin:4px 0}
.cntopt{padding:18px 0;font-size:26px;font-weight:800;cursor:pointer;background:var(--panel2);
  border:1px solid var(--line);border-radius:12px;color:var(--ink);font-variant-numeric:tabular-nums}
.cntopt:hover:not(:disabled){border-color:var(--accent)}
.cntopt:disabled{cursor:default;opacity:.92}
.cntopt:disabled:not(.right):not(.wrong){opacity:.4}   /* awaiting playback — can't guess until you've heard it */
.cntopt.right{border-color:var(--good);background:#123a2a;color:var(--good)}
.cntopt.wrong{border-color:var(--bad);background:#3a1a1e;color:var(--bad)}

/* chorDLE! wordmark — lean on brand colors instead of emoji */
.wordmark{font-weight:800;letter-spacing:.01em;white-space:nowrap;display:inline-block}
.wordmark span{color:var(--accent2)}
h1.wordmark{line-height:0}
.wm-logo{height:auto;width:auto;max-width:min(340px,72vw);max-height:120px;display:block;margin:2px auto 0}
.wm-sm{color:var(--accent2)}
.big.dqplay{touch-action:none;user-select:none}

.buildstamp{text-align:center;color:var(--dim);opacity:.55;font-size:11px;margin-top:14px;font-variant-numeric:tabular-nums}

.singready{opacity:.72;font-size:15px;font-weight:600}
.singready.on{opacity:1;color:#3ecf7a;font-weight:800}

.mp-out{background:#3a1a1f;color:#ff9d9d;border:1px solid #7a2c34;border-radius:10px;padding:10px 14px;text-align:center;font-weight:700}
.mp-warn{font-size:12px;opacity:.72;text-align:center;margin-top:6px}

.autolbl{font-size:12px;opacity:.75;align-self:center;margin-right:2px}

.g-train{border-color:#c58af0}
.perk{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:#c58af0;border:1px solid #c58af0;border-radius:6px;padding:1px 6px;margin-left:6px;vertical-align:middle}

.resume-wrap{display:flex;gap:6px;align-items:stretch}
.resume-wrap .resume{flex:1}
.resume-x{flex:0 0 auto;width:44px;border:1px solid var(--line,#2a3340);background:transparent;color:var(--dim,#8b98a5);border-radius:12px;font-size:18px;cursor:pointer}
.resume-x:active,.resume-x:hover{color:#ff6b6b;border-color:#ff6b6b}

.authbtn.joinbtn{display:block;text-decoration:none;border-color:#5865F2}
.authbtn.joinbtn:hover{background:rgba(88,101,242,.12)}

.grid.hardbul .bul{pointer-events:none}   /* hard mode: bullets not removable → whole tile is the tap target (phone misclick fix) */

.solostats{margin:14px 0 4px;padding:12px 14px;background:rgba(255,255,255,.04);border:1px solid var(--line,#2a3340);border-radius:12px;font-size:13px}
.solostats .ss-h{font-weight:700;margin-bottom:8px;color:var(--ink)}
.solostats .ss-row{margin:5px 0;line-height:1.5}
.ss-tag{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.5px;padding:1px 7px;border-radius:6px;margin-right:6px}
.ss-tag.ok{background:rgba(62,207,122,.18);color:#3ecf7a}
.ss-tag.no{background:rgba(255,107,107,.18);color:#ff6b6b}

.mini.spend{background:linear-gradient(180deg,#e8c14a,#d4a838);color:#1a1205;border:none;font-weight:800;text-decoration:underline;box-shadow:0 0 0 2px rgba(232,193,74,.35),0 0 12px rgba(232,193,74,.5);animation:spendpulse 1.3s ease-in-out infinite}
.mini.spend.on{background:transparent;color:#e8c14a;border:1px solid #e8c14a;box-shadow:none;animation:none;text-decoration:none}
@keyframes spendpulse{0%,100%{box-shadow:0 0 0 2px rgba(232,193,74,.35),0 0 8px rgba(232,193,74,.4)}50%{box-shadow:0 0 0 3px rgba(232,193,74,.6),0 0 16px rgba(232,193,74,.75)}}

.perk.on{color:#3ecf7a;border-color:#3ecf7a}

.big.g-train{position:relative;padding-bottom:30px}
.cornerbadge{position:absolute;left:14px;bottom:9px;margin:0}

.pchart-fix{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:3px;padding-bottom:26px;text-align:left}
.pchart-fix .pf-title{font-weight:800;font-size:16px}
.pchart-fix .pf-title,.pchart-fix .pf-sub{color:#08252b}
.pchart-fix .pf-sub{opacity:.9;font-weight:600;font-size:12.5px;line-height:1.35;color:#08252b}

/* ---- Daily Tournament ---- */
.big.g-tourney{background:linear-gradient(135deg,rgba(232,193,74,.20),rgba(232,193,74,.05));border-color:#e8c14a}
@media(hover:hover){.big.g-tourney:hover{border-color:#f2d372}}
.tourney-live{display:inline-block;background:rgba(62,207,122,.16);border:1px solid #3ecf7a;color:#7fe0a4;font-weight:800;padding:6px 13px;border-radius:20px;margin:4px 0 12px}
.tourney-count{font-size:20px;font-weight:800;color:#e8c14a;margin:10px 0 14px}
.tourney-board{margin-top:18px}
.tourney-board .lbrow.me{outline:1px solid var(--accent2)}

/* MP online presence */
.pstat{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:7px;vertical-align:middle;flex:0 0 auto}
.pstat.on{background:#3ecf7a;box-shadow:0 0 5px rgba(62,207,122,.7)}
.pstat.off{background:#5a6b72}

/* Tournament countdown callout (top of menu) */
.tourney-callout{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;box-sizing:border-box;text-align:center;background:linear-gradient(135deg,rgba(232,193,74,.20),rgba(232,193,74,.05));border:1px solid #e8c14a;color:#f0d478;border-radius:12px;padding:9px 12px;margin:0 0 14px;font-size:13.5px;cursor:pointer;font-weight:600}
.tourney-callout b{color:#fff;font-weight:800}
.tourney-callout .tc-go{margin-left:auto;font-size:18px;opacity:.7}
.tourney-callout.live{border-color:#3ecf7a;color:#9fe8bd;background:rgba(62,207,122,.14)}

/* Tournament board refresh affordances */
.tb-head{display:flex;align-items:center;justify-content:space-between;margin:0 0 6px}
.tb-live{font-size:11px;color:var(--dim)}
.tb-refresh,.tb-head .mini{padding:3px 9px;font-size:13px;border-radius:8px;background:var(--panel2);border:1px solid var(--line);color:var(--accent2);cursor:pointer}

/* HINTS */
.cell.hinthere{outline:3px solid #e8c14a;outline-offset:-2px;box-shadow:0 0 16px rgba(232,193,74,.65);z-index:2}
.cell.dimlock{opacity:.25;filter:grayscale(.6);pointer-events:none}
.mini.hintbtn{padding:6px 12px;font-size:13px;border-radius:8px;background:rgba(232,193,74,.14);border:1px solid #e8c14a;color:#f0d478;cursor:pointer;font-weight:700}
.mini.hintbtn b{color:#fff}
.mini.hintbtn.on{background:#e8c14a;color:#08252b}
.mini.hintbtn.spent{opacity:.5}

/* Accuracy (batting average) badge */
.acc{font-weight:800;font-size:12.5px;margin:0 6px;white-space:nowrap;flex:0 0 auto}
.acc small{opacity:.55;font-weight:600}
.acc-good{color:#3ecf7a} .acc-mid{color:#e8c14a} .acc-low{color:#ff6b6b}
.scorechip.acc-good{color:#3ecf7a;border-color:rgba(62,207,122,.5)} .scorechip.acc-mid{color:#e8c14a;border-color:rgba(232,193,74,.5)} .scorechip.acc-low{color:#ff6b6b;border-color:rgba(255,107,107,.5)}

/* Landscape on a phone isn't ready — ask for portrait (small height only; iPad/desktop unaffected) */
@media (orientation:landscape) and (max-height:500px){
  .brandbar,#app{display:none!important}
  body::after{content:"↻  Please rotate to portrait\A\A Landscape isn’t ready yet — coming soon.";white-space:pre-wrap;position:fixed;inset:0;z-index:99999;background:var(--bg);color:var(--ink);display:flex;align-items:center;justify-content:center;text-align:center;font-size:18px;font-weight:700;padding:36px;line-height:1.5}
}

/* Reward trophy in the status bar (replaces the Spend button) */
.trophybadge{cursor:pointer;font-size:15px;border-color:#e8c14a!important;background:rgba(232,193,74,.16)!important;animation:trophydance 1.2s ease-in-out infinite;transform-origin:center bottom}
.trophybadge.on{background:#e8c14a!important;color:#08252b!important;animation:none}
@keyframes trophydance{0%,100%{transform:translateY(0) rotate(-7deg)}50%{transform:translateY(-3px) rotate(7deg)}}
.dontshow{font-size:12px;color:var(--dim);display:flex;align-items:center;gap:5px;margin-right:auto;cursor:pointer}

/* Lifetime points bank (menu banner) + trophy total — the reward pot ("points", not coins) */
.pointsbank{display:inline-flex;align-items:center;gap:6px;margin:2px auto 10px;padding:6px 14px;border-radius:999px;background:linear-gradient(180deg,rgba(232,193,74,.18),rgba(232,193,74,.08));border:1px solid rgba(232,193,74,.5);color:#fff;font-weight:800;font-size:16px;box-shadow:0 2px 10px rgba(232,193,74,.12)}
.pointsbank .pb-lbl{font-weight:600;font-size:12px;color:var(--dim);letter-spacing:.4px;text-transform:uppercase}
.tr-total{margin-top:4px;font-size:15px;color:#fff;font-weight:700}
.tr-total span{font-variant-numeric:tabular-nums}
.tr-total .tr-dump{color:#ffd666;font-size:13px;margin-left:6px;font-weight:800;text-shadow:0 0 8px rgba(255,214,102,.4)}
/* Collect button BECKONS — gold glow + swell, so you know to cash out (Nathan: "pulse the collect points button") */
.trophy .tr-btns .ghost.cashpulse{color:#ffd666;border-color:#ffd666;animation:cashpulse 1.1s ease-in-out infinite}
@keyframes cashpulse{0%,100%{transform:scale(1);box-shadow:0 0 0 0 rgba(255,214,102,0)}50%{transform:scale(1.06);box-shadow:0 0 16px 3px rgba(255,214,102,.55)}}
button.cashpulse{animation:cashpulse 1.1s ease-in-out infinite}
.scorechip.bonuschip{color:#ffd666;font-weight:800}
.brandbar .navpoints.pump{animation:navpump .3s ease-in-out infinite;color:#ffd666}
@keyframes navpump{0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(1.55)}}

/* Speed-bonus floating badge (⚡ quick correct answer) */
.floatbadge{position:absolute;top:2px;left:50%;font-weight:800;font-size:15px;color:#ffe08a;text-shadow:0 1px 3px rgba(0,0,0,.6);pointer-events:none;z-index:8;animation:floatup 1.05s ease-out forwards}
@keyframes floatup{0%{opacity:0;transform:translate(-50%,6px) scale(.8)}20%{opacity:1}100%{opacity:0;transform:translate(-50%,-26px) scale(1.1)}}

/* GAME-OVER review: amber blink on clues/squares you could still have gotten (not locked) — "left on the table" */
.cardot.missed{animation:missblinkdot 1s ease-in-out infinite}
@keyframes missblinkdot{0%,100%{box-shadow:0 0 0 2px var(--bg),0 0 0 4px #e8c14a;opacity:1}50%{box-shadow:none;opacity:.45}}
.cell.missed{animation:missblinkcell 1.1s ease-in-out infinite}
@keyframes missblinkcell{0%,100%{box-shadow:inset 0 0 0 2px #e8c14a}50%{box-shadow:inset 0 0 0 2px rgba(232,193,74,.15)}}
.ss-tag.miss{background:rgba(232,193,74,.18);color:#f0d98a;border:1px solid rgba(232,193,74,.5)}

/* Mulligan/gambit: a dancing action badge in the top bar + eligible squares pulsing to the SAME beat (amber, distinct from green-selected) */
.actionbadge{border-color:#e8c14a!important;background:rgba(232,193,74,.18)!important;color:#f0d98a!important;font-weight:800;animation:trophydance 1.2s ease-in-out infinite;transform-origin:center bottom}
.cell.beathere{z-index:2;animation:beatpulse 1.2s ease-in-out infinite}
@keyframes beatpulse{0%,100%{box-shadow:inset 0 0 0 2px rgba(232,193,74,.4);transform:scale(1)}50%{box-shadow:inset 0 0 0 3px #e8c14a,0 0 16px 2px rgba(232,193,74,.5);transform:scale(1.04)}}

/* Your lifetime points, pinned at the top of the leaderboard (always visible near the board) */
.lb-mypoints{display:inline-block;margin:0 0 10px;padding:6px 14px;border-radius:999px;background:linear-gradient(180deg,rgba(232,193,74,.18),rgba(232,193,74,.08));border:1px solid rgba(232,193,74,.5);color:#fff;font-weight:700;font-size:15px}
.lb-mypoints b{font-variant-numeric:tabular-nums}

/* Points flying off a tile toward the leaderboard icon (casual-game payoff) */
.flypts{position:fixed;z-index:60;font-weight:800;font-size:17px;color:#ffe08a;text-shadow:0 2px 6px rgba(0,0,0,.65);pointer-events:none;transform:translate(0,0);transition:transform .78s cubic-bezier(.35,0,.2,1),opacity .78s ease;will-change:transform,opacity}

/* Trophy flying to the badge (mulligan bling) + running points total by the leaderboard icon */
.flytrophy{position:fixed;z-index:61;font-size:36px;pointer-events:none;transform:translate(0,0) scale(1);transition:transform .76s cubic-bezier(.3,0,.2,1),opacity .76s ease;will-change:transform,opacity;filter:drop-shadow(0 2px 6px rgba(0,0,0,.5)) drop-shadow(0 0 11px rgba(255,214,102,.9))}
#navBoard{position:relative;overflow:visible}
.brandbar .navpoints{position:absolute;left:50%;bottom:-6px;transform:translateX(-50%);font-weight:800;font-size:9.5px;line-height:1;color:#fff;white-space:nowrap;font-variant-numeric:tabular-nums;text-shadow:0 1px 2px rgba(0,0,0,.95),0 0 2px rgba(0,0,0,.8);pointer-events:none}
.pourpt{position:fixed;z-index:63;font-size:28px;color:#ffd54a;pointer-events:none;transform:translate(0,0) scale(1);transition:transform .98s cubic-bezier(.4,0,.25,1),opacity .98s ease;filter:drop-shadow(0 0 6px rgba(255,213,74,.8));will-change:transform,opacity;text-shadow:0 1px 3px rgba(0,0,0,.5)}

/* Personal Trainer (weak-spot MC drill) */
.g-solo.trainer,.big.trainer{border-color:rgba(232,193,74,.5)}
.tr-nopts{color:var(--dim);font-size:12px;white-space:nowrap}
.tr-drilled{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin:10px 0}
.tr-chip{padding:4px 10px;border-radius:999px;font-weight:700;font-size:13px;border:1px solid var(--line)}
.tr-chip.good{color:#3ecf7a;border-color:rgba(62,207,122,.5)} .tr-chip.mid{color:#e8c14a;border-color:rgba(232,193,74,.5)} .tr-chip.low{color:#ff6b6b;border-color:rgba(255,107,107,.5)}

/* Personal Trainer hub card */
.trainer-card{background:var(--panel2);border:1px solid var(--line);border-radius:14px;padding:16px;margin-top:12px;text-align:center}
.trainer-card .primary{margin-top:10px}

/* Perfect-pitch lab cards */
.ptcards{display:flex;flex-direction:column;gap:10px;margin:10px 0}
.ptcard{background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:10px 12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ptcard>b{font-size:20px;min-width:42px}
.ptcard .ptkb{flex:1 1 120px;min-width:120px}
.ptcard .mini{flex:0 0 auto}
.ptcard.right{border-color:var(--good);box-shadow:0 0 0 1px var(--good)}
.ptcard.wrong{border-color:#ff6b6b}

/* Personal Trainer — distinct violet identity so you know you're in trainer mode */
.trainer-panel{border-top:3px solid #a98bff}
.trainer-panel .dqhead h2,.trainer-card+.lbtabs,.panel .lbtab.on{}
.dqhead h2{}

/* ============ PERSONAL TRAINER — distinct violet module identity ============ */
body.in-trainer{ --accent2:#c2a8ff; background:#02040a }
body.in-trainer .panel{ background:#05080e; border:1px solid rgba(160,130,255,.32); box-shadow:0 0 0 1px rgba(160,130,255,.1),0 12px 44px rgba(0,0,0,.55) }
body.in-trainer .dqhead h2{ color:#d7c6ff }
body.in-trainer .brandbar .navbtn{ border-color:rgba(160,130,255,.4) }
.trainer-top{ display:flex; align-items:center; gap:8px; margin-bottom:12px }
.trainer-top .tr-exit{ flex:0 0 auto; color:#c2a8ff; font-weight:700 }
.trainer-tabbar{ display:flex; gap:6px; flex:1; overflow-x:auto; scrollbar-width:none }
.trainer-tabbar::-webkit-scrollbar{ display:none }
.trainer-tabbar .ttab{ background:var(--panel2); border:1px solid rgba(160,130,255,.3); color:var(--dim); border-radius:999px; padding:6px 13px; font-weight:700; font-size:13px; white-space:nowrap; cursor:pointer; flex:0 0 auto }
.trainer-tabbar .ttab.on{ background:#7c5cd6; border-color:#7c5cd6; color:#fff; box-shadow:0 2px 10px rgba(124,92,214,.4) }
/* pitch lab: keyboard = play (big), card = pick */
.ptcards{ display:flex; flex-direction:column; gap:12px; margin:12px 0 }
.ptcard{ flex-direction:column; align-items:stretch; gap:8px; cursor:pointer; transition:border-color .12s,transform .08s }
.ptcard:active{ transform:scale(.99) }
.ptcard .ptkb{ width:100%; flex:none; cursor:pointer }
.ptlabel{ display:flex; flex-direction:column; align-items:center; font-weight:800; font-size:19px; color:#d7c6ff }
.ptlabel small{ font-weight:500; font-size:10.5px; color:var(--dim); letter-spacing:.3px }
.pt-skip{ width:100%; margin-top:2px }
.tr-chordwas{ display:block; color:var(--dim); font-size:12.5px; margin-top:5px }

/* Gambit/exchange: pulse the instruction to the beat + hint-branded trade + chooser-shaped status badge */
.gridmsg.beat{border-radius:9px;padding:8px 14px;animation:gmbeat 1.2s ease-in-out infinite}
@keyframes gmbeat{0%,100%{box-shadow:0 0 0 0 rgba(232,193,74,0)}50%{box-shadow:inset 0 0 0 1px rgba(232,193,74,.5),0 0 14px rgba(232,193,74,.28)}}
.gm-hinttrade{display:inline-block;background:rgba(232,193,74,.16);border:1px solid #e8c14a;color:#f0d478;border-radius:8px;padding:2px 9px;font-weight:800;font-size:12.5px;cursor:pointer;margin-left:3px;white-space:nowrap;animation:gmtradepulse 1.2s ease-in-out infinite}
@keyframes gmtradepulse{0%,100%{box-shadow:0 0 13px rgba(232,193,74,.5);opacity:1}50%{box-shadow:0 0 0 rgba(232,193,74,0);opacity:.7}}
.gm-hinttrade:active{background:#e8c14a;color:#08252b}
.actionbadge.ivbadge{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;padding:4px 9px;border-radius:9px;background:var(--panel2)!important;border:1px solid #e8c14a!important;line-height:1;color:#f0d98a!important}
.actionbadge.ivbadge b{font-size:15px;line-height:1}
.actionbadge.ivbadge small{font-size:8px;color:var(--dim);font-weight:600;white-space:nowrap;line-height:1}

/* Gold tile that flies from the gambit selector up to the status badge (reusable: trophies/coins later) */
.fly-gold{will-change:transform,opacity;display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:9px}
.iv-pick.gold,.fly-gold.gold{background:#e8c14a!important;border:1px solid #e8c14a!important;color:#08252b!important;box-shadow:0 0 24px rgba(232,193,74,.75)!important;transition:background .18s,box-shadow .18s}
.iv-pick.gold b,.fly-gold.gold b{color:#08252b!important}
.iv-pick.gold small,.fly-gold.gold small{color:#4a3a08!important}
.badge-land{animation:badgeland .5s ease}
@keyframes badgeland{0%{transform:scale(1.55);filter:drop-shadow(0 0 13px rgba(255,214,102,.95))}55%{transform:scale(.9)}100%{transform:scale(1);filter:drop-shadow(0 0 0 rgba(255,214,102,0))}}

/* Fading gold trail behind a flyGold tile */
.fly-trail{position:fixed;width:9px;height:9px;margin:-4px 0 0 -4px;border-radius:50%;background:#f0d478;box-shadow:0 0 9px 2px rgba(232,193,74,.7);pointer-events:none;z-index:215;animation:trailfade .52s ease-out forwards}
@keyframes trailfade{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(.25)}}

/* Gambit chooser: an interval you've already used is crossed out (usable once) */
.iv-pick.used{opacity:.42;cursor:default;border-style:dashed}
.iv-pick.used b,.iv-pick.used small{text-decoration:line-through}

/* small inline cancel in the spend prompt */
.gm-cancel{display:inline-block;background:none;border:0;color:var(--dim);font-size:12.5px;font-weight:700;cursor:pointer;padding:0 4px;text-decoration:underline;white-space:nowrap}
.gm-cancel:active{color:#ff8a8a}
