/* Theory Duel (web/js/theory/). Every id and class is prefixed td-; the
   overlay is #theory-screen, a peer of #circle-screen / #vienna-screen. */
#theory-screen { padding: 0; align-items: stretch; justify-content: stretch; background: radial-gradient(ellipse at 50% 20%, #2a1c34 0%, #12101c 55%, #07060c 100%); backdrop-filter: none; }
#td-root { position: relative; width: 100%; height: 100%; overflow: hidden;
  font-family: "Avenir Next", "Segoe UI", system-ui, sans-serif; }
#td-root::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .35;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.015) 0 2px, transparent 2px 9px), radial-gradient(ellipse at 50% 100%, rgba(255,171,46,.12), transparent 60%); }
#td-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }

/* sheets: title, setup, results, codex, settings, pause */
.td-sheet { position: absolute; inset: 0; z-index: 4; display: flex; align-items: safe center; justify-content: center; overflow-y: auto; background: rgba(5,4,10,.72); backdrop-filter: blur(4px); }
.td-panel { width: min(560px, 94vw); margin: auto; padding: 26px 24px 20px; text-align: center; border-radius: 18px;
  background: linear-gradient(180deg, rgba(48,32,60,.96), rgba(18,14,26,.98)); border: 1px solid rgba(255,215,94,.28); box-shadow: 0 20px 60px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.08); }
.td-panel-wide { width: min(880px, 96vw); text-align: left; }
.td-title { font-size: 44px; font-weight: 900; font-style: italic; letter-spacing: 2px; background: linear-gradient(180deg, #fff2c2, #ffd75e 55%, #d08a1a); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 0 18px rgba(255,215,94,.35)); }
.td-sub { margin: 8px auto 18px; max-width: 460px; font-size: 14px; line-height: 1.55; opacity: .8; }
.td-h2 { font-size: 30px; font-weight: 900; letter-spacing: 2px; color: #ffd75e; margin-bottom: 10px; }
.td-h2.win { color: #7fe3a5; } .td-h2.lose { color: #ff6b7d; }
.td-hint { font-size: 12.5px; line-height: 1.55; opacity: .6; margin: 12px 0 4px; }
.td-hint-inline { font-size: 11px; font-weight: 500; opacity: .6; margin-left: 8px; letter-spacing: 0; }
.td-quests { margin: 16px auto 4px; max-width: 420px; text-align: left; font-size: 13px; line-height: 1.7; }

/* ---- The Games of Vienna: the mini-games hub (2026-09-01; Lionel picked
   D's world dressing on B's console-library layout, temp/minigames-lab.html).
   A wooden board, a venue-grouped rail on the left, ONE parchment overview
   pane per game on the right with an inked vignette of how it plays. The
   parchment is the quest book's own nine-slice (town.css .tw-dlg-body reuses
   the same file), the type is EB Garamond ink, and gold only lives OFF the
   paper, because gold on parchment is unreadable (the quest-box lesson). */
.tdm-board { width: min(960px, 96vw); margin: auto; padding: 22px 26px 18px; border-radius: 14px;
  background: linear-gradient(180deg, #3a2a1c, #2a1d12); border: 6px solid #1c1209;
  box-shadow: inset 0 0 60px rgba(0,0,0,.55), 0 16px 44px rgba(0,0,0,.55); }
.tdm-title { font-family: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  font-style: normal; font-size: 40px; letter-spacing: 1px; margin-bottom: 14px; }
.tdm-lib { display: flex; gap: 20px; align-items: stretch; text-align: left; }
.tdm-rail { width: 224px; flex: none; display: flex; flex-direction: column; gap: 3px; }
.tdm-sep { margin: 10px 4px 4px; font-size: 10px; letter-spacing: 2.2px; color: #c9ab72; opacity: .85; }
.tdm-it { display: flex; align-items: center; gap: 9px; padding: 8px 11px; border-radius: 8px; cursor: pointer; text-align: left;
  font-family: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif; font-size: 16.5px; font-weight: 600;
  color: #e8d9b5; background: none; border: 1px solid transparent; }
.tdm-it:hover { background: rgba(243,230,200,.08); }
.tdm-it.on { background: linear-gradient(180deg, #f3e6c8, #e6d3a8); color: #6b2f1c; font-weight: 700;
  box-shadow: 0 3px 8px rgba(0,0,0,.4); }
.tdm-ico { font-size: 17px; width: 22px; text-align: center; flex: none; }
.tdm-mini { display: flex; align-items: center; gap: 9px; padding: 6px 11px; border-radius: 8px; cursor: pointer; text-align: left;
  font-family: inherit; font-size: 12.5px; color: #c9ab72; background: none; border: none; }
.tdm-mini:hover { color: #f3e6c8; }
.tdm-mini i { font-style: normal; opacity: .75; font-size: 11px; }
/* the overview: one sheet of the quest book's parchment per game */
.tdm-panes { flex: 1; min-width: 0; display: flex; }
/* NO background fill: the nine-slice's `fill` keyword already paints the
   paper's middle, and a background paints the pane's own RECTANGLE — which
   the torn edges then hang over, showing as a pale square behind the sheet.
   The quest box can afford one as its failed-to-load fallback because it
   sits over a busy plate; on this dark board it reads as a bug. */
.tdm-pane { flex: 1; margin: 10px 12px; padding: 18px 26px 20px; color: #332414; text-align: left;
  border: 4px solid transparent; border-image: url(ui/quest-parchment-worn.webp) 46 fill stretch;
  border-image-width: 34px; border-image-outset: 10px; filter: drop-shadow(0 10px 24px rgba(0,0,0,.5));
  display: flex; flex-direction: column; }
.tdm-pane.hidden { display: none; }
.tdm-venue { font-size: 10.5px; letter-spacing: 2px; font-weight: 700; color: #8a5a28; margin-bottom: 3px; }
.tdm-name { margin: 0 0 8px; font-family: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  font-size: 30px; font-weight: 800; color: #6b2f1c; letter-spacing: .3px; }
.tdm-desc { margin: 0 0 12px; font-family: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  font-size: 17.5px; font-weight: 500; line-height: 1.45; color: #332414; }
.tdm-best { min-height: 18px; margin: 8px 0 10px; font-family: "EB Garamond", Palatino, Georgia, serif;
  font-style: italic; font-size: 14px; color: #7a5b2e; }
/* the player's skill rank at this game (skills.js line()): ink, under the best */
.tdm-rank { margin: -4px 0 10px; font-family: "EB Garamond", Palatino, Georgia, serif; font-size: 15px; color: #6b2f1c; font-weight: 700; }
.tdm-rank:empty { display: none; }
.tdm-acts { display: flex; gap: 9px; flex-wrap: wrap; }
.tdm-acts button { font-family: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif; font-weight: 700;
  border-radius: 6px; cursor: pointer; letter-spacing: .3px; }
.tdm-play { font-size: 17px; color: #f3e6c8; background: linear-gradient(180deg, #7d3a22, #5c2716);
  border: 1px solid #46200f; padding: 10px 24px; box-shadow: 0 3px 10px rgba(0,0,0,.3); }
.tdm-play:hover { filter: brightness(1.12); }
.tdm-act { font-size: 13.5px; color: #6b2f1c; background: rgba(120,74,32,.1);
  border: 1px solid rgba(107,47,28,.5); padding: 9px 14px; }
.tdm-act:hover { background: rgba(120,74,32,.2); }
/* the quests block keeps its writer (refreshMenu); on the board it is chalk */
.tdm-quests { max-width: none; margin: 14px 6px 2px; font-family: "EB Garamond", Palatino, Georgia, serif;
  font-style: italic; font-size: 14px; line-height: 1.6; color: #c9ab72; text-align: center; }
.tdm-quests .td-q-title { font-style: normal; font-size: 10.5px; letter-spacing: 2.2px; color: #d8b87a; margin-bottom: 2px; }
.tdm-back { color: #d8b87a; background: none; border: 1px solid rgba(216,184,122,.4); }
.tdm-back:hover { color: #f3e6c8; border-color: #f3e6c8; }

/* the inked vignettes: a little moving engraving of each game, drawn in the
   paper's own ink so the parchment stays one material. Pure CSS loops. */
/* the pane stretches to the rail's height, so the etching takes the leftover
   paper with auto margins: centered vertically, never a blank span */
.tdm-prev { position: relative; height: 116px; margin: auto 0; flex: none; overflow: hidden;
  border-top: 1px solid rgba(107,47,28,.35); border-bottom: 1px solid rgba(107,47,28,.35); }
.tdm-prev i { position: absolute; font-style: normal; }
/* tetris: four notes fall onto a standing stack */
.tp-blk { width: 15px; height: 15px; border-radius: 3px; background: #4d3a22; top: -18px; opacity: .85;
  animation: tp-fall 3.6s cubic-bezier(.4, 0, .9, 1) infinite; }
.tp-blk.b1 { left: 26%; } .tp-blk.b2 { left: 41%; animation-delay: .9s; background: #6b2f1c; }
.tp-blk.b3 { left: 56%; animation-delay: 1.8s; } .tp-blk.b4 { left: 71%; animation-delay: 2.7s; background: #6b2f1c; }
@keyframes tp-fall { 0% { transform: translateY(0); opacity: 0; } 12% { opacity: .85; }
  60%, 100% { transform: translateY(84px); opacity: .85; } }
.tp-ground { width: 15px; height: 15px; border-radius: 3px; background: rgba(77,58,34,.5); bottom: 8px; }
.tp-ground.g1 { left: 18.5%; } .tp-ground.g2 { left: 33.5%; } .tp-ground.g3 { left: 48.5%; }
.tp-ground.g4 { left: 63.5%; } .tp-ground.g5 { left: 78.5%; height: 32px; }
/* swap: two letters trade places, then the flame */
.sw-t { top: 42px; width: 26px; text-align: center; font: 700 19px "EB Garamond", Georgia, serif; color: #4d3a22; }
.sw-t.t1 { left: 16%; } .sw-t.t2 { left: 31%; animation: sw-right 4s ease-in-out infinite; }
.sw-t.t3 { left: 46%; animation: sw-left 4s ease-in-out infinite; } .sw-t.t4 { left: 61%; } .sw-t.t5 { left: 76%; }
@keyframes sw-right { 0%, 25% { transform: none; } 45%, 100% { transform: translateX(58px); } }
@keyframes sw-left { 0%, 25% { transform: none; } 45%, 100% { transform: translateX(-58px); } }
.sw-flame { top: 14px; left: 44%; font-size: 15px; opacity: 0; animation: sw-fire 4s ease-out infinite; }
@keyframes sw-fire { 0%, 50% { opacity: 0; transform: translateY(8px); } 62% { opacity: .9; } 88%, 100% { opacity: 0; transform: translateY(-10px); } }
/* mahjong: the wall slides, a tile is drawn */
.mj-t { top: 38px; width: 26px; height: 36px; border-radius: 4px; border: 1.5px solid #4d3a22; color: #4d3a22;
  font: 700 15px/34px "EB Garamond", Georgia, serif; text-align: center; background: rgba(243,230,200,.6); }
.mj-t.m1 { left: 14%; } .mj-t.m2 { left: 27%; } .mj-t.m3 { left: 40%; } .mj-t.m4 { left: 53%; } .mj-t.m5 { left: 66%; }
.mj-t.mdraw { left: 84%; animation: mj-draw 3.5s ease-in-out infinite; }
@keyframes mj-draw { 0%, 20% { transform: translateY(-46px); opacity: 0; } 40%, 75% { transform: none; opacity: 1; }
  95%, 100% { transform: translateY(46px); opacity: 0; } }
/* performance: a note flies and the rival's health falls */
.pf-bar { top: 30px; width: 34%; height: 12px; border: 1.5px solid #4d3a22; border-radius: 6px; }
.pf-bar.pf-you { left: 8%; } .pf-bar.pf-foe { right: 8%; }
.pf-fill { position: absolute; inset: 2px; border-radius: 3px; background: #6b2f1c; }
.pf-foe .pf-fill { animation: pf-hurt 4s steps(1, end) infinite; }
@keyframes pf-hurt { 0% { right: 2px; } 30% { right: 28%; } 60% { right: 55%; } 90%, 100% { right: 80%; } }
.pf-note { top: 58px; left: 20%; font-size: 22px; color: #4d3a22; opacity: 0; animation: pf-fly 4s ease-in infinite; }
@keyframes pf-fly { 0%, 10% { opacity: 0; transform: none; } 20% { opacity: .9; }
  28% { opacity: 0; transform: translateX(290px) translateY(-26px); } 100% { opacity: 0; } }
/* the bridge: planks land, then the runner crosses */
.br-road { top: 62px; height: 5px; background: #4d3a22; border-radius: 2px; }
.br-road.br-l { left: 0; width: 30%; } .br-road.br-r { right: 0; width: 30%; }
.br-plank { top: 58px; width: 11px; height: 13px; border-radius: 2px; background: #6b2f1c; opacity: 0; }
.br-plank.p1 { left: 34%; animation: br-lay 5s linear infinite; }
.br-plank.p2 { left: 47%; animation: br-lay 5s linear infinite .5s; }
.br-plank.p3 { left: 60%; animation: br-lay 5s linear infinite 1s; }
@keyframes br-lay { 0% { opacity: 0; transform: translateY(-24px); } 8%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; } }
/* the conductor: two risers of musicians raise their instruments one section at a time, the baton beats */
.cd-riser { height: 5px; background: #4d3a22; border-radius: 2px; left: 14%; width: 72%; }
.cd-riser.r1 { top: 44px; } .cd-riser.r2 { top: 74px; left: 22%; width: 56%; }
.cd-mus { width: 9px; height: 16px; border-radius: 3px 3px 1px 1px; background: #4d3a22; }
.cd-mus::after { content: ""; position: absolute; left: 6px; top: 6px; width: 2px; height: 10px; background: #6b2f1c; transform-origin: bottom; transform: rotate(40deg); animation: cd-raise 4.8s ease-in-out infinite; }
.cd-mus.m1 { top: 28px; left: 20%; } .cd-mus.m2 { top: 28px; left: 34%; } .cd-mus.m3 { top: 28px; left: 62%; animation-delay: 0s; } .cd-mus.m4 { top: 28px; left: 76%; }
.cd-mus.m5 { top: 58px; left: 36%; } .cd-mus.m6 { top: 58px; left: 58%; }
.cd-mus.m3::after, .cd-mus.m4::after { animation-delay: 1.2s; } .cd-mus.m5::after, .cd-mus.m6::after { animation-delay: 2.4s; }
@keyframes cd-raise { 0%, 20% { transform: rotate(40deg); } 30%, 80% { transform: rotate(-30deg) translateY(-4px); } 90%, 100% { transform: rotate(40deg); } }
.cd-pod { top: 96px; left: 44%; width: 12%; height: 8px; background: #332414; border-radius: 2px; }
.cd-baton { top: 78px; left: 50%; width: 2px; height: 14px; background: #332414; transform-origin: bottom; animation: cd-beat 1.2s ease-in-out infinite; }
@keyframes cd-beat { 0%, 100% { transform: rotate(-25deg); } 50% { transform: rotate(25deg); } }
.br-runner { top: 48px; left: 6%; width: 11px; height: 11px; border-radius: 50%; background: #332414;
  animation: br-run 5s ease-in-out infinite; }
@keyframes br-run { 0%, 32% { left: 6%; } 68%, 96% { left: 88%; } 100% { left: 88%; opacity: 0; } }
/* spelling: the answer letters arrive in order */
.sp-ask { top: 16px; left: 0; right: 0; text-align: center; font: italic 500 15px "EB Garamond", Georgia, serif; color: #7a5b2e; }
.sp-l { top: 52px; width: 30px; text-align: center; font: 800 24px "EB Garamond", Georgia, serif; color: #4d3a22; opacity: 0;
  animation: sp-ink 4.4s ease-out infinite; }
.sp-l.l1 { left: 24%; } .sp-l.l2 { left: 37%; animation-delay: .5s; }
.sp-l.l3 { left: 50%; animation-delay: 1s; } .sp-l.l4 { left: 63%; animation-delay: 1.5s; }
@keyframes sp-ink { 0% { opacity: 0; transform: translateY(6px); } 12%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; } }
.sp-ok { top: 48px; left: 76%; font-size: 26px; color: #4a6b2a; opacity: 0; animation: sp-tick 4.4s ease-out infinite; }
@keyframes sp-tick { 0%, 48% { opacity: 0; } 58%, 88% { opacity: .9; } 100% { opacity: 0; } }
/* poker: five cards dealt across the felt */
.pk-c { top: 34px; width: 30px; height: 42px; border-radius: 4px; border: 1.5px solid #4d3a22; background: rgba(243,230,200,.7);
  color: #6b2f1c; font: 700 13px/40px "EB Garamond", Georgia, serif; text-align: center; opacity: 0;
  animation: pk-deal 4.5s ease-out infinite; }
.pk-c.c1 { left: 16%; } .pk-c.c2 { left: 29%; animation-delay: .35s; } .pk-c.c3 { left: 42%; animation-delay: .7s; }
.pk-c.c4 { left: 55%; animation-delay: 1.05s; } .pk-c.c5 { left: 68%; animation-delay: 1.4s; }
@keyframes pk-deal { 0% { opacity: 0; transform: translateX(60px) rotate(9deg); }
  10%, 88% { opacity: 1; transform: none; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .tdm-prev i { animation: none !important; opacity: 1; } }
/* a phone gets the rail as a chip row over the sheet */
@media (max-width: 760px) {
  .tdm-lib { flex-direction: column; }
  /* the rail becomes two even columns of pills; the venue labels go */
  .tdm-rail { width: 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 5px; }
  .tdm-sep { display: none; }
  .tdm-it { font-size: 14px; padding: 8px 9px; min-height: 40px; }
  .tdm-mini { font-size: 12px; min-height: 36px; }
  .tdm-pane { margin: 12px 4px; padding: 14px 18px 16px; }
  .tdm-title { font-size: 30px; }
}
.td-q-title { font-size: 11px; font-weight: 800; letter-spacing: 2px; opacity: .55; }
.td-q.done { opacity: .55; text-decoration: line-through; }
.td-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,.07); font-size: 14px; }
.td-row > span:first-child { font-weight: 600; opacity: .85; }
.td-row input { font: inherit; padding: 6px 10px; border-radius: 8px; border: 1px solid rgba(255,255,255,.22); background: rgba(0,0,0,.3); color: #fff; width: 180px; }
.td-seg { display: inline-flex; border-radius: 10px; overflow: hidden; border: 1px solid rgba(255,255,255,.2); }
.td-seg button { font: inherit; font-size: 13px; font-weight: 700; padding: 7px 13px; color: #ddd; background: rgba(255,255,255,.06); border: none; cursor: pointer; }
.td-seg button + button { border-left: 1px solid rgba(255,255,255,.15); }
.td-seg button.on { background: #ffd75e; color: #3a2600; }
.td-actions { margin-top: 16px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.td-actions .big-btn { margin: 6px auto 4px; background: linear-gradient(180deg, #ffe58a, #ffab2e); box-shadow: 0 0 28px rgba(255,171,46,.45), 0 4px 0 #b06a10; color: #3a2000; }
.td-actions .big-btn:hover { box-shadow: 0 0 40px rgba(255,171,46,.7), 0 6px 0 #b06a10; }
.td-key { font: inherit; font-size: 13px; font-weight: 800; padding: 5px 12px; min-width: 90px; border-radius: 8px; border: 1px solid rgba(255,255,255,.25); background: rgba(0,0,0,.3); color: #fff; cursor: pointer; }
.td-key.waiting { border-color: #ffd75e; color: #ffd75e; }

/* HUD */
#td-hud { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
#td-hud > * { pointer-events: auto; }
.td-hud-top { position: absolute; top: 10px; left: 14px; right: 14px; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; pointer-events: none; }
.td-hp { flex: 1; max-width: 420px; }
.td-hp-1 { text-align: right; }
.td-hp-name { font-size: 13px; font-weight: 800; letter-spacing: 1px; margin-bottom: 4px; }
.td-hp-bar { position: relative; height: 18px; border-radius: 9px; background: rgba(0,0,0,.5); border: 1px solid rgba(255,255,255,.25); overflow: hidden; }
.td-hp-fill, .td-hp-ghost { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 9px; }
.td-hp-1 .td-hp-fill, .td-hp-1 .td-hp-ghost { left: auto; right: 0; }
.td-hp-fill { background: linear-gradient(180deg, #8dffb0, #2fc16b); transition: width .18s; z-index: 2; box-shadow: inset 0 -3px 0 rgba(0,0,0,.25); }
.td-hp-fill.low { background: linear-gradient(180deg, #ff9aa8, #ff3b5c); animation: td-hp-pulse .6s infinite alternate; }
.td-hp-ghost { background: rgba(255,90,90,.6); transition: width .6s ease-out; z-index: 1; }
@keyframes td-hp-pulse { to { filter: brightness(1.4); } }
.td-hp-meta { display: flex; gap: 10px; justify-content: space-between; margin-top: 3px; font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.td-hp-1 .td-hp-meta { flex-direction: row-reverse; }
.td-casc { color: #ffd75e; font-size: 12px; letter-spacing: 1px; }
.td-mid { text-align: center; min-width: 120px; }
.td-round { font-size: 11px; font-weight: 800; letter-spacing: 3px; opacity: .6; }
.td-timer { font-size: 34px; font-weight: 900; font-variant-numeric: tabular-nums; text-shadow: 0 0 16px rgba(255,215,94,.5); line-height: 1.1; }
.td-wins { font-size: 14px; letter-spacing: 2px; color: #ffd75e; }
.td-callout { position: absolute; text-align: center; pointer-events: none; opacity: 0; transform: scale(.7); transition: opacity .12s, transform .12s; }
.td-callout.show { opacity: 1; transform: scale(1); animation: td-co .9s forwards; }
@keyframes td-co { 0% { transform: scale(.6); } 12% { transform: scale(1.12); } 22% { transform: scale(1); } 75% { opacity: 1; } 100% { opacity: 0; transform: translateY(-14px); } }
.td-co-main { font-size: 26px; font-weight: 900; font-style: italic; letter-spacing: 1px; color: #ffd75e; text-shadow: 0 2px 0 #7a4a00, 0 0 18px rgba(255,215,94,.7); }
.td-co-sub { font-size: 13px; font-weight: 700; margin-top: 2px; color: #fff; text-shadow: 0 1px 4px #000; }
.td-callout.seventh .td-co-main { color: #ff8f45; } .td-callout.scale .td-co-main, .td-callout.mode .td-co-main { color: #5fe6ff; text-shadow: 0 2px 0 #004a5a, 0 0 18px rgba(95,230,255,.7); }
.td-callout.mirrored .td-co-main, .td-callout.triad.mirrored .td-co-main { color: #c96bff; }
.td-callout.missed .td-co-main { color: #bbb; text-shadow: 0 2px 0 #222; font-style: normal; }
.td-callout.item .td-co-main { color: #7fe3a5; font-size: 20px; }
.td-callout.cascade .td-co-main { color: #fff; font-size: 30px; }
.td-inv { position: absolute; display: flex; gap: 8px; justify-content: center; align-items: flex-end; }
.td-card { position: relative; flex: 1; max-width: 118px; height: 86px; border-radius: 12px; cursor: pointer; font: inherit; color: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  background: linear-gradient(180deg, rgba(70,50,90,.95), rgba(30,22,40,.95)); border: 2px solid rgba(255,255,255,.2); transition: transform .12s, border-color .12s, box-shadow .12s; }
.td-card.empty { opacity: .4; }
.td-card.armed { transform: translateY(-10px); border-color: #ffd75e; box-shadow: 0 0 22px rgba(255,215,94,.6); background: linear-gradient(180deg, rgba(120,90,30,.98), rgba(60,40,10,.98)); }
.td-card-key { position: absolute; top: 4px; left: 7px; font-size: 11px; font-weight: 900; opacity: .6; }
.td-card-ico { font-size: 26px; line-height: 1.1; }
.td-card-name { font-size: 11.5px; font-weight: 800; letter-spacing: .5px; }
.td-card-armed { display: none; font-size: 9px; font-weight: 900; letter-spacing: 2px; color: #ffd75e; }
.td-card.armed .td-card-armed { display: block; }
.td-incoming { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: 6px; padding: 5px 12px; border-radius: 10px; white-space: nowrap;
  background: rgba(127,227,165,.18); border: 1px solid #7fe3a5; font-size: 12px; font-weight: 800; display: flex; gap: 8px; align-items: center; }
.td-inc-label { font-size: 9px; letter-spacing: 2px; opacity: .8; } .td-inc-hint { font-size: 10px; font-weight: 500; opacity: .7; }
.td-oppinv { position: absolute; display: flex; gap: 6px; justify-content: center; }
.td-narrow .td-oppcard { width: 16px; height: 14px; font-size: 9px; border-radius: 4px; }
.td-narrow .td-oppinv { gap: 3px; }
.td-oppcard { width: 34px; height: 30px; border-radius: 7px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.2); display: grid; place-items: center; font-size: 16px; }
.td-oppcard.empty { opacity: .3; }
.td-rot { position: absolute; display: flex; flex-direction: column; gap: 12px; }
.td-rot button { width: 64px; height: 64px; border-radius: 50%; font-size: 30px; font-weight: 900; color: #3a2600; background: linear-gradient(180deg, #ffe58a, #ffab2e); border: none; box-shadow: 0 4px 0 #b06a10; cursor: pointer; }
.td-rot button:active { transform: translateY(3px); box-shadow: 0 1px 0 #b06a10; }
#td-corner { position: absolute; bottom: 12px; right: 14px; display: flex; gap: 8px; }
.td-iconbtn { width: 36px; height: 36px; border-radius: 10px; font-size: 17px; line-height: 1; color: #fff; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.25); cursor: pointer; }
.td-iconbtn:hover { background: rgba(255,215,94,.22); border-color: #ffd75e; }
.td-iconbtn.on { background: rgba(255,215,94,.3); border-color: #ffd75e; color: #ffd75e; }
.td-narrow #td-corner { bottom: 12px; right: 12px; }
.td-banner { position: absolute; top: 40%; left: 0; right: 0; text-align: center; font-size: 56px; font-weight: 900; font-style: italic; letter-spacing: 3px; color: #fff; text-shadow: 0 3px 0 #000, 0 0 30px rgba(255,215,94,.7); pointer-events: none; animation: td-banner .25s; }
.td-banner-sub { display: block; font-size: 16px; font-style: normal; letter-spacing: 3px; opacity: .8; }
.td-win { color: #7fe3a5; } .td-lose { color: #ff6b7d; } .td-fury { color: #fff; text-shadow: 0 0 40px #fff, 0 0 80px #ffd75e; }
@keyframes td-banner { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.td-tut { position: absolute; padding: 16px 18px; border-radius: 14px; background: linear-gradient(180deg, rgba(48,32,60,.97), rgba(18,14,26,.98)); border: 1px solid rgba(255,215,94,.4); box-shadow: 0 10px 40px rgba(0,0,0,.6); font-size: 14px; line-height: 1.55; }
.td-tut-step { font-size: 10px; font-weight: 800; letter-spacing: 2px; opacity: .55; }
.td-tut-title { font-size: 20px; font-weight: 900; color: #ffd75e; margin: 2px 0 6px; }
.td-tut-keys { margin-top: 8px; font-size: 11.5px; opacity: .6; }
.td-tut-actions { margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; }
.td-tut-actions .small-btn { margin: 0; padding: 7px 14px; font-size: 13px; }
.td-tut-actions #td-tut-next { background: #ffd75e; color: #3a2600; border-color: #ffd75e; font-weight: 800; }

/* results */
.td-grade { font-size: 84px; font-weight: 900; font-style: italic; text-align: center; line-height: 1; margin: 4px 0 12px; text-shadow: 0 0 30px currentColor; }
.td-grade-S { color: #ffd75e; } .td-grade-A { color: #7fe3a5; } .td-grade-B { color: #5fe6ff; } .td-grade-C { color: #fff; } .td-grade-D, .td-grade-F { color: #ff6b7d; }
.td-res-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.td-res-grid div { display: flex; flex-direction: column; padding: 8px 10px; border-radius: 8px; background: rgba(255,255,255,.05); }
.td-res-grid span { font-size: 11px; letter-spacing: 1px; opacity: .55; text-transform: uppercase; }
.td-res-grid b { font-size: 18px; }
.td-res-cats { margin: 12px 0 6px; display: flex; flex-wrap: wrap; gap: 6px; }
.td-chip { font-size: 12px; padding: 3px 9px; border-radius: 999px; background: rgba(255,215,94,.12); border: 1px solid rgba(255,215,94,.35); }
.td-res-rare, .td-res-firsts, .td-res-daily, .td-res-quests, .td-res-ach { margin-top: 8px; font-size: 13.5px; line-height: 1.6; }
.td-res-firsts { color: #5fe6ff; } .td-res-ach { color: #ffd75e; } .td-res-quests { color: #7fe3a5; }

/* codex */
.td-cx-cat { font-size: 12px; font-weight: 800; letter-spacing: 2px; color: #ffd75e; margin: 16px 0 6px; }
.td-cx-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.td-cx { padding: 10px 12px; border-radius: 10px; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); font-size: 12.5px; line-height: 1.5; }
.td-cx.locked { opacity: .45; }
.td-cx-name { font-size: 15px; font-weight: 800; text-transform: capitalize; }
.td-cx-formula { font-family: ui-monospace, monospace; opacity: .7; }
.td-cx-ex { display: flex; gap: 3px; margin: 5px 0; flex-wrap: wrap; }
.td-pc { display: inline-grid; place-items: center; width: 27px; height: 27px; border-radius: 5px; font-size: 11px; font-weight: 900; color: #222; line-height: 1; }
.td-pc b { font-size: 10px; } .td-pc i { font-size: 9px; font-style: normal; opacity: .8; }
.td-pc-0{background:#ff5a5a}.td-pc-1{background:#ff8f45}.td-pc-2{background:#ffc94a}.td-pc-3{background:#d2f04a}.td-pc-4{background:#5fe66a}.td-pc-5{background:#3fe0c0}.td-pc-6{background:#40cfff}.td-pc-7{background:#4a8dff}.td-pc-8{background:#7a6bff}.td-pc-9{background:#bf62ff}.td-pc-10{background:#ff5fd2}.td-pc-11{background:#ff5f94}
.td-cx-meta { font-size: 11px; opacity: .6; } .td-cx-note { margin-top: 4px; opacity: .75; }

.td-solo .td-hp-1, .td-solo .td-wins { visibility: hidden; }
@media (max-width: 720px) {
  .td-hp-name { font-size: 11px; } .td-timer { font-size: 26px; } .td-hp-meta { font-size: 13px; }
  .td-card { height: 70px; } .td-card-ico { font-size: 20px; } .td-card-name { font-size: 10px; }
  .td-co-main { font-size: 20px; } .td-banner { font-size: 38px; }
}
@media (prefers-reduced-motion: reduce) { .td-callout.show { animation: none; opacity: 1; } .td-banner { animation: none; } }

/* ---- replays: the list, the reviewer's side panel, the transport bar */
.td-rp-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.td-rp { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); }
.td-rp-when { display: flex; flex-direction: column; min-width: 92px; font-size: 12px; }
.td-rp-when b { font-size: 13px; letter-spacing: 1px; } .td-rp-when span { opacity: .55; }
.td-rp-mid { display: flex; flex-direction: column; flex: 1; font-size: 12.5px; }
.td-rp-mode { font-weight: 700; text-transform: capitalize; } .td-rp-stats { opacity: .6; }
.td-rp-grade { font-size: 26px; font-weight: 900; font-style: italic; width: 34px; text-align: center; }
.td-rp .small-btn { margin: 0; }
.td-rp-del { width: 30px; height: 30px; border-radius: 8px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.18); color: #ff9aa8; cursor: pointer; font-size: 13px; }
.td-rp-empty { margin: 18px 0; opacity: .6; }
.td-review { position: absolute; z-index: 3; display: flex; flex-direction: column; padding: 10px 12px; border-radius: 12px;
  background: linear-gradient(180deg, rgba(48,32,60,.96), rgba(18,14,26,.97)); border: 1px solid rgba(255,215,94,.32); overflow: hidden; }
.td-rv-head { font-size: 10px; font-weight: 900; letter-spacing: 2px; color: #ffd75e; margin-bottom: 6px; flex: none; }
.td-rv-list { overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.td-rv-item { display: flex; flex-direction: column; gap: 2px; text-align: left; padding: 8px 10px; border-radius: 9px; cursor: pointer; font: inherit; color: #eee;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.12); border-left: 3px solid #ff8f45; }
.td-rv-item:hover { background: rgba(255,215,94,.14); border-color: #ffd75e; }
.td-rv-item.on { background: rgba(255,215,94,.2); border-color: #ffd75e; }
.td-rv-small { border-left-color: #5fe6ff; } .td-rv-power { border-left-color: #c96bff; }
.td-rv-t { font-size: 13px; font-weight: 800; } .td-rv-d { font-size: 11.5px; line-height: 1.45; opacity: .72; }
.td-rv-at { font-size: 10px; letter-spacing: 1px; opacity: .45; }
.td-rv-none { font-size: 12.5px; line-height: 1.5; opacity: .6; padding: 6px 2px; }
.td-rv-banner { font-size: 30px; color: #ffd75e; }
.td-transport { position: absolute; left: 50%; transform: translateX(-50%); bottom: 10px; z-index: 6; display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-radius: 14px; background: rgba(10,8,18,.92); border: 1px solid rgba(255,255,255,.18); max-width: 96vw; }
.td-transport button { font: inherit; font-size: 15px; color: #fff; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.22); border-radius: 9px; width: 36px; height: 34px; cursor: pointer; }
.td-transport button:hover { background: rgba(255,215,94,.22); }
.td-transport .small-btn { margin: 0; width: auto; padding: 7px 14px; font-size: 13px; }
.td-transport .td-seg button { width: auto; height: auto; border-radius: 0; border: none; padding: 6px 9px; font-size: 12px; }
#td-t-scrub { width: min(340px, 34vw); accent-color: #ffd75e; }
.td-t-time { font-size: 12px; font-variant-numeric: tabular-nums; opacity: .7; min-width: 84px; }
@media (max-width: 720px) { .td-transport { gap: 6px; padding: 6px 8px; } #td-t-scrub { width: 30vw; } .td-t-time { display: none; } }

.td-panel-pause { width: min(680px, 96vw); }
.td-runlog { margin: 10px 0 4px; text-align: left; }
.td-rl-head { font-size: 10px; font-weight: 900; letter-spacing: 2px; color: #ffd75e; margin-bottom: 6px; }
.td-rl-list { max-height: min(46vh, 340px); overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
.td-rl-row { display: flex; align-items: center; gap: 10px; padding: 5px 9px; border-radius: 8px; background: rgba(255,255,255,.05); }
.td-rl-notes { display: flex; gap: 3px; flex: none; }
.td-rl-name { flex: 1; font-size: 12.5px; font-weight: 700; }
.td-rl-tag { font-style: normal; font-size: 10px; font-weight: 800; letter-spacing: 1px; padding: 1px 6px; border-radius: 6px; background: rgba(255,255,255,.1); opacity: .8; }
.td-rl-tag.td-rl-cf { background: rgba(255,215,94,.2); color: #ffd75e; }
.td-rl-pts { font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; color: #ffd75e; }
.td-rl-none { font-size: 13px; opacity: .55; padding: 6px 0; }
.td-history { position: absolute; z-index: 3; display: flex; flex-direction: column; gap: 3px; overflow: hidden; pointer-events: none; }
.td-h-head { font-size: 8.5px; font-weight: 900; letter-spacing: 2px; color: #ffd75e; opacity: .7; margin-bottom: 2px; }
.td-h-row { display: flex; align-items: center; justify-content: space-between; gap: 4px; padding: 3px 4px; border-radius: 6px;
  background: rgba(255,255,255,.11); border: 1px solid rgba(255,255,255,.07); }
/* only the NEW row animates in. The list is rebuilt on every clear, so
   animating them all made the whole history blink each time. */
.td-h-row.fresh { background: rgba(255,215,94,.24); border-color: rgba(255,215,94,.4); animation: td-h-in .25s; }
@keyframes td-h-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.td-h-notes { display: flex; gap: 1.5px; flex-wrap: nowrap; overflow: hidden; }
.td-h-pc { display: inline-grid; place-items: center; min-width: 13px; height: 13px; padding: 0 1px; border-radius: 3px;
  font-size: 8px; font-weight: 900; color: #1a1520; }
.td-h-more { font-size: 8px; font-weight: 800; opacity: .6; align-self: center; }
.td-h-pts { font-size: 10px; font-weight: 900; color: #ffe9a3; font-variant-numeric: tabular-nums; }
.td-narrow .td-h-pc { min-width: 11px; height: 11px; font-size: 7px; }
.td-tip { position: absolute; z-index: 8; width: 230px; padding: 9px 11px; border-radius: 11px; pointer-events: none;
  background: rgba(12,9,20,.97); border: 1px solid rgba(255,215,94,.45); box-shadow: 0 10px 30px rgba(0,0,0,.6); }
.td-tip-h { display: flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 900; color: #ffd75e; }
.td-tip-ico { font-size: 18px; }
.td-tip-b { margin-top: 4px; font-size: 12px; line-height: 1.5; opacity: .85; }
.td-tip-k { margin-top: 5px; font-size: 10.5px; letter-spacing: .5px; opacity: .5; }

.td-seg button i { display: block; font-style: normal; font-size: 9.5px; font-weight: 600; opacity: .6; letter-spacing: 0; }
.td-seg button.on i { opacity: .75; }
.td-var .td-seg button { padding: 5px 12px; line-height: 1.25; }

/* ---- SWAP (js/theory/swap*.js): no cards, no rotate buttons, a pointer board */
.td-swap .td-inv, .td-swap .td-oppinv, .td-swap .td-rot, .td-swap #td-undo-btn { display: none !important; }
.td-swap #td-canvas { cursor: pointer; }
.td-keys-swap { display: none; }
.td-swap .td-keys-hint:not(.td-keys-swap) { display: none; }
.td-swap .td-keys-swap { display: block; }
#td-m-swap .td-ch-ico { color: #ffb347; font-weight: 900; }
#td-sw-opp button i { font-size: 8.5px; }
.td-seg.forced { opacity: .5; pointer-events: none; }

/* ---- MUSICAL MAHJONG (js/theory/mahjong*.js): a DOM table over a keyboard-only canvas */
.td-mj .td-inv, .td-mj .td-oppinv, .td-mj .td-rot, .td-mj #td-undo-btn, .td-mj #td-focus-btn, .td-mj .td-history { display: none !important; }
.td-mj .td-timer.low { color: #ff6b7d; }
.td-mj .td-keys-hint:not(.td-keys-mj) { display: none; } .td-keys-mj { display: none; } .td-mj .td-keys-mj { display: block; }
#td-m-mahjong .td-ch-ico { filter: saturate(1.3); }
.td-panel-mj { width: min(760px, 96vw); text-align: center; }
.td-panel-mj .td-row { flex-wrap: wrap; justify-content: center; gap: 6px 12px; }
.td-panel-mj .td-row > span:first-child { min-width: 96px; text-align: left; }
.td-panel-mj .td-hint { text-align: left; }
.mj-table { position: absolute; left: 0; right: 0; top: 74px; bottom: calc(var(--mj-kb, 78px) + 6px); z-index: 3; display: flex; flex-direction: column; justify-content: space-between; gap: 6px; padding: 0 18px;
  --mj-tw: 46px; --mj-th: 62px; --mj-cw: 30px; --mj-ch: 40px; user-select: none; -webkit-user-select: none; }
.mj-table.mj-narrow { --mj-tw: 32px; --mj-th: 44px; --mj-cw: 20px; --mj-ch: 28px; padding: 0 6px; top: 68px; gap: 4px; }
.mj-narrow .mj-row { gap: 8px; } .mj-narrow .mj-groups { gap: 6px 8px; padding-top: 8px; } .mj-narrow .mj-run { gap: 2px; padding: 3px 3px 14px; } .mj-narrow .mj-group { gap: 2px; padding: 4px; }
.mj-narrow .mj-middle { gap: 8px; } .mj-narrow .mj-wall { min-width: 46px; padding: 5px 8px; } .mj-narrow .mj-wall b { font-size: 16px; }
.mj-narrow .mj-status-text { font-size: 12px; } .mj-narrow .mj-btn { font-size: 12px; padding: 6px 10px; }
.mj-row { display: flex; align-items: center; gap: 14px; min-height: 0; }
.mj-rival { align-items: flex-start; }
.mj-mine { align-items: flex-end; }
.mj-side { flex: none; width: 64px; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.mj-narrow .mj-side { width: 40px; }
.mj-portrait { width: 56px; height: 56px; border-radius: 50%; overflow: hidden; background: #1b2a3a; border: 3px solid rgba(255,255,255,.25); display: grid; place-items: center; font-size: 28px; transition: border-color .2s, box-shadow .2s; }
.mj-rival .mj-portrait { background: #3a1b2a; }
.mj-portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 15%; }
.mj-portrait.turn { border-color: #ffd75e; box-shadow: 0 0 18px rgba(255,215,94,.6); }
.mj-narrow .mj-portrait { width: 36px; height: 36px; font-size: 18px; }
.mj-sidename { font-size: 11px; font-weight: 800; letter-spacing: 1px; opacity: .8; max-width: 70px; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mj-narrow .mj-sidename { display: none; }
.mj-area { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.mj-rival .mj-area { flex-direction: column-reverse; }
/* tiles */
.mj-tile { position: relative; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; width: var(--mj-tw); height: var(--mj-th); border-radius: 8px; border: none; padding: 0; font: inherit; color: #1a1520; cursor: pointer; flex: none;
  box-shadow: inset 0 2px 0 rgba(255,255,255,.45), inset 0 -3px 0 rgba(0,0,0,.28), 0 3px 0 rgba(0,0,0,.45); transition: transform .12s, box-shadow .12s; }
.mj-tile b { font-size: calc(var(--mj-tw) * .46); font-weight: 900; line-height: 1; }
.mj-tile i { font-size: calc(var(--mj-tw) * .3); font-style: normal; opacity: .8; line-height: 1.1; margin-top: 2px; }
.mj-tile.can:hover { transform: translateY(-4px); }
.mj-tile.sel { transform: translateY(-10px); box-shadow: inset 0 2px 0 rgba(255,255,255,.45), inset 0 -3px 0 rgba(0,0,0,.28), 0 0 0 3px #fff, 0 0 22px rgba(255,255,255,.7); z-index: 2; }
.mj-tile.fresh::after { content: ""; position: absolute; inset: -3px; border-radius: 10px; border: 2px solid #ffd75e; box-shadow: 0 0 12px rgba(255,215,94,.7); pointer-events: none; animation: mj-fresh 1.2s infinite alternate; }
@keyframes mj-fresh { to { opacity: .45; } }
.mj-tile.mj-lift { opacity: .3; }
.mj-ghost { position: fixed; z-index: 99; pointer-events: none; transform: translate(-50%, -60%) scale(1.08) rotate(-4deg); box-shadow: 0 12px 30px rgba(0,0,0,.6); }
.mj-tile.mj-back { background: linear-gradient(180deg, #4a3a5c, #2a2038); border: 1px solid rgba(255,255,255,.15); box-shadow: inset 0 2px 0 rgba(255,255,255,.12), 0 3px 0 rgba(0,0,0,.45); cursor: default; }
.mj-tile.mj-back::before { content: "♪"; color: rgba(255,255,255,.25); font-size: calc(var(--mj-tw) * .5); }
.mj-chip { width: var(--mj-cw); height: var(--mj-ch); border-radius: 6px; cursor: default; box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -2px 0 rgba(0,0,0,.25), 0 2px 0 rgba(0,0,0,.4); }
.mj-chip b { font-size: calc(var(--mj-cw) * .5); } .mj-chip i { font-size: calc(var(--mj-cw) * .32); }
.mj-theirs-tile { width: calc(var(--mj-tw) * .78); height: calc(var(--mj-th) * .78); }
/* groups and runs */
.mj-groups { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 18px; min-height: calc(var(--mj-th) + 14px); padding-top: 12px; }
.mj-theirs { min-height: calc(var(--mj-th) * .78 + 6px); padding-top: 4px; gap: 6px 12px; }
.mj-group { display: inline-flex; flex-wrap: wrap; align-items: flex-end; gap: 4px; padding: 6px 6px 6px; border-radius: 12px; min-height: calc(var(--mj-th) + 12px); max-width: 100%; }
.mj-island { background: rgba(255,255,255,.05); border: 1px dashed rgba(255,255,255,.2); }
.mj-backs { gap: 2px; }
.mj-new { border: 1px dashed rgba(255,215,94,.35); color: rgba(255,215,94,.6); font-size: 12px; font-weight: 700; padding: 0 14px; min-width: 70px; justify-content: center; align-items: center; cursor: pointer; }
.mj-new:hover, .mj-dragging .mj-new, .mj-new.armed { border-color: #ffd75e; color: #ffd75e; background: rgba(255,215,94,.08); }
.mj-new.armed { border-style: solid; box-shadow: 0 0 14px rgba(255,215,94,.35); }
.mj-drop { display: inline-block; width: 10px; height: var(--mj-th); border-radius: 4px; flex: none; }
.mj-my-turn .mj-drop:hover, .mj-dragging .mj-drop { background: rgba(255,255,255,.12); }
.mj-run { position: relative; display: inline-flex; align-items: flex-end; gap: 4px; padding: 5px 5px 16px; border-radius: 10px; }
.mj-run.mj-full { background: rgba(127,227,165,.12); box-shadow: inset 0 0 0 2px rgba(127,227,165,.7), 0 0 14px rgba(127,227,165,.25); }
.mj-run.mj-near { box-shadow: inset 0 0 0 2px rgba(255,215,94,.4); background: rgba(255,215,94,.05); }
.mj-run.mj-near::before { content: ""; position: absolute; inset: 0; border-radius: 10px; border: 2px dashed rgba(255,215,94,.55); pointer-events: none; }
.mj-run em { position: absolute; left: 4px; right: 4px; bottom: 1px; font-size: 10px; font-style: normal; font-weight: 800; letter-spacing: .3px; color: #9ff0bb; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; }
.mj-run em.mj-need { color: #ffd75e; }
.mj-run em.mj-need span { display: block; font-size: 8.5px; font-weight: 600; opacity: .7; }
.mj-theirs .mj-run { padding-bottom: 14px; } .mj-theirs .mj-run em { font-size: 9px; }
/* melds */
.mj-melds { display: flex; flex-wrap: wrap; gap: 10px; min-height: 10px; }
.mj-meld { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; padding: 5px 6px 3px; border-radius: 9px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.14); }
.mj-meld-tiles { display: flex; gap: 2px; }
.mj-meld em { font-size: 9.5px; font-style: normal; font-weight: 700; opacity: .75; white-space: nowrap; }
/* the middle: wall, yard, status */
.mj-middle { gap: 14px; flex: 1; }
.mj-wall { flex: none; display: flex; flex-direction: column; align-items: center; padding: 8px 12px; border-radius: 10px; background: rgba(0,0,0,.3); border: 1px solid rgba(255,255,255,.12); min-width: 64px; }
.mj-wall span { font-size: 9px; font-weight: 900; letter-spacing: 2px; opacity: .55; } .mj-wall b { font-size: 22px; font-variant-numeric: tabular-nums; }
.mj-yard { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-content: flex-start; gap: 4px; max-height: calc(var(--mj-ch) * 3 + 14px); overflow-y: auto; padding: 6px 8px; border-radius: 12px; background: rgba(0,0,0,.28); border: 1px solid rgba(255,255,255,.1); }
.mj-my-turn .mj-yard { border-color: rgba(255,215,94,.35); }
.mj-yard-empty { font-size: 11px; letter-spacing: 2px; opacity: .35; font-weight: 800; align-self: center; margin: auto; }
.mj-yard .mj-chip { opacity: .85; }
.mj-yard .mj-y1 { box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -2px 0 rgba(0,0,0,.25), 0 2px 0 rgba(0,0,0,.4), 0 0 0 1.5px rgba(255,171,46,.6); }
.mj-yard .mj-y0 { box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -2px 0 rgba(0,0,0,.25), 0 2px 0 rgba(0,0,0,.4), 0 0 0 1.5px rgba(52,211,255,.6); }
.mj-yard .mj-eaten { opacity: .25; transform: rotate(90deg) scale(.85); }
.mj-chip.mj-last { opacity: 1; box-shadow: 0 0 0 2px #fff, 0 0 16px rgba(255,255,255,.7); transform: translateY(-2px); }
.mj-status { flex: none; width: 250px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.mj-narrow .mj-status { width: 150px; }
.mj-status-text { font-size: 14px; text-align: center; line-height: 1.4; min-height: 20px; }
.mj-status-text b { color: #ffd75e; }
.mj-timer { width: 100%; height: 6px; border-radius: 3px; background: rgba(255,255,255,.12); overflow: hidden; }
.mj-timer-fill { height: 100%; width: 100%; background: #ffd75e; transition: width .1s linear; }
.mj-timer-fill.low { background: #ff6b7d; }
.mj-claim { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 8px 10px; border-radius: 12px; background: rgba(127,227,165,.12); border: 1px solid #7fe3a5; animation: td-h-in .2s; }
.mj-claim-tiles { display: flex; gap: 3px; }
.mj-claim-name { font-size: 12.5px; font-weight: 800; } .mj-claim-name span { font-weight: 500; opacity: .7; }
.mj-claim-btns { display: flex; gap: 8px; }
.mj-btn { font: inherit; font-size: 13px; font-weight: 800; padding: 7px 13px; border-radius: 9px; color: #fff; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.25); cursor: pointer; }
.mj-btn:hover { background: rgba(255,215,94,.22); border-color: #ffd75e; }
.mj-btn:disabled { opacity: .4; cursor: default; }
.mj-btn kbd { font: inherit; font-size: 10px; opacity: .55; margin-left: 4px; }
.mj-eat { background: linear-gradient(180deg, #a9f5c6, #5fd08a); color: #0c2a18; border-color: #7fe3a5; }
.mj-eat:hover { background: linear-gradient(180deg, #c6ffdc, #7fe3a5); }
.mj-discard { background: linear-gradient(180deg, #ffe58a, #ffab2e); color: #3a2000; border-color: #ffd75e; }
.mj-actions { display: flex; align-items: center; gap: 8px; min-height: 34px; }
.mj-help { font-size: 11.5px; opacity: .5; }
.mj-help.said { opacity: 1; color: #ffd75e; font-weight: 700; }
.mj-narrow .mj-help { display: none; }
.mj-narrow .mj-help.said { display: block; }
.mj-reveal .mj-theirs .mj-group { background: rgba(255,255,255,.04); }
@media (max-height: 640px) { .mj-table { top: 62px; } .mj-groups { min-height: 0; padding-top: 8px; } }
/* the live hand-score plate: what the hand is worth now, and how close the goal is */
.mj-score { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px 6px 0; margin-right: 6px; border-right: 1px solid rgba(255,255,255,.14); min-width: 190px; }
.mj-sc-num { display: flex; align-items: baseline; gap: 6px; line-height: 1; }
.mj-sc-num b { font-size: 24px; font-weight: 900; font-variant-numeric: tabular-nums; color: #ffd75e; }
.mj-sc-num span { font-size: 10px; font-weight: 800; letter-spacing: 1.5px; text-transform: uppercase; opacity: .5; }
.mj-sc-bd { font-size: 10.5px; opacity: .65; } .mj-sc-bd em { font-style: normal; opacity: .55; }
.mj-sc-loose { color: #ff9aa8; font-weight: 800; }
.mj-sc-goal { display: flex; align-items: center; gap: 6px; font-size: 10.5px; opacity: .8; }
.mj-sc-goal.ok { color: #7fe3a5; opacity: 1; font-weight: 700; }
.mj-sc-bar { flex: none; width: 62px; height: 5px; border-radius: 3px; background: rgba(255,255,255,.14); overflow: hidden; }
.mj-sc-bar i { display: block; height: 100%; background: linear-gradient(90deg, #ffab2e, #ffd75e); }
.mj-sc-goal.ok .mj-sc-bar i { background: #7fe3a5; }
.mj-score.ready { animation: mj-ready 1.4s infinite alternate; }
@keyframes mj-ready { to { filter: brightness(1.25); } }
.mj-keepbtn { background: linear-gradient(180deg, #cfd6ff, #8f9ce8); color: #14183a; border-color: #b9c2ff; }
.mj-discard small, .mj-keepbtn small { font-size: 10px; font-weight: 700; opacity: .7; }
.mj-meld-sum { align-self: flex-end; display: flex; flex-direction: column; align-items: center; padding: 4px 8px; border-radius: 8px; background: rgba(255,215,94,.12); border: 1px solid rgba(255,215,94,.3);
  font-size: 14px; font-weight: 900; color: #ffd75e; font-variant-numeric: tabular-nums; }
.mj-meld-sum span { font-size: 8px; font-weight: 700; letter-spacing: 1px; opacity: .6; color: #fff; }
.mj-narrow .mj-score { min-width: 0; padding-right: 8px; margin-right: 4px; }
.mj-narrow .mj-sc-num b { font-size: 18px; } .mj-narrow .mj-sc-bd { display: none; }
@media (max-width: 720px) { .mj-actions { flex-wrap: wrap; } }

/* ---- PERFORMANCE DUEL (js/theory/perform*.js): the same table with health bars */
/* Composition Mahjong has no health; the duel does. (The hiding rule above
   deliberately does NOT list .td-hp-bar: an !important there outranked this
   and left the duel with invisible health bars.) */
.td-mj:not(.td-perf) .td-hp-bar { display: none !important; }
.mj-perform { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 6px 0 2px; }
.mj-perf-label { font-size: 9px; font-weight: 900; letter-spacing: 2px; color: #ffd75e; opacity: .75; margin-right: 2px; }
.mj-perf-btn { display: flex; align-items: center; gap: 7px; padding: 5px 10px 5px 6px; border-radius: 10px; font: inherit; color: #fff; cursor: pointer;
  background: linear-gradient(180deg, rgba(90,60,120,.9), rgba(40,26,60,.95)); border: 1px solid rgba(255,215,94,.35); transition: transform .1s, box-shadow .1s, border-color .1s; }
.mj-perf-btn:hover { transform: translateY(-2px); border-color: #ffd75e; box-shadow: 0 0 16px rgba(255,215,94,.4); }
.mj-perf-btn.top { background: linear-gradient(180deg, rgba(255,171,46,.3), rgba(90,50,10,.9)); border-color: #ffd75e; }
.mj-perf-dmg { font-size: 19px; font-weight: 900; color: #ffd75e; font-variant-numeric: tabular-nums; min-width: 26px; text-align: center; text-shadow: 0 0 10px rgba(255,215,94,.5); }
.mj-perf-body { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.mj-perf-name { font-size: 11.5px; font-weight: 800; white-space: nowrap; }
.mj-perf-notes { display: flex; gap: 2px; }
.mj-perf-notes i { display: inline-grid; place-items: center; min-width: 13px; height: 13px; padding: 0 2px; border-radius: 3px; font-size: 8px; font-style: normal; font-weight: 900; color: #1a1520; }
.mj-perf-more { font-size: 10.5px; opacity: .5; }
.mj-sc-hold { font-size: 10.5px; opacity: .75; color: #9fd7ff; }
.mj-sc-hold b { color: #5fe6ff; font-size: 12px; } .mj-sc-hold span { opacity: .7; }
.td-perf .td-keys-mj { display: none; } .td-keys-perf { display: none; } .td-perf .td-keys-perf { display: block; }
.td-dmg-table { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 12px 0 2px; }
.td-dmg-table span { display: flex; flex-direction: column; align-items: center; min-width: 74px; padding: 5px 8px; border-radius: 8px; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); font-size: 10px; opacity: .8; }
.td-dmg-table b { font-size: 17px; color: #ffd75e; }
#td-m-perform .td-ch-ico { filter: saturate(1.2); }
/* the eat offer, when it stands BESIDE your own turn (playing at the same time) */
.mj-claim-bar { width: 100%; height: 4px; border-radius: 2px; background: rgba(255,255,255,.15); overflow: hidden; margin-bottom: 2px; }
.mj-claim-left { height: 100%; width: 100%; background: #7fe3a5; transition: width .1s linear; }
.mj-claim.mj-beside { box-shadow: 0 0 22px rgba(127,227,165,.45); }
.mj-claim.mj-beside::before { content: "while you play"; position: absolute; top: -9px; left: 50%; transform: translateX(-50%); font-size: 8.5px; font-weight: 900; letter-spacing: 1.5px; color: #7fe3a5; background: #14121c; padding: 0 6px; border-radius: 4px; }
.mj-claim { position: relative; }
/* playing at the same time: a phase you have committed to, and the wait */
.mj-wait { font-size: 11px; font-weight: 800; letter-spacing: 1px; opacity: .55; text-align: center; animation: mj-ready 1.2s infinite alternate; }
.mj-skip { margin-left: 4px; background: rgba(255,255,255,.08); }
.mj-committed .mj-tile.can { cursor: default; }

/* ---------------------------------------------------------- SPELLING DUEL */
.td-spell .td-inv, .td-spell .td-oppinv, .td-spell .td-rot, .td-spell #td-undo-btn, .td-spell #td-focus-btn, .td-spell .td-history { display: none !important; }
.td-spell .td-keys-hint { display: none; }
.sp-table { position: absolute; left: 0; right: 0; top: 74px; bottom: 10px; z-index: 3; padding: 0 18px; overflow: auto; --sp-glow: 0; }
.sp-wrap { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 16px; height: 100%; align-items: start; }
.sp-wrap.sp-solo { grid-template-columns: minmax(0, 1.5fr) minmax(0, .7fr); }
.sp-narrow .sp-wrap { grid-template-columns: 1fr; }
.sp-side { background: rgba(10,10,24,.72); border: 1px solid rgba(255,255,255,.14); border-radius: 14px; padding: 12px 14px; color: #eee; box-shadow: 0 0 0 calc(var(--sp-glow) * 3px) rgba(125,255,178,.6); }
.sp-side.rival { opacity: .92; }
.sp-side.locked .sp-keys, .sp-side.locked .sp-letters { opacity: .35; pointer-events: none; }
.sp-who { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; opacity: .7; display: flex; justify-content: space-between; }
.sp-foe-hp { color: #ff8a9b; letter-spacing: 0; text-transform: none; }
.sp-prompt { display: flex; align-items: baseline; gap: 14px; margin: 6px 0 4px; flex-wrap: wrap; }
.sp-sym { font-size: 44px; font-weight: 800; color: #ffd75e; letter-spacing: 1px; line-height: 1; }
.sp-side.rival .sp-sym { font-size: 30px; }
.sp-name { font-size: 14px; opacity: .85; flex: 1; min-width: 120px; }
.sp-secs { font-variant-numeric: tabular-nums; font-size: 14px; opacity: .6; }
.sp-slots { display: flex; gap: 8px; margin: 6px 0; }
.sp-slot { min-width: 40px; height: 40px; border-radius: 8px; border: 1px solid rgba(255,255,255,.2); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 20px; background: rgba(255,255,255,.04); }
.sp-slot.on { background: rgba(125,255,178,.18); border-color: #7dffb2; color: #7dffb2; }
.sp-slot.next { border-color: #34d3ff; box-shadow: 0 0 0 2px rgba(52,211,255,.35); }
.sp-side.rival .sp-slot { min-width: 32px; height: 32px; font-size: 15px; }
.sp-staff { display: block; color: #f7f2e4; margin: 2px 0 8px; max-width: 100%; }
.sp-keys { display: flex; position: relative; height: 84px; margin-top: 6px; }
.sp-wk { flex: 1; background: #f4f1ea; color: #333; border: 1px solid #999; border-radius: 0 0 6px 6px; font-size: 11px; font-weight: 700; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 5px; cursor: pointer; }
.sp-wk:hover { background: #dbe9ff; }
.sp-blacks { position: relative; height: 0; }
.sp-bk { position: absolute; top: -84px; width: 4.4%; height: 52px; transform: translateX(-50%); background: #16161f; border: 1px solid #000; border-radius: 0 0 4px 4px; cursor: pointer; z-index: 2; }
.sp-bk:hover { background: #33334a; }
.sp-letters { display: flex; gap: 5px; margin-top: 12px; flex-wrap: wrap; align-items: center; }
.sp-lt, .sp-acc, .sp-ctl { min-width: 40px; height: 38px; border-radius: 8px; border: 1px solid rgba(255,255,255,.22); background: rgba(255,255,255,.06); color: #eee; font-weight: 800; font-size: 16px; cursor: pointer; }
.sp-lt:hover, .sp-acc:hover, .sp-ctl:hover { background: rgba(255,255,255,.14); }
.sp-acc.on { background: rgba(255,215,94,.25); border-color: #ffd75e; color: #ffd75e; }
.sp-ctl { font-size: 13px; font-weight: 600; padding: 0 10px; }
.sp-gap { width: 10px; }
.sp-streak { min-height: 18px; font-size: 13px; margin-top: 8px; color: #ffd75e; }
.sp-lock { color: #ff8a9b; }
.sp-rival-note { font-size: 13px; opacity: .7; margin-top: 8px; }
.sp-drill-text { font-size: 13px; opacity: .8; margin: 8px 0; line-height: 1.45; }
.sp-drill-score { font-size: 18px; font-weight: 800; color: #7dffb2; }

/* ---- the volume popover (js/theory/volume.js, 2026-09-01): one control in
   every mini-game — the duel HUD corner (opens upward), the Chord Bridge bar
   and the poker top bar (open downward), and inline on the settings sheet.
   .tv is its own stacking context so a popover hung from a bar paints over
   the positioned canvas wrapper that follows it in the DOM. */
.tv { position: relative; display: inline-flex; z-index: 30; }
.tv-pop { position: absolute; right: 0; width: 236px; padding: 10px 12px; border-radius: 12px; background: #15121e; border: 1px solid rgba(255,215,94,.4); box-shadow: 0 8px 28px rgba(0,0,0,.55); color: #f1ecff; font-size: 12.5px; text-align: left; font-family: "Avenir Next", "Segoe UI", system-ui, sans-serif; }
.tv[data-dir="up"] .tv-pop { bottom: calc(100% + 8px); }
.tv[data-dir="down"] .tv-pop { top: calc(100% + 8px); }
.tv-head { font-size: 11px; font-weight: 800; letter-spacing: .1em; color: #ffd75e; margin-bottom: 6px; }
.tv-row { display: grid; grid-template-columns: 18px 52px 1fr 30px; align-items: center; gap: 6px; margin: 5px 0; cursor: pointer; }
.tv-row input[type=range] { width: 100%; min-width: 0; margin: 0; accent-color: #ffd75e; }
.tv-name { font-weight: 600; }
.tv-val { text-align: right; font-variant-numeric: tabular-nums; opacity: .75; font-weight: 600; }
.tv-mute { margin-top: 8px; width: 100%; padding: 6px; border-radius: 8px; border: 1px solid rgba(255,255,255,.25); background: rgba(255,255,255,.08); color: #fff; font: inherit; font-weight: 600; cursor: pointer; }
.tv-mute:hover { border-color: #ffd75e; }
.tv-mute.on { border-color: #ff7b8a; color: #ff9aa6; }
/* inline on the settings sheet: the rows in the sheet's own column */
.tv-inline { display: flex; flex-direction: column; width: min(420px, 100%); margin: 6px 0 10px; }
.tv-inline .tv-row { grid-template-columns: 20px 70px 1fr 34px; }
.tv-inline .tv-mute { width: auto; align-self: flex-start; padding: 6px 14px; }
/* scales & arpeggios: a run of keys climbing to the right, the two placed first notes marked */
.sc-ask { top: 14px; left: 0; right: 0; text-align: center; font: italic 500 14px "EB Garamond", Georgia, serif; color: #7a5b2e; }
.sc-k { top: 92px; width: 9%; height: 16px; border-radius: 3px; background: #d9cfb0; opacity: .35; animation: sc-lit 4.8s linear infinite; }
.sc-k.k1 { left: 8%; } .sc-k.k2 { left: 18%; animation-delay: .4s; } .sc-k.k3 { left: 28%; animation-delay: .8s; } .sc-k.k4 { left: 38%; animation-delay: 1.2s; }
.sc-k.k5 { left: 48%; animation-delay: 1.6s; } .sc-k.k6 { left: 58%; animation-delay: 2s; } .sc-k.k7 { left: 68%; animation-delay: 2.4s; } .sc-k.k8 { left: 78%; animation-delay: 2.8s; }
@keyframes sc-lit { 0%, 8% { opacity: .35; transform: none; } 12%, 70% { opacity: 1; background: #4a6b2a; transform: translateY(-14px); } 100% { opacity: .35; transform: none; } }
.sc-dot { top: 52px; width: 22px; height: 22px; border-radius: 50%; color: #fff; font: 800 8px "Segoe UI", sans-serif; display: flex; align-items: center; justify-content: center; }
.sc-dot.d1 { left: 78%; background: #3b82c4; } .sc-dot.d2 { left: 8%; background: #d9832b; }
/* the hand reader: a row of keys, three fingertips on E G♯ B, the names that come to mind before the right one */
.hv-ask { top: 10px; left: 0; right: 0; text-align: center; font: italic 500 14px "EB Garamond", Georgia, serif; color: #7a5b2e; }
.hv-key { top: 58px; width: 8%; height: 46px; border-radius: 0 0 3px 3px; background: #f3efe4; border: 1px solid #cdbf9c; }
.hv-key.k1 { left: 14%; } .hv-key.k2 { left: 23%; } .hv-key.k3 { left: 32%; } .hv-key.k4 { left: 41%; } .hv-key.k5 { left: 50%; } .hv-key.k6 { left: 59%; } .hv-key.k7 { left: 68%; }
.hv-blk { top: 58px; width: 5%; height: 27px; background: #3b2f22; border-radius: 0 0 2px 2px; }
.hv-blk.b1 { left: 20.5%; } .hv-blk.b2 { left: 29.5%; } .hv-blk.b3 { left: 47.5%; } .hv-blk.b4 { left: 56.5%; } .hv-blk.b5 { left: 65.5%; }
.hv-fd { width: 15px; height: 15px; border-radius: 50%; background: #3b82c4; border: 2px solid #f6e9cf; box-shadow: 0 1px 2px rgba(0,0,0,.25); }
.hv-fd.f1 { top: 86px; left: 33.5%; } .hv-fd.f2 { top: 66px; left: 48%; } .hv-fd.f3 { top: 86px; left: 69.5%; }
.hv-n { top: 32px; left: 0; right: 0; text-align: center; font: 700 15px "EB Garamond", Georgia, serif; color: #4d3a22; opacity: 0; animation: hv-name 4.8s ease-in-out infinite; }
.hv-n.n2 { animation-delay: 1.6s; } .hv-n.n3 { animation-delay: 3.2s; color: #4a6b2a; }
@keyframes hv-name { 0%, 4% { opacity: 0; transform: translateY(4px); } 10%, 26% { opacity: 1; transform: none; } 33%, 100% { opacity: 0; transform: translateY(-4px); } }
/* classic tetris (2026-09-04): a T settles onto a stack and a row goes white */
.ct-row { height: 15px; border-radius: 3px; background: rgba(77,58,34,.5); left: 18.5%; }
.ct-row.r1 { bottom: 8px; width: 45%; } .ct-row.r2 { bottom: 26px; width: 30%; }
.ct-row.r3 { bottom: 8px; left: 71%; width: 12%; height: 33px; }
.ct-gap { bottom: 8px; left: 63.5%; width: 7.5%; height: 15px; border-radius: 3px; border: 1px dashed rgba(107,47,28,.45); }
.ct-blk { width: 15px; height: 15px; border-radius: 3px; background: #6b2f1c; top: -18px; opacity: .85;
  animation: ct-fall 3.2s cubic-bezier(.4, 0, .9, 1) infinite; }
.ct-blk.c1 { left: 56%; } .ct-blk.c2 { left: 63.5%; } .ct-blk.c3 { left: 71%; } .ct-blk.c4 { left: 63.5%; top: -34px; }
@keyframes ct-fall { 0% { transform: translateY(0); opacity: 0; } 12% { opacity: .85; }
  55% { transform: translateY(84px); opacity: .85; } 70% { transform: translateY(84px); opacity: .2; } 100% { transform: translateY(84px); opacity: 0; } }
