/* src/ui.css */
/* Straits Mahjong design system. One material world: lamplit felt, varnished
   walnut, ivory and jade tiles, quiet hairline gold. Tokens first, then the
   shared components every screen uses. Legacy rules sit in @layer legacy
   (legacy.css), so anything here wins without specificity tricks. */
:root{
  --room:#0b1310;          /* the dark room around the table */
  --room-2:#101b16;
  --panel:#13231c;         /* raised dark-green panels */
  --panel-2:#0e1a15;
  --panel-line:rgba(201,168,106,.24);
  --felt:#1c4a33;
  --felt-deep:#0f2b1e;
  --walnut:#4a2e1c;
  --gold:#c9a86a;          /* lines, icons, labels */
  --gold-bright:#e6c88f;
  --gold-deep:#a8844c;
  --gold-line:rgba(201,168,106,.34);
  --gold-line-strong:rgba(214,182,120,.62);
  --ivory:#f3ead8;         /* primary text */
  --ivory-2:#d9d0bd;
  --sage:#a3b0a2;          /* secondary text */
  --sage-2:#7f8d80;
  --positive:#8fd0a2;
  --negative:#e0897a;
  --ink-on-gold:#1f1a10;
  --serif:'Straits Serif','Straits Tamil Serif','Straits Kai',Georgia,'Times New Roman',serif;
  --sans:Outfit,'Straits Tamil','Straits Kai',system-ui,sans-serif;
  --radius-control:10px;
  --radius-card:14px;
  --radius-sheet:20px;
  --hairline:1px solid var(--gold-line);
  --shadow-soft:0 10px 30px rgba(0,0,0,.35);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --primary-fill:linear-gradient(180deg,#eed5a2 0%,#d4b277 48%,#b9945b 100%);
  --panel-fill:linear-gradient(180deg,rgba(24,41,33,.94),rgba(13,24,19,.94));
  --safe-top:env(safe-area-inset-top,0px);--safe-right:env(safe-area-inset-right,0px);--safe-bottom:env(safe-area-inset-bottom,0px);--safe-left:env(safe-area-inset-left,0px);
}

/* ---------- Shell ---------- */
[hidden]{display:none!important}
/* Installed iPhone app in portrait: iOS 26 blurs a band about 30 px deep at the top of the
   content, below the opaque status bar (startup.js detects the mode). Every screen already
   pads for --safe-top, so the band shows only the room's background. */
@media (orientation:portrait){html[data-ios-edge-band]{--safe-top:32px}}
html,body{background:var(--room);color:var(--ivory);font-family:var(--sans)}
/* Lining figures everywhere: Cormorant's old-style figures make 72 read as 7².
   The font shorthand resets numeric variants, so this must be important. */
*,*::before,*::after{font-variant-numeric:lining-nums tabular-nums!important}
.room{background:var(--room)}
.surface{background:radial-gradient(120% 70% at 50% 0%,#15261e 0%,var(--room) 58%,#080d0b 100%);color:var(--ivory);border:0;border-radius:0;box-shadow:none}
.surface:before{opacity:0}
.surface>main{color:var(--ivory)}
h1,h2,h3{color:var(--ivory)}
.eyebrow{font:500 .7rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.sr-text{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
::selection{background:rgba(201,168,106,.35)}

/* Inner-screen header: back chevron, centred title, one icon on the right. */
.surface>header.app-header{position:relative;z-index:6;display:grid;grid-template-columns:48px minmax(0,1fr) auto;align-items:center;gap:6px;height:58px;min-height:58px;padding:0 8px;border:0;background:none;box-shadow:none}
.app-header .app-back,.app-header .table-menu,.app-header .header-actions>button{width:44px;height:44px;min-height:44px;min-width:44px;padding:0;display:grid;place-items:center;border:0;border-radius:50%;background:transparent;color:var(--gold);box-shadow:none}
.app-header .app-back span,.app-header .table-menu span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.app-header .icon{width:24px;height:24px;stroke-width:1.5}
.app-header .header-actions{grid-column:3;justify-self:end;display:flex;gap:4px}
/* The saving-paused warning shares the header row (it follows the actions in
   the markup, so it needs an explicit row or it drops below the header). */
.app-header .save-status{grid-column:2;grid-row:1;justify-self:center;min-width:0;max-width:100%;display:flex;flex-direction:column;align-items:center;gap:1px;padding:6px 14px;border-radius:999px;border:1px solid rgba(224,137,122,.5);background:rgba(60,20,16,.6);color:var(--ivory);font:500 .72rem/1.1 var(--sans)}
.app-header .save-status[hidden]{display:none}
.app-header .save-status span{color:var(--sage);font-size:.66rem}
@media (hover:hover) and (pointer:fine){.app-header button:hover{background:rgba(201,168,106,.1)}}
.app-header button{cursor:pointer;transition:background .18s,border-color .18s,color .18s}
.app-header button:active{background:rgba(201,168,106,.16)}
/* Desktop: the same 58 px bar (its box never moves between screens), with
   wider gutters and Back and Menu named beside their icons for the pointer.
   The game screen keeps its own compact header (game.css). */
@media (min-width:1100px) and (min-height:700px){
  html:not([data-screen=round]) .surface>header.app-header{grid-template-columns:auto minmax(0,1fr) auto;padding:0 max(clamp(16px,2.4vw - 6px,52px),var(--safe-right)) 0 max(clamp(16px,2.4vw - 6px,52px),var(--safe-left))}
  html:not([data-screen=round]) .app-header :is(.app-back,.table-menu){display:inline-flex;align-items:center;gap:8px;width:auto;padding:0 18px 0 12px;border:1px solid transparent;border-radius:999px;color:var(--gold);font:500 .9rem/1 var(--sans);letter-spacing:.02em}
  html:not([data-screen=round]) .app-header .table-menu{flex-direction:row-reverse;padding:0 12px 0 18px}
  html:not([data-screen=round]) .app-header :is(.app-back,.table-menu) span{position:static;width:auto;height:auto;overflow:visible;clip:auto;color:var(--ivory-2)}
  html:not([data-screen=round]) .app-header :is(.app-back,.table-menu) .icon{width:22px;height:22px}
}
@media (min-width:1100px) and (min-height:700px) and (hover:hover) and (pointer:fine){
  html:not([data-screen=round]) .app-header :is(.app-back,.table-menu):hover{border-color:var(--gold-line);background:rgba(201,168,106,.08)}
  html:not([data-screen=round]) .app-header :is(.app-back,.table-menu):hover span{color:var(--ivory)}
}

/* ---------- Buttons ---------- */
button,.file-label{font-family:var(--sans)}
button.primary:not(.menu-item),.file-label.primary{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 22px;border-radius:var(--radius-control);border:1px solid #f0d9a8;background:var(--primary-fill);color:var(--ink-on-gold);font:600 .95rem/1.15 var(--sans);letter-spacing:.01em;box-shadow:inset 0 1px 0 rgba(255,250,235,.7),inset 0 -2px 0 rgba(120,85,40,.35),0 6px 16px rgba(0,0,0,.35);cursor:pointer;transition:background .18s,transform .12s,filter .18s}
button.primary .icon{color:var(--ink-on-gold);width:18px;height:18px}
button.outline,.file-label{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 18px;border-radius:var(--radius-control);border:1px solid var(--gold-line);background:linear-gradient(180deg,rgba(28,44,36,.9),rgba(14,24,19,.9));color:var(--ivory);font:500 .92rem/1.15 var(--sans);box-shadow:inset 0 1px 0 rgba(255,240,210,.06);cursor:pointer;transition:background .18s,border-color .18s,transform .12s}
button.outline .icon,.file-label .icon{color:var(--gold);width:18px;height:18px}
button.quiet{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 12px;border-radius:var(--radius-control);border:1px solid transparent;background:transparent;color:var(--ivory);font:500 .92rem/1.15 var(--sans);box-shadow:none;cursor:pointer}
button.quiet .icon{color:var(--gold);width:19px;height:19px}
button.text-button{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 6px;border:0;border-radius:6px;background:transparent;color:var(--gold);font:500 .9rem/1.2 var(--sans);box-shadow:none;cursor:pointer;text-decoration:none}
button.icon-button{width:44px;height:44px;min-height:44px;min-width:44px;padding:0;display:grid;place-items:center;border:0;border-radius:50%;background:transparent;color:var(--gold);box-shadow:none;cursor:pointer}
button.icon-button span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
button.icon-button .icon{width:22px;height:22px}
button:is(.primary,.outline,.quiet,.text-button,.icon-button):disabled{cursor:default;opacity:1;border-color:rgba(201,168,106,.2);background:rgba(20,32,26,.8);color:var(--sage-2);box-shadow:none}
button:is(.primary,.outline,.quiet):active:not(:disabled){transform:translateY(1px)}
@media (hover:hover) and (pointer:fine){
  button.primary:hover:not(:disabled){filter:brightness(1.06)}
  button.outline:hover:not(:disabled),.file-label:hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(38,58,47,.95),rgba(18,30,24,.95))}
  button.quiet:hover:not(:disabled),button.icon-button:hover{background:rgba(201,168,106,.1)}
  button.text-button:hover{text-decoration:underline;text-underline-offset:3px}
}
:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px}

/* ---------- Destination rows (home, play modes, menus) ---------- */
.menu-item,.play-mode,.table-menu-list>button{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px;width:100%;min-height:72px;padding:12px 16px 12px 12px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:linear-gradient(180deg,rgba(25,45,35,.92),rgba(14,27,21,.92));color:var(--ivory);text-align:left;box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 8px 22px rgba(0,0,0,.25);cursor:pointer;transition:border-color .2s,background .2s,transform .15s}
.menu-item>.icon:first-child,.play-mode>.mode-icon,.table-menu-list>button>.icon:first-child{box-sizing:content-box;width:22px;height:22px;padding:11px;border-radius:50%;color:var(--gold);background:radial-gradient(circle at 50% 35%,#1d3228,#0b1511 72%);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(201,168,106,.22)}
.menu-item>span,.play-mode>span.mode-copy{display:grid;gap:3px;min-width:0}
.menu-item strong,.play-mode strong{font:500 1.42rem/1.1 var(--serif);color:var(--ivory);letter-spacing:.005em}
.menu-item small,.play-mode .mode-copy>span{font:400 .84rem/1.3 var(--sans);color:var(--sage)}
.play-mode small{font:500 .66rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
.menu-item>.icon:last-child,.play-mode>.icon:last-child{width:18px;height:18px;color:var(--gold)}
.menu-item.primary{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(35,62,47,.95),rgba(17,33,25,.95));box-shadow:inset 0 1px 0 rgba(255,240,210,.08),0 0 0 1px rgba(214,182,120,.12),0 10px 26px rgba(0,0,0,.3)}
.menu-item.primary>.icon:first-child{color:var(--gold-bright);box-shadow:0 0 0 1px var(--gold-bright),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(230,200,143,.4)}
/* Hover lifts the row and warms its ring; press settles it. The chevron leans
   towards where the row goes. */
.menu-item>.icon:first-child,.play-mode>.mode-icon,.table-menu-list>button>.icon:first-child{transition:color .2s,box-shadow .2s}
.menu-item>.icon:last-child,.play-mode>.icon:last-child{transition:transform .22s var(--ease-out)}
@media (hover:hover) and (pointer:fine){
  :is(.menu-item,.play-mode,.table-menu-list>button):hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(34,60,46,.96),rgba(17,33,25,.96));box-shadow:inset 0 1px 0 rgba(255,240,210,.08),0 0 0 1px rgba(214,182,120,.08),0 14px 30px rgba(0,0,0,.34);transform:translateY(-1px)}
  :is(.menu-item,.table-menu-list>button):hover>.icon:first-child,.play-mode:hover>.mode-icon{color:var(--gold-bright);box-shadow:0 0 0 1px var(--gold-bright),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(230,200,143,.38),0 0 18px rgba(230,200,143,.14)}
  :is(.menu-item,.play-mode):hover>.icon:last-child{transform:translateX(3px);color:var(--gold-bright)}
}
:is(.menu-item,.play-mode,.table-menu-list>button):active{transform:translateY(1px);background:linear-gradient(180deg,rgba(20,37,29,.96),rgba(12,23,18,.96));box-shadow:inset 0 1px 3px rgba(0,0,0,.35)}
:is(.menu-item,.play-mode,.table-menu-list>button):focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}

.play-modes{display:grid;gap:10px;margin:14px 0}
.play-intro{margin:0 0 4px;color:var(--ivory-2)}
.saved-table{display:grid;gap:10px;margin:0 0 12px;padding:14px;border-radius:var(--radius-card);border:1px solid var(--gold-line-strong);background:rgba(201,168,106,.06)}
.saved-table p,#overlay .dialog-body .saved-table p{display:grid;gap:3px;margin:0}
/* Only the note is muted; the Continue label keeps its dark ink on gold. */
.saved-table p>span{color:var(--sage);font-size:.86rem}

/* ---------- Dialogs: a dark sheet with a hairline edge ---------- */
#overlay{box-sizing:border-box;width:min(560px,calc(100vw - 24px));max-width:none;max-height:min(86vh,calc(var(--app-frame-height,100dvh) - 32px));padding:0;margin:auto;border:1px solid var(--gold-line);border-radius:var(--radius-sheet);background:linear-gradient(180deg,#15271f 0%,#0e1a15 100%);color:var(--ivory);box-shadow:0 30px 80px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,240,210,.06);overflow:hidden;display:none;flex-direction:column}
#overlay[open]{display:flex}
#overlay::backdrop{background:rgba(3,7,5,.72);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
#overlay .dialog-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 10px 12px 22px;border-bottom:1px solid rgba(201,168,106,.16);background:none}
#overlay .dialog-header h2{margin:0;font:500 1.55rem/1.15 var(--serif);color:var(--ivory)}
/* The last few pixels fade, so long content shows that it scrolls. */
#overlay .dialog-body{padding:16px 22px calc(22px + var(--safe-bottom));overflow:auto;overscroll-behavior:contain;font:400 .95rem/1.55 var(--sans);color:var(--ivory-2);-webkit-mask-image:linear-gradient(#000 calc(100% - 22px),transparent);mask-image:linear-gradient(#000 calc(100% - 22px),transparent)}
#overlay .dialog-body>*:first-child{margin-top:0}
#overlay .dialog-body h3{margin:22px 0 8px;font:500 .72rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
#overlay .dialog-body p{margin:0 0 12px}
#overlay .dialog-body strong{color:var(--ivory);font-weight:600}
#overlay .dialog-body ul,#overlay .dialog-body ol{padding-left:1.2em;margin:0 0 12px}
#overlay .dialog-body li{margin:0 0 6px}
#overlay details{margin:14px 0;border-top:1px solid rgba(201,168,106,.14);padding-top:10px}
#overlay summary{cursor:pointer;min-height:40px;display:flex;align-items:center;gap:8px;font:500 .9rem var(--sans);color:var(--gold);list-style:none}
#overlay summary::-webkit-details-marker{display:none}
/* The Play setup's House Rules (Singapore): the summary names the rules in one line, under its title. */
#overlay .house-rules>summary{flex-wrap:wrap;row-gap:2px;padding:4px 0}
#overlay .house-rules .house-line{flex:1 1 100%;margin-left:15px;font:400 .84rem/1.35 var(--sans);color:var(--ivory-2)}
.house-list{margin:2px 0 0}
.settings-list.house-list>label{min-height:56px}
#overlay .house-note{margin:8px 0 0;font:400 .8rem/1.4 var(--sans);color:var(--sage)}
.house-rules .dialog-actions{margin-top:6px}
#overlay summary:before{content:'';width:7px;height:7px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);transition:transform .2s}
#overlay details[open]>summary:before{transform:rotate(45deg)}
.dialog-actions{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 4px}
.dialog-actions>*{flex:1 1 180px}
@media (max-width:600px){
  #overlay{width:100vw;max-width:100vw;margin:auto 0 0;border-radius:var(--radius-sheet) var(--radius-sheet) 0 0;border-bottom:0;max-height:calc(var(--app-frame-height,100dvh) - 36px - var(--safe-top))}
  html[data-motion=on] #overlay[open][data-entering]{animation:sheet-up .32s var(--ease-out)}
}
@media (prefers-reduced-motion:reduce){#overlay[open]{animation:none}}
/* Short phones: the sheet rises higher and its spacing tightens, so a saved
   table and all three ways to play fit without scrolling. */
@media (max-width:600px) and (max-height:740px){
  #overlay{max-height:calc(var(--app-frame-height,100dvh) - 12px - var(--safe-top))}
  #overlay .dialog-header{padding:6px 8px 6px 20px}
  #overlay .dialog-header h2{font-size:1.35rem}
  #overlay .dialog-body{padding-top:12px}
  #overlay .dialog-body .play-intro{margin-bottom:8px;font-size:.88rem;line-height:1.4}
  .saved-table{gap:8px;margin-bottom:8px;padding:10px 12px}
  .saved-table p>span{font-size:.8rem;line-height:1.35}
  .saved-table>button.primary{min-height:44px}
  .play-modes{gap:8px;margin:8px 0}
  .play-mode{gap:10px;min-height:0;padding:8px 10px 8px 8px}
  .play-mode>.mode-icon{width:18px;height:18px;padding:8px}
  .play-mode .mode-copy{gap:2px}
  .play-mode strong{font-size:1.2rem}
  .play-mode .mode-copy>span{font-size:.8rem;line-height:1.3}
  .play-mode small{font-size:.6rem}
}
/* The smallest phones: with a saved table, its card already says progress is
   kept, so the intro gives way to the choices. */
@media (max-width:600px) and (max-height:620px){
  .play-entry:has(.saved-table) .play-intro{display:none}
}
/* Short landscape screens: wider sheets, compact rows, settings in two columns. */
@media (orientation:landscape) and (max-height:520px){
  #overlay{width:min(760px,calc(100vw - 32px));max-height:calc(var(--app-frame-height,100dvh) - 20px)}
  #overlay .dialog-header{padding:8px 10px 8px 22px}
  #overlay .dialog-header h2{font-size:1.3rem}
  #overlay .dialog-body{padding-top:10px}
  #overlay .dialog-body .play-intro{margin-bottom:8px}
  .saved-table{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:16px;margin-bottom:8px;padding:10px 12px 10px 16px}
  .saved-table>button.primary{min-height:44px}
  .play-modes{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:8px 0}
  .play-mode{grid-template-columns:auto minmax(0,1fr);align-items:start;min-height:0;padding:10px}
  .play-mode>.icon:last-child{display:none}
  .play-mode strong{font-size:1.15rem}
  .play-mode .mode-copy>span{font-size:.78rem}
  .play-mode small{letter-spacing:.1em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .settings-list{grid-template-columns:1fr 1fr;column-gap:26px}
  .settings-list>label{min-height:54px}
}
@keyframes sheet-up{from{transform:translateY(24px);opacity:.4}}
/* Tablets and desktops: a centred modal that settles into place, with a
   longer hairline shadow. Large windows scale the whole modal (zoom keeps its
   proportions for every sheet that shares #overlay); the viewport limits are
   divided by that scale so it never outgrows the window. */
@media (min-width:601px) and (min-height:521px){
  html[data-motion=on] #overlay[open][data-entering]{animation:dialog-in .3s var(--ease-out)}
  html[data-motion=on] #overlay[open][data-entering]::backdrop{animation:backdrop-in .3s ease-out}
  #overlay{box-shadow:0 40px 100px rgba(0,0,0,.62),0 0 0 1px rgba(0,0,0,.4),inset 0 1px 0 rgba(255,240,210,.07)}
}
@media (min-width:1100px) and (min-height:700px){
  #overlay{--dz:1;zoom:var(--dz);width:min(600px,calc((100vw - 64px) / var(--dz)));max-height:calc(min(88vh,var(--app-frame-height,100dvh) - 64px) / var(--dz))}
  #overlay .dialog-header{padding:18px 14px 16px 28px}
  #overlay .dialog-header h2{font-size:1.75rem}
  #overlay .dialog-body{padding:20px 28px calc(26px + var(--safe-bottom))}
}
@media (min-width:1600px) and (min-height:900px){#overlay{--dz:1.1}}
@media (min-width:1900px) and (min-height:1040px){#overlay{--dz:1.2}}
@media (min-width:2300px) and (min-height:1250px){#overlay{--dz:1.42}}
@media (prefers-reduced-motion:reduce){#overlay[open],#overlay[open]::backdrop{animation:none}}
@keyframes dialog-in{from{opacity:0;transform:translateY(12px) scale(.985)}}
@keyframes backdrop-in{from{opacity:0}}
#overlay .dialog-body>:last-child,#overlay .dialog-body>:last-child>details:last-child{margin-bottom:0}
@media (hover:hover) and (pointer:fine){
  #overlay summary:hover{color:var(--gold-bright)}
  .settings-list>label:hover>span{color:#fff8ea}
  .settings-list>label:hover input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]){border-color:var(--gold-bright)}
  select:hover{border-color:var(--gold-line-strong)}
}

/* Key-value rows used by journals and point tables. */
.journal-entry,.payment-breakdown>div{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:11px 0;border-bottom:1px solid rgba(201,168,106,.12)}
.journal-entry span,.payment-breakdown span{color:var(--sage)}
.journal-entry strong,.payment-breakdown strong{font:500 1.05rem var(--serif);color:var(--ivory)}
.payment-breakdown{display:grid;margin:6px 0 12px}

/* Menu lists inside dialogs. */
.table-menu-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.table-menu-list>button{min-height:62px;grid-template-columns:auto minmax(0,1fr);padding:10px 12px;font:500 .95rem/1.2 var(--sans)}
.table-menu-list>button>.icon:first-child{width:18px;height:18px;padding:8px}
@media (max-width:600px){.table-menu-list{grid-template-columns:1fr}}
/* This hand's own controls (Restart, New, End) sit above the help: a compact row of three. */
.table-game-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px;margin:0 0 14px;padding:0 0 14px;border-bottom:1px solid rgba(201,168,106,.18)}
.table-game-list>button{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-width:0;min-height:74px;padding:10px 6px;border:1px solid var(--gold-line);border-radius:14px;background:rgba(12,22,17,.55);color:var(--ivory);font:500 .88rem/1.15 var(--sans);text-align:center}
.table-game-list>button>.icon{width:20px;height:20px;color:var(--gold)}
.table-game-list>button:last-child>.icon{color:var(--negative)}
@media (hover:hover){.table-game-list>button:hover{border-color:var(--gold-line-strong);background:rgba(26,46,36,.8)}.table-game-list>button:hover>.icon{color:var(--gold-bright)}}
.table-game-list>button:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}

/* Match Complete: the four seats ranked, your row in gold. */
.match-final{display:grid;gap:4px;text-align:center}
.mf-eyebrow{margin:0;font:600 .7rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
#overlay .dialog-body .mf-head{margin:2px 0 10px;text-transform:none;letter-spacing:0;font:500 clamp(1.5rem,5vw,2rem)/1.1 var(--serif);color:var(--ivory)}
.mf-standings{display:grid;gap:8px;margin:0;padding:0;list-style:none;text-align:left}
.mf-standings>li{display:grid;grid-template-columns:28px auto minmax(0,1fr) auto;align-items:center;column-gap:12px;padding:10px 14px;border:1px solid rgba(201,168,106,.22);border-radius:14px;background:rgba(12,22,17,.5)}
.mf-standings>li.is-you{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(64,50,24,.5),rgba(22,26,18,.6))}
.mf-rank{font:500 1.35rem/1 var(--serif);color:var(--sage);text-align:center}
.mf-standings>li.is-top .mf-rank{color:var(--gold-bright)}
.mf-name{display:grid;font:500 .95rem/1.2 var(--sans);color:var(--ivory)}
.mf-name small{font-size:.72rem;color:var(--sage)}
.mf-standings strong{font:500 1.45rem/1 var(--serif);color:var(--ivory)}
.mf-standings strong.positive{color:var(--positive)}.mf-standings strong.negative{color:var(--negative)}

/* ---------- Forms: settings rows, toggles and selects ---------- */
.settings-list{display:grid;margin:0 0 8px}
.settings-list>label{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:64px;padding:10px 0;border-bottom:1px solid rgba(201,168,106,.12);cursor:pointer}
.settings-list>label>span{display:grid;gap:2px;font:500 1rem/1.25 var(--sans);color:var(--ivory)}
.settings-list>label small{font:400 .8rem/1.3 var(--sans);color:var(--sage)}
.settings-list>label.settings-language>span{grid-template-columns:auto minmax(0,1fr);column-gap:10px;align-items:center}
.settings-language>span>.icon{grid-row:span 2;width:22px;height:22px;color:var(--gold)}
input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]){appearance:none;-webkit-appearance:none;flex:none;position:relative;width:60px;height:30px;margin:0;border-radius:999px;border:1px solid var(--gold-line-strong);background:#1b2c24;box-shadow:inset 0 2px 4px rgba(0,0,0,.45);cursor:pointer;transition:background .2s,border-color .2s}
input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]):after{content:'';position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:linear-gradient(180deg,#e9e2d0,#b8af9b);box-shadow:0 2px 4px rgba(0,0,0,.5);transition:transform .22s var(--ease-out),background .2s}
input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]):checked{background:linear-gradient(180deg,#2a5b41,#1c4430);border-color:var(--gold-line-strong)}
input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]):checked:after{transform:translateX(30px);background:var(--primary-fill)}
/* State words in the track, so On and Off never depend on colour alone. */
input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]):before{content:attr(data-off);position:absolute;top:0;bottom:0;right:9px;display:grid;place-items:center;font:600 .52rem/1 var(--sans);letter-spacing:.08em;text-transform:uppercase;color:var(--sage)}
input[type=checkbox]:is([data-setting],[data-sol-setting],[data-house]):checked:before{content:attr(data-on);right:auto;left:10px;color:var(--gold-bright)}
select{appearance:none;-webkit-appearance:none;min-height:44px;padding:0 38px 0 14px;border-radius:var(--radius-control);border:1px solid var(--gold-line);background:#0c1712 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='m1 1.5 5 5 5-5' fill='none' stroke='%23c9a86a' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") right 14px center/12px 8px no-repeat;color:var(--ivory);font:500 .92rem var(--sans);cursor:pointer}
.file-label{position:relative;overflow:hidden}
.file-label input{position:absolute;inset:0;opacity:0;cursor:pointer}
.settings-links{display:flex;flex-wrap:wrap;gap:8px 16px;margin-top:10px}
.error-text{color:var(--negative)}

/* ---------- Toast ---------- */
/* Status drops in just below the header. Every screen keeps its actions at the
   bottom (home rows, the library dock, lesson and game bars), so the top is the
   one place a message never covers something to press. Width is its own, up to
   the safe width, so it does not shrink to half the screen. */
#notice.notice{position:fixed;left:50%;top:calc(var(--safe-top) + 64px);bottom:auto;transform:translateX(-50%);z-index:50;box-sizing:border-box;width:max-content;max-width:min(520px,calc(100vw - 32px - var(--safe-left) - var(--safe-right)));padding:0;text-align:center;border-radius:12px;background:none;color:var(--ivory);font:500 .88rem/1.4 var(--sans);box-shadow:none;border:0;outline:0;pointer-events:none}
#notice.notice:not(:empty){padding:12px 18px;background:rgba(9,16,13,.95);box-shadow:0 0 0 1px var(--gold-line),0 12px 30px rgba(0,0,0,.5)}
.surface>#notice.notice{position:fixed}

/* Launch: the opening screen is styled inline in index.html, so it paints before these stylesheets arrive. */

/* ---------- Tiles in the DOM ---------- */
/* DOM tiles show the rendered 3D portrait of the same tile the table uses;
   the SVG art underneath is the fallback until portraits are ready. */
html[data-portraits] .tile[data-tile-id] .tile-face{background:var(--portrait) center/contain no-repeat}
html[data-portraits] .tile[data-tile-id] .tile-face>svg{opacity:0}
html[data-portraits] .tile-back{background:var(--portrait-back) center/contain no-repeat;border:0;box-shadow:none}
/* Large desktops: the header grows with the content it frames (every screen alike). */
@media (orientation:landscape) and (min-width:1700px) and (min-height:940px){
  .surface>header.app-header{zoom:1.18}
}
@media (orientation:landscape) and (min-width:2300px) and (min-height:1250px){
  .surface>header.app-header{zoom:1.42}
}
/* Coaching in a Guided Hand: the guide's tile wears a gold tab riding on its top edge, lifted with it
   (a tab on the slot stayed put and covered the lifted face in landscape),
   the guide's move is ringed in the action bar and the move sheet, and a hint leads to its lesson. */
.gm-rack .gm-slot.guide-pick.guide-pick:before{display:none}
.gm-rack .gm-slot.guide-pick.guide-pick>.tile:before{content:attr(data-tag);display:block;position:absolute;z-index:3;left:50%;top:-11px;visibility:visible;transform:translateX(-50%);padding:1px 6px;border-radius:5px;background:var(--gold-bright);box-shadow:0 2px 6px rgba(0,0,0,.45);font:700 .52rem/1.25 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:#1c1407;pointer-events:none;white-space:nowrap}
.game-screen .gm-button[data-suggested]{box-shadow:0 0 0 2px var(--gold-bright),0 0 14px rgba(230,200,143,.45)}
#overlay .claim-choice{position:relative}
#overlay .claim-choice.is-suggested{border-color:var(--gold-bright);box-shadow:0 0 0 1px var(--gold-bright)}
#overlay .claim-choice .guide-tag{position:absolute;top:-9px;right:14px;padding:1px 7px;border-radius:5px;background:var(--gold-bright);font:700 .56rem/1.3 var(--sans);font-style:normal;letter-spacing:.1em;text-transform:uppercase;color:#1c1407}
#overlay .hint-lesson{justify-content:flex-start;margin-top:4px}
.rs-lesson{max-width:34rem;margin:6px auto 10px;padding:8px 14px;border-radius:12px;background:rgba(6,11,9,.55);box-shadow:inset 0 0 0 1px var(--gold-line);font:400 min(.88rem,18px)/1.4 var(--sans);color:var(--ivory-2);text-align:center;text-wrap:pretty}
@media (prefers-reduced-motion:no-preference){.game-screen .gm-button[data-suggested]{animation:guide-glow 2.4s ease-in-out infinite}}
@keyframes guide-glow{50%{box-shadow:0 0 0 2px var(--gold-bright),0 0 22px rgba(230,200,143,.7)}}
/* The message line keeps one height (three lines, measured by a hidden ghost in the same grid
   cell) whatever it says, so coaching, claims and blocked wins never move the table; the full
   reason is always in Hint. Short landscape keeps its floating two-line bubble. */
.game-screen .gm-message{display:grid;place-items:center}
.game-screen .gm-message>*{grid-area:1/1;min-width:0}
.game-screen .gm-message>.gm-ghost{visibility:hidden;pointer-events:none}
.game-screen .gm-message>p.gm-feedback{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
@media (orientation:landscape) and (max-height:620px){.game-screen .gm-message{display:flex}.game-screen .gm-message>.gm-ghost{display:none}
  /* The bottom padding becomes a transparent border, so the clamp never shows a sliver of a fourth line. */
  .game-screen .gm-message>p.gm-feedback{-webkit-line-clamp:3;padding-bottom:0;border-bottom:6px solid transparent}}
/* The move sheet's coaching line: the guide's choice in gold, then its reason. */
#overlay .sheet-guide{margin:2px 0 10px;padding:10px 14px;border-radius:12px;background:rgba(201,168,106,.08);box-shadow:inset 0 0 0 1px var(--gold-line);font:400 .92rem/1.45 var(--sans);color:var(--ivory-2)}
#overlay .sheet-guide strong{color:var(--gold-bright);font-weight:600}
/* Large text (the setting, or the browser's own enlargement) on a narrow phone: Hint and Guide show
   their icons alone (their names stay in the accessible labels) so the move in the middle keeps its
   whole word and nothing reads "Gui…". */
@media (max-width:520px){
  html:is([data-text=large],[data-expanded-text=true]) .game-screen .gm-actions{grid-template-columns:52px minmax(0,1fr) 52px}
  html:is([data-text=large],[data-expanded-text=true]) .game-screen .gm-actions>.gm-button{padding:0}
  html:is([data-text=large],[data-expanded-text=true]) .game-screen .gm-actions>.gm-button>span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
}
/* The bonus strip is a quiet button: it opens your tiles, enlarged and named. */
.game-screen button.gm-bonus{padding:0;margin-top:0;margin-bottom:0;margin-left:0;min-height:0;border:0;border-radius:4px;background:none;box-shadow:none;cursor:pointer}
.game-screen button.gm-bonus:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px}
/* The win moment names the hand's value and your points before the result arrives. */
.gm-celebrate .gm-celebrate-sum{margin:0;padding:4px 14px;border-radius:999px;background:rgba(10,18,14,.88);box-shadow:0 0 0 1px var(--gold-line);font:600 min(1rem,20px)/1.3 var(--sans);letter-spacing:.02em;color:var(--ivory)}
html[data-motion=on] .gm-celebrate .gm-celebrate-sum{animation:rs-rise .6s var(--ease-out) .3s both}
/* A claim offer keeps the message line's height too: the tile's name line, then at most two lines
   of question and the guide's reason (the whole reason is in the claim sheet and Hint). */
.game-screen .gm-message .gm-offer .gm-feedback{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.game-screen .gm-message .gm-offer p{gap:0}
.game-screen .gm-message .gm-offer-line{line-height:1.1}

/* Scrollbars: a slim gold pill on no track, with no arrow buttons, faint until the pointer is over what
   scrolls, fuller under the pointer and while dragged (director, 26 Sep: more polished than the browser's).
   Native scrolling is kept (momentum, keys, assistive technology); Firefox takes only the standard thin colours,
   and phones keep their own auto-hiding indicators. An element that hides its scrollbar still does. */
@supports selector(::-webkit-scrollbar){
  ::-webkit-scrollbar{width:10px;height:10px;background:transparent}
  ::-webkit-scrollbar-track,::-webkit-scrollbar-corner{background:transparent}
  ::-webkit-scrollbar-button{display:none;width:0;height:0}
  ::-webkit-scrollbar-thumb{min-height:36px;min-width:36px;border:3px solid transparent;border-radius:999px;background:rgba(201,168,106,.24) padding-box}
  :hover::-webkit-scrollbar-thumb{background-color:rgba(201,168,106,.46)}
  ::-webkit-scrollbar-thumb:hover{border-width:2px;background-color:rgba(230,200,143,.72)}
  ::-webkit-scrollbar-thumb:active{border-width:2px;background-color:rgba(230,200,143,.88)}
}
@supports not selector(::-webkit-scrollbar){*{scrollbar-width:thin;scrollbar-color:rgba(201,168,106,.5) transparent}}
/* The mode switcher (modes.js): on Home the brand names the game being played, with a chevron that
   opens the list of games; each is a card with its tile, name and one line. */
.app-header .brand.mode-switch small{display:inline-flex;align-items:center;gap:5px}
.app-header .brand.mode-switch small .icon{width:11px;height:11px;transform:rotate(90deg);color:var(--gold)}
@media (hover:hover){.app-header .brand.mode-switch:hover strong{color:var(--gold-bright)}}
/* The brand is a name, not a pill: no filled box on hover, press or focus (a restored focus after a switch once left a faint box behind it on the director's phone). */
.app-header .brand:is(:hover,:active,:focus){background:none}
#overlay .dialog-body .mode-list,.mode-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr));gap:10px;margin:0;padding:0;list-style:none}
.mode-list>li{display:grid}
.mode-card{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:14px;width:100%;min-height:68px;padding:10px 16px 10px 12px;border:1px solid var(--gold-line);border-radius:14px;background:rgba(255,255,255,.025);color:var(--ivory);text-align:left;cursor:pointer}
.mode-card .tile{--w:40px;width:40px;height:auto;aspect-ratio:1/1.52;pointer-events:none}
.mode-card strong{display:block;font:500 1.22rem/1.15 var(--serif);color:var(--ivory)}
.mode-card small{display:block;margin-top:3px;font:400 .84rem/1.35 var(--sans);color:var(--sage)}
.mode-card .row-tag{margin-left:10px;padding:2px 8px;border-radius:999px;border:1px solid var(--gold-line-strong);font:500 .56rem/1.4 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-bright);font-style:normal;vertical-align:.3em;white-space:nowrap}
.mode-card.current{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(25,45,35,.92),rgba(14,27,21,.92))}
@media (hover:hover){.mode-card:not(.current):hover{border-color:var(--gold-line-strong)}}

/* ---------- Press feedback (docs/motion.md) ----------
   Everything pressable gives under the finger (80 ms in) and springs back on the house curve (220 ms);
   small buttons give more than rows and cards. Transform only, so nothing around it moves. */
html[data-motion=on] :is(button.primary,button.outline,button.quiet,.file-label,.gm-button){transition:background .18s,border-color .18s,filter .18s,transform .22s var(--ease-out)}
html[data-motion=on] :is(button.text-button,button.icon-button,.app-header button,.mode-card,.app-lesson .tutorial-choice,.first-steps .first-choice,.chapter-piece){transition:background .18s,border-color .18s,color .18s,box-shadow .2s,transform .22s var(--ease-out)}
html[data-motion=on] :is(.menu-item,.play-mode,.table-menu-list>button,.sol-card){transition:border-color .2s,background .2s,transform .22s var(--ease-out)}
html[data-motion=on] :is(button.primary,button.outline,button.quiet,.file-label,.gm-button,.app-header .brand):active:not(:disabled){transform:scale(.965);transition-duration:.08s}
html[data-motion=on] :is(button.text-button,button.icon-button):active:not(:disabled){transform:scale(.9);transition-duration:.08s}
html[data-motion=on] :is(.menu-item,.play-mode,.table-menu-list>button,.mode-card,.sol-card,.welcome-choice,.app-lesson .tutorial-choice,.first-steps .first-choice,.score-choices>button,.chapter-piece):active:not(:disabled){transform:scale(.982);transition-duration:.08s}
/* Dialogs open with motion at every size (docs/motion.md): a landscape phone gets the centred settle,
   and a phone's bottom sheet fades its backdrop in as it rises. */
@media (min-width:601px) and (max-height:520px){
  html[data-motion=on] #overlay[open][data-entering]{animation:dialog-in .3s var(--ease-out)}
  html[data-motion=on] #overlay[open][data-entering]::backdrop{animation:backdrop-in .3s ease-out}
}
@media (max-width:600px){html[data-motion=on] #overlay[open][data-entering]::backdrop{animation:backdrop-in .32s ease-out}}
/* Reduced motion wins over every dialog animation above, the backdrop included (* does not reach ::backdrop). */
@media (prefers-reduced-motion:reduce){#overlay[open],#overlay[open]::backdrop{animation:none!important}}

/* A game, not a document: no page pinch or double-tap zoom (director, 26 Sep 2026). Settings' Text Size enlarges
   the words and the Gwai Lou board zooms itself. touch-action only reaches up to the nearest scrolling box, so every
   element restates it; what needs more or less (the board, buttons) says so with its own rule. */
*{touch-action:pan-x pan-y}
html #app{touch-action:pan-y}

/* src/home.css */
/* Home: a lamplit still life of real tiles, a serif headline, then the
   destination rows, as in home-dark.png. */
html[data-screen=home] .surface{background:radial-gradient(110% 60% at 50% 30%,#132019 0%,var(--room) 60%,#070b09 100%)}
html[data-screen=home] .surface>header.app-header{grid-template-columns:minmax(0,1fr) auto;padding:0 10px 0 14px}
.app-header .brand{grid-column:1;justify-self:start;display:flex;justify-content:flex-start;align-items:center;gap:11px;min-width:0;min-height:44px;padding:0;border:0;background:none;box-shadow:none;color:var(--ivory);text-align:left;cursor:pointer}
.app-header .brand-mark{display:grid;place-items:center;width:36px;height:36px;flex:none;border-radius:50%;background:radial-gradient(circle at 50% 35%,#1d3228,#0b1511 72%);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(201,168,106,.25)}
/* The brand mark: a tiny ivory tile with jade backing carrying the mosaic dragon
   playground (the small cut from src/brand.js). */
.app-header .brand-tile{display:grid;place-items:center;width:16px;height:21px;border-radius:3px;background:linear-gradient(170deg,#fffaf0,#eadfc8);box-shadow:0 2px 0 #1d6844,0 3px 3px rgba(0,0,0,.45)}
.app-header .brand-dragon{display:block;width:88%;height:auto}
.app-header .brand-text{display:grid;gap:2px;min-width:0}
.app-header .brand-text strong{font:500 1.28rem/1.05 var(--serif);letter-spacing:.01em;color:var(--ivory);white-space:nowrap}
.app-header .brand-text small{font:500 .6rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
html[data-screen=home] .app-header .header-actions{grid-column:2}
/* With saving paused, the warning sits between the brand and Settings; on
   narrow phones the brand keeps only its medallion so all three fit. */
html[data-screen=home] .surface>header.app-header:has(>.save-status:not([hidden])){grid-template-columns:auto minmax(0,1fr) auto}
html[data-screen=home] .app-header:has(>.save-status:not([hidden])) .header-actions{grid-column:3}
@media (max-width:479px){html[data-screen=home] .app-header:has(>.save-status:not([hidden])) .brand-text{display:none}}

.surface>main.home-screen{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(250px,1fr) auto auto;grid-template-areas:"hero" "menu" "note";row-gap:10px;width:100%;max-width:640px;margin:0 auto;padding:0 14px calc(10px + var(--safe-bottom));overflow:hidden auto}
.home-hero{grid-area:hero;position:relative;min-height:0;margin:0 -14px;overflow:hidden;isolation:isolate;--still-life-y:.64;--still-life-x:.1}
.home-hero .home-table{position:absolute;inset:0;z-index:0}
.home-hero .home-table canvas{display:block;width:100%;height:100%}
/* The table dissolves into the room at the edges; the headline sits on its dark top. */
.home-hero:after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(180deg,var(--room) 0%,rgba(11,19,16,.55) 16%,rgba(11,19,16,0) 36%,rgba(11,19,16,0) 78%,var(--room) 100%),radial-gradient(95% 75% at 60% 62%,transparent 50%,rgba(6,10,8,.6) 100%)}
.home-hero .hero-tiles{position:absolute;right:8%;bottom:18%;z-index:1;display:flex;gap:6px}
.home-hero .hero-tiles .tile{--w:64px;width:64px;height:auto;aspect-ratio:1/1.52}
.home-hero:has(.home-table[data-ready=true]) .hero-tiles{display:none}
.home-headline{grid-area:hero;align-self:start;justify-self:start;position:relative;z-index:2;display:grid;gap:10px;max-width:78%;margin:10px 0 0 8px;pointer-events:none}
.home-headline h1{margin:0;font:500 clamp(2.1rem,9vw,3rem)/1 var(--serif);letter-spacing:.005em;color:var(--ivory);text-shadow:0 2px 18px rgba(0,0,0,.6)}
.home-rule{display:block;width:34px;height:1px;background:var(--gold)}
.home-headline .eyebrow{margin:0}

.home-screen .main-menu{grid-area:menu;position:relative;z-index:2;display:grid;gap:10px}
.home-screen .scope-note{grid-area:note;position:relative;z-index:2;display:flex;justify-content:flex-end;align-items:center;min-height:44px}
/* The quiet way into the whole library: a small outlined pill, not a bare link. */
.home-screen .scope-note button.text-button{min-height:44px;padding:0 16px;border:1px solid var(--gold-line);border-radius:999px;font-size:.84rem;letter-spacing:.02em;background:rgba(12,22,17,.5)}
.home-screen .scope-note button.text-button:hover{text-decoration:none;border-color:var(--gold-line-strong);color:var(--gold-bright)}
/* One quiet tag marks where to begin; every row keeps the same frame. */
.menu-item .row-tag{margin-left:10px;padding:2px 8px;border-radius:999px;border:1px solid var(--gold-line-strong);font:500 .56rem/1.4 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-bright);font-style:normal;vertical-align:.3em;white-space:nowrap}
.home-screen .menu-item.primary{border-color:var(--gold-line);background:linear-gradient(180deg,rgba(25,45,35,.92),rgba(14,27,21,.92));box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 8px 22px rgba(0,0,0,.25)}
.home-screen .menu-item.primary>.icon:first-child{color:var(--gold);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(201,168,106,.22)}

@media (max-height:700px) and (orientation:portrait){
  .surface>main.home-screen{grid-template-rows:minmax(190px,1fr) auto auto}
  .home-headline h1{font-size:1.9rem}
  .menu-item{min-height:62px}
  .menu-item strong{font-size:1.25rem}
}
/* Small phones: shorter rows and headline so every destination fits. */
@media (max-width:374px),(max-height:620px) and (orientation:portrait){
  .surface>main.home-screen{row-gap:8px;grid-template-rows:minmax(160px,1fr) auto auto}
  .home-headline{gap:6px}
  .home-headline h1{font-size:1.6rem}
  .home-screen .main-menu{gap:8px}
  .menu-item{min-height:56px;padding:8px 12px 8px 8px;gap:10px}
  .menu-item strong{font-size:1.12rem}
  .menu-item small{font-size:.76rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .menu-item>.icon:first-child{width:17px;height:17px;padding:9px}
  .menu-item .row-tag{display:none}
  .home-screen .scope-note{min-height:36px}
}
/* Landscape: the still life bleeds from the left edge; headline and rows share the right column.
   The header floats full width, as on every other screen, and its padding keeps
   the brand and Settings inside the safe area. The column starts below it when
   there is room and centres in the height otherwise. */
@media (orientation:landscape) and (min-width:700px){
  html[data-screen=home] .surface>header.app-header{position:absolute;left:0;right:0;top:var(--safe-top);padding:0 max(10px,var(--safe-right)) 0 max(14px,var(--safe-left));background:linear-gradient(#0b1310d9,#0b131000)}
  .surface>main.home-screen{grid-template-columns:minmax(0,1.15fr) minmax(320px,.85fr);grid-template-rows:minmax(calc(58px + var(--safe-top)),1fr) auto auto auto 1fr;grid-template-areas:"hero ." "hero headline" "hero menu" "hero note" "hero .";column-gap:30px;row-gap:0;max-width:none;height:100%;padding:0 max(24px,var(--safe-right)) calc(8px + var(--safe-bottom)) 0}
  .home-screen .main-menu{margin-top:12px}
  .home-screen .scope-note{margin-top:10px}
  /* A status message sits over the still life, clear of the headline and rows. */
  html[data-screen=home] #notice.notice{left:calc(var(--safe-left) + (100vw - var(--safe-left) - var(--safe-right)) * .28);max-width:min(520px,calc((100vw - var(--safe-left) - var(--safe-right)) * .46))}
  /* The hero runs under the column gap and the bottom inset, and a mask (not a
     colour wash) fades it into whatever the room behind it is, so there is no seam. */
  .home-hero{margin:0 -30px calc(-8px - var(--safe-bottom)) 0;height:auto;--still-life-y:.56;--still-life-x:-.04;-webkit-mask-image:linear-gradient(90deg,#000 58%,transparent 97%);mask-image:linear-gradient(90deg,#000 58%,transparent 97%)}
  .home-hero:after{background:linear-gradient(180deg,var(--room) 0%,rgba(11,19,16,0) 22%,rgba(11,19,16,0) 80%,rgba(11,19,16,.9) 100%),radial-gradient(80% 80% at 45% 55%,transparent 55%,rgba(6,10,8,.5) 100%)}
  .home-headline{grid-area:headline;margin:0;max-width:none;align-self:end}
  .home-headline h1{font-size:clamp(1.9rem,3.6vw,2.9rem)}
  .home-screen .scope-note{justify-content:flex-start;min-height:36px}
}
/* Short landscape phones: the headline runs on one line, then the column sheds
   ornament in steps (rule, eyebrow, headline) so a saved game's four rows and
   the pill link always fit. */
@media (orientation:landscape) and (max-height:480px){
  .home-headline{gap:6px}
  .home-headline h1{font-size:1.75rem}
  .home-headline h1 br{display:none}
  .menu-item{min-height:56px;padding-block:7px}
  .menu-item strong{font-size:1.16rem}
  .menu-item small{font-size:.78rem}
  .menu-item>.icon:first-child{width:17px;height:17px;padding:9px}
  .home-screen .main-menu{gap:8px}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:420px){
  .home-headline h1{font-size:1.5rem}
  .home-rule{display:none}
  .home-screen .main-menu{gap:6px;margin-top:10px}
  .menu-item{min-height:50px;padding-block:5px}
  .menu-item>span{gap:1px}
  .menu-item strong{font-size:1.1rem}
  .menu-item small{font-size:.74rem}
  .home-screen .scope-note{margin-top:8px}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:380px){
  .home-headline .eyebrow{display:none}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:360px){
  .home-headline{display:none}
  .home-screen .main-menu{margin-top:4px}
  .menu-item{min-height:48px;padding-block:4px}
}

/* Tablets and desktops: a title screen. One scale unit (the main's font size,
   rem-based so Large Text still applies) grows with the window, so the
   headline, rows and gaps scale together instead of stretching. */
@media (orientation:landscape) and (min-width:1100px) and (min-height:700px),(orientation:portrait) and (min-width:700px) and (min-height:900px){
  .home-headline{gap:.9em}
  .home-headline h1{line-height:.98;letter-spacing:-.005em}
  .home-rule{width:2.6em}
  .home-headline .eyebrow{font-size:.74em;letter-spacing:.26em}
  .home-screen .main-menu{gap:.8em}
  .home-screen .menu-item{min-height:5.1em;padding:.9em 1.3em .9em .95em;gap:1.1em;border-radius:1em}
  .home-screen .menu-item>.icon:first-child{width:1.3em;height:1.3em;padding:.78em}
  .home-screen .menu-item>span{gap:.25em}
  .home-screen .menu-item strong{font-size:1.62em}
  .home-screen .menu-item small{font-size:.9em}
  .home-screen .menu-item .row-tag{font-size:.36em;padding:.2em .8em;margin-left:.7em}
  .home-screen .menu-item>.icon:last-child{width:1.1em;height:1.1em}
  .home-screen .scope-note{min-height:0}
  .home-screen .scope-note button.text-button{min-height:3.1em;padding:0 1.5em;font-size:.86em}
  .home-hero .hero-tiles .tile{--w:6em;width:6em}
}
/* Landscape: the still life runs large from the left edge, past the table's
   corner, and fades under a capped column that sits in the dark room. */
@media (orientation:landscape) and (min-width:1100px) and (min-height:700px){
  html[data-screen=home] .surface{--home-gutter:clamp(32px,5vw - 24px,112px)}
  html[data-screen=home] .surface>header.app-header{padding:0 max(var(--home-gutter),var(--safe-right)) 0 max(calc(var(--home-gutter) - 8px),var(--safe-left));background:linear-gradient(#0b1310cc,#0b131000)}
  .surface>main.home-screen{font-size:clamp(1rem,min(.42rem + .714vw,.3rem + 1.35vh),1.6rem);grid-template-columns:minmax(0,1fr) minmax(0,28em);grid-template-rows:minmax(calc(58px + var(--safe-top)),1fr) auto auto auto minmax(24px,1fr);column-gap:3.5em;padding:0 max(var(--home-gutter),var(--safe-right)) var(--safe-bottom) 0}
  .home-hero{pointer-events:none;margin:0 -12em calc(0px - var(--safe-bottom)) 0;--still-life-x:-.16;--still-life-y:.53;--still-life-fit-w:.78;--still-life-fit-h:.64;-webkit-mask-image:linear-gradient(90deg,#000 62%,transparent 97%);mask-image:linear-gradient(90deg,#000 62%,transparent 97%)}
  .home-hero:after{background:linear-gradient(180deg,var(--room) 0%,rgba(11,19,16,.35) 12%,rgba(11,19,16,0) 30%,rgba(11,19,16,0) 78%,rgba(11,19,16,.92) 100%),radial-gradient(75% 85% at 38% 55%,transparent 52%,rgba(6,10,8,.55) 100%)}
  .home-headline h1{font-size:3.9em}
  .home-screen .main-menu{margin-top:1.7em}
  .home-screen .scope-note{margin-top:1.3em}
  .home-hero .hero-tiles{right:30%;bottom:26%}
}
/* Portrait tablets: the still life spans the full width under the headline;
   headline, rows and header share one centred column. */
@media (orientation:portrait) and (min-width:700px) and (min-height:900px){
  html[data-screen=home] .surface{--home-col:min(100vw - 80px,44rem)}
  html[data-screen=home] .surface>header.app-header{padding:0 max(calc((100vw - var(--home-col)) / 2 - 4px),var(--safe-right)) 0 max(calc((100vw - var(--home-col)) / 2 - 8px),var(--safe-left))}
  .surface>main.home-screen{font-size:clamp(1rem,.45rem + 1.05vw,1.45rem);grid-template-rows:minmax(0,1fr) auto auto;row-gap:0;max-width:none;padding:0 0 calc(1.6em + var(--safe-bottom))}
  .home-hero{margin:0 0 .6em;--still-life-y:.66;--still-life-fit-w:.84;--still-life-fit-h:.46}
  .home-hero:after{background:linear-gradient(180deg,var(--room) 0%,rgba(11,19,16,.5) 18%,rgba(11,19,16,0) 38%,rgba(11,19,16,0) 80%,var(--room) 100%),radial-gradient(90% 70% at 55% 62%,transparent 52%,rgba(6,10,8,.55) 100%)}
  .home-headline{max-width:var(--home-col);margin:1.6em 0 0 calc((100vw - var(--home-col)) / 2)}
  .home-headline h1{font-size:3.7em}
  .home-screen .main-menu,.home-screen .scope-note{justify-self:center;width:var(--home-col)}
  .home-screen .scope-note{margin-top:1.1em}
}
/* Tablet widths: a tighter still life, so the table's corner turns before the column. */
@media (orientation:landscape) and (min-width:1100px) and (max-width:1399px) and (min-height:700px){
  .home-hero{--still-life-x:-.2;--still-life-fit-w:.71}
  html[data-text=large] .home-hero{--still-life-x:-.26;--still-life-fit-w:.64}
}
@media (hover:hover) and (pointer:fine){
  .home-screen .menu-item:hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(34,60,46,.96),rgba(17,33,25,.96));box-shadow:inset 0 1px 0 rgba(255,240,210,.08),0 0 0 1px rgba(214,182,120,.08),0 14px 30px rgba(0,0,0,.34)}
  .home-screen .menu-item:hover>.icon:first-child{color:var(--gold-bright);box-shadow:0 0 0 1px var(--gold-bright),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(230,200,143,.38),0 0 18px rgba(230,200,143,.14)}
}
.home-screen .menu-item:active{background:linear-gradient(180deg,rgba(20,37,29,.96),rgba(12,23,18,.96));box-shadow:inset 0 1px 3px rgba(0,0,0,.35)}
.home-screen .scope-note button.text-button:active{background:rgba(201,168,106,.1)}
/* Wide windows: the brand grows inside the same 58 px bar. */
@media (min-width:1600px) and (min-height:900px){
  .app-header .brand{gap:13px}
  .app-header .brand-mark{width:42px;height:42px}
  .app-header .brand-tile{width:19px;height:25px;border-radius:3.5px}
  .app-header .brand-text strong{font-size:1.46rem}
  .app-header .brand-text small{font-size:.64rem;letter-spacing:.22em}
  html[data-screen=home] .app-header .header-actions .icon{width:26px;height:26px}
}
@media (min-width:2300px) and (min-height:1250px){
  .app-header .brand-mark{width:46px;height:46px}
  .app-header .brand-tile{width:21px;height:28px}
  .app-header .brand-text strong{font-size:1.62rem}
  .app-header .brand-text small{font-size:.7rem}
  html[data-screen=home] .app-header .header-actions .icon{width:28px;height:28px}
}

/* ---------- Welcome: the first launch ----------
   "How much Mahjong do you know?" over the same still life as Home, then a
   five-question check with large answers, then where to start. */
html[data-screen=welcome] .surface{background:radial-gradient(110% 60% at 50% 30%,#132019 0%,var(--room) 60%,#070b09 100%)}
html[data-screen=welcome] .surface>header.app-header:has(.brand){grid-template-columns:minmax(0,1fr) auto;padding:0 10px 0 14px}
html[data-screen=welcome] .app-header:has(.brand) .header-actions{grid-column:2}
.surface>main.welcome-screen{display:flex;flex-direction:column;gap:12px;width:100%;max-width:640px;min-height:0;margin:0 auto;padding:0 18px calc(12px + var(--safe-bottom));overflow:hidden auto}
.welcome-hero{position:relative;flex:1 1 220px;min-height:140px;margin:0 -18px;overflow:hidden;isolation:isolate;--still-life-y:.6;--still-life-x:.1}
.welcome-hero .home-table{position:absolute;inset:0;z-index:0}
.welcome-hero .home-table canvas{display:block;width:100%;height:100%}
/* Wider screens: the still life fades into the room at its sides too, never a boxed picture. */
@media (min-width:600px){.welcome-hero{-webkit-mask-image:linear-gradient(90deg,transparent,#000 16%,#000 84%,transparent);mask-image:linear-gradient(90deg,transparent,#000 16%,#000 84%,transparent)}}
.welcome-hero:after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(180deg,var(--room) 0%,rgba(11,19,16,0) 30%,rgba(11,19,16,0) 70%,var(--room) 100%)}
.welcome-question{display:grid;grid-template-columns:minmax(0,1fr);gap:10px;align-content:start}
.welcome-eyebrow{margin:0;font:600 .7rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.welcome-question h1{margin:0;font:500 clamp(1.85rem,7.4vw,2.6rem)/1.06 var(--serif);letter-spacing:.005em;color:var(--ivory);text-wrap:balance;overflow-wrap:break-word}
/* Tamil's long words (அமைத்துக்கொள்ளுங்கள்) once pushed the whole step wider than a phone. */
html:lang(ta) .welcome-question h1{font-size:clamp(1.25rem,5.6vw,2.2rem);line-height:1.2}
.welcome-lead{margin:0;max-width:60ch;font:400 .98rem/1.5 var(--sans);color:var(--ivory-2)}
.welcome-levels{display:grid;gap:10px;margin-top:6px}
.welcome-dock{display:flex;justify-content:center;gap:10px;margin-top:auto;padding-top:6px}
.welcome-dock .text-button{min-height:44px;padding:0 16px}
.welcome-finish{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr))}
.welcome-finish button{width:100%;min-height:52px}
.welcome-top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-top:6px}
.welcome-top .lesson-dots{display:flex;gap:6px}
.welcome-top .lesson-dots i{width:7px;height:7px;border-radius:50%;background:rgba(201,168,106,.25)}
.welcome-top .lesson-dots i.past{background:var(--gold-deep)}
.welcome-top .lesson-dots i.now{background:var(--gold-bright);box-shadow:0 0 0 3px rgba(230,200,143,.18)}
/* Answers: three large tiles or sets side by side, or short answers stacked. */
.welcome-choices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:10px}
.welcome-choices:has(.is-text){grid-template-columns:minmax(0,1fr)}
.welcome-choice{position:relative;display:grid;place-items:center;min-height:clamp(132px,38vw,184px);padding:16px 6px;border:1px solid var(--gold-line);border-radius:16px;background:radial-gradient(120% 90% at 50% 20%,rgba(36,72,52,.55),rgba(10,20,15,.7));color:var(--ivory);cursor:pointer;transition:border-color .18s,transform .12s,opacity .2s,box-shadow .2s}
.welcome-choice.is-text{justify-items:start;min-height:58px;padding:0 18px;background:rgba(12,22,17,.6)}
.welcome-answer{font:500 1rem/1.25 var(--sans)}
.welcome-tiles{display:flex;justify-content:center;gap:4px}
.welcome-choice .tile{--w:clamp(60px,19vw,88px);width:clamp(60px,19vw,88px);height:auto;aspect-ratio:1/1.52}
.welcome-choice .tile:not(:only-child){--w:clamp(26px,8.6vw,46px);width:clamp(26px,8.6vw,46px)}
@media (hover:hover){.welcome-choice:not(:disabled):hover{border-color:var(--gold-line-strong);transform:translateY(-2px)}}
.welcome-choice:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}
.welcome-choice:disabled{cursor:default}
.welcome-choice.correct{border-color:var(--positive);box-shadow:0 0 0 1px var(--positive),0 0 22px rgba(143,208,162,.22)}
.welcome-choice.wrong{border-color:var(--negative);box-shadow:0 0 0 1px var(--negative)}
.welcome-choice.dim{opacity:.42}
.welcome-feedback{display:grid;gap:4px;margin-top:6px;padding:12px 14px;border-left:3px solid var(--positive);border-radius:0 12px 12px 0;background:rgba(12,22,17,.6);outline:0}
.welcome-feedback.retry{border-left-color:var(--gold)}
.welcome-feedback strong{font:500 1.05rem/1.2 var(--serif);color:var(--ivory)}
.welcome-feedback p{margin:0;font:400 .92rem/1.45 var(--sans);color:var(--ivory-2)}
/* Where to start: each question with a tick or a cross. */
.welcome-marks{display:grid;gap:6px;margin:6px 0 0;padding:0;list-style:none}
.welcome-marks li{display:flex;align-items:center;gap:10px;font:400 .92rem/1.3 var(--sans);color:var(--ivory-2)}
.welcome-marks .icon{flex:none;width:18px;height:18px;padding:3px;border-radius:50%}
.welcome-marks .right .icon{color:var(--positive);box-shadow:0 0 0 1px rgba(143,208,162,.5)}
.welcome-marks .missed .icon{color:var(--negative);box-shadow:0 0 0 1px rgba(224,137,122,.5)}
/* The newcomer's first five tiles, each with its name. */
.welcome-sample{flex-wrap:wrap;justify-content:flex-start;gap:12px;margin-top:8px}
.welcome-sample>span{display:grid;justify-items:center;gap:6px}
.welcome-sample .tile{--w:56px;width:56px;height:auto;aspect-ratio:1/1.52}
.welcome-sample small{font:500 .74rem/1.2 var(--sans);color:var(--sage);text-align:center;max-width:72px}
/* The newcomer’s Tile Labels switch, framed like a settings row. */
.welcome-switch{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:60px;margin-top:4px;padding:10px 14px;border:1px solid var(--gold-line);border-radius:14px;background:rgba(12,22,17,.55);cursor:pointer}
.welcome-switch>span{display:grid;gap:2px;font:500 1rem/1.25 var(--sans);color:var(--ivory)}
.welcome-switch small{font:400 .8rem/1.35 var(--sans);color:var(--sage)}
/* The first launch's settings (after the introduction): switches framed like the one above,
   and a choice (text size, language) as a row of large buttons, so a tap previews it at once. */
.welcome-settings{display:grid;gap:8px;margin-top:6px}
/* Continue stays in view at the foot while the settings scroll under it. */
.welcome-setup .welcome-dock{position:sticky;bottom:0;z-index:2;margin-bottom:calc(-12px - var(--safe-bottom));padding:18px 0 calc(12px + var(--safe-bottom));background:linear-gradient(rgba(11,19,16,0),var(--room) 42%)}
.welcome-settings .welcome-switch{margin-top:0}
.welcome-options{min-width:0;margin:0;padding:10px 14px 12px;border:1px solid var(--gold-line);border-radius:14px;background:rgba(12,22,17,.55)}
.welcome-options legend{float:left;width:100%;margin:0 0 8px;padding:0;font:500 1rem/1.25 var(--sans);color:var(--ivory)}
.welcome-options legend .icon{width:18px;height:18px;margin-right:7px;vertical-align:-3px;color:var(--gold)}
.welcome-options legend small{margin-left:8px;font:400 .8rem/1.25 var(--sans);color:var(--sage)}
.welcome-options>div{clear:both;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,120px),1fr));gap:8px}
.welcome-options label{position:relative;display:flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:6px 12px;border:1px solid var(--gold-line);border-radius:12px;font:500 .98rem/1.2 var(--sans);color:var(--ivory-2);text-align:center;cursor:pointer}
.welcome-options input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.welcome-options label:has(input:checked){border-color:var(--gold-bright);background:rgba(201,168,106,.14);box-shadow:0 0 0 1px var(--gold-bright);color:var(--ivory)}
.welcome-options label:has(input:focus-visible){outline:2px solid var(--gold-bright);outline-offset:3px}
.welcome-theme-tile{display:inline-block;width:26px;margin:-4px 10px -4px 0;vertical-align:middle}
/* Themes: a row of tiles, each named under it, that scrolls sideways when there are more than fit. */
/* The themes in one row: they share the width when it holds them all, and scroll (inside the box's own
   padding, snapping clear of its edge) when it does not (director, 26 Sep: the row ran off, clipped). */
.welcome-options.welcome-themes>div{display:grid;grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:minmax(84px,1fr);gap:8px;margin:0 -14px;padding:2px 14px 6px;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;scroll-padding-inline:14px;scrollbar-width:none}
.welcome-themes label{flex-direction:column;gap:6px;min-width:0;min-height:0;padding:10px 6px 8px;font-size:.8rem;line-height:1.15;scroll-snap-align:start}
.welcome-theme-name{display:grid;align-items:center;min-height:2.3em}
.welcome-themes label>span{display:grid;justify-items:center;gap:6px}
.welcome-themes .welcome-theme-tile{width:34px;margin:0}
.welcome-theme-tile svg{display:block;width:100%;height:auto}
/* Short landscape phones: no still life, and the three levels side by side. */
@media (orientation:landscape) and (max-height:620px){
  .surface>main.welcome-screen{max-width:900px;padding-left:max(18px,var(--safe-left));padding-right:max(18px,var(--safe-right))}
  .welcome-hero{display:none}
  .welcome-levels{grid-template-columns:repeat(3,minmax(0,1fr))}
  .welcome-levels .menu-item{min-height:0;grid-template-columns:auto minmax(0,1fr)}
  .welcome-levels .menu-item>.icon:last-child{display:none}
  .welcome-choice{min-height:96px}
  .welcome-choice .tile:only-child{--w:58px;width:58px}
  .welcome-choice .tile:not(:only-child){--w:36px;width:36px}
  /* The first settings (laid out in the landscape block below), compact: Language and Text Size side by
     side over the themes and the switches, which keep their names (their details stay in Settings). */
  .welcome-setup h1{font-size:clamp(1.6rem,4vw,2.2rem)}
  .welcome-setup .welcome-lead{font-size:.9rem}
  .welcome-setup .welcome-settings{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-flow:row dense;gap:6px}
  .welcome-setup .welcome-settings>:is(.welcome-switch,.welcome-themes){grid-column:1/-1}
  .welcome-setup .welcome-switch{min-height:46px;padding:6px 14px}
  .welcome-setup .welcome-options{padding:8px 14px 10px}
  .welcome-setup .welcome-options legend{margin-bottom:6px}
  .welcome-setup .welcome-options:not(.welcome-themes)>div{grid-template-columns:repeat(auto-fit,minmax(min(100%,84px),1fr))}
  .welcome-setup .welcome-switch small{display:none}
}
/* Desktop: a centred column over the still life, sized like Home. */
@media (min-width:1100px) and (min-height:700px){
  .surface>main.welcome-screen{max-width:720px;padding-top:12px}
  .welcome-question h1{font-size:2.9rem}
  .welcome-choice{min-height:168px}
  .welcome-choice .tile:only-child{--w:84px;width:84px}
  .welcome-choice .tile:not(:only-child){--w:56px;width:56px}
  /* The first settings stand centred, with Continue just below them. */
  .surface>main.welcome-setup{justify-content:center;padding-bottom:48px}
  .welcome-setup .welcome-dock{margin-top:14px}
}
/* Landscape, from a phone held sideways to a desktop: the heading, its line and Continue on the left, the
   settings beside them, scrolling on their own if they must (director, 26 Sep: a portrait column on a wide
   screen, with Continue under the fold; a phone held sideways lost the top and bottom settings). */
@media (orientation:landscape) and (min-width:700px){
  .surface>main.welcome-setup{display:grid;max-width:1180px;grid-template-columns:minmax(0,1fr) minmax(0,min(700px,62%));grid-template-rows:1fr auto auto auto auto 1fr;grid-template-areas:". settings" "top settings" "title settings" "lead settings" "dock settings" ". settings";column-gap:clamp(28px,5vw,80px);row-gap:10px;padding:0 max(24px,var(--safe-right)) calc(12px + var(--safe-bottom)) max(24px,var(--safe-left));overflow:hidden}
  .welcome-setup .welcome-question{display:contents}
  .welcome-setup .welcome-top{grid-area:top;padding-top:0}
  .welcome-setup h1{grid-area:title}
  .welcome-setup .welcome-lead{grid-area:lead}
  .welcome-setup .welcome-dock{grid-area:dock;position:static;justify-content:flex-start;margin:10px 0 0;padding:0;background:none}
  .welcome-setup .welcome-settings{grid-area:settings;align-self:center;min-height:0;max-height:100%;margin:0 -6px;padding:12px 6px;overflow:hidden auto;overscroll-behavior:contain}
}
@media (orientation:landscape) and (min-width:700px) and (min-height:621px){
  .welcome-setup h1{font-size:clamp(2.2rem,3.4vw,3.2rem)}
  /* Which Game: the question, the games and Skip together in the middle of the screen, not spread from top to foot. */
  .surface>main.welcome-game{justify-content:center;padding-bottom:calc(40px + var(--safe-bottom))}
  .welcome-game .welcome-dock{margin-top:10px}
}
/* The introduction: quoted lines fade up one at a time on the dark room, the last one
   larger in gold; the attribution and Begin follow. A tap (intro-shown) or reduced motion shows all. */
.surface>main.welcome-intro{justify-content:center;gap:28px;max-width:720px;cursor:default}
.intro-quote{display:grid;gap:22px;margin:0;padding:0 4px}
.intro-quote blockquote{display:grid;gap:18px;margin:0}
.intro-line{margin:0;opacity:0;transform:translateY(10px);animation:intro-rise .8s cubic-bezier(.2,.7,.2,1) forwards;animation-delay:calc(.4s + var(--i) * 1.5s + var(--intro-clock,0ms))}
.intro-quote p{font:italic 400 clamp(1.25rem,5.2vw,2.35rem)/1.3 var(--serif);color:var(--ivory);text-wrap:balance}
.intro-quote p.intro-punch{font:500 clamp(1.6rem,7vw,3.1rem)/1.15 var(--serif);font-style:normal;color:var(--gold-bright)}
.intro-quote figcaption{display:grid;gap:3px;font:600 .72rem/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.intro-quote figcaption span{font-weight:500;letter-spacing:.06em;text-transform:none;font-size:.82rem;color:var(--sage)}
.intro-dock{justify-content:flex-end;align-items:center;margin-top:0}
.intro-dock .intro-begin{animation:intro-rise .6s ease forwards;opacity:0;transform:translateY(6px);animation-delay:calc(.6s + var(--intro-clock,0ms))}
.intro-dock .intro-begin{min-width:160px;min-height:52px}
.welcome-intro.intro-shown .intro-line{animation:none;opacity:1;transform:none}
@keyframes intro-rise{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.intro-line,.intro-dock .intro-begin{animation:none;opacity:1;transform:none}}
html[data-motion=off] :is(.intro-line,.intro-dock .intro-begin){animation:none;opacity:1;transform:none}
/* Landscape: the welcome question takes Home's composition. The still life runs from the
   left edge and fades under a column holding the question, its three answers stacked, and
   Skip; nothing is hidden on a phone held sideways, and desktops scale the column up. */
@media (orientation:landscape) and (min-width:700px){
  html[data-screen=welcome]:has(main.welcome-ask) .surface>header.app-header{position:absolute;left:0;right:0;top:var(--safe-top);z-index:3;padding:0 max(10px,var(--safe-right)) 0 max(14px,var(--safe-left));background:linear-gradient(#0b1310d9,#0b131000)}
  .surface>main.welcome-ask{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(300px,.9fr);grid-template-rows:minmax(calc(58px + var(--safe-top)),1fr) auto auto minmax(8px,1fr);grid-template-areas:"hero ." "hero question" "hero dock" "hero .";column-gap:28px;row-gap:0;max-width:none;height:100%;padding:0 max(24px,var(--safe-right)) calc(8px + var(--safe-bottom)) 0;overflow:hidden}
  /* The still life is decoration: it runs under the column but never takes a tap or click. */
  .welcome-ask .welcome-hero{pointer-events:none;display:block;grid-area:hero;flex:none;height:auto;min-height:0;margin:0 -28px calc(-8px - var(--safe-bottom)) 0;--still-life-y:.56;--still-life-x:-.04;-webkit-mask-image:linear-gradient(90deg,#000 58%,transparent 97%);mask-image:linear-gradient(90deg,#000 58%,transparent 97%)}
  .welcome-ask .welcome-hero:after{background:linear-gradient(180deg,var(--room) 0%,rgba(11,19,16,0) 22%,rgba(11,19,16,0) 80%,rgba(11,19,16,.9) 100%)}
  .welcome-ask .welcome-question{grid-area:question;gap:8px;position:relative;z-index:1}
  .welcome-ask .welcome-question h1{font-size:clamp(1.6rem,3.3vw,2.5rem)}
  .welcome-ask .welcome-levels{grid-template-columns:minmax(0,1fr);gap:8px}
  .welcome-ask .welcome-levels .menu-item{min-height:60px;grid-template-columns:auto minmax(0,1fr) auto}
  .welcome-ask .welcome-levels .menu-item>.icon:last-child{display:block}
  .welcome-ask .welcome-dock{grid-area:dock;justify-content:flex-start;margin:4px 0 0 -16px;padding-top:0;position:relative;z-index:1}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:480px){
  .welcome-ask .welcome-eyebrow{display:none}
  .welcome-ask .welcome-question h1{font-size:1.5rem}
  .welcome-ask .welcome-lead{font-size:.84rem;line-height:1.35}
  .welcome-ask .welcome-levels{gap:6px;margin-top:2px}
  .welcome-ask .welcome-levels .menu-item{min-height:50px;padding-block:5px}
  .welcome-ask .welcome-levels .menu-item strong{font-size:1.08rem}
  .welcome-ask .welcome-levels .menu-item small{font-size:.74rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .welcome-ask .welcome-levels .menu-item>.icon:first-child{width:16px;height:16px;padding:8px}
  .welcome-ask .welcome-dock .text-button{min-height:44px}
}
@media (orientation:landscape) and (min-width:1100px) and (min-height:700px){
  html[data-screen=welcome]:has(main.welcome-ask) .surface{--home-gutter:clamp(32px,5vw - 24px,112px)}
  .surface>main.welcome-ask{font-size:clamp(1rem,min(.42rem + .714vw,.3rem + 1.35vh),1.6rem);grid-template-columns:minmax(0,1fr) minmax(0,30em);column-gap:3.5em;padding:0 max(var(--home-gutter),var(--safe-right)) calc(12px + var(--safe-bottom)) 0}
  .welcome-ask .welcome-hero{margin:0 -12em calc(0px - var(--safe-bottom)) 0;--still-life-x:-.16;--still-life-y:.53;-webkit-mask-image:linear-gradient(90deg,#000 62%,transparent 97%);mask-image:linear-gradient(90deg,#000 62%,transparent 97%)}
  .welcome-ask .welcome-question{gap:.8em}
  .welcome-ask .welcome-eyebrow{font-size:.74em}
  .welcome-ask .welcome-question h1{font-size:3.3em;line-height:1}
  .welcome-ask .welcome-lead{font-size:1em}
  .welcome-ask .welcome-levels{gap:.8em;margin-top:.6em}
  .welcome-ask .welcome-levels .menu-item{min-height:5.1em;padding:.9em 1.3em .9em .95em;gap:1.1em;border-radius:1em}
  .welcome-ask .welcome-levels .menu-item>.icon:first-child{width:1.3em;height:1.3em;padding:.78em}
  .welcome-ask .welcome-levels .menu-item strong{font-size:1.5em}
  .welcome-ask .welcome-levels .menu-item small{font-size:.9em}
  .welcome-ask .welcome-dock .text-button{min-height:3em;font-size:.9em}
}
/* Short portrait phones: the still life shrinks, then steps aside, so all three answers and Skip fit. */
@media (orientation:portrait) and (max-height:700px){
  .welcome-ask .welcome-hero{flex:0 1 120px;min-height:0}
  .welcome-ask .welcome-eyebrow{display:none}
  .welcome-ask .welcome-question h1{font-size:1.7rem}
  .welcome-ask .welcome-lead{font-size:.88rem;line-height:1.4}
  .welcome-ask .welcome-levels{gap:8px}
  .welcome-ask .welcome-levels .menu-item{min-height:56px;padding-block:6px}
}
@media (orientation:portrait) and (max-height:600px){.welcome-ask .welcome-hero{display:none}.welcome-ask{padding-top:8px}}
/* Home entrance (docs/motion.md): on arrival and when the game changes, the headline rises, its gold
   rule draws out and the rows follow one by one, while the still life settles. app.js sets
   .launch-enter for the first 900 ms and --launch-delay keeps the timeline across a rerender. */
@keyframes home-rise{from{opacity:0;transform:translateY(12px)}}
@keyframes home-rule{from{transform:scaleX(0)}}
@keyframes home-fade{from{opacity:0}}
html[data-motion=on] .launch-enter .home-headline h1{animation:home-rise .52s var(--ease-out) calc(.1s + var(--launch-delay,0ms)) both}
html[data-motion=on] .launch-enter .home-rule{transform-origin:0 50%;animation:home-rule .5s var(--ease-out) calc(.22s + var(--launch-delay,0ms)) both}
html[data-motion=on] .launch-enter .home-screen .main-menu>*{animation:home-rise .42s var(--ease-out) calc(.24s + var(--row,0) * 50ms + var(--launch-delay,0ms)) both}
html[data-motion=on] .launch-enter .brand small{animation:home-fade .36s ease-out calc(.04s + var(--launch-delay,0ms)) both}
.home-screen .main-menu>:nth-child(2){--row:1}.home-screen .main-menu>:nth-child(3){--row:2}.home-screen .main-menu>:nth-child(4){--row:3}.home-screen .main-menu>:nth-child(5){--row:4}.home-screen .main-menu>:nth-child(n+6){--row:5}

/* A change of game on Home: the new words replace the old at once and settle in, never from blank (director,
   26 Sep: the screen flickered as the whole entrance replayed), while the still life's tiles turn over. */
@keyframes home-swap{from{opacity:.3;transform:translateY(6px)}}
html[data-motion=on] .mode-enter .home-headline h1{animation:home-swap .34s var(--ease-out) both}
html[data-motion=on] .mode-enter .home-screen .main-menu>*{animation:home-swap .3s var(--ease-out) calc(var(--row,0) * 35ms) both}

/* src/game.css */
/* Game screen: the physical table fills the frame; the hand strip and the
   action bar sit over its near rail, as in table-portrait/landscape.png. */
html[data-screen=round] .surface{background:radial-gradient(120% 80% at 50% 38%,#16271f 0%,var(--room) 62%,#070c0a 100%)}
html[data-screen=round] .surface:before{opacity:0}

/* Header: back chevron, serif title with a tracked subtitle, menu icon. */
html[data-screen=round] .surface>header{position:relative;z-index:6;display:grid;grid-template-columns:48px minmax(0,1fr) 48px;align-items:center;gap:4px;height:58px;min-height:58px;padding:0 8px;border:0;background:linear-gradient(#0a110ee6,#0a110e00)}
html[data-screen=round] .app-header .app-back,html[data-screen=round] .app-header .table-menu{width:44px;height:44px;min-height:44px;padding:0;display:grid;place-items:center;border:0;border-radius:50%;background:transparent;color:var(--gold);box-shadow:none}
html[data-screen=round] .app-header .app-back span,html[data-screen=round] .app-header .table-menu span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
html[data-screen=round] .app-header .icon{width:24px;height:24px;stroke-width:1.5}
html[data-screen=round] .app-header .header-actions{justify-self:end;display:flex}
html[data-screen=round] .app-header .save-status{position:absolute;right:56px;top:9px}
.gm-title{text-align:center;min-width:0;padding:0;margin:0}
/* Table text grows with the text size but stops at a pixel cap (min(rem, px)), as the controls do, so
   browser text enlargement cannot push the header into the far seat or the seat names across the cloth. */
.gm-title h1{margin:0;font:500 min(1.35rem,28px)/1.2 var(--serif);letter-spacing:.01em;color:var(--ivory);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gm-title p{max-width:none;margin:3px 0 0;font:500 min(.62rem,13px)/1.2 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--sage);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.surface>main.game-screen{display:grid;grid-template-rows:minmax(0,1fr) auto;overflow:hidden;width:100%;max-width:none;margin:-58px 0 0;padding:0}
.game-screen .gm-table{position:relative;min-height:0;overflow:hidden;isolation:isolate}
/* The canvas spans the whole table area, under the header's fade and the hand. Your own sets lie
   just clear of the hand's label row, which holds your bonus tiles (landscape runs the cloth under it). */
.game-screen .physical-table{position:absolute;inset:0;z-index:0;--table-top:80px;--hand-overlap:0px}
.game-screen .physical-table canvas{display:block;width:100%;height:100%}
.game-screen .gm-table:after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(130% 95% at 50% 42%,transparent 58%,rgba(3,8,6,.55) 100%)}

/* Central plaque: round, tiles left and whose turn it is, drawn crisply over the
   black glass slab. One centred stack sized from the plaque itself, so its lines
   can never collide; smaller plaques drop the winds, then everything but the count. */
.game-screen .table-counter{position:absolute;z-index:2;display:none;pointer-events:none;container-type:size;color:var(--ivory)}
.gm-table[data-physical] .table-counter{display:flex;flex-direction:column;align-items:center;justify-content:center}
.table-counter>*{display:block;text-align:center;white-space:nowrap;line-height:1}
.table-counter .plaque-round{font:500 clamp(7px,13cqh,12px)/1 var(--serif);letter-spacing:.02em;color:var(--ivory-2)}
.table-counter strong{margin:4cqh 0 2cqh;font:500 clamp(15px,38cqh,40px)/.95 var(--serif);font-variant-numeric:lining-nums tabular-nums;color:var(--ivory)}
.table-counter .plaque-label{font:500 clamp(7px,11cqh,11px)/1 var(--serif);color:var(--ivory-2)}
.table-counter .plaque-turn{display:flex;justify-content:center;gap:clamp(4px,7cqw,9px);margin-top:7cqh;font:600 clamp(7px,10cqh,10px)/1 var(--sans);letter-spacing:.08em;color:var(--sage-2)}
@container (max-height:60px){.table-counter .plaque-turn{display:none}}
@container (max-height:38px){.table-counter .plaque-round,.table-counter .plaque-label{display:none}.table-counter strong{margin:0;font-size:min(62cqh,42cqw)}}
@container (max-width:46px){.table-counter .plaque-round,.table-counter .plaque-label,.table-counter .plaque-turn{display:none}.table-counter strong{margin:0;font-size:min(62cqh,42cqw)}}
/* Whose turn: the four winds with the one to play lit in gold and underlined. */
.table-counter .plaque-turn i{font-style:normal;position:relative;opacity:.75}
.table-counter .plaque-turn i.now{opacity:1;color:var(--gold-bright);text-shadow:0 0 8px rgba(240,200,120,.7)}
.table-counter .plaque-turn i.now:after{content:'';position:absolute;left:-2px;right:-2px;top:calc(100% + 2px);height:2px;border-radius:2px;background:var(--gold-bright)}

/* The win moment: a gold seal and the winner's name over the lamplit table. */
/* Light enough to see the table stage the win (camera, lamp, the hand tipping up). */
.gm-scrim{position:absolute;inset:0;z-index:5;pointer-events:none;background:radial-gradient(70% 55% at 50% 42%,rgba(4,8,6,.5),rgba(4,8,6,.2) 60%,rgba(4,8,6,.55))}
/* One announcement: the plaque text, the event line and the guide line step aside. */
.gm-table:has(.gm-celebrate) .table-counter,.gm-table:has(.gm-celebrate) .physical-event,.game-screen:has(.gm-celebrate) .gm-message{visibility:hidden}
html[data-motion=on] .gm-scrim{animation:fade-in .5s ease both}
@keyframes fade-in{from{opacity:0}}
.gm-celebrate{position:absolute;left:50%;top:42%;z-index:6;display:grid;justify-items:center;gap:12px;width:min(92%,640px);transform:translate(-50%,-50%);pointer-events:none;text-align:center}
.gm-celebrate .rs-seal{width:78px;height:78px}
.gm-celebrate .rs-seal span{font-size:2.3rem}
.gm-celebrate strong{padding:8px 24px;border-radius:999px;background:#0a120e;box-shadow:0 0 0 1px var(--gold-line-strong),0 10px 30px rgba(0,0,0,.6);font:500 2.1rem/1.1 var(--serif);color:var(--gold-bright);white-space:nowrap}
/* The winning hand is laid out on its own strip of baize in a walnut edge. */
.gm-win-hand{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 9px;padding:12px 14px;border:6px solid transparent;border-radius:16px;background:radial-gradient(80% 90% at 50% 20%,rgba(255,226,170,.12),transparent 70%) padding-box,linear-gradient(rgb(30,64,46),rgb(30,64,46)) padding-box,url('/felt-v1.webp') center/200px padding-box,linear-gradient(160deg,#76492b 0%,#4a2d19 35%,#3a2314 60%,#6b4428 100%) border-box;background-blend-mode:normal,color,normal,normal;box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 6px 14px rgba(0,0,0,.4),0 0 0 1px rgba(255,220,180,.14),0 16px 36px rgba(0,0,0,.6)}
.gm-win-set{display:flex;gap:1px}
.gm-win-set .tile{--w:26px;width:26px;height:auto;aspect-ratio:1/1.52;margin:0}
@media (min-width:600px){.gm-win-set .tile{--w:32px;width:32px}}
html[data-motion=on] .gm-celebrate .rs-seal{animation:rs-seal .7s var(--ease-out) both}
/* Two gold ripples leave the seal as it lands, and a glint crosses the name. */
html[data-motion=on] .gm-celebrate .rs-seal:after{content:'';position:absolute;inset:-2px;border-radius:50%;box-shadow:0 0 0 2px rgba(240,205,130,.85),0 0 22px rgba(240,200,120,.6);animation:seal-ripple 1.5s cubic-bezier(.2,.6,.3,1) .35s 2 both;pointer-events:none}
@keyframes seal-ripple{from{transform:scale(1);opacity:.9}to{transform:scale(3.1);opacity:0}}
.gm-celebrate strong{position:relative;overflow:hidden}
html[data-motion=on] .gm-celebrate strong:after{content:'';position:absolute;top:0;bottom:0;left:-40%;width:30%;background:linear-gradient(100deg,transparent,rgba(255,236,190,.35),transparent);transform:skewX(-18deg);animation:name-glint 1.1s ease-in-out .7s both}
@keyframes name-glint{from{left:-40%}to{left:120%}}
html[data-motion=on] .gm-celebrate strong{animation:rs-rise .6s var(--ease-out) .12s both}
html[data-motion=on] .gm-win-hand{animation:rs-rise .6s var(--ease-out) .24s both}

/* A call (Chow, Pong, Kong) rises beside the seat that made it. */
.table-call{position:fixed;z-index:40;pointer-events:none;transform:translate(-50%,-50%);display:grid;justify-items:center;gap:2px;padding:12px 20px 10px;border-radius:18px;background:radial-gradient(120% 140% at 50% 0%,rgba(40,58,44,.97),rgba(8,14,11,.95));box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 5px rgba(8,14,11,.55),0 0 36px rgba(230,190,110,.4),0 14px 34px rgba(0,0,0,.6);color:var(--gold-bright);white-space:nowrap}
.table-call .call-glyph{font:600 3.1rem/1 'Songti SC','STSong','Noto Serif CJK TC','Noto Serif TC','SimSun',var(--serif);text-shadow:0 0 18px rgba(240,200,120,.5)}
.table-call .call-word{font:500 .78rem/1 var(--sans);letter-spacing:.24em;text-transform:uppercase;color:var(--ivory-2)}
.table-call:not(:has(.call-glyph)) .call-word{font:500 1.9rem/1 var(--serif);letter-spacing:.03em;text-transform:none;color:var(--gold-bright)}
@media (min-width:1100px){.table-call{padding:16px 26px 12px}.table-call .call-glyph{font-size:4rem}.table-call .call-word{font-size:.9rem}}

/* Desktop: the name of the tile under the pointer. */
.table-tip{position:fixed;z-index:45;pointer-events:none;transform:translate(-50%,-100%);padding:5px 12px;border-radius:999px;background:rgba(8,14,11,.92);box-shadow:0 0 0 1px var(--gold-line),0 8px 20px rgba(0,0,0,.45);font:500 .82rem/1.2 var(--sans);color:var(--ivory);white-space:nowrap}

/* The table's entrance: labels wait for the camera to land, then fade in. */
.gm-table .gm-seats,.gm-table .table-counter{transition:opacity .45s ease}
.game-screen .gm-controls{transition:opacity .45s ease .15s}
.game-screen:has(.physical-table[data-entering]) .gm-controls{opacity:0;transition:none}
.gm-table:has(.physical-table[data-entering]) :is(.gm-seats,.table-counter){opacity:0;transition:none}

/* Seat medallions: gold ring, emblem, name and points. */
/* The ring carries the seat's wind as it is written on the wind tiles. */
.medallion-ring .wind-glyph{display:block;width:auto;height:auto;font:600 21px/1 'Songti SC','STSong','Noto Serif CJK TC','Noto Serif TC','SimSun',var(--serif);color:inherit;transform:translateY(-.03em)}
.gm-hand-label .medallion-ring .wind-glyph{font-size:14px}
@media (min-width:1100px) and (min-height:700px){.gm-seats .medallion-ring .wind-glyph{font-size:27px}.gm-hand-label .medallion-ring .wind-glyph{font-size:18px}}
.gm-seats{position:absolute;inset:0;z-index:3;pointer-events:none;display:none}
.gm-table[data-physical] .gm-seats{display:block}
.seat-medallion{position:absolute;display:grid;justify-items:center;gap:1px;width:auto;min-width:48px;min-height:0;padding:0;border:0;background:none;box-shadow:none;color:var(--ivory);transform:translate(-50%,-50%);pointer-events:auto;cursor:pointer;font:inherit}
.seat-medallion .medallion-ring{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;color:var(--gold);background:radial-gradient(circle at 50% 35%,#1d3027,#0a130f 70%);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(201,168,106,.28),0 4px 10px rgba(0,0,0,.55)}
.seat-medallion .emblem{width:22px;height:22px}
/* Name over points in one soft plate: serif name as in the reference, clear figures. */
/* Plain serif name and points under the ring, as in the references; a soft shadow keeps them legible on felt and wood. */
.gm-seats .medallion-plate{display:grid;justify-items:center;margin-top:3px;padding:0;background:none;box-shadow:none;text-shadow:0 1px 2px rgba(0,0,0,.95),0 0 10px rgba(0,0,0,.75)}
.gm-seats .medallion-name{font:500 min(.92rem,19px)/1.05 var(--serif);white-space:nowrap}
.gm-seats .medallion-points{font:600 min(.66rem,14px)/1.15 var(--sans);color:var(--ivory-2)}
/* The opposite seat sits on the far rail: ring on the anchor, plate beside it. */
.gm-seats .seat-medallion[data-seat-button="3"]{grid-template-columns:auto auto;align-items:center;column-gap:6px;min-height:44px;transform:translate(-19px,-50%)}
.gm-seats .seat-medallion[data-seat-button="3"] .medallion-plate{margin:0;justify-items:start}
/* While one seat must act, the others step back. */
.gm-table:has(.seat-medallion.active-seat) .gm-seats .seat-medallion:not(.active-seat){opacity:.7}
.seat-medallion.active-seat .medallion-ring{color:var(--gold-bright);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(230,200,143,.55),0 0 18px rgba(230,190,110,.55)}
.seat-medallion.active-seat .medallion-name{color:var(--gold-bright)}
html[data-motion=on] .seat-medallion.active-seat .medallion-ring{animation:seat-glow 2.4s ease-in-out infinite}
@keyframes seat-glow{50%{box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(230,200,143,.35),0 0 8px rgba(230,190,110,.25)}}
@media (prefers-reduced-motion:reduce){.seat-medallion.active-seat .medallion-ring{animation:none}}

/* Hand strip over the near rail. Buttons stay real, focusable DOM controls;
   the 3D pass paints the tiles under them. */
/* The game and result screens handle the safe area themselves, so the table can run to the screen edges. */
html[data-screen=round] .surface:has(>main.game-screen){padding-left:0;padding-right:0;padding-bottom:0}
html[data-screen=round] .surface:has(>main.rs-screen){padding-bottom:0}
.game-screen .gm-hand{position:absolute;left:0;right:0;bottom:0;z-index:4;padding:0 6px 8px;display:grid;grid-template-columns:minmax(0,1fr);gap:10px;background:none}
.gm-hand-label{--bonus-w:28px;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:calc(var(--bonus-w) * 1.52 + 2px);padding:0 6px}
.gm-hand-label .seat-medallion{position:static;transform:none;display:flex;align-items:center;gap:7px;min-width:0}
/* A full 44 px target that grows upward over the felt, never down onto the rack. */
.gm-hand-label .seat-medallion{min-height:44px;margin-top:-16px;padding-top:16px}
.gm-hand-label .seat-medallion .medallion-ring{width:26px;height:26px}
.gm-hand-label .seat-medallion .emblem{width:16px;height:16px}
.gm-hand-label .medallion-plate{display:flex;align-items:baseline;gap:8px}
.gm-hand-label .seat-medallion .medallion-name{margin:0;font:500 min(1rem,20px)/1.1 var(--serif);white-space:nowrap}
.gm-hand-label .medallion-points{font:600 min(.8rem,17px)/1.2 var(--sans);color:var(--ivory-2)}
.gm-hand-label .physical-event{flex:0 10 auto;min-width:0;margin-left:auto;padding:3px 10px;border-radius:12px;background:rgba(6,11,9,.72);font:400 min(.76rem,16px)/1.2 var(--sans);color:var(--ivory-2);text-align:right;text-wrap:balance;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.gm-hand-label .physical-event:empty{display:none}
/* Your flowers, seasons and animals beside your name, as tile portraits (the rim keeps copies).
   The label row keeps their height before the first one arrives, so the table never jumps; a
   long event wraps to a second line before a tile is squeezed. */
.gm-bonus{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(18px,var(--bonus-w));gap:3px;flex:0 1 auto;min-width:0;margin-right:auto}
.gm-bonus .tile{--w:100%;width:100%;height:auto;aspect-ratio:1/1.52;min-width:0;min-height:0;margin:0}
/* Many bonus tiles (the Malaysian table has sixteen, and Flies set aside): on an upright phone they
   stand in two half-height rows, so the row keeps its height and the event beside it stays readable. */
@media (orientation:portrait) and (max-width:599px){.gm-bonus[data-many]{grid-template-rows:repeat(2,auto);grid-auto-columns:calc(var(--bonus-w) * .49);gap:2px}}
.gm-hand-label .seat-medallion.active-seat .medallion-ring{box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 14px rgba(240,200,120,.7)}
/* Portrait hand tiles stand taller than the table's (the renderer reads --hand-stature),
   so the hand is the biggest thing on screen, as in table-portrait.png. */
.gm-rack{--hand-stature:1.45;--hand-aspect:1.98;--slot-gap:1px;--slot-w:min(60px,calc((100vw - 14px - 13 * var(--slot-gap) - 10px) / 14));display:flex;justify-content:center;align-items:flex-end;gap:var(--slot-gap);padding:0;margin:0;min-height:calc(var(--slot-w) * var(--hand-aspect))}
.gm-slot{display:block;flex:0 0 var(--slot-w);width:var(--slot-w);height:calc(var(--slot-w) * var(--hand-aspect));position:relative;padding:0;margin:0}
.gm-slot.new-draw{margin-left:10px}
/* The newly drawn tile wears a small gold tab on its top edge. */
.gm-slot.new-draw:before{content:attr(data-tag);position:absolute;z-index:2;left:50%;top:-9px;transform:translateX(-50%);padding:1px 5px;border-radius:5px;background:var(--room);box-shadow:0 0 0 1px var(--gold-line-strong);font:600 .52rem/1.2 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--gold-bright);pointer-events:none;white-space:nowrap}
.gm-slot.new-draw.partner:before,.gm-slot.new-draw:has(.selected):before{display:none}
/* Sort My Hand (src/hand-drag.js, src/hand-order.js). A rack tile can be pressed and dragged, so a touch on it
   never scrolls or zooms the page. In Manual the drawn tile joins the row (no pocket) and keeps its New tab.
   The held tile rides above the rest; without the 3D hand the others glide apart (with it, the 3D hand moves). */
.gm-rack [data-tile]{touch-action:none}
.gm-rack[data-arrange=manual] .gm-slot.new-draw.new-draw{--pocket:0px;margin-left:var(--shift,0px)}
.gm-rack .gm-slot.is-held{z-index:5}
.gm-rack .gm-slot.is-held,.gm-rack .gm-slot.is-held *{cursor:grabbing}
html[data-motion=on] .gm-table:not([data-hand-drawn=true]) .gm-rack[data-arranging] .gm-slot:not(.is-held){transition:transform .18s var(--ease-out)}
/* Sort Now: beside the rack in Manual; a 44 px target around a small gold-edged pill. */
.gm-sort{position:relative;isolation:isolate;flex:0 0 auto;display:inline-flex;align-items:center;gap:5px;min-height:44px;margin:-8px -2px -8px 0;padding:0 11px 0 9px;background:none;color:var(--ivory);font:600 min(.74rem,15px)/1 var(--sans);letter-spacing:.01em;white-space:nowrap}
.gm-sort:before{content:"";position:absolute;inset:8px 0;z-index:-1;border-radius:14px;background:rgba(6,11,9,.72);box-shadow:inset 0 0 0 1px var(--gold-line-strong)}
.gm-sort .icon{width:16px;height:16px;color:var(--gold-bright)}
@media (hover:hover) and (pointer:fine){.gm-sort:hover:before{background:rgba(20,32,26,.86)}}
.gm-sort:focus-visible{outline:none}.gm-sort:focus-visible:before{box-shadow:inset 0 0 0 2px var(--gold-bright)}
/* On a phone the pill is the icon alone (its name is its label), so the event line beside it keeps its room. */
@media (max-width:599px),(max-height:500px){.gm-sort>span{display:none}.gm-sort{padding:0 12px}}
/* Narrow phones and large text: two rows of seven, so tiles stay big enough to read. */
@media (max-width:374px) and (orientation:portrait){.gm-rack{--hand-stature:1;--hand-aspect:1.49;--slot-w:min(52px,calc((100vw - 20px - 6 * var(--slot-gap)) / 7));flex-wrap:wrap;row-gap:10px;max-width:calc(var(--slot-w) * 7 + 6 * var(--slot-gap) + 12px);margin:0 auto}.gm-slot.new-draw{margin-left:0}}
html[data-text=large] .gm-rack{--hand-stature:1;--hand-aspect:1.49;--slot-w:min(56px,calc((100vw - 20px - 6 * var(--slot-gap)) / 7));flex-wrap:wrap;row-gap:10px;max-width:calc(var(--slot-w) * 7 + 6 * var(--slot-gap) + 12px);margin:0 auto}
html[data-text=large] .gm-slot.new-draw{margin-left:0}
/* Portrait phones: two rows by default, tiles about 50 px wide (html[data-hand-rows=one] keeps
   the single row above). Columns follow the hand's size, so a draw drops into the pocket at the
   end of the second row and nothing else moves: 7/6 then 7/7; after one set 6/4 then 6/5 (the
   second row centred); after two 4/3 then 4/4; after three, one row. The first row stays centred;
   the drawn tile keeps a gap in the margin on the right. On a short screen (a phone browser with its
   bars, under about 620 px) the tiles narrow, down to 38 px, so the table keeps its share. */
@media (orientation:portrait) and (max-width:599px){
  html:not([data-hand-rows=one]) .gm-rack{--hand-stature:1;--hand-aspect:1.49;--slot-gap:2px;--draw-gap:8px;--cols:7;--slot-w:min(56px,calc((100vw - 12px - 6 * var(--slot-gap) - 2 * var(--draw-gap)) / 7),max(38px,calc((var(--app-frame-height,100dvh) - 320px) / 5.5)));display:grid;grid-template-columns:repeat(var(--cols),var(--slot-w));justify-content:center;column-gap:var(--slot-gap);row-gap:10px;max-width:none;margin:0;padding:0 var(--draw-gap)}
  html:not([data-hand-rows=one]) .game-screen .gm-hand{padding-bottom:4px}
  html:not([data-hand-rows=one]) .game-screen .gm-controls{padding-top:2px}
  html:not([data-hand-rows=one]) .gm-rack .gm-slot{margin-left:calc(var(--shift,0px) + var(--pocket,0px))}
  html:not([data-hand-rows=one]) .gm-rack .gm-slot.new-draw{--pocket:var(--draw-gap)}
  html:not([data-hand-rows=one]) .gm-rack:is([data-count="10"],[data-count="11"]){--cols:6}
  html:not([data-hand-rows=one]) .gm-rack:is([data-count="10"],[data-count="11"]) .gm-slot:nth-child(n+7){--shift:calc((var(--slot-w) + var(--slot-gap)) / 2)}
  html:not([data-hand-rows=one]) .gm-rack:is([data-count="7"],[data-count="8"]){--cols:4}
  html:not([data-hand-rows=one]) .gm-rack:is([data-count="4"],[data-count="5"]){--cols:5}
  html:not([data-hand-rows=one]) .gm-rack:is([data-count="1"],[data-count="2"]){--cols:2}
}
.gm-slot .tile{--w:100%;display:block;width:100%;height:100%;min-height:0;max-width:none;margin:0;padding:0;border:0;border-radius:5px;background:none;box-shadow:none;transform:none;cursor:pointer;transition:transform .16s var(--ease-out)}
.gm-slot .tile .tile-face{display:block;width:100%;height:100%}
.gm-slot .tile .tile-code{display:none}
/* A lift that never reaches the label row, whatever the tile size (at most 9 px). */
.gm-slot .tile.selected{transform:translateY(calc(-1 * min(var(--slot-w) * var(--hand-aspect) * .13, 9px)))}
.gm-slot .tile.selected:after{display:none}
/* Tiles a single possible claim would use rise a little, ringed in gold. */
.gm-slot.partner .tile{transform:translateY(-9%);box-shadow:0 0 0 2px var(--gold-bright),0 0 14px rgba(240,200,120,.5);border-radius:6px}
/* Once the physical hand is drawn, the DOM tile art steps aside but the
   button keeps its focus ring and hit area. */
.gm-table:has(.physical-table[data-hand=true]) .gm-slot .tile>*,.gm-table[data-hand-drawn=true] .gm-slot .tile>*{visibility:hidden}
.gm-slot .tile:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px}
html[data-input=keyboard] .gm-slot .tile:focus{outline:2px solid var(--gold-bright);outline-offset:2px}

/* Fallback DOM board, shown only when WebGL is unavailable. */
.game-screen .table-arena{position:absolute;inset:8px 8px 120px;z-index:1;overflow:auto;border:10px solid #3d2718;border-radius:28px;background:radial-gradient(ellipse at 50% 40%,#23583f,#133726);padding:12px;color:var(--ivory)}
.gm-table[data-physical] .table-arena{display:none}
/* While a 3D table compiles its shaders (physical-table.js), the flat fallback does not flash. */
.gm-table[data-table-pending] .table-arena{visibility:hidden}
.table-arena .board-seats{display:grid;gap:10px}
.table-arena .live-seat{background:none;border:0;padding:0}
.table-arena .seat-river,.table-arena .opponent-melds,.table-arena .table-exposed{display:flex;flex-wrap:wrap;gap:3px}
.table-arena .tile{--w:26px;width:26px}

/* Action bar: one gold primary action, dark outlined secondaries. */
.gm-controls{position:relative;z-index:5;display:grid;gap:8px;padding:6px 10px calc(10px + var(--safe-bottom,0px));background:#070d0b}
/* The message line keeps one height (two lines of text, or the offered tile
   beside its question), so a claim or a longer hint never moves the table. */
.gm-message{display:flex;align-items:center;justify-content:center;min-height:46px;min-width:0}
.gm-feedback{margin:0;font:400 min(.8rem,17px)/1.3 var(--sans);color:var(--ivory-2);text-align:center;text-wrap:balance}
.gm-offer{display:flex;align-items:center;gap:10px;min-width:0;text-align:left}
.gm-offer-tile{display:block;flex:none;line-height:0}
.gm-offer .tile{--w:28px;width:28px;height:auto;aspect-ratio:1/1.52}
.gm-offer p{display:grid;gap:2px;min-width:0;margin:0}
.gm-offer-line{font:400 min(.84rem,18px)/1.2 var(--sans);color:var(--sage)}
.gm-offer-line strong{font-weight:600;color:var(--ivory)}

.gm-offer .gm-feedback{text-align:left;text-wrap:pretty}
.gm-actions{display:grid;grid-template-columns:1fr minmax(0,1.6fr) 1fr;gap:8px;align-items:stretch;width:100%;max-width:760px;margin:0 auto}
/* Moves share the row; with very large text they wrap rather than cut a label. */
.gm-moves{display:flex;flex-wrap:wrap;gap:8px;min-width:0}
.gm-moves>*{flex:1 0 auto}
.gm-spacer{display:block}
/* A label too long for its button (a longer language): Hint and Guide show their icons (app.js, fitTableText). */
.gm-actions[data-icons=true]>.gm-button{padding:0}
.gm-actions[data-icons=true]>.gm-button>span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
/* Two moves at once (a claim and Pass): the moves get the room; on phones
   Hint and Guide become icons so no move label is ever cut short. */
.gm-actions:has(.gm-moves>:nth-child(2)){grid-template-columns:minmax(0,.85fr) minmax(0,2fr) minmax(0,.85fr);gap:6px}
.gm-actions:has(.gm-moves>:nth-child(2)) .gm-moves{gap:6px}
.gm-actions:has(.gm-moves>:nth-child(2))>.gm-button{padding:0 6px;gap:5px}
@media (max-width:520px){
  .gm-actions:has(.gm-moves>:nth-child(2)){grid-template-columns:48px minmax(0,1fr) 48px}
  .gm-actions:has(.gm-moves>:nth-child(2))>.gm-button{padding:0}
  .gm-actions:has(.gm-moves>:nth-child(2))>.gm-button span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .gm-actions:has(.gm-moves>:nth-child(2)) .gm-moves .gm-button{padding:0 8px}
}
@media (max-width:374px){
  .gm-actions{grid-template-columns:48px minmax(0,1fr) 48px}
  .gm-actions>.gm-button{padding:0}
  .gm-actions>.gm-button span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .gm-moves .gm-button{padding:0 6px;font-size:min(.84rem,19px)}
  .gm-moves .gm-button .icon{display:none}
  .gm-moves .gm-long{display:none}
  .gm-title .gm-sub-extra{display:none}
}
.gm-slot .tile.selected{box-shadow:0 0 0 2px var(--gold-bright),0 0 16px rgba(240,200,120,.55);border-radius:6px}
.gm-button{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:48px;min-width:0;padding:0 12px;border-radius:var(--radius-control);border:1px solid rgba(214,182,120,.42);background:linear-gradient(180deg,rgba(22,36,29,.62),rgba(10,18,14,.62));color:var(--ivory);font:500 min(.92rem,20px)/1.1 var(--sans);letter-spacing:.01em;box-shadow:inset 0 1px 0 rgba(255,240,210,.06);cursor:pointer;transition:background .18s,border-color .18s,transform .12s}
.gm-button .icon{width:19px;height:19px;color:var(--gold);flex:none}
.gm-button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gm-button.gm-primary{border-color:#f0d9a8;background:var(--primary-fill);color:var(--ink-on-gold);font-weight:600;box-shadow:inset 0 1px 0 rgba(255,250,235,.7),inset 0 -2px 0 rgba(120,85,40,.35),0 6px 16px rgba(0,0,0,.35)}
.gm-button.gm-primary .icon{color:var(--ink-on-gold)}
.gm-button:disabled{cursor:default;opacity:1;border-color:rgba(201,168,106,.2);background:transparent;color:var(--sage-2);box-shadow:none}
/* An idle primary still reads as the gold action, waiting for a tile. */
.gm-button.gm-primary:disabled{border-color:rgba(214,182,120,.34);background:transparent;color:rgba(230,200,143,.6)}
.gm-button:active:not(:disabled){transform:translateY(1px)}
@media (hover:hover) and (pointer:fine){.gm-button:hover:not(:disabled){border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(38,58,47,.95),rgba(18,30,24,.95))}.gm-button.gm-primary:hover:not(:disabled){background:linear-gradient(180deg,#f3dcab,#d8b77e 50%,#bf9a60)}}
.gm-waiting{display:flex;align-items:center;justify-content:center;gap:5px;min-height:48px;color:var(--sage);font:400 .82rem var(--sans)}
.gm-waiting i{width:5px;height:5px;border-radius:50%;background:var(--gold);opacity:.35}
html[data-motion=on] .gm-waiting i{animation:waiting 1.2s ease-in-out infinite}
.gm-waiting i:nth-child(2){animation-delay:.2s}.gm-waiting i:nth-child(3){animation-delay:.4s}
/* A longer language wraps the words at their spaces rather than running into Guide. */
.gm-waiting{min-width:0}
.gm-moves>.gm-waiting{flex:1 1 0}
.gm-waiting span{min-width:0;margin-left:6px;line-height:1.15;text-align:left}
@keyframes waiting{50%{opacity:1}}


/* Landscape: the table takes the whole frame; header and controls float over it.
   Everything stays inside the safe area (notched phones report side insets). */
/* Landscape phones up to 1000 px wide are handled after this block: see "one right-hand column". */
@media (orientation:landscape) and (max-height:620px){
  .game-screen{--pad-l:max(10px,var(--safe-left,0px));--pad-r:max(10px,var(--safe-right,0px));--col-l:clamp(112px,11.5vw,150px);--col-r:52px}
  html[data-screen=round] .surface:has(>.game-screen)>header{position:absolute;left:0;right:0;top:var(--safe-top,0px);height:58px;min-height:58px;padding:0 max(8px,var(--safe-right,0px)) 0 max(8px,var(--safe-left,0px));background:linear-gradient(#0a110ecc,#0a110e00);pointer-events:none}
  /* The header floats over the far rail: only its buttons take taps, so North's medallion stays reachable. */
  html[data-screen=round] .surface:has(>.game-screen)>header button{pointer-events:auto}
  .surface>main.game-screen{margin:0;grid-template-rows:minmax(0,1fr)}
  .game-screen .physical-table{--table-top:40px;--hand-overlap:8px}
  .surface:has(>.game-screen) .gm-title{text-align:left}
  html[data-screen=round] .surface>header{grid-template-columns:48px minmax(0,1fr) 48px}
  .surface>main.game-screen{position:relative}
  .gm-controls{position:absolute;inset:0;padding:0;background:none;pointer-events:none;display:block;z-index:7}
  .gm-controls>*{pointer-events:auto}
  /* The message floats top right, clear of North's medallion and the menu. */
  .gm-message{position:absolute;top:10px;right:calc(var(--pad-r) + 50px);min-height:0;max-width:max(200px,calc(50% - 170px - var(--pad-r)));justify-content:flex-end}
  .gm-message>.gm-feedback{padding:6px 14px;border-radius:14px;background:rgba(7,13,11,.8);box-shadow:0 0 0 1px rgba(201,168,106,.2);font-size:min(.78rem,16px);text-align:left;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .gm-message>.gm-feedback:empty{display:none}
  .gm-offer{padding:8px 12px 8px 8px;border-radius:var(--radius-card);background:rgba(7,13,11,.88);box-shadow:0 0 0 1px var(--gold-line-strong),0 10px 24px rgba(0,0,0,.4)}
  .gm-offer .gm-feedback{font-size:min(.78rem,16px)}
  /* Moves stack in the left column; Hint and Guide are labelled icons on the right,
     so the hand gets the width between them. */
  .gm-actions,.gm-actions:has(.gm-moves>:nth-child(2)){position:absolute;left:var(--pad-l);right:var(--pad-r);bottom:calc(8px + var(--safe-bottom,0px));max-width:none;width:auto;margin:0;display:grid;grid-template-columns:var(--col-l) 1fr var(--col-r);grid-template-areas:". . hint" "moves . guide";gap:8px;align-items:end;pointer-events:none}
  .gm-actions>*{pointer-events:auto}
  .gm-actions>:first-child{grid-area:hint}
  /* With guidance off, the empty Hint slot keeps its height, so nothing shifts. */
  .gm-actions>.gm-spacer:first-child{min-height:52px}
  .gm-moves{grid-area:moves;flex-direction:column}
  .gm-actions>:last-child{grid-area:guide}
  .gm-moves .gm-button{min-height:46px;padding:0 8px;font-size:.86rem}
  /* The header already names the wait; the column keeps just the dots. */
  .gm-moves .gm-waiting span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .gm-actions>.gm-button,.gm-actions:has(.gm-moves>:nth-child(2))>.gm-button{flex-direction:column;gap:3px;min-height:52px;padding:5px 0 4px;font-size:clamp(9px,.64rem,12px);letter-spacing:.04em}
  .gm-actions>.gm-button .icon{width:18px;height:18px}
  .gm-actions>.gm-button span,.gm-actions:has(.gm-moves>:nth-child(2))>.gm-button span{position:static;width:auto;height:auto;overflow:visible;clip:auto}
  .game-screen .gm-hand{left:calc(var(--pad-l) + var(--col-l) + 8px);right:calc(var(--pad-r) + var(--col-r) + 8px);bottom:0;padding-bottom:calc(6px + var(--safe-bottom,0px));background:none}
  .gm-rack{--hand-stature:1;--hand-aspect:1.49;--slot-w:min(58px,calc((100vw - var(--pad-l) - var(--col-l) - var(--pad-r) - var(--col-r) - 16px - 13 * var(--slot-gap) - 6px) / 14))}
  .gm-slot.new-draw{margin-left:6px}
  /* Your bonus tiles stand in the room above your name, left of the table, so the hand keeps its height. */
  .gm-hand-label{position:relative;min-height:28px}
  .gm-hand-label .physical-event{-webkit-line-clamp:1}
  .gm-bonus{position:absolute;left:6px;bottom:calc(100% + 6px);display:flex;flex-wrap:wrap-reverse;gap:3px;max-width:calc(3 * var(--bonus-w) + 6px)}
  .gm-bonus .tile{width:var(--bonus-w);flex:none}
}
/* Small landscape phones, one right-hand column: fourteen 44 px tiles need the whole
   row, so the moves join Hint and Guide on the right, the main move lowest, under the thumb. */
@media (orientation:landscape) and (max-height:620px) and (max-width:1000px){
  /* 76 px at normal text; larger text widens the column (to 104 px) so move names never wrap. */
  .game-screen{--col-l:0px;--col-r:clamp(76px,calc(3.2rem + 20px),104px)}
  .gm-actions,.gm-actions:has(.gm-moves>:nth-child(2)){grid-template-columns:1fr var(--col-r);grid-template-areas:". hint" ". guide" ". moves"}
  /* Capped so a move's name always fits the column, even with very large text. */
  .gm-moves .gm-button{padding:0 4px;font-size:min(.86rem,18px);white-space:nowrap}
  .gm-moves .gm-long{display:none}
  .game-screen .gm-hand{left:var(--pad-l)}
  .gm-rack{--slot-w:min(58px,calc((100vw - var(--pad-l) - var(--pad-r) - var(--col-r) - 8px - 13 * var(--slot-gap) - 6px) / 14))}
}
/* Desktop and large tablets: the chrome scales with the table, and the hand's
   label row sits over the rack instead of spanning the whole screen. */
@media (min-width:1100px) and (min-height:700px){
  /* The same named Back and Menu pills as every other screen on desktop. */
  html[data-screen=round] .surface>header{grid-template-columns:minmax(150px,auto) minmax(0,1fr) minmax(150px,auto);padding:0 max(clamp(16px,2.4vw - 6px,52px),var(--safe-right)) 0 max(clamp(16px,2.4vw - 6px,52px),var(--safe-left))}
  html[data-screen=round] .app-header .header-actions{justify-self:end}
  html[data-screen=round] .app-header :is(.app-back,.table-menu){display:inline-flex;align-items:center;gap:8px;width:auto;padding:0 18px 0 12px;border:1px solid transparent;border-radius:999px;font:500 .9rem/1 var(--sans);letter-spacing:.02em;justify-self:start}
  html[data-screen=round] .app-header .table-menu{flex-direction:row-reverse;padding:0 12px 0 18px}
  html[data-screen=round] .app-header :is(.app-back,.table-menu) span{position:static;width:auto;height:auto;overflow:visible;clip:auto;color:var(--ivory-2)}
  html[data-screen=round] .app-header :is(.app-back,.table-menu) .icon{width:22px;height:22px}
  html[data-screen=round] .app-header :is(.app-back,.table-menu):hover{border-color:var(--gold-line);background:rgba(201,168,106,.08)}
  .gm-title h1{font-size:min(1.75rem,34px)}
  .gm-title p{font-size:min(.7rem,14px);margin-top:4px}
  .seat-medallion .medallion-ring{width:50px;height:50px}
  .seat-medallion .emblem{width:28px;height:28px}
  .gm-seats .medallion-name{font-size:min(1.15rem,22px)}
  .gm-seats .medallion-points{font-size:.78rem}
  .gm-seats .seat-medallion[data-seat-button="3"]{transform:translate(-25px,-50%)}
  /* Fourteen 60 px slots plus gaps: the rack's width on desktop. */
  .gm-hand-label{width:100%;max-width:900px;margin:0 auto;--bonus-w:34px}
  .gm-hand-label .seat-medallion .medallion-ring{width:34px;height:34px}
  .gm-hand-label .seat-medallion .medallion-name{font-size:min(1.15rem,22px)}
  .gm-hand-label .physical-event{font-size:min(.86rem,17px);padding:5px 14px}
  .gm-feedback{font-size:min(.95rem,18px)}
  .gm-actions{max-width:860px}
  .gm-button{min-height:54px;font-size:min(1rem,20px)}
  .gm-button .icon{width:21px;height:21px}
}
/* Desktop: each game button shows its keyboard shortcut as a small keycap. The keycap
   has empty alternative text, so the button keeps its name; aria-keyshortcuts announces the key. */
@media (hover:hover) and (pointer:fine) and (min-width:1100px) and (min-height:700px){
  .gm-button[data-key]::after{content:attr(data-key) / '';margin-left:4px;padding:2px 6px;border-radius:5px;border:1px solid currentColor;font:600 .62rem/1 var(--sans);letter-spacing:.04em;opacity:.55}
  .gm-button.gm-primary[data-key]::after{opacity:.5}
  .gm-button:disabled[data-key]::after{display:none}
}
/* Points changing at a seat (docs/motion.md): the change rises from the medallion and fades. */
.points-float-layer{position:fixed;inset:0;z-index:40;pointer-events:none;overflow:hidden}
.points-float{position:absolute;transform:translate(-50%,0);padding:1px 7px;border-radius:999px;background:rgba(8,16,12,.78);border:1px solid var(--gold-line);font:600 min(.8rem,15px)/1.3 var(--sans);letter-spacing:.02em;white-space:nowrap;box-shadow:0 4px 14px rgba(0,0,0,.4)}
.points-float.gain{color:var(--positive)}.points-float.loss{color:var(--negative)}

/* src/result.css */
/* Result: felt panel under a walnut edge, gold seal, winning tiles, summary
   card and seat cards, as in result-table.png. */
.rs-title{display:grid;justify-items:center;text-align:center}
.rs-title p{max-width:100%}
.rs-title .rs-title-main{margin:0;font:500 min(1.35rem,28px)/1.1 var(--serif);letter-spacing:.01em;text-transform:none;color:var(--ivory)}
.surface>main.rs-screen{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr) auto;width:100%;max-width:none;margin:0;padding:0;overflow:hidden}
.rs-scroll{overflow:auto;overscroll-behavior:contain;padding:4px 14px 12px;display:flex;flex-direction:column;align-items:center;gap:12px}
.rs-scroll>*{flex:none;width:100%;max-width:560px}
/* Centred when it fits, top-aligned when it scrolls (auto margins never clip). */
.rs-scroll>:first-child{margin-top:auto}.rs-scroll>:last-child{margin-bottom:auto}

/* The same bottle-green baize as the table, framed in varnished walnut. */
.rs-felt{position:relative;display:grid;justify-items:center;align-content:start;gap:6px;padding:26px 16px 20px;border:9px solid transparent;border-radius:22px;isolation:isolate;
  background:radial-gradient(80% 60% at 50% 22%,rgba(255,226,170,.14),transparent 70%) padding-box,radial-gradient(130% 110% at 50% 30%,transparent 45%,rgba(2,10,6,.66) 100%) padding-box,linear-gradient(rgb(30,64,46),rgb(30,64,46)) padding-box,url('/felt-v1.webp') center/200px padding-box,linear-gradient(160deg,#76492b 0%,#4a2d19 30%,#3a2314 55%,#5d3a21 80%,#6b4428 100%) border-box;
  background-blend-mode:normal,normal,color,normal,normal;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 10px 22px rgba(0,0,0,.45),0 0 0 1px rgba(255,220,180,.14),0 14px 34px rgba(0,0,0,.45)}
.rs-seal{position:relative;display:grid;place-items:center;width:70px;height:70px;margin:4px 0 2px;border-radius:50%;color:var(--gold-bright);background:radial-gradient(circle at 50% 35%,#20382c,#0b1511 72%);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 4px rgba(9,17,13,.9),0 0 0 5px rgba(230,200,143,.45),0 0 34px rgba(240,200,120,.45)}
.rs-seal:before{content:'';position:absolute;inset:-46px;z-index:-1;border-radius:50%;background:repeating-conic-gradient(from 0deg,rgba(255,220,150,.22) 0deg 3deg,transparent 3deg 15deg);-webkit-mask:radial-gradient(circle,#000 30%,transparent 70%);mask:radial-gradient(circle,#000 30%,transparent 70%)}
html[data-motion=on] .rs-seal:before{animation:seal-rays 30s linear infinite}
@keyframes seal-rays{to{transform:rotate(360deg)}}
.rs-seal span{font:500 2.1rem/1 var(--serif)}
.rs-felt h1{margin:4px 0 0;font:500 clamp(2.3rem,10vw,3rem)/1 var(--serif);color:var(--ivory);text-shadow:0 2px 14px rgba(0,0,0,.55)}
.is-win .rs-felt h1{background:linear-gradient(180deg,#fff3d6,#e3c58c);-webkit-background-clip:text;background-clip:text;color:transparent}
.rs-reason{margin:0 0 10px;font:400 .9rem/1.3 var(--sans);color:var(--ivory-2)}
.rs-hand{display:flex;flex-wrap:wrap;justify-content:center;gap:12px 10px;width:100%}
.rs-set{display:grid;justify-items:center;gap:5px}
.rs-set-tiles{display:flex;gap:2px}
.rs-set .tile,.rs-bonuses .tile{--w:34px;width:34px;height:auto;aspect-ratio:1/1.52;min-height:0;margin:0;transform:none}
.rs-set>span{font:500 .62rem/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.rs-drawn .rs-set .tile{--w:26px;width:26px}
.rs-bonuses{display:flex;flex-wrap:wrap;justify-content:center;gap:8px 14px;margin-top:8px;padding-top:12px;border-top:1px solid rgba(230,200,143,.18);width:100%}
.rs-bonuses>div{display:flex;align-items:center;gap:7px;font:500 .8rem var(--sans);color:var(--ivory-2)}
.rs-bonuses .tile{--w:24px;width:24px}

.rs-card{padding:14px 18px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:var(--panel-fill);box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 10px 26px rgba(0,0,0,.28)}
.rs-card-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-bottom:10px;margin-bottom:4px;border-bottom:1px solid rgba(201,168,106,.2)}
.rs-card-head h2{margin:0;font:500 1.45rem/1.1 var(--serif);color:var(--ivory)}
.rs-card-head strong{font:500 1.45rem/1 var(--serif);color:var(--gold-bright)}
.rs-line{display:flex;justify-content:space-between;gap:12px;padding:7px 0;font:400 .92rem/1.3 var(--sans);color:var(--ivory-2)}
.rs-line strong{font-weight:400;color:var(--ivory-2);font-variant-numeric:lining-nums tabular-nums}
.rs-total{margin-top:6px;padding-top:12px;border-top:1px solid rgba(201,168,106,.2)}
.rs-total span{font:500 1.2rem var(--serif);color:var(--ivory)}
.rs-total strong{font:500 1.35rem var(--serif);color:var(--gold-bright)}
/* A table other than Singapore says how it paid, under the total (round-view.js payLine). */
.rs-how{margin:10px 0 0;font:400 .8rem/1.35 var(--sans);color:var(--sage);text-wrap:pretty}

.rs-seats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.rs-seat{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto auto;align-items:center;column-gap:10px;row-gap:2px;padding:12px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:var(--panel-fill)}
.rs-seat .medallion-ring{grid-row:1/3;width:40px;height:40px;border-radius:50%;display:grid;place-items:center;color:var(--gold);background:radial-gradient(circle at 50% 35%,#1d3027,#0a130f 70%);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(201,168,106,.25)}
.rs-seat .emblem{width:22px;height:22px}
.rs-seat .medallion-ring .wind-glyph{width:auto;height:auto;font-size:20px}
.rs-seat-name{display:grid;font:500 .9rem/1.2 var(--sans);color:var(--ivory)}
.rs-seat-name small{font:400 .72rem var(--sans);color:var(--sage)}
/* Outfit figures: Cormorant's 1 and 0 read as I and O at a glance. */
.rs-seat>strong{grid-column:2;font:600 1.3rem/1 var(--sans);font-variant-numeric:lining-nums tabular-nums;color:var(--ivory)}
.rs-seat>strong.positive{color:var(--positive)}
.rs-seat>strong.negative{color:var(--negative)}
.rs-seat .rs-running{grid-column:2;font:500 .76rem var(--sans);color:var(--sage)}
.rs-seats>.rs-note{grid-column:1/-1;margin:0;font:400 .76rem/1.3 var(--sans);color:var(--sage);text-align:center}
/* Your own card keeps a quiet marker, separate from the winner's glow. */
.rs-seat.is-you{background:linear-gradient(90deg,rgba(201,168,106,.1),transparent 45%),var(--panel-fill)}
.rs-seat.is-you .rs-seat-name small{color:var(--gold)}
.rs-seat.is-winner{border-color:var(--gold-line-strong);box-shadow:0 0 0 1px rgba(230,200,143,.18),0 0 24px rgba(230,190,110,.12)}
.rs-seat.is-winner .medallion-ring{color:var(--gold-bright);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 14px rgba(230,190,110,.5)}
@media (min-width:380px){.rs-seat{grid-template-columns:auto minmax(0,1fr) auto}.rs-seat>strong{grid-column:3;grid-row:1}.rs-seat .rs-running{grid-column:3;grid-row:2;justify-self:end}}

/* A solid footer with a soft scrim above it, so nothing is sliced as it scrolls under. */
.rs-footer{position:relative;display:grid;grid-template-columns:minmax(0,1fr);gap:4px;justify-items:center;padding:10px 14px calc(8px + var(--safe-bottom));background:var(--room)}
.rs-footer:before{content:'';position:absolute;left:0;right:0;bottom:100%;height:26px;background:linear-gradient(rgba(11,19,16,0),var(--room));pointer-events:none}
/* View Table and Replay This Deal: quiet outlined pills, not bare links. */
.rs-links{display:flex;flex-wrap:wrap;justify-content:center;gap:0 8px}
.rs-links>button.text-button{margin-top:6px;min-height:44px;padding:0 18px;border:1px solid var(--gold-line);border-radius:999px;font-size:.84rem;background:rgba(12,22,17,.5)}
.rs-links>button.text-button:hover{text-decoration:none;border-color:var(--gold-line-strong)}
@media (max-height:1000px) and (orientation:portrait){
  .rs-felt{padding:18px 12px 14px;gap:4px}
  .rs-seal{width:54px;height:54px;margin:0}.rs-seal span{font-size:1.6rem}.rs-seal:before{inset:-34px}
  .rs-felt h1{font-size:2.2rem}
  .rs-reason{margin-bottom:6px}
  .rs-set .tile{--w:30px;width:30px}
  .rs-hand{gap:8px 8px}
  .rs-bonuses{margin-top:4px;padding-top:8px}
  .rs-card{padding:10px 16px}.rs-card-head{padding-bottom:6px}.rs-line{padding:4px 0}.rs-total{padding-top:8px;margin-top:4px}
  .rs-seat{padding:9px 10px}
  .rs-seat .medallion-ring{width:34px;height:34px}
}
.rs-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,8.6em),1fr));gap:10px;width:100%;max-width:560px}
/* Labels never wrap; with very large text the two actions stack instead. */
.rs-actions button span{white-space:nowrap}
.rs-actions button{width:100%}
html[data-motion=on] .rs-felt>*{animation:rs-rise .6s var(--ease-out) both}
html[data-motion=on] .rs-felt>.rs-seal{animation:rs-seal .7s var(--ease-out) both}
html[data-motion=on] .rs-felt>h1{animation-delay:.08s}
html[data-motion=on] .rs-felt>.rs-hand{animation-delay:.16s}
@keyframes rs-rise{from{opacity:0;transform:translateY(8px)}}
@keyframes rs-seal{from{opacity:0;transform:scale(.6)}60%{transform:scale(1.06)}}
@media (prefers-reduced-motion:reduce){.rs-felt>*,.rs-seal:before{animation:none!important}}

@media (orientation:landscape) and (min-width:700px){
  .rs-scroll{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);grid-template-rows:auto auto;align-content:center;align-items:start;column-gap:16px;max-width:1100px;margin:0 auto;width:100%;justify-items:stretch}
  .rs-scroll>*{max-width:none}
  .rs-felt{grid-row:1/3}
  .rs-actions{max-width:640px}
}
/* Short landscape phones: summary at the top, seats at the bottom beside the actions, no dead band. */
@media (orientation:landscape) and (max-height:620px){
  .rs-scroll{grid-template-rows:auto 1fr;align-content:stretch}
  .rs-felt{align-self:stretch}
  .rs-seats{align-self:end}
}
/* Desktop and large tablets: one centred composition at a readable scale. */
@media (min-width:1100px) and (min-height:700px){
  .rs-scroll{grid-template-rows:auto 1fr;max-width:1240px;column-gap:28px;row-gap:18px;padding:24px 32px}
  .rs-seats{align-self:start}
  .rs-felt{padding:38px 30px 30px;gap:10px}
  .rs-seal{width:92px;height:92px}.rs-seal span{font-size:2.7rem}.rs-seal:before{inset:-58px}
  .rs-felt h1{font-size:3.8rem}
  .rs-reason{font-size:1.05rem;margin-bottom:14px}
  .rs-hand{gap:18px 14px}
  .rs-set .tile{--w:48px;width:48px}
  .rs-set>span{font-size:.7rem}
  .rs-bonuses{margin-top:14px;padding-top:16px}
  .rs-bonuses .tile{--w:30px;width:30px}.rs-bonuses>div{font-size:.92rem}
  .rs-card{padding:20px 26px}
  .rs-card-head h2,.rs-card-head strong{font-size:1.8rem}
  .rs-line{padding:10px 0;font-size:1.02rem}
  .rs-total span{font-size:1.4rem}.rs-total strong{font-size:1.55rem}
  .rs-seats{gap:12px}
  .rs-seat{padding:16px 18px}
  .rs-seat .medallion-ring{width:46px;height:46px}
  .rs-seat-name{font-size:1rem}
  .rs-seat>strong{font-size:1.55rem}
  .rs-footer{padding-top:14px}
  .rs-actions{max-width:720px}
  .rs-actions button{min-height:54px;font-size:1.02rem}
}
@media (orientation:landscape) and (max-height:480px){
  .rs-scroll{padding-top:0;row-gap:8px}
  .rs-felt{padding:14px 12px 12px;gap:3px}
  .rs-seal{width:46px;height:46px;margin:0}.rs-seal span{font-size:1.4rem}.rs-seal:before{inset:-30px}
  .rs-felt h1{font-size:1.9rem}
  .rs-reason{margin-bottom:6px;font-size:.8rem}
  .rs-set .tile{--w:28px;width:28px}
  .rs-hand{gap:6px 8px}
  .rs-set>span{font-size:.55rem}
  .rs-bonuses{margin-top:2px;padding-top:6px;gap:4px 10px}
  .rs-bonuses .tile{--w:20px;width:20px}
  .rs-bonuses>div{font-size:.72rem}
  .rs-card{padding:8px 14px}.rs-card-head{padding-bottom:6px}.rs-card-head h2,.rs-card-head strong{font-size:1.2rem}
  .rs-line{padding:3px 0;font-size:.84rem}.rs-total{padding-top:6px;margin-top:3px}.rs-total span{font-size:1.02rem}.rs-total strong{font-size:1.1rem}
  .rs-seats{gap:6px}
  .rs-seat{padding:6px 10px;column-gap:8px}
  .rs-seat .medallion-ring{width:30px;height:30px}.rs-seat .emblem{width:17px;height:17px}
  .rs-seat-name{font-size:.8rem}.rs-seat-name small{font-size:.64rem}
  .rs-seat>strong{font-size:1.25rem}
  .rs-footer{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);column-gap:16px;align-items:center;width:100%;max-width:1100px;margin:0 auto;padding-top:6px}
  .rs-footer>.rs-links{grid-column:1;grid-row:1;justify-self:start;justify-content:flex-start}
  .rs-actions{grid-column:2;grid-row:1;width:100%}
  .rs-actions button{min-height:44px}
}
/* A result with only the felt (a Guided Hand has no tai or points) is one centred column. */
@media (orientation:landscape) and (min-width:700px){
  .rs-scroll:not(:has(>.rs-summary,>.rs-seats)){grid-template-columns:minmax(0,760px);grid-template-rows:auto;justify-content:center;align-content:safe center}
  .rs-scroll:not(:has(>.rs-summary,>.rs-seats))>.rs-felt{grid-row:auto;align-self:center}
}
/* Desktop: wide enough for the winning hand in one row. */
@media (min-width:1100px) and (min-height:700px){.rs-scroll:not(:has(>.rs-summary,>.rs-seats)){grid-template-columns:minmax(0,980px)}}
/* Short landscape phones fit the whole result without scrolling. On its own the felt sets the
   seal and heading beside the winning tiles; beside the cards its seal sits by the heading. */
@media (orientation:landscape) and (max-height:620px){
  .rs-scroll:not(:has(>.rs-summary,>.rs-seats))>.rs-felt{grid-template-columns:auto minmax(0,1fr);grid-template-rows:1fr auto auto auto 1fr auto auto;grid-template-areas:". hand" "seal hand" "title hand" "reason hand" ". hand" ". bonus" "lesson lesson";column-gap:28px;align-content:center;padding:12px 20px}
  .rs-felt>.rs-seal{grid-area:seal}.rs-felt>h1{grid-area:title}.rs-felt>.rs-reason{grid-area:reason}.rs-felt>.rs-hand{grid-area:hand;align-self:center}.rs-felt>.rs-bonuses{grid-area:bonus}.rs-felt>.rs-lesson{grid-area:lesson}
  .rs-scroll:not(:has(>.rs-summary,>.rs-seats)) .rs-set .tile{--w:30px;width:30px}
  .rs-felt>.rs-lesson{margin:4px auto 0;padding:6px 12px;font-size:min(.8rem,17px)}
  .rs-scroll:has(>.rs-summary,>.rs-seats)>.rs-felt{grid-template-columns:1fr auto auto 1fr;grid-template-areas:". seal title ." "reason reason reason reason" "lesson lesson lesson lesson" "hand hand hand hand" "bonus bonus bonus bonus";align-items:center;column-gap:12px}
  .rs-scroll:has(>.rs-summary,>.rs-seats)>.rs-felt>.rs-seal:before{inset:-22px}
}
@media (orientation:landscape) and (max-height:480px){
  .rs-scroll:has(>.rs-summary,>.rs-seats){row-gap:6px;padding-bottom:8px}
  .rs-scroll:has(>.rs-summary,>.rs-seats)>.rs-felt>.rs-seal{width:38px;height:38px}
  .rs-scroll:has(>.rs-summary,>.rs-seats)>.rs-felt>.rs-seal span{font-size:1.15rem}
  .rs-scroll:has(>.rs-summary,>.rs-seats) .rs-set .tile{--w:25px;width:25px}
  .rs-line{padding:2px 0}
  .rs-seat{padding:4px 10px}
  .rs-seat .medallion-ring{width:28px;height:28px}
}
/* Tall desktops: the whole result, actions included, sits centred as one piece. */
@media (min-width:1100px) and (min-height:820px){
  .surface>main.rs-screen{grid-template-rows:auto auto;align-content:center}
  .rs-footer{background:none;padding-top:22px}
  .rs-footer:before{display:none}
}
/* Portrait tablets: the whole result, actions included, centres as one piece. */
@media (orientation:portrait) and (min-width:700px) and (min-height:1100px){
  .surface>main.rs-screen{grid-template-rows:auto auto;align-content:center}
  .rs-footer{background:none;padding-top:18px}
  .rs-footer:before{display:none}
  .rs-scroll>*{max-width:600px}
  .rs-set .tile{--w:40px;width:40px}
}
/* Large desktops: the whole result scales up as one piece, like the lessons. */
@media (orientation:landscape) and (min-width:1700px) and (min-height:940px){
  .surface>main.rs-screen{zoom:1.2}
}
@media (orientation:landscape) and (min-width:2300px) and (min-height:1250px){
  .surface>main.rs-screen{zoom:1.5}
}
/* Browser text enlargement (html[data-expanded-text]: root text of 28 px or more). The headline, reason and
   actions stop at a pixel cap, as the table's controls do, so the winning hand and its tai stay in view;
   the set names, tai lines and payments still grow, and anything longer scrolls. */
html[data-expanded-text=true] .rs-felt h1{font-size:min(2.3rem,44px)}
html[data-expanded-text=true] .rs-reason{font-size:min(.9rem,20px)}
html[data-expanded-text=true] .rs-actions button{font-size:min(1rem,20px)}
html[data-expanded-text=true] .rs-links>button.text-button{font-size:min(.84rem,17px)}
/* Enlarged text can outgrow a landscape phone: both columns then start at the top and scroll, so the
   winning hand is not centred half out of view. */
html[data-expanded-text=true] .rs-scroll{align-content:start}
html[data-expanded-text=true] .rs-scroll>.rs-felt{align-self:start;margin-top:0}
/* A seat card too narrow for the enlarged name and points puts the points under the name. */
html[data-expanded-text=true] .rs-seat{grid-template-columns:auto minmax(0,1fr)}
html[data-expanded-text=true] .rs-seat>strong,html[data-expanded-text=true] .rs-seat .rs-running{grid-column:2;grid-row:auto;justify-self:start}

/* src/riichi.css */
/* Riichi at the table (riichi-view.js). The Riichi table reuses the Singapore table's styles
   (html[data-screen=round], game.css and result.css); these rules add only what Riichi has:
   honba and riichi sticks on the plaque, the riichi and furiten badges, tiles that cannot be
   discarded now, the red-five marks, and the result's yaku, fu, dora and payments. */

/* Sticks, drawn in CSS: a 1,000-point riichi stick (white, one red dot) and a 100-point honba stick
   (white, rows of black dots). */
.stick-mark,.honba-mark{position:relative;display:inline-block;width:1.9em;height:.42em;border-radius:.21em;background:linear-gradient(#fbf7ee,#d9d0bf);box-shadow:0 0 0 .5px rgba(0,0,0,.35);vertical-align:.12em}
.stick-mark:after{content:'';position:absolute;left:50%;top:50%;width:.26em;height:.26em;border-radius:50%;background:#c0191b;transform:translate(-50%,-50%)}
.honba-mark:after{content:'';position:absolute;inset:.09em .3em;background:radial-gradient(circle,#161616 42%,transparent 46%) 0 0/.24em .24em}

/* The plaque: tiles left, then the honba and the riichi sticks on the table. */
.riichi-counter .plaque-sticks{display:flex;justify-content:center;gap:clamp(6px,9cqw,14px);margin-top:3cqh;font:600 clamp(7px,10cqh,12px)/1 var(--sans);font-variant-numeric:tabular-nums;color:var(--ivory-2)}
.riichi-counter .plaque-sticks>span{display:inline-flex;align-items:center;gap:.35em}
.riichi-counter strong{margin:2cqh 0 1cqh;font-size:clamp(14px,32cqh,36px)}
.riichi-counter .plaque-turn{margin-top:5cqh}
@container (max-height:78px){.riichi-counter .plaque-turn{display:none}}
@container (max-height:52px){.riichi-counter .plaque-label{display:none}}
@container (max-height:40px){.riichi-counter .plaque-sticks{display:none}}

/* The dora, readable at any size (the indicators lie on the 3D dead wall): top left of the table. */
.riichi-dora-hud{position:absolute;z-index:3;left:max(10px,var(--safe-left,0px));top:66px;display:none;align-items:center;gap:8px;padding:6px 10px 6px 12px;border-radius:12px;background:rgba(6,11,9,.72);box-shadow:0 0 0 1px var(--gold-line);pointer-events:none}
.gm-table[data-physical] .riichi-dora-hud{display:flex}
.riichi-dora-hud>span:first-child{font:600 .64rem/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.riichi-dora-hud .dora-tiles{display:flex;gap:3px}
.riichi-dora-hud .tile{--w:26px;width:26px;height:auto;aspect-ratio:1/1.52;min-height:0;margin:0;transform:none}
@media (orientation:landscape) and (max-height:500px){.riichi-dora-hud{top:62px;left:max(16px,var(--safe-left,0px))}.riichi-dora-hud .tile{--w:24px;width:24px}}
@media (min-width:1100px) and (min-height:700px){.riichi-dora-hud{top:76px;left:max(36px,var(--safe-left,0px));padding:8px 12px 8px 14px}.riichi-dora-hud .tile{--w:34px;width:34px}}
.gm-table:has(.gm-celebrate) .riichi-dora-hud{visibility:hidden}
/* A portrait phone: the word over the tiles, so the readout stays in the corner, clear of the far hand. */
@media (orientation:portrait) and (max-width:600px){
  .riichi-dora-hud{flex-direction:column;gap:4px;padding:6px 8px}
  .riichi-dora-hud>span:first-child{font-size:.56rem}
  .riichi-dora-hud .tile{--w:22px;width:22px}
  /* Four or five dora (after kans): smaller tiles still. */
  .riichi-dora-hud:has(.tile:nth-child(4)) .tile{--w:16px;width:16px}
}

/* A seat in riichi: a small stick under its medallion. */
.seat-medallion .medallion-riichi{display:grid;place-items:center;margin-top:2px;font-size:11px;line-height:1}
.gm-hand-label .seat-medallion .medallion-riichi{display:none}

/* Your own riichi, and furiten, beside your name. */
.riichi-badge{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;min-height:26px;padding:3px 10px;border-radius:999px;font:600 min(.72rem,15px)/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}
.riichi-badge.riichi-on{color:var(--ivory);background:rgba(6,11,9,.72);box-shadow:0 0 0 1px var(--gold-line)}
.riichi-badge.riichi-on .stick-mark{font-size:13px}
/* Furiten is a warning: warm red, and a button that explains it. */
button.riichi-badge.furiten-badge{min-width:44px;min-height:44px;margin:-9px 0;padding:0 12px;border:0;color:#ffd7cf;background:rgba(92,22,18,.82);box-shadow:0 0 0 1px rgba(224,137,122,.75),0 0 14px rgba(224,100,80,.35);cursor:pointer}
button.riichi-badge.furiten-badge:before{content:'';width:8px;height:8px;border-radius:50%;background:var(--negative)}
button.riichi-badge.furiten-badge:hover{background:rgba(120,30,24,.9)}
.gm-hand-label:has(.riichi-badge) .physical-event{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Tiles that cannot be discarded now (in riichi, after a call, or while choosing the riichi discard)
   are shaded over the 3D tile; while choosing, the tiles that keep you ready are underlined in gold. */
.riichi-table .gm-slot.is-dimmed:after{content:'';position:absolute;inset:2px 2px 10%;z-index:1;border-radius:6px;background:rgba(5,10,8,.52);pointer-events:none}
.riichi-table .gm-slot.is-dimmed .tile{cursor:default}
.riichi-table .gm-slot.riichi-choice:after{content:'';position:absolute;left:14%;right:14%;bottom:-5px;height:3px;border-radius:3px;background:var(--gold-bright);box-shadow:0 0 10px rgba(240,200,120,.7);pointer-events:none}
html[data-motion=on] .riichi-table .gm-slot.riichi-choice:after{animation:riichi-choice 1.8s ease-in-out infinite}
@keyframes riichi-choice{50%{opacity:.45}}
@media (prefers-reduced-motion:reduce){html .riichi-table .gm-slot.riichi-choice:after{animation:none}}

/* The win moment sits higher than at the Singapore table, so the dead wall opening below it (the ura
   dora turned over beside each indicator) stays in view. */
.riichi-table .gm-celebrate{top:31%}

/* A call rising at a seat: Riichi's two-character calls (立直, 荣和, 自摸) set a little smaller. */
.table-call .call-glyph[data-long]{font-size:2.4rem;letter-spacing:.04em}
@media (min-width:1100px){.table-call .call-glyph[data-long]{font-size:3rem}}

/* Without WebGL: the dora line and the sideways riichi discard. */
.riichi-dora-line{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:6px;font:500 .8rem var(--sans);color:var(--ivory-2)}
.riichi-dora-line .tile,.public-dora .tile{--w:28px;width:28px}
.river-tile.riichi-discard .tile,.river-entry.riichi-discard .tile{transform:rotate(90deg)}
.river-tile.called{opacity:.45}

/* The call sheet's red-five choices use the same rows as every call. */
.public-dora{display:grid;gap:6px;margin:4px 0 12px}
.public-dora>div{display:flex;gap:4px}

/* The result: the winning tile marked, the dora and ura dora, fu, tenpai and payments. */
.rs-win-tile{position:relative;display:block}
.rs-win-tile:after{content:'';position:absolute;left:50%;top:-9px;width:6px;height:6px;border-radius:50%;background:var(--gold-bright);box-shadow:0 0 8px rgba(240,200,120,.8);transform:translateX(-50%)}
.rs-dora{display:flex;flex-wrap:wrap;justify-content:center;gap:10px 22px;width:100%;margin-top:10px;padding-top:12px;border-top:1px solid rgba(230,200,143,.18)}
.rs-indicators{display:grid;justify-items:center;gap:6px}
.rs-indicators>span{font:500 .62rem/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.rs-indicators>div{display:flex;gap:3px}
.rs-indicators .tile{--w:28px;width:28px;height:auto;aspect-ratio:1/1.52;min-height:0;margin:0;transform:none}
.rs-line small{font-size:.8em;color:var(--sage)}
.rs-dora-line span{color:var(--gold-bright)}
.rs-fu{margin-top:8px;border-top:1px solid rgba(201,168,106,.2);padding-top:6px}
.rs-fu>summary{min-height:44px;display:flex;align-items:center;cursor:pointer;font:500 .88rem var(--sans);color:var(--gold-bright)}
.rs-fu .rs-line{padding:4px 0;font-size:.86rem}
.rs-note-line{margin:8px 0 0;font:400 .82rem/1.35 var(--sans);color:var(--sage)}
.rs-tenpai{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 12px;width:100%;margin:6px 0 10px}
.rs-tenpai>div{display:flex;justify-content:space-between;gap:8px;padding:6px 10px;border-radius:10px;background:rgba(6,11,9,.45);font:400 .86rem var(--sans);color:var(--ivory-2)}
.rs-tenpai>div strong{font-weight:600;color:var(--sage)}
.rs-tenpai>div.is-tenpai strong{color:var(--gold-bright)}
.rs-payments .rs-line{font-size:.88rem}
.rs-payments .rs-line small{display:block;font:600 .62rem/1.3 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--gold)}
/* Two columns on a wide screen: the felt on the left; the hand's value, payments and seats on the right. */
.riichi-result .rs-main,.riichi-result .rs-side{display:flex;flex-direction:column;gap:12px;min-width:0}
.riichi-result .rs-seats{grid-template-columns:minmax(0,1fr);gap:6px}
.riichi-result .rs-seat{grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:auto auto;padding:8px 12px}
.riichi-result .rs-seat>strong{grid-column:3;grid-row:1;justify-self:end}
.riichi-result .rs-seat .rs-running{grid-column:3;grid-row:2;justify-self:end}
.riichi-result .rs-seat .medallion-ring{width:34px;height:34px}
@media (orientation:landscape) and (min-width:700px){
  .riichi-result .rs-scroll{grid-template-rows:auto;align-items:start;align-content:start}
  .riichi-result .rs-scroll>.rs-main,.riichi-result .rs-scroll>.rs-side{margin:0}
  .riichi-result .rs-main{grid-column:1}
  .riichi-result .rs-side{grid-column:2}
  .riichi-result .rs-seats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .riichi-result .rs-seat{grid-template-columns:auto minmax(0,1fr)}
  .riichi-result .rs-seat>strong,.riichi-result .rs-seat .rs-running{grid-column:2;grid-row:auto;justify-self:start}
}
/* Short landscape phones: the seal beside the heading, then the reason, the hand, the dora. */
@media (orientation:landscape) and (max-height:620px){
  .riichi-result .rs-scroll{align-content:start}
  .riichi-result .rs-felt{grid-template-columns:1fr auto auto 1fr;grid-template-areas:". seal title ." "reason reason reason reason" "lesson lesson lesson lesson" "tenpai tenpai tenpai tenpai" "hand hand hand hand" "dora dora dora dora";align-items:center;column-gap:12px}
  .riichi-result .rs-felt>.rs-dora{grid-area:dora}
  .riichi-result .rs-felt>.rs-tenpai{grid-area:tenpai}
  .riichi-result .rs-felt>.rs-seal:before{inset:-22px}
  .riichi-result .rs-felt>.rs-seal{width:38px;height:38px}.riichi-result .rs-felt>.rs-seal span{font-size:1.15rem}
  .riichi-result .rs-set .tile{--w:25px;width:25px}
  .riichi-result .rs-dora{margin-top:4px;padding-top:6px}
  .riichi-result .rs-indicators .tile{--w:22px;width:22px}
}
/* A drawn hand's revealed hands: smaller tiles that wrap rather than overflow. */
.riichi-result .rs-drawn .rs-set-tiles{flex-wrap:wrap;justify-content:center;max-width:100%}
.riichi-result .rs-drawn .rs-set .tile{--w:22px;width:22px}
@media (min-width:1100px) and (min-height:700px){.riichi-result .rs-drawn .rs-set .tile{--w:30px;width:30px}}
@media (max-width:479px){.rs-tenpai{grid-template-columns:minmax(0,1fr)}}
.riichi-result .rs-felt+.rs-felt{margin-top:4px}
.riichi-result .rs-drawn{margin-top:4px}

/* Final standings with uma and oka. */
.riichi-standings .mf-name small{display:block}
.riichi-standings .medallion-ring{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;color:var(--gold);background:radial-gradient(circle at 50% 35%,#1d3027,#0a130f 70%);box-shadow:0 0 0 1px var(--gold-line-strong)}

/* The Hand Guide and the rules reference. */
.riichi-guide p{margin:0 0 10px}
.riichi-guide .guide-furiten{padding:8px 12px;border-radius:10px;background:rgba(92,22,18,.4);box-shadow:0 0 0 1px rgba(224,137,122,.45)}
.riichi-yaku-list{display:grid;gap:8px;margin:6px 0 14px;padding:0;list-style:none}
.riichi-yaku-list li{padding:8px 12px;border-radius:10px;background:rgba(6,11,9,.35)}
.riichi-yaku-list li span{font:600 .8rem var(--sans);color:var(--gold-bright);white-space:nowrap}
.riichi-yaku-list li small{font:400 .84rem/1.35 var(--sans);color:var(--ivory-2)}
/* A long "tiles left" (Tamil, Malay) wraps onto two short lines rather than spilling past the plaque. */
.riichi-counter .plaque-label{max-width:96cqw;white-space:normal;line-height:1.08;text-wrap:balance}
/* The fu breakdown opens on a tap: a chevron says so (display:flex drops the native marker). */
.rs-fu>summary{justify-content:space-between;list-style:none}
.rs-fu>summary::-webkit-details-marker{display:none}
.rs-fu>summary::after{content:"";flex:none;width:7px;height:7px;margin:0 8px 4px 12px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg)}
.rs-fu[open]>summary::after{margin-bottom:-4px;transform:rotate(-135deg)}
/* A value (8 Fu, 1,300) stays on one line beside a long label. */
.riichi-result .rs-line>strong{flex:none;white-space:nowrap;padding-left:10px}

/* src/learn.css */
/* Learning: the lesson library, lessons, First Steps and the Chow drills, in
   the language of lesson-landscape.png. The example lies on felt inside a
   walnut rail; the teaching panel beside it has a tracked chapter label, a
   serif title, tracked phase tabs with a gold underline, a tip card and the
   actions at the bottom. Portrait stacks the same parts above an anchored
   action dock. Legacy rules sit in @layer legacy, so every element restyled
   here sets its whole layout. */

/* ---------- Shared pieces ---------- */
/* Grid placement from the old single-column layouts must not leak into the
   new ones (the table demonstrations keep their own). */
:where(.app-learning,.app-lesson,.first-steps,.play-screen) :where(:not(.table-demo,.table-demo *)){grid-area:auto;align-self:auto;justify-self:auto;order:0}
/* Cormorant defaults to old-style figures; counts and scores read better lining. */
:is(.app-learning,.app-lesson,.first-steps,.play-screen),:is(.app-learning,.app-lesson,.first-steps,.play-screen) *{font-variant-numeric:lining-nums!important}

:is(.lesson-eyebrow,.learning-hud .eyebrow,.tray-heading .eyebrow,.stage-label){display:block;margin:0;font:500 .7rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}

/* Felt inside a varnished walnut rail, lit from above: the same materials as
   the table and the result screen. */
:is(.lesson-stage,.first-table,.play-screen .game-table){
  position:relative;isolation:isolate;box-sizing:border-box;min-width:0;border:10px solid transparent;border-radius:24px;
  background:
    radial-gradient(75% 60% at 50% 26%,rgba(255,228,176,.15),transparent 72%) padding-box,
    radial-gradient(135% 115% at 50% 32%,transparent 46%,rgba(2,10,6,.66) 100%) padding-box,
    url('/felt-v1.webp') center/320px padding-box,
    linear-gradient(#1b4a31,#1b4a31) padding-box,
    linear-gradient(180deg,rgba(255,222,184,.34),rgba(255,222,184,.06) 22%,rgba(0,0,0,0) 55%,rgba(0,0,0,.4)) border-box,
    url('/walnut-v1.webp') center/260px border-box,
    #4a2e1c;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5),inset 0 10px 22px rgba(0,0,0,.5),0 0 0 1px rgba(10,5,2,.7),0 1px 0 1px rgba(255,214,160,.08),0 18px 36px rgba(0,0,0,.45);
  color:var(--ivory)}

/* DOM tiles are rendered portraits of the table tiles. */
:where(.app-learning,.app-lesson,.first-steps,.play-screen) .tile:where(:not(.table-demo .tile)){--t:48px;--w:var(--t);width:var(--t);height:auto;aspect-ratio:1/1.52;min-width:0;min-height:0;max-width:none;flex:none;margin:0;padding:0;border:0;border-radius:6px;background:none;box-shadow:none;transform:none;transition:none}
/* Body copy never leaves one word (or "9.") alone on its last line. */
:is(.app-learning,.app-lesson,.first-steps,.play-screen,.scoring-screen) p{text-wrap:pretty}
:where(.app-learning,.app-lesson,.first-steps,.play-screen) .tile:where(:not(.table-demo .tile)) .tile-face{inset:0;border:0;border-radius:6px;box-shadow:none;filter:drop-shadow(0 5px 5px rgba(0,0,0,.42))}
@media (hover:hover){:is(.app-learning,.app-lesson,.first-steps) div.tile:hover{transform:none}}

/* Ringed numbers and letters, as on the medallions. */
:is(.topic-number,.choice-letter,.coach-mark,.feedback-mark){box-sizing:border-box;display:grid;place-items:center;flex:none;border-radius:50%;color:var(--gold);background:radial-gradient(circle at 50% 35%,#1d3228,#0b1511 72%);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(201,168,106,.2)}
:is(.coach-mark,.feedback-mark) .icon{width:18px;height:18px}

/* Position dots between the dock actions. */
.lesson-dots{display:flex;flex:1 1 auto;justify-content:center;align-items:center;gap:8px;min-width:0}
.lesson-dots i{display:block;width:6px;height:6px;border-radius:50%;background:rgba(201,168,106,.28)}
.lesson-dots i.past{background:rgba(201,168,106,.62)}
.lesson-dots i.now{width:7px;height:7px;background:var(--gold-bright);box-shadow:0 0 0 3px rgba(230,200,143,.14)}

/* Landscape phones: the back and menu buttons float over the first row, as
   on the game screen, so the lesson can use the whole height. The header keeps
   Home's full-width 58 px box; its padding holds the buttons inside the safe
   area, and each screen's first row is the same 58 px. */
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:is([data-screen=learn],[data-screen=tutorial],[data-screen=first],[data-screen=practice],[data-screen=guided],[data-screen=scoring],[data-screen=drill],[data-screen=defence],[data-screen=movie]):not([data-expanded-text=true]) .surface>header.app-header{position:absolute;top:var(--safe-top);left:0;right:0;height:58px;min-height:58px;padding:0 max(8px,var(--safe-right)) 0 max(8px,var(--safe-left));background:none;pointer-events:none}
  html:is([data-screen=learn],[data-screen=tutorial],[data-screen=first],[data-screen=practice],[data-screen=guided],[data-screen=scoring],[data-screen=drill],[data-screen=defence],[data-screen=movie]):not([data-expanded-text=true]) .surface>header.app-header :is(button,.save-status:not([hidden])){pointer-events:auto}
}

/* ---------- Library ---------- */
.surface>main.curriculum-screen{position:relative;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:max-content max-content max-content max-content 1fr max-content;grid-template-areas:"hud" "deck" "tray" "dock" "." "next";align-content:start;gap:0;width:100%;max-width:720px;margin:0 auto;padding:0 16px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scroll-padding:12px 0 90px;flex:1 1 auto;min-height:0}
.curriculum-screen .learning-hud{grid-area:hud;display:grid;gap:6px;justify-items:start;min-height:auto;margin:2px 0 0;padding:0}
.curriculum-screen .learning-hud h1{margin:0;font:500 2.6rem/1 var(--serif);letter-spacing:.005em;color:var(--ivory)}
.curriculum-screen .chapter-picker{display:none}

.curriculum-screen .chapter-deck{grid-area:deck;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(142px,40%);grid-template-columns:none;gap:10px;margin:16px -16px 0;padding:4px 16px 12px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x proximity;scroll-padding:0 16px;scrollbar-width:none;overscroll-behavior-x:contain}
.curriculum-screen .chapter-deck::-webkit-scrollbar{display:none}
.curriculum-screen .chapter-piece{position:relative;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto auto 1fr auto;justify-content:stretch;justify-items:start;align-content:start;gap:3px;min-width:0;min-height:0;margin:0;padding:12px 12px 12px;border:1px solid var(--gold-line);border-radius:var(--radius-card);background:linear-gradient(180deg,rgba(25,45,35,.92),rgba(14,27,21,.92));box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 8px 20px rgba(0,0,0,.25);color:var(--ivory);text-align:left;scroll-snap-align:start;cursor:pointer;transform:none;transition:border-color .2s,background .2s}
.curriculum-screen .chapter-piece>*{pointer-events:none}
.curriculum-screen .chapter-piece.current-chapter{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(38,68,51,.96),rgba(17,33,25,.96));box-shadow:inset 0 1px 0 rgba(255,240,210,.08),0 0 0 1px rgba(214,182,120,.28),0 10px 26px rgba(0,0,0,.32)}
.curriculum-screen .chapter-art{display:flex;align-items:flex-end;justify-content:flex-start;gap:2px;height:auto;margin:0 0 8px;padding:0}
.curriculum-screen .chapter-art .tile{--t:25px}
.curriculum-screen .chapter-number{display:block;margin:0;font:500 .62rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.curriculum-screen .chapter-piece strong{display:block;width:auto;min-height:0;margin:0;font:500 1.12rem/1.12 var(--serif);color:var(--ivory);text-wrap:balance}
.curriculum-screen .chapter-count{display:block;align-self:end;margin:6px 0 0;font:400 .74rem/1.2 var(--sans);color:var(--sage)}
.curriculum-screen .chapter-track{display:block;width:100%;height:3px;margin:6px 0 0;border-radius:3px;background:rgba(201,168,106,.18);overflow:hidden}
.curriculum-screen .chapter-track i{display:block;height:100%;border-radius:3px;background:linear-gradient(90deg,var(--gold-deep),var(--gold-bright))}
@media (hover:hover) and (pointer:fine){.curriculum-screen .chapter-piece:hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(33,58,45,.95),rgba(16,30,23,.95))}}

.curriculum-screen .chapter-tray{grid-area:tray;display:block;min-height:auto;margin:10px 0 0;padding:0;border:0;border-radius:0;background:none;box-shadow:none}
.curriculum-screen .tray-heading{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"title progress" "text text";align-items:baseline;gap:4px 12px;margin:0;padding:0 0 10px;border-bottom:1px solid rgba(201,168,106,.2)}
.curriculum-screen .tray-heading h2{grid-area:title;display:block;margin:0;font:500 1.6rem/1.1 var(--serif);color:var(--ivory)}
.curriculum-screen .chapter-progress{grid-area:progress;display:block;font:500 .78rem/1.2 var(--sans);color:var(--gold);white-space:nowrap}
.curriculum-screen .tray-heading p{grid-area:text;display:block;margin:0;font:400 .88rem/1.4 var(--sans);color:var(--sage)}
.curriculum-screen .topic-drawer{display:grid;grid-template-columns:minmax(0,1fr);grid-auto-rows:auto;gap:0;min-height:0;margin:0;padding:0;overflow:visible}

.curriculum-screen .tutorial-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px;width:100%;min-height:72px;margin:0;padding:12px 4px 12px 2px;border:0;border-bottom:1px solid rgba(201,168,106,.14);border-radius:0;background:none;box-shadow:none;color:var(--ivory);text-align:left;cursor:pointer;transform:none;transition:background .18s}
.curriculum-screen .topic-number{width:34px;height:34px;font:500 1.05rem/1 var(--serif)}
.curriculum-screen .tutorial-row.is-correct .topic-number{color:var(--ink-on-gold);background:var(--primary-fill);box-shadow:0 0 0 1px #f0d9a8,0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(230,200,143,.3)}
.curriculum-screen .topic-copy{display:grid;gap:3px;min-width:0}
.curriculum-screen .tutorial-row strong{display:block;font:500 1.22rem/1.15 var(--serif);color:var(--ivory)}
.curriculum-screen .tutorial-row small{display:block;font:400 .84rem/1.35 var(--sans);color:var(--sage)}
.curriculum-screen .topic-end{display:flex;align-items:center;gap:8px;color:var(--gold)}
.curriculum-screen .topic-status{display:block;margin:0;font:500 .74rem/1.2 var(--sans);letter-spacing:.02em;white-space:nowrap}
.curriculum-screen .is-correct .topic-status{color:var(--positive)}
.curriculum-screen .is-retry .topic-status{color:#e7b48a}
.curriculum-screen .topic-arrow{display:grid;place-items:center}
.curriculum-screen .topic-arrow .icon{width:18px;height:18px;color:var(--gold)}
.curriculum-screen .is-correct .topic-arrow .icon{color:var(--positive)}
@media (hover:hover) and (pointer:fine){.curriculum-screen .tutorial-row:hover{background:linear-gradient(90deg,rgba(201,168,106,.06),rgba(201,168,106,0))}}

/* The bonus chapter, At The Movies: a cinema ticket (notched at both ends) in the
   library's heading, beside "Learn". It shares the heading's cell, so the chapters,
   tray and tools keep their places; chosen, it lights like a chapter card and the
   tray lists the scenes. */
.curriculum-screen .bonus-ticket{grid-area:hud;justify-self:end;align-self:end;position:relative;box-sizing:border-box;display:flex;align-items:center;gap:10px;min-width:44px;min-height:48px;max-width:min(62%,300px);margin:0;padding:5px 18px 5px 16px;border:1px solid var(--gold-line);border-radius:10px;
  background:linear-gradient(180deg,rgba(25,45,35,.94),rgba(14,27,21,.94));box-shadow:inset 0 1px 0 rgba(255,240,210,.06),0 6px 16px rgba(0,0,0,.28);color:var(--ivory);text-align:left;cursor:pointer;transform:none;
  -webkit-mask:radial-gradient(circle 6px at 0 50%,#0000 97%,#000) left/51% 100% no-repeat,radial-gradient(circle 6px at 100% 50%,#0000 97%,#000) right/51% 100% no-repeat;
  mask:radial-gradient(circle 6px at 0 50%,#0000 97%,#000) left/51% 100% no-repeat,radial-gradient(circle 6px at 100% 50%,#0000 97%,#000) right/51% 100% no-repeat;transition:border-color .2s,background .2s}
.curriculum-screen .bonus-ticket>*{pointer-events:none}
.curriculum-screen .bonus-ticket>.icon{flex:none;width:22px;height:22px;color:var(--gold)}
.curriculum-screen .bonus-ticket>span{display:grid;gap:1px;min-width:0}
.curriculum-screen .bonus-ticket small{display:block;font:500 .6rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.curriculum-screen .bonus-ticket strong{display:block;overflow:hidden;font:500 1.08rem/1.1 var(--serif);color:var(--ivory);white-space:nowrap;text-overflow:ellipsis}
.curriculum-screen .bonus-ticket.current-chapter{border-color:var(--gold-bright);background:linear-gradient(180deg,rgba(40,70,52,.97),rgba(18,35,26,.97))}
.curriculum-screen .bonus-ticket.current-chapter>.icon{color:var(--gold-bright)}
@media (hover:hover) and (pointer:fine){.curriculum-screen .bonus-ticket:hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(33,58,45,.96),rgba(16,30,23,.96))}}
/* Its one scene: a clapperboard where a lesson has its number, at the top of the tray. */
.curriculum-screen .movies-tray .topic-drawer{align-content:start}
.curriculum-screen .movie-row .topic-number .icon{width:17px;height:17px}

/* The six tools that span chapters, two by two under the lessons: on phones a
   centred name each; from 600 px wide with their icons and a line of detail.
   Beside the chapters (landscape) the four practices share one row under the
   cards, and Count This Hand and Mahjong Terms share the row under them. */
.curriculum-screen .learning-dock{grid-area:dock;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:16px 0 0;padding:0;border:0;background:none}
.curriculum-screen .learning-dock>button>.icon{flex:none;width:20px;height:20px;color:var(--gold)}
/* The bar sits on the room with a 24 px fade above it; at the end of the
   scroll, content stops clear of the fade (16 px above the bar and more). */
.curriculum-screen .learning-next{grid-area:next;position:sticky;bottom:0;z-index:3;display:grid;margin:28px -16px 0;padding:12px 16px 12px;background:none}
.curriculum-screen .learning-next>.primary{width:100%;min-height:50px;margin:0;font-size:1rem}
/* A passed chapter: the next chapter beside the gold hand at the table. */
.curriculum-screen .learning-next.has-pair{grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);gap:10px}
.curriculum-screen .learning-next.has-pair>button{width:100%;min-width:0;min-height:50px;margin:0;padding:4px 12px;white-space:normal;line-height:1.15;text-align:center;text-wrap:balance}
.curriculum-screen .learning-dock>button{width:100%;min-width:0;min-height:52px;margin:0;padding:6px 12px;flex:none}
.curriculum-screen .learning-dock>button.outline{font-size:.86rem;line-height:1.15;text-align:left;justify-content:flex-start}
.curriculum-screen .learning-dock>button>span{display:grid;gap:2px}
.curriculum-screen .learning-dock button small{display:block;margin:0;font:400 .72rem/1.2 var(--sans);color:var(--sage)}
@media (max-width:599px){
  .curriculum-screen .learning-dock>button.outline{justify-content:center;padding:4px 8px;font-size:.82rem;text-align:center;text-wrap:balance}
  .curriculum-screen .learning-dock>button :is(.icon,small){display:none}
}

@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .surface>main.curriculum-screen{max-width:1180px;height:100%;padding:0 18px 10px;overflow:hidden;
    grid-template-columns:repeat(4,minmax(0,.255fr)) minmax(0,.98fr);grid-template-rows:auto minmax(0,1fr) auto auto;
    grid-template-areas:"hud hud hud hud ." "deck deck deck deck tray" "practise drill read fold tray" "count count terms terms next";column-gap:12px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-deck{grid-auto-flow:row;grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-columns:auto;grid-auto-rows:minmax(0,1fr);align-content:stretch;margin:12px 12px 0 0;padding:0;overflow:visible}
  /* The ticket takes the heading row's free cell, above the tray. */
  html:not([data-expanded-text=true]) .curriculum-screen .bonus-ticket{grid-area:1/5/2/6;justify-self:end;align-self:end;margin:0 0 0 12px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece{padding:10px 11px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art{margin-bottom:6px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art .tile{--t:22px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece strong{font-size:1.02rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-tray{display:flex;flex-direction:column;min-height:0;margin:12px 0 0 12px;overflow:hidden}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-deck{min-height:0}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-drawer{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row{min-height:60px;padding:8px 4px 8px 2px}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock{display:contents}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button{min-height:50px;margin-top:10px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=tutorial-review]{grid-area:practise}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=drill-open]{grid-area:drill}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=read-open]{grid-area:read}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=fold-open]{grid-area:fold;margin-right:12px}
  /* Four tools share the width under the chapters: a centred name each. */
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button.outline{justify-content:center;padding:4px 8px;text-align:center;text-wrap:balance}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button small{display:none}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=score-open]{grid-area:count}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=glossary]{grid-area:terms;margin-right:12px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-next{position:static;margin:10px 0 0 12px;padding:0;background:none}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-next:before{content:none}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  /* The chapter cards keep their height: the four practices take the row under
     them, and Count This Hand and Mahjong Terms sit beside each other under the
     lessons, above the gold action. */
  html:not([data-expanded-text=true]) .surface>main.curriculum-screen{grid-template-columns:repeat(4,minmax(0,.255fr)) repeat(2,minmax(0,.49fr));grid-template-rows:58px minmax(0,1fr) auto auto;
    grid-template-areas:"hud hud hud hud . ." "deck deck deck deck tray tray" "deck deck deck deck count terms" "practise drill read fold next next";padding-bottom:8px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=score-open]{width:auto;margin-left:12px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>[data-action=glossary]{margin-right:0}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-hud{display:flex;flex-direction:row;align-items:baseline;gap:16px;margin:0;padding:0 0 0 38px;align-self:center}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-hud h1{order:-1;font-size:1.9rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-deck{margin-top:4px;gap:8px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-tray{margin-top:4px}
  /* The ticket starts the tray's columns in the heading row, clear of the floating menu. */
  html:not([data-expanded-text=true]) .curriculum-screen .bonus-ticket{grid-area:1/5/2/7;justify-self:start;align-self:center;min-height:44px;margin:0 0 0 12px;padding:3px 16px 3px 14px}
  html:not([data-expanded-text=true]) .curriculum-screen .bonus-ticket strong{font-size:1rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading{padding-bottom:6px}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading p{display:none}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading h2{font-size:1.45rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row{min-height:56px;padding:6px 4px 6px 2px}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row strong{font-size:1.12rem}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-number{width:30px;height:30px;font-size:.95rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-count{margin-top:2px}
  /* The tools: a centred name each. */
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button.outline{justify-content:center;padding:4px 8px;font-size:.8rem;text-align:center;text-wrap:balance}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button :is(.icon,small){display:none}
}
/* Shorter still, the chapter cards tighten so the name never runs into its
   label; on the shortest screens the count carries the progress and the small
   tile emblems give way. */
@media (orientation:landscape) and (min-width:700px) and (max-height:420px){
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece{padding:8px 10px;gap:2px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art{margin-bottom:3px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art .tile{--t:18px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece strong{line-height:1.04}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-count{margin-top:1px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-track{display:none}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:370px){
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art{display:none}
}

/* ---------- Lesson ---------- */
/* Fit the screen and hold still (director, 24 Sep 2026). A lesson is a compact
   heading (place, chapter, title, steps), the felt, the step's text box and the
   actions. The text box is as tall as the lesson's longest step text (--text-h,
   measured by step-fit.js from sizing copies of every step) and the felt takes
   the rest, so its size depends on the window alone: a step changes what the
   felt and the box hold, never where they are. What lies on the felt is zoomed
   to fill it (.felt-fit). Only when even that cannot fit (Large text on a small
   phone) does the text box, or at last the page, scroll. Portrait stacks felt,
   text and actions; landscape puts the felt beside the text and actions. */
.surface>main.app-lesson{display:flex;flex-direction:column;gap:0;width:100%;max-width:none;margin:0;padding:0;overflow:hidden;flex:1 1 auto;min-height:0}
.app-lesson{--felt-room:calc(var(--app-frame-height,100dvh) - var(--safe-top) - var(--safe-bottom) - 58px)}
.app-lesson>.teaching-table{
  --felt-min:150px;--text-max:calc(var(--felt-room) * .46);
  position:relative;isolation:auto;flex:1 1 auto;min-height:0;box-sizing:border-box;
  display:grid;grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto auto auto minmax(var(--felt-min),1fr) minmax(0,min(var(--text-h,9999px),var(--text-max))) auto;
  grid-template-areas:"hud" "title" "tabs" "stage" "body" "dock";align-content:stretch;align-items:stretch;justify-content:stretch;justify-items:stretch;gap:0;
  width:100%;max-width:720px;margin:0 auto;padding:0 16px;
  overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scroll-padding:12px 0 96px;
  border:0;border-radius:0;background:none;box-shadow:none;color:var(--ivory)}
/* A demonstration's table needs more of the screen than a question's tiles. */
.app-lesson>.teaching-table.demo-lesson{--felt-min:clamp(200px,calc(var(--felt-room) * .45),340px);--text-max:calc(var(--felt-room) * .35)}
.app-lesson .lesson-hud{grid-area:hud;display:flex;align-items:center;justify-content:space-between;gap:12px;width:auto;height:auto;min-height:44px;margin:0;padding:0;font-size:1rem;color:var(--sage)}
.app-lesson .lesson-place{display:block;min-width:0;font:500 .98rem/1.2 var(--sans);font-variant-caps:all-small-caps;letter-spacing:.14em;color:var(--sage);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.app-lesson .lesson-place .review-mode{color:var(--gold-bright)}
.app-lesson .lesson-hud button.quiet{min-height:44px;margin:0 -10px 0 0;padding:0 10px;font-size:.88rem;color:var(--ivory-2)}
.app-lesson .lesson-title{grid-area:title;display:grid;gap:4px;justify-items:start;margin:0;padding:0;text-align:left}
.app-lesson .lesson-title h1{margin:0;font:500 1.8rem/1.06 var(--serif);letter-spacing:.005em;color:var(--ivory);text-wrap:balance}
.app-lesson .lesson-phases{grid-area:tabs;display:flex;justify-content:flex-start;align-items:stretch;gap:24px;margin:8px 0 0;padding:0;border-bottom:1px solid rgba(201,168,106,.18);white-space:nowrap}
/* A longer language shortens the steps you are not on (with an ellipsis) before the page would scroll. */
.app-lesson .lesson-phases span{display:block;flex:0 1 auto;min-width:0;height:34px;margin:0 0 -1px;padding:0 1px;overflow:hidden;text-overflow:ellipsis;line-height:34px;border:0;border-bottom:2px solid transparent;font:500 .98rem/1 var(--sans);font-variant-caps:all-small-caps;letter-spacing:.16em;color:var(--sage-2)}
.app-lesson .lesson-phases span.active{flex-shrink:0;color:var(--gold-bright);border-bottom-color:var(--gold)}
.app-lesson .eyebrow-place{display:none}
/* Portrait lessons keep the heading to two rows: the chapter (with the lesson's
   number) and title, then the steps with Lesson Notes at their end. */
@media (orientation:portrait){
  .app-lesson>.teaching-table:has(>.lesson-phases){grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto auto minmax(var(--felt-min),1fr) minmax(0,min(var(--text-h,9999px),var(--text-max))) auto;
    grid-template-areas:"title title" "tabs hud" "stage stage" "body body" "dock dock"}
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-title{margin-top:4px}
  .app-lesson>.teaching-table:has(>.lesson-phases) .eyebrow-place{display:inline}
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-phases{margin-top:6px}
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud{align-self:stretch;min-height:0;margin:6px 0 0;padding:0 0 0 12px;border-bottom:1px solid rgba(201,168,106,.18)}
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud>.lesson-place{display:none}
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud>button.quiet{min-height:44px;margin:0 -10px 0 0}
}
/* Narrow phones and larger text: Lesson Notes shows its book alone (its name stays
   for assistive technology), so the steps keep one line. */
@media (orientation:portrait) and (max-width:429px){
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud>button.quiet{position:relative;width:44px;padding:0;gap:0;justify-content:center}
  .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud>button.quiet>span{width:0;height:0;margin:0;overflow:hidden;font-size:0;line-height:0;white-space:nowrap}
}
@media (orientation:portrait){
  html:is([data-text=large],[data-expanded-text=true]) .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud>button.quiet{position:relative;width:44px;padding:0;gap:0;justify-content:center}
  html:is([data-text=large],[data-expanded-text=true]) .app-lesson>.teaching-table:has(>.lesson-phases)>.lesson-hud>button.quiet>span{width:0;height:0;margin:0;overflow:hidden;font-size:0;line-height:0;white-space:nowrap}
  html[data-text=large] .app-lesson .lesson-phases{gap:16px}
}
@media (orientation:portrait) and (max-width:359px){
  .app-lesson .lesson-phases{gap:14px}
  .app-lesson .lesson-phases span{font-size:.9rem;letter-spacing:.12em}
}

/* The felt. Its size comes from the grid alone (size containment), and its
   contents are zoomed to fill it and centred. */
.app-lesson .lesson-stage{grid-area:stage;position:relative;box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);place-items:center;align-self:stretch;height:auto;min-height:0;margin:12px 0 0;padding:14px;overflow:hidden;container:felt/size}
.app-lesson .lesson-stage:has(>.stage-label){padding-top:28px}
.app-lesson .stage-label{position:absolute;top:10px;left:14px;margin:0;color:var(--gold-bright);opacity:.9}
.app-lesson .felt-fit{box-sizing:border-box;flex:none;max-width:none;min-width:0;margin:0}
.fit-probe{position:absolute;left:0;top:0;z-index:-1;visibility:hidden;pointer-events:none}
.fit-requery *{container-type:normal!important}
.fit-measuring .tile-face>*{display:none}

/* The step's text box: the lead (a caption, the question, the verdict) and the
   panel (the tip, the answers, the right answer). Sizing copies (.step-size)
   lay out exactly like it. */
.app-lesson .lesson-body,.app-lesson .step-size{display:flex;flex-direction:column;gap:12px;min-width:0}
.app-lesson .lesson-body{grid-area:body;position:relative;box-sizing:border-box;align-self:stretch;min-height:0;margin:0;padding:14px 0 6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}
.app-lesson .lesson-body.has-more{-webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(180deg,#000 calc(100% - 28px),transparent)}
.app-lesson .lesson-lead{display:block;flex:none;margin:0;padding:0}
.app-lesson .lesson-lead:empty,.app-lesson .lesson-panel:empty{display:none}
.app-lesson .lesson-panel{display:flex;flex-direction:column;gap:12px;flex:none;min-width:0;margin:0;padding:0;text-align:left}
.app-lesson :is(.object-caption,.exercise-prompt){display:block;max-width:62ch;margin:0;padding:0;font:400 1rem/1.5 var(--sans);text-align:left;color:var(--ivory-2)}
.app-lesson .exercise-prompt{font-weight:500;font-size:1.02rem;line-height:1.45;color:var(--ivory)}

/* What lies on the felt, at its natural size: step-fit.js zooms it to fill the
   felt (never beyond --fit-max). */
.app-lesson .lesson-objects{--fit-max:4.2;display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;align-content:center;gap:6px;max-width:none;margin:0;padding:0}
.app-lesson .lesson-objects .tile{--t:48px}
.app-lesson .lesson-objects.small-example{gap:10px}
/* A question's single tile is the whole example: it may grow to fill most of a large felt. */
.app-lesson .lesson-objects.small-example:has(>.tile:only-child){--fit-max:6}
.app-lesson .lesson-objects.medium-example{gap:8px}
.app-lesson .lesson-objects.full-hand{gap:8px 4px;max-width:calc(7 * 48px + 6 * 4px + 1px)}
/* Claim Or Pass?: the discard on offer ends the hand, ringed in gold under its tag. The tag stays
   in the flow, wrapping between words (a long word widens the tile's place in the row), so the hand
   never overflows its felt. */
.app-lesson .lesson-objects.full-hand:has(.offered-tile){row-gap:10px}
.app-lesson .offered-tile{display:flex;flex-direction:column;align-items:center;gap:5px;width:min-content}
.app-lesson .offered-tile>.tile{border-radius:7px;outline:2px solid var(--gold-bright);outline-offset:2px;box-shadow:0 0 16px rgba(240,200,120,.45)}
.app-lesson .offered-tile>.added-label{padding:2px 4px 1px;border-radius:6px;background:var(--gold-bright);box-shadow:0 2px 6px rgba(0,0,0,.45);font:700 .5rem/1.15 var(--sans);letter-spacing:.08em;text-transform:uppercase;text-align:center;color:var(--ink-on-gold)}
/* A question with no tiles shows the lesson's seal, filling about three fifths of the felt. */
.app-lesson .lesson-objects.no-example{--fit-max:5}
.app-lesson .lesson-emblem{display:grid;place-items:center;width:88px;height:88px;margin:20px;border:0;border-radius:50%;color:var(--gold-bright);background:radial-gradient(circle at 50% 35%,#20382c,#0b1511 72%);box-shadow:0 0 0 1.5px var(--gold-line-strong),0 0 0 5px rgba(9,17,13,.85),0 0 0 6px rgba(230,200,143,.3),0 0 34px rgba(240,200,120,.22)}
.app-lesson .lesson-emblem .icon{width:36px;height:36px;stroke-width:1.3}

/* Named sets on the felt. */
.app-lesson .lesson-objects.grouped-hand{--fit-max:2.6;display:block;padding:0}
.app-lesson .hand-groups{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;gap:14px 16px;max-width:100%;margin:0 auto}
.app-lesson .teaching-set{display:flex;flex-direction:column;align-items:center;gap:6px;flex:none;min-width:0}
.app-lesson .teaching-set>span{display:block;font:500 .66rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold-bright);text-shadow:0 1px 3px rgba(0,0,0,.6)}
.app-lesson .teaching-set>div{display:flex;align-items:flex-start;gap:2px;padding:0}
.app-lesson .grouped-hand .tile{--t:40px}
/* The added tile is ringed in gold with a small tag on its top edge, so the
   completed hand takes no more height than the hand itself. */
.app-lesson .completion-added{position:relative;border-radius:7px;outline:2px solid var(--gold-bright);outline-offset:2px;box-shadow:0 0 16px rgba(240,200,120,.45)}
.app-lesson .completion-added .added-label{position:absolute;bottom:calc(100% - 6px);left:50%;z-index:1;transform:translateX(-50%);padding:2px 6px 1px;border-radius:999px;background:var(--gold-bright);box-shadow:0 2px 6px rgba(0,0,0,.45);font:700 .5rem/1.2 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-on-gold);white-space:nowrap}
/* Tile families and honours: bigger faces with their names. */
.app-lesson .hand-groups:is(.family-examples,.honour-examples){gap:18px 26px}
.app-lesson :is(.family-examples,.honour-examples) .teaching-set>span{font-size:.64rem}
.app-lesson :is(.family-examples,.honour-examples) .teaching-set>div{gap:8px}
.app-lesson .family-tile{display:flex;flex-direction:column;align-items:center;gap:6px;font:500 .72rem/1.2 var(--sans);color:var(--ivory-2);text-align:center}
.app-lesson .family-examples .tile{--t:64px}
.app-lesson .honour-examples .tile{--t:52px}

/* A tip card for the coach's note. */
.app-lesson .coach-note{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:14px;width:auto;max-width:none;margin:0;padding:14px 16px 14px 14px;border:1px solid var(--gold-line);border-radius:var(--radius-card);background:var(--panel-fill);box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 10px 24px rgba(0,0,0,.25);color:var(--ivory-2)}
.app-lesson .coach-mark{width:32px;height:32px;margin-top:1px;color:var(--gold-bright)}
.app-lesson .coach-copy{display:grid;gap:8px;min-width:0}
.app-lesson .coach-copy strong{display:block;font:500 .7rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.app-lesson .coach-note p{margin:0;font:400 .96rem/1.5 var(--sans);text-align:left;color:var(--ivory-2)}

/* Answer choices: dark hairline cards with a lettered ring. */
.app-lesson .tutorial-choices{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,max(148px,calc(50% - 5px))),1fr));gap:8px;width:100%;max-width:none;margin:0}
.app-lesson .tutorial-choice{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;justify-content:stretch;gap:10px;min-width:0;min-height:54px;margin:0;padding:7px 10px;border:1px solid var(--gold-line);border-radius:var(--radius-card);background:linear-gradient(180deg,rgba(25,45,35,.92),rgba(14,27,21,.92));box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 6px 16px rgba(0,0,0,.24);color:var(--ivory);text-align:left;font:500 .93rem/1.25 var(--sans);cursor:pointer;transform:none;transition:border-color .18s,background .18s}
.app-lesson .choice-letter{width:28px;height:28px;font:500 .98rem/1 var(--serif);opacity:1}
.app-lesson .choice-content{display:flex;flex-direction:column;align-items:flex-start;gap:5px;min-width:0;font:500 .93rem/1.25 var(--sans);color:var(--ivory);overflow-wrap:break-word}
.app-lesson .choice-tiles{display:flex;flex-wrap:wrap;gap:2px}
.app-lesson .choice-tiles .tile{--t:40px}
/* Tile answers show their tiles, their names underneath. */
.app-lesson .tutorial-choice.chosen{border-color:var(--gold-bright);background:linear-gradient(180deg,rgba(40,70,52,.96),rgba(18,35,26,.96));box-shadow:0 0 0 1px rgba(230,200,143,.35),0 0 18px rgba(230,190,110,.14)}
.app-lesson .tutorial-choice.chosen .choice-letter{color:var(--ink-on-gold);background:var(--primary-fill);box-shadow:0 0 0 1px #f0d9a8,0 0 0 3px rgba(9,17,13,.9),0 0 0 4px rgba(230,200,143,.4)}
@media (hover:hover) and (pointer:fine){.app-lesson .tutorial-choice:hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(33,58,45,.95),rgba(16,30,23,.95))}}
.app-lesson .answer-cue{display:block;margin:0;font:400 .9rem/1.4 var(--sans);color:var(--gold-bright);text-align:left}
.app-lesson .answer-cue:empty{display:none}

/* Feedback: marked by an icon and words, never by colour alone. */
/* One way to mark an answer on every learning screen (Explain, First Steps,
   Count This Hand): a ringed mark beside a serif line, the explanation under
   the line. */
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback){display:grid;grid-template-columns:minmax(0,1fr);align-items:center;column-gap:14px;row-gap:6px;max-width:none;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;text-align:left;outline:0}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback):has(>.feedback-mark){grid-template-columns:38px minmax(0,1fr)}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback)>.feedback-mark{grid-column:1;grid-row:1;width:38px;height:38px;margin:0}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback):has(>.feedback-mark)>:not(.feedback-mark){grid-column:2}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback).success>.feedback-mark{color:var(--positive);box-shadow:0 0 0 1.5px rgba(143,208,162,.75),0 0 0 4px rgba(9,17,13,.9),0 0 0 5px rgba(143,208,162,.3),0 0 18px rgba(143,208,162,.2)}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback).retry>.feedback-mark{color:#eea08f;box-shadow:0 0 0 1.5px rgba(224,137,122,.7),0 0 0 4px rgba(9,17,13,.9),0 0 0 5px rgba(224,137,122,.28)}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback)>:is(h2,strong){display:block;margin:0;font:500 1.65rem/1.1 var(--serif);letter-spacing:0;color:var(--ivory)}
:is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost),.scoring-screen .score-feedback)>p{margin:0;font:400 1rem/1.5 var(--sans);color:var(--ivory-2)}
.app-lesson .feedback-mark{width:38px;height:38px}
.app-lesson .tutorial-feedback>h2{font-size:1.45rem}
.app-lesson .tutorial-feedback>p{font-size:.96rem;line-height:1.45}
/* The right answer after a wrong one: a label, the answer in plain words, its
   tiles, then the learner's own choice. */
.app-lesson .answer-reveal{display:grid;justify-items:start;gap:5px;max-width:none;margin:0;padding:12px 14px;border:1px solid var(--gold-line);border-radius:var(--radius-card);background:var(--panel-fill);color:var(--ivory);text-align:left}
.app-lesson .answer-reveal>span{font:500 .92rem/1.2 var(--sans);font-variant-caps:all-small-caps;letter-spacing:.16em;color:var(--gold)}
.app-lesson .answer-reveal p{margin:0;font:400 .92rem/1.45 var(--sans);color:var(--ivory-2)}
.app-lesson .answer-reveal p.reveal-answer{font:500 1.05rem/1.35 var(--sans);color:var(--ivory)}
.app-lesson .answer-reveal .your-answer{color:var(--sage)}
.app-lesson .reveal-tiles{display:flex;flex-wrap:wrap;gap:3px;margin:2px 0}
.app-lesson .reveal-tiles .tile{--t:38px}
.app-lesson .wait-selection{display:grid;gap:10px}
.app-lesson .wait-selection>p{margin:0;font:400 .95rem/1.45 var(--sans);color:var(--ivory-2)}
.app-lesson .tutorial-choices.wait-completions{display:flex;flex-wrap:wrap;justify-content:flex-start;gap:8px;margin:0;width:auto}
.app-lesson .wait-completions .tutorial-choice{grid-template-columns:minmax(0,1fr);min-height:48px;padding:6px 14px 6px 8px}
.app-lesson .wait-completions .choice-content{flex-direction:row;align-items:center;gap:10px;font-size:.9rem}
.app-lesson .wait-completions .choice-tiles .tile{--t:40px}

/* The actions, fixed at the foot. They are pinned only for the fallback when the
   page scrolls, and then sit on the room under a short fade. */
.app-lesson .lesson-dock{grid-area:dock;position:sticky;bottom:0;z-index:4;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:auto;height:auto;margin:0 -16px;padding:8px 16px 10px;border:0;background:none}
:is(.app-lesson,.first-steps,.curriculum-screen){--dock-fill:#090e0c}
@media (orientation:portrait){
  :is(.app-lesson>.teaching-table,main.first-steps).has-more>.lesson-dock,main.curriculum-screen.has-more>.learning-next{background:linear-gradient(180deg,rgba(9,14,12,.84),var(--dock-fill) 60%)}
  /* The words pass under the bar through a long, eased fade that meets it without a line (no hard edge cuts a row in half). */
  :is(.app-lesson>.teaching-table,main.first-steps).has-more>.lesson-dock:before,main.curriculum-screen.has-more>.learning-next:before{content:'';position:absolute;left:0;right:0;bottom:100%;height:48px;background:linear-gradient(180deg,rgba(9,14,12,0) 0%,rgba(9,14,12,.12) 22%,rgba(9,14,12,.34) 45%,rgba(9,14,12,.6) 70%,rgba(9,14,12,.84) 100%);pointer-events:none}
  /* A small gold chevron in the fade: there is more below. */
  :is(.app-lesson>.teaching-table,main.first-steps).has-more>.lesson-dock:after,main.curriculum-screen.has-more>.learning-next:after{content:'';position:absolute;left:50%;bottom:calc(100% + 8px);width:8px;height:8px;border-right:1.6px solid var(--gold);border-bottom:1.6px solid var(--gold);transform:translateX(-50%) rotate(45deg);pointer-events:none}
}
.app-lesson .lesson-dock>button{flex:0 1 auto;min-width:0;min-height:48px;margin:0;font-size:.95rem;white-space:nowrap}
.app-lesson .lesson-dock>button.primary{flex:0 1 auto;min-width:148px;margin-left:auto;padding:0 22px}
.app-lesson .lesson-dock>button.primary:first-child{margin-left:0}
.app-lesson .lesson-dock>.lesson-dots:first-child{flex:1 1 auto;justify-content:flex-start;padding-left:4px}
.app-lesson .lesson-dock .lesson-dots+button.primary{margin-left:0}
@media (max-width:520px){
  /* Two actions always share one row, half each; a long label wraps to a second
     line inside its 48 px button, so the bar never grows or moves. */
  .app-lesson .lesson-dock:has(>button~button)>button:is(.primary,.outline,.quiet){flex:1 1 0;min-width:0;margin:0;padding:0 12px;white-space:normal;line-height:1.15;text-align:center;text-wrap:balance}
  .app-lesson .lesson-dock:has(>button~button)>button.primary{flex-grow:1.3}
  .app-lesson .lesson-dock:has(>button~button) .lesson-dots{display:none}
  .app-lesson .lesson-dock>button.primary:only-of-type{flex:1 1 auto}
  .app-lesson .lesson-dock>button{padding:0 14px}
}

/* Forward and back chevrons, as on the reference's Previous and Next. */
:is(.app-lesson,.first-steps) .lesson-dock>button:is(.primary,[data-action=tutorial-observe]){gap:10px}
:is(.app-lesson,.first-steps) .lesson-dock>button.primary:after,.app-lesson .lesson-dock>[data-action=tutorial-observe]:before{content:'';flex:none;width:8px;height:8px;border-top:1.6px solid currentColor;border-right:1.6px solid currentColor;transform:rotate(45deg);margin-right:2px}
.app-lesson .lesson-dock>[data-action=tutorial-observe]:before{transform:rotate(-135deg);margin:0 0 0 3px;color:var(--gold)}

/* Table demonstrations: the table is the felt's scene (teach.css). */
.app-lesson .has-table-demo .lesson-dots{display:none}

/* Practice Complete: the score under a gold seal (the result screen's motif),
   the questions as ruled rows, then the last question with its worked answer
   and any tiles on a small felt tray. It is a summary, not a step, so it keeps
   its own page. */
.app-lesson>.teaching-table.practice-summary{grid-template-rows:max-content max-content max-content max-content minmax(0,1fr) max-content;grid-template-areas:"hud" "title" "score" "panel" "." "dock"}
.app-lesson>.practice-summary .lesson-body{display:contents}
.app-lesson .practice-summary .lesson-panel{grid-area:panel}
.app-lesson .teaching-table.practice-summary .practice-score{grid-area:score;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:22px;margin:22px 0 0 6px;outline:0}
.app-lesson .practice-seal{position:relative;isolation:isolate;display:grid;place-items:center;width:78px;height:78px;box-sizing:border-box;padding:0 0 3px 4px;border-radius:50%;color:var(--gold-bright);background:radial-gradient(circle at 50% 35%,#20382c,#0b1511 72%);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 4px rgba(9,17,13,.9),0 0 0 5px rgba(230,200,143,.45),0 0 30px rgba(240,200,120,.35)}
.app-lesson .practice-seal:before{content:'';position:absolute;inset:-34px;z-index:-1;border-radius:50%;background:repeating-conic-gradient(from 0deg,rgba(255,220,150,.2) 0deg 3deg,transparent 3deg 15deg);-webkit-mask:radial-gradient(circle,#000 30%,transparent 70%);mask:radial-gradient(circle,#000 30%,transparent 70%)}
.app-lesson .practice-seal strong{font:500 2.2rem/1 var(--serif)}
.app-lesson .practice-seal small{font:500 1rem/1 var(--serif);color:var(--gold)}
.app-lesson .teaching-table.practice-summary .practice-score h2{margin:0;font:500 1.75rem/1.1 var(--serif);color:var(--ivory)}
.app-lesson .teaching-table.practice-summary .practice-score.success h2{background:linear-gradient(180deg,#fff3d6,#e3c58c);-webkit-background-clip:text;background-clip:text;color:transparent}
.app-lesson .teaching-table.practice-summary .practice-score p{margin:6px 0 0;font:400 1rem/1.5 var(--sans);color:var(--ivory-2)}
html[data-motion=on] .app-lesson .practice-seal{animation:practice-seal .7s var(--ease-out) both}
@keyframes practice-seal{from{opacity:0;transform:scale(.6)}60%{transform:scale(1.06)}}
@media (prefers-reduced-motion:reduce){.app-lesson .practice-seal{animation:none!important}}
.app-lesson .practice-summary .lesson-panel{margin-top:22px}
.app-lesson .answer-reveal.last-question{gap:8px}
/* The last question's tiles lie on a small felt tray inside its card. */
.app-lesson .reveal-felt{box-sizing:border-box;display:flex;justify-content:center;width:100%;margin:4px 0;padding:14px 10px;border-radius:12px;container-type:inline-size;background:radial-gradient(90% 80% at 50% 30%,rgba(255,226,170,.1),transparent 70%),radial-gradient(140% 120% at 50% 40%,transparent 50%,rgba(2,10,6,.5) 100%),url('/felt-v1.webp') center/300px,#1b4a31;box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 4px 12px rgba(0,0,0,.4),0 0 0 1px rgba(201,168,106,.2)}
.app-lesson .reveal-felt:not(.grouped-hand){width:auto;padding:12px 18px;container-type:normal}
.app-lesson .practice-seal>span{display:flex;align-items:baseline;gap:1px}
.app-lesson .reveal-felt .reveal-tiles{justify-content:center;margin:0}
.app-lesson .reveal-felt.grouped-hand{display:block}
html .app-lesson .practice-summary .reveal-felt .hand-groups{gap:12px 14px}
html .app-lesson .practice-summary .reveal-felt.grouped-hand .tile{--t:min(40px,calc((100cqw - 24px) / 9 - 2px))}
html .app-lesson .practice-summary .reveal-felt .teaching-set>span{font-size:.6rem}
.app-lesson .practice-topics{display:grid;gap:0;margin:0;padding:0;list-style:none;text-align:left;line-height:1.3}
.app-lesson .practice-topics li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;min-height:52px;padding:8px 2px;border-bottom:1px solid rgba(201,168,106,.14)}
.app-lesson .practice-topics .topic-number{width:28px;height:28px;font:500 .95rem/1 var(--serif)}
.app-lesson .practice-topics li>span:not(.topic-number){font:500 1.08rem/1.2 var(--serif);color:var(--ivory)}
.app-lesson .practice-topics li strong{display:flex;align-items:center;gap:6px;font:500 .78rem/1.2 var(--sans);white-space:nowrap;color:var(--sage)}
.app-lesson .practice-topics li.is-correct strong{color:var(--positive)}
.app-lesson .practice-topics li.is-missed strong{color:#eea08f}
.app-lesson .practice-topics li.is-correct strong:before,.app-lesson .practice-topics li.is-missed strong:before{content:'';width:14px;height:14px;background:currentColor;-webkit-mask:var(--mark) center/contain no-repeat;mask:var(--mark) center/contain no-repeat}
.app-lesson .practice-topics li.is-correct{--mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m5 12 4 4L19 6' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.app-lesson .practice-topics li.is-missed{--mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 6 12 12M6 18 18 6' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E")}

/* Landscape: the felt fills the height on the left; the title, the step's text
   and the actions share the column beside it. */
@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table{max-width:1180px;height:100%;padding:0 18px 10px;overflow:hidden;
    grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr) auto;
    grid-template-areas:"hud tabs" "stage title" "stage body" "stage dock";column-gap:24px}
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.demo-lesson{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr)}
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud{align-self:center;justify-content:flex-start;gap:22px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-phases{justify-self:end;align-self:end;gap:22px;margin:0;border-bottom:0}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage{grid-row:2/5;margin:6px 0 0}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title{margin:12px 0 0}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title h1{font-size:2.1rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-body{padding:12px 0 8px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock{position:static;margin:0;padding:10px 0 0;background:none}
  html:not([data-expanded-text=true]) :is(.app-lesson,.first-steps) .lesson-dock:before{content:none}
  /* Practice Complete: the score and its actions beside the list. */
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.practice-summary{grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);grid-template-rows:auto auto auto auto minmax(0,1fr);grid-template-areas:"hud hud" "title body" "score body" "dock body" ". body";column-gap:48px}
  html:not([data-expanded-text=true]) .app-lesson>.practice-summary .lesson-body{grid-area:body;display:flex;flex-direction:column;min-height:0;margin:8px 0 0 -6px;padding:6px 4px 16px 6px;overflow-x:hidden;overflow-y:auto}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-title{margin-top:10px}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-dock{justify-content:flex-start;flex-wrap:wrap;margin-top:28px}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-dock>button.primary{margin-left:0}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-panel{margin-top:0}
}
/* Short landscape phones: the header floats, so the steps share its row; the
   felt runs from under that row to the foot of the screen. */
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table{grid-template-rows:58px auto minmax(0,1fr) auto;padding-bottom:8px;grid-template-columns:minmax(0,.84fr) minmax(0,1fr)}
  /* A demonstration's felt keeps room for seven 44 px tiles to a row. */
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.demo-lesson{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr)}
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud{padding:0 0 0 max(38px,calc(52px - 18px));min-height:58px}
  /* Lesson Notes shows its book alone here, so the lesson's place is never cut short. */
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud>button.quiet{position:relative;width:44px;padding:0;gap:0;justify-content:center}
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud>button.quiet>span{width:0;height:0;margin:0;overflow:hidden;font-size:0;line-height:0;white-space:nowrap}
  html:not([data-expanded-text=true]) .app-lesson .lesson-phases{align-self:stretch;padding-right:40px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-phases span{min-height:58px;font-size:.92rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage{margin:0;padding:8px;border-width:8px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage:has(>.stage-label){padding-top:26px}
  html:not([data-expanded-text=true]) .app-lesson .stage-label{top:8px;left:12px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title{margin:4px 0 0}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title h1{font-size:1.6rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title .lesson-eyebrow{font-size:.64rem}
  html:not([data-expanded-text=true]) .app-lesson :is(.lesson-body,.step-size),html:not([data-expanded-text=true]) .app-lesson .lesson-panel{gap:8px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-body{padding:8px 0 4px}
  html:not([data-expanded-text=true]) .app-lesson :is(.object-caption,.exercise-prompt){font-size:.93rem;line-height:1.4}
  html:not([data-expanded-text=true]) .app-lesson .coach-note{padding:10px 12px 10px 10px;gap:10px}
  html:not([data-expanded-text=true]) .app-lesson .coach-mark{width:28px;height:28px}
  html:not([data-expanded-text=true]) .app-lesson .coach-note p{font-size:.9rem;line-height:1.45}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choice{min-height:48px;padding:4px 10px}
  html:not([data-expanded-text=true]) .app-lesson .choice-letter{width:26px;height:26px;font-size:.92rem}
  html:not([data-expanded-text=true]) .app-lesson .choice-content{font-size:.88rem;gap:3px}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices{gap:6px}
  /* Tile answers keep their tiles on one row; the tile names stay in the
     button's accessible name but give their height to the answers. */
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions) .choice-content:has(.choice-tiles){flex-direction:row;align-items:center}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions) .choice-content>.choice-tiles{flex-wrap:nowrap}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions) .choice-content>.choice-tiles .tile{--t:40px}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions) .choice-content>.choice-tiles~span{flex:none;width:0;height:0;margin:0;padding:0;overflow:hidden;font-size:0;line-height:0;white-space:nowrap}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions)>.tutorial-choice:has(.choice-tiles){min-height:48px;padding-top:4px;padding-bottom:4px}
  /* Answers of three or more tiles take the full width, one to a row. */
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions):has(.choice-tiles .tile:nth-child(3)){grid-template-columns:minmax(0,1fr)}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-feedback>h2{font-size:1.3rem}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-feedback>p{font-size:.9rem;line-height:1.4}
  html:not([data-expanded-text=true]) .app-lesson .lesson-lead .feedback-mark{width:30px;height:30px}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-feedback:has(>.feedback-mark){grid-template-columns:30px minmax(0,1fr);column-gap:10px;row-gap:3px}
  html:not([data-expanded-text=true]) .app-lesson .answer-reveal{gap:3px;padding:8px 12px}
  html:not([data-expanded-text=true]) .app-lesson .answer-reveal p.reveal-answer{font-size:.95rem}
  html:not([data-expanded-text=true]) .app-lesson .reveal-tiles .tile{--t:32px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock{padding-top:6px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock>button{min-height:46px}
  html:not([data-expanded-text=true]) .app-lesson .practice-topics li{min-height:44px;padding:4px 2px}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score{margin-top:14px;gap:18px}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal{width:62px;height:62px}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal strong{font-size:1.8rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score h2{font-size:1.45rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score p{font-size:.92rem}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-dock{margin-top:16px}
}

/* The shortest landscape phones: the chapter's name gives way and the answers and
   actions take their 44 px minimum, so a question fits its column. */
@media (orientation:landscape) and (min-width:700px) and (max-height:400px){
  html:not([data-expanded-text=true]) .app-lesson .lesson-title .lesson-eyebrow{display:none}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title h1{font-size:1.45rem}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choice,html:not([data-expanded-text=true]) .app-lesson .tutorial-choices:not(.wait-completions)>.tutorial-choice:has(.choice-tiles){min-height:44px;padding-top:2px;padding-bottom:2px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock>button{min-height:44px}
}
/* Short portrait phones: tighter chrome, so the felt keeps its share. */
@media (orientation:portrait) and (max-height:760px){
  .app-lesson .lesson-title h1{font-size:1.6rem}
  .app-lesson .lesson-phases{gap:20px}
  .app-lesson .lesson-phases span{min-height:36px}
  .app-lesson .lesson-stage{margin-top:8px;padding:10px}
  .app-lesson .lesson-stage:has(>.stage-label){padding-top:24px}
  .app-lesson .stage-label{top:7px;left:12px}
  .app-lesson :is(.lesson-body,.step-size),.app-lesson .lesson-panel{gap:8px}
  .app-lesson .lesson-body{padding-top:10px}
  .app-lesson :is(.object-caption,.exercise-prompt){font-size:.93rem;line-height:1.42}
  .app-lesson .coach-note{padding:10px 12px 10px 10px;gap:10px}
  .app-lesson .coach-mark{width:28px;height:28px}
  .app-lesson .coach-note p{font-size:.9rem;line-height:1.45}
  .app-lesson .tutorial-choice{min-height:48px;padding:4px 8px;gap:8px}
  .app-lesson .choice-letter{width:24px;height:24px;font-size:.88rem}
  .app-lesson .choice-content{font-size:.88rem}
  .app-lesson .tutorial-choices:not(.wait-completions) .choice-content>.choice-tiles .tile{--t:40px}
  .app-lesson .tutorial-feedback>h2{font-size:1.25rem}
  .app-lesson .tutorial-feedback>p{font-size:.9rem;line-height:1.4}
  .app-lesson .tutorial-feedback:has(>.feedback-mark){grid-template-columns:30px minmax(0,1fr);column-gap:10px;row-gap:3px}
  .app-lesson .lesson-lead .feedback-mark{width:30px;height:30px}
  .app-lesson .answer-reveal{gap:3px;padding:8px 12px}
  .app-lesson .reveal-tiles .tile{--t:30px}
  .app-lesson .family-tile{gap:3px}
  .app-lesson .lesson-dock{padding-top:6px;padding-bottom:8px}
}
/* Phones held upright: a thinner rail and less padding, so the table gets the width;
   a question and its answers a little tighter, so they fit beside a demonstration. */
@media (orientation:portrait) and (max-width:520px){
  .app-lesson .exercise-prompt{font-size:.96rem;line-height:1.42}
  .app-lesson .tutorial-choice{min-height:50px}
  .app-lesson .lesson-stage{border-width:8px;padding:8px}
  .app-lesson .lesson-stage:has(>.stage-label){padding-top:26px}
  .app-lesson .stage-label{top:7px;left:12px}
}
/* The smallest phones (iPhone SE and below) cannot fit a readable felt and the
   step's text on one screen: like very large text, the lesson becomes one page
   that scrolls, the felt a fixed share of the window and the text box as tall as
   the lesson's longest step, so nothing moves; the actions stay pinned. */
@media (orientation:portrait) and (max-height:620px){
  .app-lesson .lesson-title .lesson-eyebrow{display:none}
  .app-lesson .lesson-title h1{font-size:1.4rem}
  .app-lesson .lesson-stage{margin-top:6px}
  .app-lesson>.teaching-table:not(.practice-summary){grid-template-rows:auto auto auto auto auto auto}
  .app-lesson .lesson-stage{height:min(max(260px,118vw),calc(var(--felt-room) * .9))}
  .app-lesson .demo-lesson>.lesson-stage{height:clamp(400px,calc(var(--felt-room) * .9),480px)}
  .app-lesson .lesson-body{min-height:var(--text-h,0px);overflow:visible;-webkit-mask-image:none;mask-image:none}
}

/* ---------- First Steps ---------- */
.surface>main.first-steps{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:max-content max-content minmax(max-content,1fr) max-content;grid-template-areas:"hud" "heading" "table" "dock";gap:0;width:100%;max-width:720px;margin:0 auto;padding:0 16px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scroll-padding:12px 0 96px;flex:1 1 auto;min-height:0;color:var(--ivory)}
.first-steps .first-progress{grid-area:hud;display:flex;align-items:center;min-height:44px;margin:0;padding:0;font:500 .98rem/1.2 var(--sans);font-variant-caps:all-small-caps;letter-spacing:.14em;color:var(--sage);text-align:left}
.first-steps .first-heading{grid-area:heading;display:grid;gap:6px;justify-items:start;width:auto;max-width:none;margin:0;padding:0;text-align:left}
.first-steps .first-heading h1{margin:0;font:500 2.05rem/1.06 var(--serif);color:var(--ivory)}
/* The step's text, then the same answer mark as the lessons. The box keeps its
   height, so the felt does not jump when feedback arrives. */
.first-steps .first-feedback-stack{display:grid;max-width:60ch;margin:8px 0 0}
.first-steps .first-feedback-stack>*{grid-area:1/1;align-self:start;width:auto;height:auto;min-height:0;margin:0;color:var(--ivory-2)}
.first-steps .feedback-ghost{visibility:hidden;pointer-events:none}
/* Short phones: tighter chrome so the step, the felt and its choices all fit
   the screen, even with Large text. */
@media (orientation:portrait) and (max-height:760px){
  main.first-steps .first-progress{min-height:34px}
  main.first-steps .first-heading .lesson-eyebrow{display:none}
  main.first-steps .first-heading h1{font-size:1.6rem}
  main.first-steps .first-feedback-stack{margin-top:6px}
  main.first-steps :is(.first-feedback,.feedback-ghost)>p{font-size:.92rem;line-height:1.42}
  main.first-steps :is(.first-feedback,.feedback-ghost)>strong{font-size:1.28rem}
  main.first-steps :is(.first-feedback,.feedback-ghost):has(>.feedback-mark){grid-template-columns:30px minmax(0,1fr);column-gap:10px;row-gap:3px}
  main.first-steps :is(.first-feedback,.feedback-ghost)>.feedback-mark{width:30px;height:30px}
  main.first-steps :is(.first-feedback,.feedback-ghost)>.feedback-mark .icon{width:15px;height:15px}
  main.first-steps .first-table{margin-top:12px;padding:14px 8px;gap:12px}
  main.first-steps .first-example{gap:8px}
  main.first-steps .first-example h2{font-size:1.14rem}
  main.first-steps .first-choices{gap:8px}
  /* 2 px side padding: "Characters" with Large text is 80 px in Firefox, 2 px wider than the 4 px padding left. */
  main.first-steps .first-choice{padding:8px 2px;gap:5px}
  main.first-steps .first-choice>span{font-size:.78rem}
  main.first-steps .first-choice .tile{--t:clamp(44px,18cqw,68px)}
  main.first-steps .first-arrangement .tile,main.first-steps .tile-space{--t:clamp(44px,15cqw,62px);width:var(--t)}
  main.first-steps>.lesson-dock{margin-top:12px;padding-top:10px;padding-bottom:10px}
  main.first-steps>.lesson-dock>button{min-height:44px}
}
@media (orientation:portrait) and (max-height:620px){
  main.first-steps .first-progress{min-height:26px}
  main.first-steps .first-heading h1{font-size:1.3rem}
  main.first-steps :is(.first-feedback,.feedback-ghost)>p{font-size:.84rem;line-height:1.34}
  main.first-steps :is(.first-feedback,.feedback-ghost)>strong{font-size:1.14rem}
  main.first-steps .first-table{margin-top:8px;padding:8px 6px;gap:6px}
  main.first-steps .first-example h2{font-size:1.02rem}
  main.first-steps .first-choice .tile,main.first-steps .first-arrangement .tile,main.first-steps .tile-space{--t:44px}
  main.first-steps>.lesson-dock{margin-top:6px;padding-top:6px;padding-bottom:6px}
}
/* Narrow phones: Start Again stays on one line; the dots give way to it. */
@media (max-width:374px){
  main.first-steps>.lesson-dock:has(.first-restart)>.lesson-dots{display:none}
  main.first-steps>.lesson-dock>button.primary{min-width:0;padding:0 18px}
  main.first-steps>.lesson-dock>button.first-restart{white-space:nowrap}
}
.first-steps .first-table{grid-area:table;align-self:stretch;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:26px;min-height:320px;max-height:560px;margin:14px 0 0;padding:26px 12px 24px;overflow:hidden;container-type:inline-size}
.first-steps .first-example{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;width:100%;height:auto;min-height:0}
.first-steps .first-example h2{max-width:none;margin:0;font:500 1.35rem/1.2 var(--serif);color:var(--ivory);text-align:center;text-shadow:0 2px 10px rgba(0,0,0,.5)}
.first-steps .first-arrangement{display:flex;align-items:flex-end;justify-content:center;gap:6px;padding:0}
.first-steps .first-arrangement .tile{--t:clamp(52px,17cqw,68px)}
.first-steps .tile-space{box-sizing:border-box;display:grid;place-items:center;width:clamp(52px,17cqw,68px);height:auto;min-width:0;aspect-ratio:1/1.52;border:1.5px dashed rgba(230,200,143,.6);border-radius:7px;background:rgba(6,20,13,.35);font:500 1.8rem/1 var(--serif);color:var(--gold-bright)}
.first-steps .first-choices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;width:100%;max-width:460px;margin:0;padding:0}
.first-steps .first-choice{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:8px;min-width:0;min-height:0;margin:0;padding:12px 6px 10px;border:1px solid rgba(230,200,143,.18);border-radius:var(--radius-card);background:rgba(6,20,13,.32);box-shadow:none;color:var(--ivory);cursor:pointer;transform:none;transition:border-color .18s,background .18s}
.first-steps .first-choice .tile{--t:clamp(52px,19cqw,78px);pointer-events:none}
.first-steps .first-choice>span{display:block;font:500 .82rem/1.25 var(--sans);color:var(--ivory-2);text-align:center}
.first-steps .first-choice.chosen{border-color:var(--gold-bright);background:rgba(20,44,31,.55);box-shadow:0 0 0 1px rgba(230,200,143,.3),0 0 18px rgba(230,190,110,.18)}
.first-steps .first-choice.chosen:not(.correct){border-color:rgba(224,137,122,.75);box-shadow:none}
.first-steps .first-choice.correct{border-color:var(--positive);opacity:1;box-shadow:0 0 0 1px rgba(143,208,162,.35),0 0 18px rgba(143,208,162,.18)}
.first-steps .first-choice:disabled{cursor:default;opacity:1}
.first-steps .first-choice:disabled:not(.correct){opacity:.55}
.first-steps .first-choice:is(.correct,.chosen):after{content:'';position:absolute;top:6px;right:6px;width:20px;height:20px;border-radius:50%;background:var(--positive) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 12 4 4 8-9' fill='none' stroke='%23102218' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat}
.first-steps .first-choice.chosen:not(.correct):after{background:#e0897a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m7 7 10 10M7 17 17 7' fill='none' stroke='%23240d09' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E") center/13px no-repeat}
@media (hover:hover) and (pointer:fine){.first-steps .first-choice:hover:not(:disabled){border-color:var(--gold-line-strong);background:rgba(20,44,31,.5)}}
.first-steps>.lesson-dock{grid-area:dock;position:sticky;bottom:0;z-index:3;display:flex;align-items:center;justify-content:flex-end;gap:10px;height:auto;min-height:auto;margin:24px -16px 0;padding:12px 16px 12px;background:none}
.first-steps>.lesson-dock>button{flex:0 1 auto;min-width:0;min-height:48px;margin:0;font-size:.95rem}
.first-steps>.lesson-dock>button.primary{min-width:148px;padding:0 22px}
.first-steps>.lesson-dock>.lesson-dots{flex:1 1 auto;justify-content:flex-start;padding-left:4px}
/* Starting again is a quiet link after the step's own action. */
.first-steps>.lesson-dock>button.first-restart{min-height:44px;padding:0 4px;font:500 .9rem/1 var(--sans);color:var(--gold);background:none;border:0;box-shadow:none}
@media (hover:hover) and (pointer:fine){.first-steps>.lesson-dock>button.first-restart:hover{color:var(--gold-bright);text-decoration:underline;text-underline-offset:4px}}
@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .surface>main.first-steps{max-width:1180px;height:100%;padding:0 18px 8px;overflow:hidden;grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;grid-template-areas:"hud ." "table heading" "table dock";column-gap:24px}
  html:not([data-expanded-text=true]) .first-steps .first-table{grid-row:2/4}
  html:not([data-expanded-text=true]) .first-steps .first-table{min-height:0;margin:6px 0 0;align-self:stretch;container-type:size}
  html:not([data-expanded-text=true]) .first-steps .first-heading{align-self:center;margin:0}
  html:not([data-expanded-text=true]) .first-steps>.lesson-dock{position:static;margin:0;padding:12px 0 0;background:none}
  html:not([data-expanded-text=true]) .first-steps>.lesson-dock:before{content:none}
  html:not([data-expanded-text=true]) .first-steps .first-arrangement .tile,html:not([data-expanded-text=true]) .first-steps .tile-space{--t:min(64px,calc((100cqh - 150px) / 1.52 / 2 + 20px));width:var(--t)}
  html:not([data-expanded-text=true]) .first-steps .first-choice .tile{--t:min(66px,calc((100cqh - 140px) / 1.52 / 2 + 10px))}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .surface>main.first-steps{grid-template-rows:58px minmax(0,1fr) auto}
  html:not([data-expanded-text=true]) .first-steps .first-progress{min-height:58px;padding-left:34px}
  html:not([data-expanded-text=true]) .first-steps .first-table{margin:0;gap:12px;padding:14px 10px}
  html:not([data-expanded-text=true]) .first-steps .first-example{gap:10px}
  html:not([data-expanded-text=true]) .first-steps .first-example h2{font-size:1.15rem}
  html:not([data-expanded-text=true]) .first-steps .first-choice{padding:8px 4px 6px;gap:5px}
  html:not([data-expanded-text=true]) .first-steps .first-heading h1{font-size:1.8rem}
}

/* ---------- Chow drills (practice and guided turn) ---------- */
.surface>main.play-screen{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:max-content max-content minmax(max-content,1fr) max-content max-content;grid-template-areas:"top" "instruction" "table" "actions" "note";gap:0;width:100%;max-width:720px;margin:0 auto;padding:0 16px 10px;overflow-x:hidden;overflow-y:auto;flex:1 1 auto;min-height:0;color:var(--ivory)}
.play-screen .play-top{grid-area:top;display:flex;align-items:center;min-height:44px;margin:0;font:500 .98rem/1.2 var(--sans);font-variant-caps:all-small-caps;letter-spacing:.14em;color:var(--sage)}
.play-screen .instruction{grid-area:instruction;display:grid;gap:6px;margin:0;padding:0;text-align:left}
.play-screen .instruction h1{margin:0;font:500 2rem/1.06 var(--serif);color:var(--ivory)}
.play-screen .instruction p{max-width:60ch;margin:0;font:400 1rem/1.5 var(--sans);color:var(--ivory-2)}
.play-screen .game-table{grid-area:table;display:flex;flex-direction:column;justify-content:flex-end;align-items:stretch;gap:10px;min-height:340px;margin:14px 0 0;padding:14px 10px 12px;overflow:hidden;container-type:inline-size}
.play-screen .game-table>.table-ring{display:none}
.play-screen .small-label{display:block;font:500 .64rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold-bright)}
.play-screen .discard-area{position:relative;z-index:1;display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:10px 0}
.play-screen .discard-area>.tile{--t:clamp(56px,17cqw,72px);transform:rotate(-4deg)}
.play-screen .source-label{font:400 .78rem/1.2 var(--sans);color:var(--ivory-2)}
.play-screen .meld{display:flex;gap:2px}
.play-screen .meld .tile{--t:clamp(40px,12cqw,52px)}
.play-screen .your-discard{position:absolute;right:14px;top:56px;z-index:2;display:grid;justify-items:center;gap:6px;text-align:center}
.play-screen .your-discard>.tile{--t:38px;margin:0}
.play-screen .opponent{position:absolute;z-index:1;display:flex;flex-direction:column;align-items:center;gap:6px;font:500 .72rem/1.2 var(--sans);color:var(--ivory-2);text-shadow:0 1px 3px #000}
.play-screen .opponent small{display:block;margin-top:2px;font-size:.62rem;color:var(--sage);text-align:center}
.play-screen .opponent.north{top:10px;left:50%;transform:translateX(-50%)}
.play-screen .opponent.west{top:64px;left:10px}
.play-screen .opponent.east{top:64px;right:10px}
.play-screen .concealed{display:flex;gap:2px}
.play-screen .concealed i{display:block;width:12px;height:19px;border:0;border-radius:3px 3px 2px 2px;background:linear-gradient(180deg,#2f7a58,#0f4431 62%,#f0e5cf 62%,#d9ccb2);box-shadow:0 2px 3px rgba(0,0,0,.5)}
html[data-portraits] .play-screen .concealed i{width:12px;height:auto;aspect-ratio:1/1.52;border-radius:0;background:var(--portrait-back) center/contain no-repeat;box-shadow:none;filter:drop-shadow(0 1.5px 1px rgba(0,0,0,.5))}
.play-screen :is(.opponent.west,.opponent.east) .concealed{display:none}
.play-screen .hand-area{position:relative;z-index:1;width:100%;margin:0}
.play-screen .hand-label{display:flex;justify-content:space-between;gap:10px;padding:0 4px 10px;font:500 .74rem/1.2 var(--sans);color:var(--ivory-2)}
.play-screen .hand-label span:first-child{letter-spacing:.14em;text-transform:uppercase;color:var(--gold-bright);font-size:.64rem}
.play-screen .hand-rack{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;padding:14px 4px 6px;margin:0}
.play-screen .hand-rack:after{display:none}
.play-screen .hand-rack .tile{--t:clamp(46px,calc((100cqw - 32px) / 5),64px);border-radius:7px;cursor:pointer;transition:transform .16s var(--ease-out),box-shadow .16s var(--ease-out)}
.play-screen.guided .hand-rack .tile{--t:min(48px,calc((100cqw - 32px) / 7))}
/* A chosen tile: the same tile lifted 8 px with a 2 px gold ring and a shadow,
   as in the game's hand. */
.play-screen .hand-rack .tile.selected{transform:translateY(-8px);box-shadow:0 0 0 2px var(--gold-bright),0 12px 18px rgba(0,0,0,.42),0 0 18px rgba(240,200,120,.3);filter:none}
.play-screen .hand-rack .tile.selected:after,.play-screen .hand-rack .tile.selected:before{content:none;display:none}
/* The lifted tile casts one shadow (the ring's), not a second tile-shaped one. */
.play-screen .hand-rack .tile.selected .tile-face{filter:none}
.play-screen .hand-rack .tile:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}
.play-screen .action-bar{grid-area:actions;display:grid;gap:10px;margin:0;padding:14px 0 0}
.play-screen .action-bar .feedback{display:block;max-width:none;min-height:1.5em;margin:0;font:400 .96rem/1.45 var(--sans);color:var(--ivory-2)}
.play-screen .action-bar .feedback.success{color:var(--positive)}
/* Hint sits beside the answer it helps with. */
.play-screen .game-actions{display:flex;justify-content:flex-start;gap:10px;width:100%}
.play-screen .game-actions>button{min-height:48px;flex:0 1 auto}
.play-screen .game-actions>button.primary{flex:1 1 auto;max-width:280px;margin-left:0}
.play-screen .scenario-note{grid-area:note;max-width:none;margin:10px 0 0;font:400 .76rem/1.4 var(--sans);color:var(--sage-2);text-align:left}
@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .surface>main.play-screen{max-width:1180px;height:100%;padding:0 18px 8px;overflow:hidden;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr) auto auto;grid-template-areas:"top ." "table instruction" "table ." "table actions" "table note";column-gap:24px}
  html:not([data-expanded-text=true]) .play-screen .game-table{min-height:0;margin:0;align-self:stretch}
  html:not([data-expanded-text=true]) .play-screen .instruction{margin-top:4px}
  html:not([data-expanded-text=true]) .play-screen .instruction h1{font-size:1.8rem}
  html:not([data-expanded-text=true]) .play-screen .hand-rack .tile{--t:min(58px,calc((100cqw - 32px) / 5))}
  html:not([data-expanded-text=true]) .play-screen.guided .hand-rack .tile{--t:min(44px,calc((100cqw - 30px) / 7))}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .surface>main.play-screen{grid-template-rows:58px auto minmax(0,1fr) auto auto}
  html:not([data-expanded-text=true]) .play-screen .play-top{min-height:58px;padding-left:34px}
  html:not([data-expanded-text=true]) .play-screen .game-table{grid-row:2/6;gap:6px;padding:8px 10px 10px}
  html:not([data-expanded-text=true]) .play-screen .discard-area{gap:6px;padding:4px 0}
}

/* ---------- Fit and fill ---------- */
/* The row the gold button opens carries a small tracked tag above its title. */
.curriculum-screen .topic-next{display:block;margin:0 0 1px;padding:0;font:600 .6rem/1.3 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold-bright);white-space:nowrap}
/* Beside the chapters (landscape and desktop) every row keeps one height, so the
   tag sits beside the title. */
@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .curriculum-screen .topic-copy:has(.topic-next){grid-template-columns:auto minmax(0,1fr);align-items:baseline;column-gap:10px}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-copy:has(.topic-next)>.topic-next{grid-column:1;grid-row:1;margin:0}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-copy:has(.topic-next)>strong{grid-column:2;grid-row:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-copy:has(.topic-next)>small{grid-column:1/-1}
}

/* Hint is an outlined button everywhere, including the Chow drills. */
.play-screen .game-actions>button.quiet{min-height:48px;padding:0 18px;border:1px solid var(--gold-line);background:linear-gradient(180deg,rgba(28,44,36,.9),rgba(14,24,19,.9));box-shadow:inset 0 1px 0 rgba(255,240,210,.06);color:var(--ivory)}
@media (hover:hover) and (pointer:fine){.play-screen .game-actions>button.quiet:hover:not(:disabled){border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(38,58,47,.95),rgba(18,30,24,.95))}}

.first-steps .first-table{align-self:stretch;min-height:0;max-height:none;gap:20px;padding:22px 12px 20px}
.first-steps .first-arrangement .tile{--t:clamp(56px,21cqw,84px)}
.first-steps .tile-space{width:clamp(56px,21cqw,84px)}
.first-steps .first-choice .tile{--t:clamp(56px,26cqw,96px)}
/* Tablets have room for the lesson's further paragraphs beside the example. */
.app-lesson .coach-more{display:none}
@media (min-width:700px) and (min-height:621px){
  html:not([data-expanded-text=true]) .app-lesson .coach-more{display:block}
}
/* Tablet landscape: larger tiles and type, so neither the felt nor the
   teaching column is a stretched phone layout. */
@media (orientation:landscape) and (min-width:700px) and (min-height:621px){
  html:not([data-expanded-text=true]) .app-lesson .lesson-title h1{font-size:2.6rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-eyebrow{font-size:.78rem}
  html:not([data-expanded-text=true]) .app-lesson :is(.object-caption,.exercise-prompt){font-size:1.14rem}
  html:not([data-expanded-text=true]) .app-lesson :is(.lesson-body,.step-size){gap:18px}
  html:not([data-expanded-text=true]) .app-lesson .coach-note{gap:16px;padding:20px 22px 20px 18px}
  html:not([data-expanded-text=true]) .app-lesson .coach-mark{width:38px;height:38px}
  html:not([data-expanded-text=true]) .app-lesson .coach-copy{gap:14px}
  html:not([data-expanded-text=true]) .app-lesson .coach-note p{font-size:1.1rem;line-height:1.6}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices{gap:10px}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choice{min-height:76px;padding:12px 16px 12px 14px}
  html:not([data-expanded-text=true]) .app-lesson .choice-letter{width:36px;height:36px;font-size:1.18rem}
  html:not([data-expanded-text=true]) .app-lesson .choice-content{font-size:1.06rem}
  html:not([data-expanded-text=true]) .app-lesson .choice-tiles .tile{--t:48px}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-feedback h2{font-size:2.1rem}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-feedback p{font-size:1.1rem}
  html:not([data-expanded-text=true]) .app-lesson .answer-reveal strong{font-size:1.5rem}
  html:not([data-expanded-text=true]) .app-lesson .reveal-tiles .tile{--t:52px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock>button{min-height:52px;font-size:1rem}
  html:not([data-expanded-text=true]) .app-lesson .stage-label{font-size:.78rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-set>span{font-size:.74rem}
  /* Chow drills: larger tiles; the instruction, answer and actions sit together
     at the top of the column, level with the felt. */
  html:not([data-expanded-text=true]) .surface>main.play-screen{grid-template-rows:auto auto auto auto minmax(0,1fr);grid-template-areas:"top ." "table instruction" "table actions" "table note" "table ."}
  html:not([data-expanded-text=true]) .play-screen .game-table{grid-row:2/6}
  html:not([data-expanded-text=true]) .play-screen .instruction{margin:0}
  html:not([data-expanded-text=true]) .play-screen .instruction h1{font-size:2.6rem}
  html:not([data-expanded-text=true]) .play-screen .instruction p{font-size:1.14rem}
  html:not([data-expanded-text=true]) .play-screen .action-bar{gap:14px;padding-top:22px}
  html:not([data-expanded-text=true]) .play-screen .action-bar .feedback{font-size:1.06rem}
  html:not([data-expanded-text=true]) .play-screen .game-actions>button{min-height:52px;font-size:1rem}
  html:not([data-expanded-text=true]) .play-screen .scenario-note{margin-top:16px;font-size:.84rem}
  html:not([data-expanded-text=true]) .play-screen .game-table{gap:18px;padding:22px 16px 20px}
  html:not([data-expanded-text=true]) .play-screen .small-label{font-size:.74rem}
  html:not([data-expanded-text=true]) .play-screen .source-label{font-size:.92rem}
  html:not([data-expanded-text=true]) .play-screen .hand-label{font-size:.86rem}
  html:not([data-expanded-text=true]) .play-screen .hand-label span:first-child{font-size:.74rem}
  html:not([data-expanded-text=true]) .play-screen .discard-area>.tile{--t:min(124px,24cqw)}
  html:not([data-expanded-text=true]) .play-screen .meld .tile{--t:min(88px,17cqw)}
  html:not([data-expanded-text=true]) .play-screen .hand-rack{gap:8px}
  html:not([data-expanded-text=true]) .play-screen .hand-rack .tile{--t:min(96px,calc((100cqw - 72px) / 5))}
  html:not([data-expanded-text=true]) .play-screen.guided .hand-rack .tile{--t:min(68px,calc((100cqw - 40px) / 7))}
}

/* ---------- Tablet portrait ---------- */
/* A tablet held upright is composed for itself, not a stretched phone column:
   a wider column, type and tiles about 1.2 times larger, a felt at least 40%
   of the height, answers and tips 24 px after it, and actions as wide as the
   content. */
@media (orientation:portrait) and (min-width:700px){
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table,
  html:not([data-expanded-text=true]) .surface>main:is(.first-steps,.play-screen,.curriculum-screen){max-width:880px;padding-left:36px;padding-right:36px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock{margin:0 -36px;padding:16px 36px 24px}
  html:not([data-expanded-text=true]) .first-steps>.lesson-dock{margin:32px -36px 0;padding:16px 36px 28px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-next{margin:32px -36px 0;padding:16px 36px 28px}
  html:not([data-expanded-text=true]) :is(.app-lesson .lesson-dock,.first-steps>.lesson-dock)>button{min-height:58px;padding:0 28px;font-size:1.12rem}
  html:not([data-expanded-text=true]) :is(.app-lesson .lesson-dock,.first-steps>.lesson-dock)>button.primary{min-width:210px}
  html:not([data-expanded-text=true]) .lesson-dots{gap:10px}
  html:not([data-expanded-text=true]) .lesson-dots i{width:7px;height:7px}
  html:not([data-expanded-text=true]) :is(.first-steps .first-progress,.play-screen .play-top){min-height:56px}
  html:not([data-expanded-text=true]) :is(.app-lesson .lesson-place,.first-steps .first-progress,.play-screen .play-top){font-size:1.14rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud{min-height:56px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud button.quiet{font-size:1.06rem}
  html:not([data-expanded-text=true]) :is(.lesson-eyebrow,.stage-label){font-size:.84rem}
  html:not([data-expanded-text=true]) :is(.app-lesson .lesson-title h1,.first-steps .first-heading h1,.play-screen .instruction h1){font-size:2.9rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-phases{margin-top:14px;gap:34px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-phases span{min-height:46px;font-size:1.16rem}
  html:not([data-expanded-text=true]) :is(.app-lesson .object-caption,.app-lesson .exercise-prompt,.first-steps :is(.first-feedback,.feedback-ghost) p,.play-screen .instruction p){font-size:1.2rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage{margin-top:20px;padding:24px 22px;border-width:12px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage:has(>.stage-label){padding-top:40px}
  html:not([data-expanded-text=true]) .app-lesson .stage-label{top:14px;left:20px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-body{padding:22px 0 8px}
  html:not([data-expanded-text=true]) .app-lesson :is(.lesson-body,.step-size),html:not([data-expanded-text=true]) .app-lesson .lesson-panel{gap:18px}
  html:not([data-expanded-text=true]) .app-lesson .coach-note{gap:18px;padding:22px 26px 22px 20px}
  html:not([data-expanded-text=true]) .app-lesson .coach-mark{width:42px;height:42px}
  html:not([data-expanded-text=true]) .app-lesson .coach-copy{gap:12px}
  html:not([data-expanded-text=true]) .app-lesson .coach-note p{font-size:1.16rem;line-height:1.6}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choices{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-choice{min-height:80px;gap:16px;padding:12px 18px 12px 16px}
  html:not([data-expanded-text=true]) .app-lesson .choice-letter{width:40px;height:40px;font-size:1.24rem}
  html:not([data-expanded-text=true]) .app-lesson .choice-content{font-size:1.16rem}
  html:not([data-expanded-text=true]) .app-lesson .choice-content:has(.choice-tiles){flex-direction:row;align-items:center;gap:14px}
  html:not([data-expanded-text=true]) .app-lesson .choice-tiles .tile{--t:52px}
  html:not([data-expanded-text=true]) .app-lesson .answer-cue{font-size:1.08rem}
  html:not([data-expanded-text=true]) :is(.app-lesson .tutorial-feedback,.first-steps :is(.first-feedback,.feedback-ghost))>:is(h2,strong){font-size:2rem}
  html:not([data-expanded-text=true]) .app-lesson .tutorial-feedback>p{font-size:1.18rem}
  html:not([data-expanded-text=true]) .app-lesson .answer-reveal p.reveal-answer{font-size:1.2rem}
  html:not([data-expanded-text=true]) .app-lesson .reveal-tiles .tile{--t:54px}
  /* The felt's zoom makes the example larger (step-fit.js). */
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table{--text-max:calc(var(--felt-room) * .5)}
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.demo-lesson{--text-max:calc(var(--felt-room) * .4)}
  /* Practice Complete: the actions follow the last question. */
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.practice-summary{grid-template-rows:repeat(5,max-content) minmax(0,1fr);grid-template-areas:"hud" "title" "score" "panel" "dock" "."}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-dock{margin-top:32px}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal{width:96px;height:96px}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal strong{font-size:2.8rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score h2{font-size:2.2rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score p{font-size:1.16rem}
  html:not([data-expanded-text=true]) .app-lesson .practice-topics li{min-height:60px}
  html:not([data-expanded-text=true]) .app-lesson .practice-topics li>span:not(.topic-number){font-size:1.3rem}
  html:not([data-expanded-text=true]) .app-lesson .practice-topics li strong{font-size:.92rem}
  /* First Steps: the tiles take the height the step leaves (about 45rem of
     text and actions), so every step fits the screen without scrolling. */
  html:not([data-expanded-text=true]) .first-steps{--first-fit:calc((100dvh - 45rem) / 1.52)}
  html:not([data-expanded-text=true]) .first-steps .first-table{min-height:40dvh;margin-top:22px;gap:30px;padding:34px 22px 32px;border-width:12px}
  html:not([data-expanded-text=true]) .first-steps .first-example h2{font-size:1.7rem}
  html:not([data-expanded-text=true]) .first-steps .first-arrangement .tile,html:not([data-expanded-text=true]) .first-steps .tile-space{--t:max(64px,min(150px,22cqw,calc(var(--first-fit) * .42)));width:var(--t)}
  html:not([data-expanded-text=true]) .first-steps .tile-space{font-size:2.6rem}
  html:not([data-expanded-text=true]) .first-steps .first-choices{max-width:none;gap:18px}
  html:not([data-expanded-text=true]) .first-steps .first-choice{padding:22px 8px 18px;gap:14px}
  html:not([data-expanded-text=true]) .first-steps .first-choice .tile{--t:max(72px,min(172px,calc((100cqw - 36px) / 3 - 40px),calc(var(--first-fit) * .56)))}
  html:not([data-expanded-text=true]) .first-steps .first-choice>span{font-size:1.08rem}
  /* The Chow drills. */
  html:not([data-expanded-text=true]) .play-screen .game-table{min-height:40dvh;margin-top:22px;gap:18px;padding:22px 16px 20px;border-width:12px}
  html:not([data-expanded-text=true]) .play-screen .discard-area>.tile{--t:min(124px,24cqw)}
  html:not([data-expanded-text=true]) .play-screen .meld .tile{--t:min(92px,17cqw)}
  html:not([data-expanded-text=true]) .play-screen .hand-rack{gap:8px}
  html:not([data-expanded-text=true]) .play-screen .hand-rack .tile{--t:min(108px,calc((100cqw - 72px) / 5))}
  html:not([data-expanded-text=true]) .play-screen.guided .hand-rack .tile{--t:min(76px,calc((100cqw - 40px) / 7))}
  html:not([data-expanded-text=true]) :is(.play-screen .small-label,.play-screen .hand-label span:first-child){font-size:.76rem}
  html:not([data-expanded-text=true]) :is(.play-screen .source-label,.play-screen .hand-label){font-size:.96rem}
  html:not([data-expanded-text=true]) .play-screen .action-bar{gap:14px;padding-top:24px}
  html:not([data-expanded-text=true]) .play-screen .action-bar .feedback{font-size:1.1rem}
  html:not([data-expanded-text=true]) .play-screen .game-actions>button{min-height:58px;padding:0 26px;font-size:1.1rem}
  html:not([data-expanded-text=true]) .play-screen .scenario-note{margin-top:16px;font-size:.9rem}
  /* The library. */
  html:not([data-expanded-text=true]) .curriculum-screen .learning-hud h1{font-size:3.2rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-deck{grid-auto-columns:minmax(180px,30%);gap:14px;margin:20px -36px 0;padding:4px 36px 14px;scroll-padding:0 36px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece{padding:16px 16px 14px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art .tile{--t:30px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece strong{font-size:1.32rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-count{font-size:.86rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading h2{font-size:2rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading p{font-size:1.04rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row{min-height:84px;gap:18px}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row strong{font-size:1.46rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row small{font-size:1rem}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-number{width:40px;height:40px;font-size:1.2rem}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button{min-height:62px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button.outline{font-size:1rem}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-next>.primary{min-height:58px;font-size:1.12rem}
}

/* ---------- Tablets and desktop ---------- */
/* Each learning screen is one composition: capped, centred and starting 24 px
   under the header. A lesson fits the window: the felt fills the height on the
   left, its example zoomed to fill it; the column beside it holds the title, the
   step's text and the actions at its foot, level with the felt's lower edge, so
   nothing moves; a long step scrolls inside the column under a fade. */
@media (orientation:landscape) and (min-width:1000px) and (min-height:621px){
  html:not([data-expanded-text=true]){--learn-max:1180px;--felt-min:420px;--felt-fill:clamp(var(--felt-min),calc(100dvh - 176px),720px);--learn-pad:clamp(18px,calc(2.4vw + 12px),44px);--learn-gutter:max(var(--learn-pad),calc((100% - var(--learn-max)) / 2 + var(--learn-pad)))}
  /* A step that makes a page just long enough to scroll must not nudge it
     sideways as the scrollbar arrives. */
  html:not([data-expanded-text=true]) .surface>main:is(.first-steps,.play-screen,.curriculum-screen,.scoring-screen){scrollbar-gutter:stable both-edges}
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table{flex:1 1 auto;width:100%;max-width:var(--learn-max);height:auto;min-height:0;max-height:none;margin:0 auto;padding:24px var(--learn-pad) 32px;overflow:hidden;
    grid-template-columns:minmax(0,1.12fr) minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr) auto;grid-template-areas:"hud tabs" "stage title" "stage body" "stage dock";column-gap:40px;align-items:stretch}
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.demo-lesson{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr)}
  html:not([data-expanded-text=true]) .surface>main:is(.first-steps,.play-screen){container-type:inline-size}
  html:not([data-expanded-text=true]) .app-lesson .lesson-hud{min-height:44px;margin-bottom:10px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-phases{align-self:center}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage{grid-row:2/5;align-self:stretch;height:auto;min-height:0;margin:0;padding:22px 18px 26px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-stage:has(>.stage-label){padding-top:46px}
  html:not([data-expanded-text=true]) .app-lesson .stage-label{top:20px;left:24px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title{margin:0}
  html:not([data-expanded-text=true]) .app-lesson .lesson-body{margin:0;padding:18px 0 12px}
  html:not([data-expanded-text=true]) .app-lesson .lesson-dock{margin:12px 0 0;padding:0}
  /* Practice Complete: title, score and actions beside the list and last question. */
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.practice-summary{grid-template-areas:"hud hud" "title body" "score body" "dock body" ". body";column-gap:56px}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-title{margin-top:6px}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-title h1{font-size:2.9rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score{margin-top:30px}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal{width:92px;height:92px}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal strong{font-size:2.7rem}
  html:not([data-expanded-text=true]) .app-lesson .practice-seal:before{inset:-46px}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score h2{font-size:2.1rem}
  html:not([data-expanded-text=true]) .app-lesson .teaching-table.practice-summary .practice-score p{font-size:1.1rem}
  html:not([data-expanded-text=true]) .app-lesson .practice-summary .lesson-dock{margin-top:36px}
  html:not([data-expanded-text=true]) .app-lesson .practice-topics li{min-height:56px}
  html:not([data-expanded-text=true]) .app-lesson .practice-topics li>span:not(.topic-number){font-size:1.22rem}
  /* First Steps and the drills: the felt holds larger tiles; the step sits beside it. */
  /* These screens are their own grid; they are as tall as their content (up to
     the window, then they scroll), so the felt keeps to its tiles. */
  html:not([data-expanded-text=true]) .surface>main:is(.first-steps,.play-screen){flex:0 1 auto;width:100%;max-width:none;height:auto;min-height:0;max-height:100%;margin:0;padding:24px var(--learn-gutter) 32px;overflow-x:hidden;overflow-y:auto;align-content:start;column-gap:24px}
  html:not([data-expanded-text=true]) .surface>main.first-steps{grid-template-rows:auto auto auto minmax(0,1fr);grid-template-areas:"hud ." "table heading" "table dock" "table ."}
  html:not([data-expanded-text=true]) .first-steps .first-progress{min-height:44px;margin-bottom:10px}
  html:not([data-expanded-text=true]) .first-steps .first-table{grid-row:2/5;align-self:start;min-height:min(var(--felt-fill),calc((100cqw - 24px) * .519 * .95));margin:0;gap:26px;padding:30px 22px;container-type:inline-size}
  html:not([data-expanded-text=true]) .first-steps .first-heading{align-self:start;margin:0}
  html:not([data-expanded-text=true]) .first-steps>.lesson-dock{align-self:start;margin:32px 0 0;padding:0}
  html:not([data-expanded-text=true]) .first-steps .first-example h2{font-size:1.6rem}
  html:not([data-expanded-text=true]) .first-steps .first-arrangement .tile,html:not([data-expanded-text=true]) .first-steps .tile-space{--t:min(110px,calc((100cqw - 60px) / 4));width:var(--t)}
  html:not([data-expanded-text=true]) .first-steps .first-choices{max-width:none;gap:14px}
  html:not([data-expanded-text=true]) .first-steps .first-choice{padding:16px 8px 14px;gap:12px}
  html:not([data-expanded-text=true]) .first-steps .first-choice .tile{--t:min(118px,calc((100cqw - 28px) / 3 - 40px))}
  html:not([data-expanded-text=true]) .first-steps .first-choice>span{font-size:1rem}
  html:not([data-expanded-text=true]) .first-steps .first-heading h1{font-size:2.6rem}
  html:not([data-expanded-text=true]) .first-steps :is(.first-feedback,.feedback-ghost) p{font-size:1.14rem}
  html:not([data-expanded-text=true]) .first-steps>.lesson-dock>button{min-height:52px;font-size:1rem}
  html:not([data-expanded-text=true]) .surface>main.play-screen{grid-template-rows:auto auto auto auto minmax(0,1fr);grid-template-areas:"top ." "table instruction" "table actions" "table note" "table ."}
  html:not([data-expanded-text=true]) .play-screen .play-top{min-height:44px;margin-bottom:10px}
  html:not([data-expanded-text=true]) .play-screen .game-table{grid-row:2/6;align-self:start;min-height:min(var(--felt-fill),calc((100cqw - 24px) * .524));margin:0;padding-top:30px}
  html:not([data-expanded-text=true]) .play-screen .instruction{align-self:start}
  html:not([data-expanded-text=true]) .play-screen .action-bar{padding-top:28px}
  /* Library: the chapter cards set the height of their row; the tray beside them
     is contained, so a chapter with longer text scrolls its list a little instead
     of stretching the cards and moving the tools below. */
  html:not([data-expanded-text=true]) .surface>main.curriculum-screen{flex:1 1 auto;width:100%;max-width:none;height:auto;max-height:none;margin:0;padding:24px var(--learn-gutter) 32px;overflow-x:hidden;overflow-y:auto;grid-template-rows:auto auto auto auto;align-content:start}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-hud{margin-bottom:6px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-hud h1{font-size:3rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-deck{gap:12px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece{min-height:210px;padding:16px 16px 14px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-tray{contain:size}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art .tile{--t:30px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece strong{font-size:1.28rem}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-count{font-size:.82rem}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-drawer{align-content:start}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading h2{font-size:1.9rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading p{font-size:.96rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row{min-height:70px}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row strong{font-size:1.36rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row small{font-size:.92rem}
  html:not([data-expanded-text=true]) .curriculum-screen .topic-number{width:38px;height:38px;font-size:1.12rem}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-dock>button{min-height:56px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-next>.primary{min-height:56px;font-size:1.05rem}
}
/* Desktop: a little wider, with slightly larger tiles on the felt. */
@media (orientation:landscape) and (min-width:1400px) and (min-height:700px){
  html:not([data-expanded-text=true]){--learn-max:1320px;--felt-min:470px}
  /* The library's cards and rows grow with the room. */
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece{min-height:232px;padding:18px 18px 16px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-art .tile{--t:34px}
  html:not([data-expanded-text=true]) .curriculum-screen .chapter-piece strong{font-size:1.4rem}
  html:not([data-expanded-text=true]) .curriculum-screen .tutorial-row{min-height:80px}
  html:not([data-expanded-text=true]) .curriculum-screen .tray-heading{padding-bottom:14px}
  html:not([data-expanded-text=true]) .curriculum-screen .learning-hud h1{font-size:3.3rem}
  html:not([data-expanded-text=true]) .app-lesson .lesson-title h1{font-size:2.9rem}
  html:not([data-expanded-text=true]) .play-screen .instruction h1,html:not([data-expanded-text=true]) .first-steps .first-heading h1{font-size:2.9rem}
}

/* Large desktops: the same composition, scaled up as one piece (type, tiles and
   felt together) so it fills the window instead of floating in empty room. */
@media (orientation:landscape) and (min-width:1700px) and (min-height:940px){
  html:not([data-expanded-text=true]):is([data-screen=learn],[data-screen=lesson],[data-screen=tutorial],[data-screen=first],[data-screen=practice],[data-screen=guided],[data-screen=scoring],[data-screen=drill],[data-screen=defence],[data-screen=movie]) .surface>main{zoom:1.28}
  /* Inside the zoom, viewport units grow with it; the felt still fits the window. */
  html:not([data-expanded-text=true]){--felt-fill:clamp(var(--felt-min),calc(100dvh / 1.28 - 176px),720px)}
}
/* The library needs about 845 px of height at that scale (a 1080 px window): on a shorter one it keeps its desktop
   size, where its two rows of chapters and the tools fit (director, 26 Sep: at 2000 x 990 they overlapped). */
@media (orientation:landscape) and (min-width:1700px) and (min-height:940px) and (max-height:1079px){
  html:not([data-expanded-text=true])[data-screen=learn] .surface>main{zoom:1}
}
@media (orientation:landscape) and (min-width:2300px) and (min-height:1250px){
  html:not([data-expanded-text=true]):is([data-screen=learn],[data-screen=lesson],[data-screen=tutorial],[data-screen=first],[data-screen=practice],[data-screen=guided],[data-screen=scoring],[data-screen=drill],[data-screen=defence],[data-screen=movie]) .surface>main{zoom:1.62}
  html:not([data-expanded-text=true]){--felt-fill:clamp(var(--felt-min),calc(100dvh / 1.62 - 176px),720px)}
}
/* ---------- Larger text ---------- */
/* Very large text cannot share one screen with the felt: a lesson becomes one
   page that scrolls, the felt a fixed share of the window, the text in full. */
html[data-expanded-text=true] .app-lesson>.teaching-table:not(.practice-summary){grid-template-rows:auto auto auto auto auto auto}
html[data-expanded-text=true] .app-lesson .lesson-stage{height:max(var(--felt-min),36vh)}
html[data-expanded-text=true] .app-lesson .demo-lesson>.lesson-stage{height:max(360px,70vh)}
html[data-expanded-text=true] .app-lesson .lesson-body{min-height:var(--text-h,0px);overflow:visible;-webkit-mask-image:none;mask-image:none}
html[data-expanded-text=true] .surface>main.scoring-screen{grid-template-rows:auto auto auto auto auto auto}
html[data-expanded-text=true] .scoring-screen .score-felt{height:max(var(--felt-min),36vh)}
html[data-expanded-text=true] .scoring-screen .score-work{min-height:var(--text-h,0px);overflow:visible;-webkit-mask-image:none;mask-image:none}
html[data-expanded-text=true] .scoring-screen>.lesson-dock{position:sticky;bottom:0;z-index:4;background:#090e0c}
html[data-expanded-text=true] .curriculum-screen .chapter-picker{grid-area:deck;display:grid;gap:6px;margin:14px 0 0;font:500 .7rem/1.2 var(--sans);color:var(--sage)}
html[data-expanded-text=true] .curriculum-screen .chapter-picker select{width:100%;min-height:48px;font-size:.8rem}
html[data-expanded-text=true] .curriculum-screen .chapter-deck{display:none}
/* The ticket takes its own row under the heading. */
html[data-expanded-text=true] .surface>main.curriculum-screen{grid-template-rows:max-content max-content max-content max-content max-content 1fr max-content;grid-template-areas:"hud" "bonus" "deck" "tray" "dock" "." "next"}
html[data-expanded-text=true] .curriculum-screen .bonus-ticket{grid-area:bonus;justify-self:stretch;max-width:none;margin:14px 0 0}
html[data-expanded-text=true] .curriculum-screen .learning-hud h1,html[data-expanded-text=true] :is(.app-lesson .lesson-title h1,.first-steps .first-heading h1,.play-screen .instruction h1){font-size:1.4rem}
html[data-expanded-text=true] .curriculum-screen .chapter-deck{grid-auto-columns:minmax(200px,70%)}
html[data-expanded-text=true] .app-lesson .tutorial-choices{grid-template-columns:minmax(0,1fr)}
html[data-expanded-text=true] :is(.app-lesson .coach-note p,.app-lesson .object-caption,.app-lesson .exercise-prompt,.app-lesson .tutorial-feedback p){font-size:.8rem}
html[data-expanded-text=true] .app-lesson .lesson-phases{gap:14px;overflow-x:auto}
html[data-expanded-text=true] .app-lesson .lesson-phases span{font-size:.7rem}
/* Very large text: the library's tools stack, one to a row. */
html[data-expanded-text=true] .curriculum-screen .learning-dock{grid-template-columns:minmax(0,1fr)}

/* ---------- What Would You Discard? ---------- */
/* The lesson layout. The felt holds two fixed areas, so nothing moves within a
   problem and every problem of a set takes the same zoom: above, two rows for the
   discards so far (after answering, the improving tiles for one discard); below,
   your fourteen tiles in two rows, each with room for its count underneath. */
.drill-screen .lesson-stage{padding:8px 6px}
.drill-screen .drill-felt{--fit-max:2.2;display:flex;flex-direction:column;align-items:center;gap:8px}
.drill-screen .drill-label{max-width:100%;margin:0 0 5px;overflow:hidden;font:500 .6rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-bright);text-align:center;text-overflow:ellipsis;text-shadow:0 1px 3px rgba(0,0,0,.6);white-space:nowrap}
/* Thirteen small tiles to a row, smaller still where the felt is narrow. */
.drill-screen .drill-shelf{display:flex;flex-direction:column;align-items:center;width:100%;max-width:calc(13 * 24px + 12 * 2px + 1px);container-type:inline-size}
.drill-screen .drill-shelf-tiles{--s:min(24px,calc((100cqw - 25px) / 13));display:flex;flex-wrap:wrap;justify-content:center;align-content:flex-start;gap:3px 2px;width:100%;height:calc(2 * var(--s) * 1.52 + 3px)}
.drill-screen .drill-shelf .tile{--t:var(--s)}
.drill-screen .drill-chip{position:relative;display:block;flex:none}
.drill-screen .drill-chip>b{position:absolute;right:-3px;bottom:-2px;z-index:1;min-width:15px;padding:1px 3px;border-radius:999px;background:#0b1511;box-shadow:0 0 0 1px var(--gold-line-strong);font:600 .58rem/1.2 var(--sans);color:var(--gold-bright);text-align:center}
.drill-screen .drill-none{align-self:center;margin:auto;font:400 .8rem/1.4 var(--sans);color:var(--ivory-2)}
.drill-screen .drill-hand{display:flex;flex-direction:column;align-items:center;width:100%}
/* Seven to a row where the screen allows (a pixel spare: Firefox rounds lengths under zoom,
   and an exact fit there wraps the seventh tile); a narrow phone wraps rather than let a tile
   drop under 44 px. */
.drill-screen .drill-rack{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 1px;width:100%;max-width:calc(7 * 48px + 6 * 1px + 1px)}
.drill-screen .drill-tile{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;width:48px;min-width:0;min-height:0;margin:0;padding:0;border:0;border-radius:7px;background:none;box-shadow:none;color:var(--ivory);cursor:pointer;transform:none}
.drill-screen .drill-tile .tile{--t:48px;transition:transform .15s var(--ease-out,ease)}
.drill-screen .drill-tile.chosen .tile{transform:translateY(-4px)}
.drill-screen .drill-tile:is(.chosen,.is-shown) .tile-face{border-radius:6px;outline:2px solid var(--gold-bright);outline-offset:1px}
.drill-screen .drill-count{display:block;min-width:26px;min-height:1.2em;padding:0 5px;border-radius:999px;font:600 .8rem/1.2 var(--sans);color:var(--ivory);text-align:center}
.drill-screen .drill-note{display:block;min-height:1.1em;font:600 .5rem/1.1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--sage)}
.drill-screen .drill-tile.is-best .drill-count{background:var(--primary-fill);color:var(--ink-on-gold)}
.drill-screen .drill-tile.is-ready .drill-note{color:var(--positive)}
.drill-screen .drill-tile.is-back .drill-count{color:var(--sage);opacity:.75}
.drill-screen .drill-tag{position:absolute;top:-8px;left:50%;z-index:2;transform:translateX(-50%);padding:2px 5px 1px;border-radius:999px;background:var(--gold-bright);box-shadow:0 2px 6px rgba(0,0,0,.45);font:700 .48rem/1.2 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-on-gold);white-space:nowrap;pointer-events:none}
.drill-screen .drill-tile.chosen .drill-tag{top:-12px}
.drill-screen .drill-guide{margin:0;padding:8px 12px;border-left:2px solid var(--gold-line-strong);font:400 .9rem/1.42 var(--sans);color:var(--ivory-2)}
.drill-screen .drill-guide strong{font-weight:600;color:var(--ivory)}
@media (hover:hover) and (pointer:fine){.drill-screen .drill-tile:hover .tile{transform:translateY(-2px)}}
/* Short landscape phones: like a demonstration, the felt keeps room for seven 44 px
   tiles to a row; the discards shrink a little and the words under the counts give
   their line to the tiles (each tile's name still says "ready" or "a step further
   from ready"). */
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.discard-drill{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr)}
  html:not([data-expanded-text=true]) .drill-screen .lesson-stage{padding:6px 4px}
}
@media (orientation:landscape) and (max-height:500px){
  .drill-screen .drill-note{display:none}
  .drill-screen .drill-felt{gap:6px}
  .drill-screen .drill-label{margin-bottom:3px}
  .drill-screen .drill-shelf-tiles{--s:min(22px,calc((100cqw - 25px) / 13))}
  .drill-screen .drill-rack{row-gap:4px}
  .drill-screen .drill-tile{gap:2px}
}
/* The smallest phones scroll as one page: the felt takes the height its wrapped rows need. */
@media (orientation:portrait) and (max-height:620px){.drill-screen .lesson-stage{height:max(400px,min(max(260px,118vw),calc(var(--felt-room) * .9)))}}
@media (prefers-reduced-motion:reduce){.drill-screen .drill-tile .tile{transition:none}}
/* The results list: your discard, and the best one when yours was not. Ten rows. */
.app-lesson .drill-summary .practice-topics li{min-height:44px;padding:4px 2px}
.drill-summary .practice-topics li>span:not(.topic-number)>small{display:block;margin-top:1px;font:400 .8rem/1.25 var(--sans);color:var(--sage)}
/* The lesson's finish: try the skill in a hand. */
.app-lesson .lesson-try-hand{display:flex;justify-content:flex-start}
.app-lesson .lesson-try-hand>button{min-height:44px;margin:0;padding:0 16px;gap:8px;font-size:.92rem}
.app-lesson .lesson-try-hand .icon{width:16px;height:16px;color:var(--gold)}

/* ---------- Read The Discards and Push Or Fold ---------- */
/* The lesson layout again. The felt shows the table as everyone sees it: a line of
   how things stand (tiles left to draw; in Push Or Fold, your hand), then each other
   player (left, opposite, right) and you. Each has a name column beside one flowing
   row: sets, bonus tiles and hidden tiles face down (Read The Discards), then the
   discards on a darker strip of their own. It is information, never tapped, so it zooms to fill the felt; the answers
   are cards in the text box. The question and the answer show the same pieces
   (hidden tiles only turn face up), so nothing moves. */
.defence-screen .lesson-stage{padding:8px}
/* Large text: the place's line box is a pixel taller than its row; give it room. */
.defence-screen .lesson-place{padding-block:1px}
.defence-felt{--fit-max:2;--s:22px;display:flex;flex-direction:column;align-items:stretch;gap:4px;padding:0}
.defence-felt .tile{--t:var(--s)}
.defence-felt .tile-back{display:block;box-sizing:border-box;flex:none;width:var(--s);height:auto;aspect-ratio:1/1.52;min-height:0;margin:0;border:1px solid var(--theme-back-edge,#6c977c);border-radius:3px;background:linear-gradient(110deg,var(--theme-back-lit,#2e6b51),var(--theme-back,#0a352a));box-shadow:none}
html[data-portraits] .defence-felt .tile-back{border:0;border-radius:0;background:var(--portrait-back) center/contain no-repeat;filter:drop-shadow(0 2px 1.5px rgba(0,0,0,.42))}
.defence-felt .defence-status{display:flex;flex-wrap:wrap;justify-content:center;gap:2px 14px;margin:0;font:500 .56rem/1.25 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--gold-bright);text-align:center;text-shadow:0 1px 3px rgba(0,0,0,.6)}
.defence-felt .defence-status strong{font-weight:700}
.defence-felt .defence-seats{display:flex;flex-direction:column;gap:4px}
.defence-felt :is(.defence-seat,.defence-you){display:grid;grid-template-columns:58px minmax(0,1fr);align-items:start;column-gap:6px;min-width:0;padding:4px 5px;border-radius:8px;background:rgba(3,14,9,.2);box-shadow:inset 0 0 0 1px rgba(201,168,106,.16)}
.defence-felt .defence-you{background:rgba(3,14,9,.3);box-shadow:inset 0 0 0 1px rgba(201,168,106,.3)}
.defence-felt .defence-seat.is-target{box-shadow:inset 0 0 0 1.5px var(--gold-bright),0 0 14px rgba(230,190,110,.18)}
.defence-felt .defence-label{display:flex;flex-direction:column;align-items:flex-start;gap:1px;min-width:0;margin:0;padding-top:1px;font:500 .52rem/1.2 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--sage)}
.defence-felt .defence-label strong{font-weight:700;font-size:.64rem;letter-spacing:.12em;color:var(--gold-bright)}
.defence-felt .defence-label em{font-style:normal;font-weight:600;color:var(--ivory-2)}
.defence-felt .defence-seat.is-threat :is(.defence-count,.defence-threat){color:#f0b3a5}
/* The hidden hand's distance from ready appears once you answer; its line is kept. */
.defence-felt .defence-truth{min-height:1.2em;color:var(--positive)}
.defence-felt .defence-flow{display:flex;flex-wrap:wrap;align-items:flex-start;gap:3px 5px;min-width:0;min-height:calc(var(--s) * 1.52)}
.defence-felt .defence-set{display:flex;flex:none;gap:1px}
.defence-felt .defence-river{display:flex;flex-wrap:wrap;flex:1 1 100%;gap:3px 1px;min-width:0;min-height:calc(var(--s) * 1.52);padding:2px 3px;border-radius:4px;background:rgba(0,0,0,.2)}
.defence-felt .defence-discard{display:block;flex:none}
.defence-felt .defence-discard.is-claimed{opacity:.42}
.defence-felt .defence-tiles{flex-wrap:wrap;row-gap:3px}
.defence-felt .defence-hand{padding-top:7px}
.defence-felt .defence-own{position:relative;display:block;flex:none}
.defence-felt .defence-own:is(.is-guide,.is-likely) .tile-face,.defence-felt .defence-own.is-offered .tile-face{border-radius:4px;outline:1.5px solid var(--gold-bright);outline-offset:1px}
.defence-felt .defence-own:is(.is-push,.is-safest) .tile-face{border-radius:4px;outline:1.5px dashed rgba(230,200,143,.8);outline-offset:1px}
.defence-felt .defence-tag{position:absolute;top:-8px;left:50%;z-index:2;transform:translateX(-50%);padding:1px 3px 0;border-radius:999px;background:var(--gold-bright);box-shadow:0 2px 5px rgba(0,0,0,.45);font:700 .4rem/1.2 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-on-gold);white-space:nowrap;pointer-events:none}
.defence-felt .defence-own:is(.is-push,.is-safest) .defence-tag{background:#e9dcc0}
/* Answers: three short cards side by side (players or tiles); the plans one to a row. */
.defence-screen .defence-choices{grid-template-columns:repeat(3,minmax(0,1fr))}
/* The plans: Push and Push, But Avoid side by side, Fold under them across the row. */
.defence-screen .fold-drill .defence-choices{grid-template-columns:repeat(2,minmax(0,1fr))}
.defence-screen .fold-drill .defence-choices .tutorial-choice:last-child{grid-column:1/-1}
.defence-screen .defence-choices .tutorial-choice{min-height:48px;gap:8px;padding:6px 8px}
.defence-screen .fold-drill .defence-choices .tutorial-choice{min-height:46px}
.defence-screen .defence-choices .choice-content small{display:block;margin-top:1px;font:400 .74rem/1.2 var(--sans);color:var(--sage)}
.defence-screen .defence-choices .choice-tiles .tile{--t:30px}
.defence-screen .drill-guide{margin:0;padding:8px 12px;border-left:2px solid var(--gold-line-strong);font:400 .9rem/1.42 var(--sans);color:var(--ivory-2)}
.defence-screen .drill-guide strong{font-weight:600;color:var(--ivory)}
/* Large text: answers two to a row where they fit, and the text box takes a little
   more of the screen from the felt. */
html[data-text=large]:not([data-expanded-text=true]) .defence-screen .defence-choices{grid-template-columns:repeat(auto-fit,minmax(min(100%,150px),1fr))}
html[data-text=large]:not([data-expanded-text=true]) .app-lesson>.teaching-table.defence-drill{--text-max:calc(var(--felt-room) * .5)}
/* Short screens: the verdict and the guide's words set a little tighter, so the
   longest answer fits its box without scrolling. */
@media (max-height:700px){
  html:not([data-expanded-text=true]) .defence-screen .tutorial-feedback>p{font-size:.92rem;line-height:1.4}
  html:not([data-expanded-text=true]) .defence-screen .drill-guide{font-size:.86rem;line-height:1.38}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.defence-drill{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr)}
  html:not([data-expanded-text=true]) .defence-screen .lesson-stage{padding:6px}
  html:not([data-expanded-text=true]) .defence-screen .lesson-body{gap:10px;padding-top:10px}
  html:not([data-expanded-text=true]) .defence-screen .tutorial-feedback>h2{font-size:1.3rem}
  html:not([data-expanded-text=true]) .defence-screen .lesson-title h1{font-size:1.5rem}
  html:not([data-expanded-text=true]) .defence-screen .drill-guide{padding:4px 10px}
}
/* The smallest phones scroll as one page: the felt takes the height its rows need. */
@media (orientation:portrait) and (max-height:620px){.defence-screen .lesson-stage{height:max(360px,min(max(260px,110vw),calc(var(--felt-room) * .9)))}}
.app-lesson .defence-summary .practice-topics li{min-height:44px;padding:4px 2px}
/* The answer's tick keeps its ring and glow at the edge of the step text, which scrolls and so clips
   sideways (director, 26 Sep: the tick was cut off): a little room either side, offset so nothing moves.
   Specific enough to outlast the per-size paddings above; the practice summary sets its own. */
html .app-lesson .lesson-body:not(.practice-summary .lesson-body){padding-inline:12px;margin-inline:-12px}

/* src/riichi-learn.css */
/* Learn Riichi (src/riichi-learn-view.js). Its screens use the Singapore Learn's markup and styles
   (learn.css: the library, the lesson layout, the drill); these rules only add what Riichi needs:
   ten chapters in the deck, its practice tools in the dock, the felt's hands, rivers, chips and
   indicators, and the 3D table for a demonstration. Scoped to [data-track=riichi]. */

/* ---------- The felt ---------- */
/* Nothing on the felt is tapped (tiles only name themselves), so a full felt may zoom well down. */
.app-lesson .rl-felt{--fit-max:3.2;--fit-min:.3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;max-width:100%;margin:0;padding:0}
.app-lesson .rl-felt.is-empty{--fit-max:5}
.app-lesson .rl-felt .tile{--t:44px}
.app-lesson .rl-felt .hand-groups .tile{--t:40px}
.app-lesson .rl-felt .rl-groups{max-width:calc(4 * 3 * 42px + 3 * 18px)}
.app-lesson .rl-felt .teaching-set.is-called>div{padding:3px 4px;border-radius:6px;background:rgba(0,0,0,.22);box-shadow:inset 0 0 0 1px rgba(214,180,120,.28)}
.app-lesson .rl-felt .rl-win-set>span{color:var(--ivory-2)}
.app-lesson .rl-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 8px;max-width:520px}
.app-lesson .rl-chips>span{padding:5px 11px;border:1px solid var(--gold-line);border-radius:999px;background:rgba(8,18,13,.5);font:500 .74rem/1.2 var(--sans);letter-spacing:.06em;color:var(--ivory);white-space:nowrap}
.app-lesson .rl-label{display:block;margin:0 0 6px;text-align:center;font:500 .66rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold-bright);text-shadow:0 1px 3px rgba(0,0,0,.6)}
.app-lesson .rl-hand>div{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;gap:6px 3px;max-width:calc(7 * 44px + 6 * 3px + 1px)}
.app-lesson .rl-hand:not(.is-full)>div{max-width:none}
.app-lesson .rl-win{display:inline-flex;align-items:center;gap:4px;margin-left:8px}
.app-lesson .rl-win>.icon{width:16px;height:16px;color:var(--gold-bright)}
.app-lesson .rl-win .tile{box-shadow:0 0 0 2px var(--gold-bright),0 6px 14px rgba(0,0,0,.35)}
.app-lesson .rl-river>div{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:4px 3px;max-width:calc(6 * 38px + 20px);padding:6px 8px;border-radius:10px;background:rgba(0,0,0,.2);box-shadow:inset 0 0 0 1px rgba(214,180,120,.2)}
.app-lesson .rl-river .tile{--t:36px}
.app-lesson .rl-river-tile{display:inline-flex}
.app-lesson .rl-river-tile.is-sideways{margin:0 10px}
.app-lesson .rl-river-tile.is-sideways .tile{transform:rotate(90deg)}
.app-lesson .rl-indicators .tile{--t:44px}
.app-lesson .rl-standings{display:grid;gap:6px;min-width:240px;margin:0;padding:0;list-style:none}
.app-lesson .rl-standings li{display:flex;justify-content:space-between;gap:24px;padding:8px 14px;border-radius:10px;background:rgba(0,0,0,.22);font:500 .95rem/1.2 var(--sans);color:var(--ivory)}
.app-lesson .rl-standings li.is-you{box-shadow:inset 0 0 0 1px var(--gold-bright);background:rgba(40,70,52,.6)}
.app-lesson .rl-standings strong{font-variant-numeric:tabular-nums}
.app-lesson .rl-rounds{display:grid;grid-template-columns:repeat(4,auto);gap:6px}
.app-lesson .rl-rounds>span{padding:6px 10px;border:1px solid var(--gold-line);border-radius:8px;font:500 .8rem/1.2 var(--sans);color:var(--ivory-2);text-align:center}
.app-lesson .rl-rounds>span.is-on{border-color:var(--gold-bright);color:var(--ivory);background:rgba(40,70,52,.6)}
.app-lesson .rl-points{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;gap:14px 22px;font:500 .86rem/1.25 var(--sans);color:var(--ivory)}
.app-lesson .rl-points table{border-collapse:collapse}
.app-lesson .rl-points caption{padding-bottom:6px;font:500 .66rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold-bright)}
.app-lesson .rl-points :is(th,td){padding:5px 12px;border-bottom:1px solid rgba(214,180,120,.18);text-align:right;font-variant-numeric:tabular-nums}
.app-lesson .rl-points thead th{color:var(--gold)}
.app-lesson .rl-points tbody th{text-align:left;color:var(--ivory-2)}
.app-lesson .rl-points ul{display:grid;gap:4px;margin:0;padding:0;list-style:none}
.app-lesson .rl-points li{display:grid;grid-template-columns:auto auto auto;gap:10px;align-items:baseline;justify-content:space-between;padding:4px 10px;border-radius:8px;background:rgba(0,0,0,.2)}
.app-lesson .rl-points li span{color:var(--ivory-2)}
.app-lesson .rl-points li em{font-style:normal;font-variant-numeric:tabular-nums;color:var(--gold-bright)}

/* ---------- A demonstration on the 3D table ---------- */
.app-lesson .rl-table3d{position:absolute;inset:0;border-radius:inherit;overflow:hidden}
.app-lesson .rl-table3d .physical-table{position:absolute;inset:0;--table-top:6px}
.app-lesson .rl-table3d .physical-table canvas{display:block;width:100%;height:100%}
.app-lesson .rl-table3d .rl-demo-fallback{display:none;position:absolute;inset:0;place-items:center}
.app-lesson .rl-table3d:has(.physical-table[data-ready=false]) .rl-demo-fallback{display:grid}
.app-lesson .rl-demo-text p{margin:0}
.app-lesson .rl-demo-text .demo-label{margin-bottom:6px}
.app-lesson .rl-demo-tiles{display:flex;flex-wrap:wrap;gap:6px;justify-content:center}
.app-lesson .rl-demo-tiles .tile{--t:40px}
.app-lesson .rl-demo-tiles:empty{display:none}
.app-lesson .lesson-dock .rl-skip{min-height:44px}

/* ---------- The library: ten chapters, and the practice tools under them ---------- */
.curriculum-screen.rl-library .rl-basics{color:var(--ivory-2)}
.curriculum-screen.rl-library .tutorial-row.is-basics:not(.is-correct):not(.is-retry) strong{color:var(--ivory-2)}
@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-deck{grid-template-columns:repeat(5,minmax(0,1fr))}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-piece{padding:8px 9px}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-piece strong{font-size:.92rem;line-height:1.12}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-art .tile{--t:18px}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-practice-five]{grid-area:practise}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-practice-drill]{grid-area:drill}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-practice-read]{grid-area:read}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-practice-fold]{grid-area:fold;margin-right:12px}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-practice-count]{grid-area:count}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-glossary]{grid-area:terms;margin-right:12px}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  /* Ten chapters in two rows of five: each card keeps its number, its name and its bar. */
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-hud h1{white-space:nowrap;font-size:1.7rem}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-hud .eyebrow{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-art,
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-count{display:none}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-piece{padding:6px 7px;align-content:start;gap:3px}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-number{font-size:.56rem;letter-spacing:.06em}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-piece strong{font-size:.8rem;line-height:1.12;overflow-wrap:anywhere;hyphens:auto}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .tutorial-row strong{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:1.05rem}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .tutorial-row .topic-next{display:none}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-practice-count]{width:auto;margin-left:12px}
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .learning-dock>[data-action=rl-glossary]{margin-right:0}
}
/* What Would You Discard? on the narrowest phones: seven 44 px tiles to a row, so the hand keeps
   to two rows and the discards above it stay in view. */
@media (max-width:400px){
  .drill-screen.rl-drill .drill-rack{max-width:calc(7 * 44px + 1px);column-gap:0}
  .drill-screen.rl-drill .drill-tile{width:44px}
  .drill-screen.rl-drill .drill-tile .tile{--t:44px}
}
@media (max-width:400px) and (max-height:700px){
  .drill-screen.rl-drill .drill-felt{gap:3px}
  .drill-screen.rl-drill .drill-label{margin-bottom:2px}
  .drill-screen.rl-drill .drill-shelf-tiles{--s:min(17px,calc((100cqw - 25px) / 13));gap:2px}
  .drill-screen.rl-drill .drill-rack{row-gap:1px}
  .drill-screen.rl-drill .drill-tile{gap:0}
}
/* A phone held upright: "Learn Riichi" and the way-in ticket share the heading's row. */
@media (max-width:520px){
  .curriculum-screen.rl-library .learning-hud h1{font-size:2.05rem}
  .curriculum-screen.rl-library .rl-path{max-width:min(50%,210px);padding:4px 12px 4px 10px;gap:7px}
  .curriculum-screen.rl-library .rl-path strong{font-size:.92rem}
  .curriculum-screen.rl-library .rl-path>.icon{width:18px;height:18px}
}
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .curriculum-screen.rl-library .chapter-number{white-space:nowrap;letter-spacing:.1em}
}
/* The demonstration has no hand strip: the table uses the whole stage, and a stage held upright takes the
   deep cloth (600 wide), which fills it, rather than the wide cloth letterboxed small. */
.app-lesson .rl-table3d .physical-table{--hand-reserve:4px}
@media (orientation:portrait){.app-lesson .rl-table3d .physical-table{--table-cloth:deep}}

/* src/teach.css */
/* Teaching surfaces: the lesson table demonstrations, Count This Hand and the
   teaching dialogs (hand guide, glossary, lesson notes, round details).
   One material world with result.css: lamplit felt under a walnut rail,
   rendered tile portraits, ringed gold medallions, serif heads, hairline gold.
   Legacy rules still match many of these class names, so each restyled
   element sets its complete property set. */

/* ---------- Shared materials ---------- */
/* Cormorant's old-style figures read as letters in counts and scores ("13"
   looks like "ı3"); use lining figures. Important because the font shorthand
   used below resets font-variant-numeric. */
:is(.table-demo,.scoring-screen,#overlay .dialog-body),:is(.table-demo,.scoring-screen,#overlay .dialog-body) *{font-variant-numeric:lining-nums!important}

/* A felt table seen from above: lamplit centre, vignette, varnished rail. */
.score-felt,#overlay .winning-felt{
  --rail:9px;
  position:relative;box-sizing:border-box;min-width:0;margin:0;padding:16px 12px;
  border:var(--rail) solid transparent;border-radius:22px;
  background:
    radial-gradient(70% 55% at 50% 40%,rgba(255,226,170,.15),transparent 72%) padding-box,
    radial-gradient(135% 115% at 50% 40%,transparent 48%,rgba(2,10,6,.62) 100%) padding-box,
    url('/felt-v1.webp') center/300px padding-box,
    linear-gradient(#1b4a31,#1b4a31) padding-box,
    linear-gradient(180deg,rgba(255,224,186,.3),rgba(255,224,186,0) 22%,rgba(0,0,0,0) 70%,rgba(0,0,0,.42)) border-box,
    url('/walnut-v1.webp') center/220px border-box,
    linear-gradient(#4a2e1c,#4a2e1c) border-box;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5),inset 0 10px 22px rgba(0,0,0,.42),inset 0 -6px 16px rgba(0,0,0,.28),0 0 0 1px rgba(0,0,0,.55),0 14px 30px rgba(0,0,0,.45);
  color:var(--ivory);text-align:center;text-shadow:0 1px 3px rgba(0,0,0,.55)}
/* Lacquer highlight along the rail's outer edge. */
.score-felt:before,#overlay .winning-felt:before{content:'';position:absolute;inset:calc(var(--rail) * -1);border-radius:inherit;pointer-events:none;box-shadow:inset 0 1px 0 rgba(255,232,200,.38),inset 0 -1px 0 rgba(0,0,0,.55),inset 1px 0 0 rgba(255,232,200,.1),inset -1px 0 0 rgba(255,232,200,.1)}

/* Rendered tile portraits: the true 1:1.52 shape, no legacy slab behind them. */
html[data-portraits] :where(.table-demo,.scoring-screen,#overlay .dialog-body) .tile{box-sizing:border-box;width:var(--w);height:auto;aspect-ratio:1/1.52;min-width:0;min-height:0;max-width:none;flex:none;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;transform:none;transition:none}
html[data-portraits] :where(.table-demo,.scoring-screen,#overlay .dialog-body) .tile .tile-face{inset:0;border:0;border-radius:0;box-shadow:none;filter:drop-shadow(0 3px 2.5px rgba(0,0,0,.42))}
html[data-portraits] :where(.table-demo,.scoring-screen,#overlay .dialog-body) .tile:hover{background:none;transform:none}
html[data-portraits] :where(.table-demo,.scoring-screen,#overlay .dialog-body) .tile-back{display:block;box-sizing:border-box;width:var(--w,40px);height:auto;aspect-ratio:1/1.52;min-height:0;margin:0;border:0;border-radius:0;background:var(--portrait-back) center/contain no-repeat;box-shadow:none;filter:drop-shadow(0 3px 2.5px rgba(0,0,0,.42))}
:where(.table-demo,.scoring-screen,#overlay .dialog-body) .tile .tile-code{display:none}

/* Ringed gold medallion with a seat emblem, as on the game table. */
.table-demo .medallion-ring,#overlay .medallion-ring{box-sizing:border-box;display:grid;place-items:center;flex:none;width:40px;height:40px;margin:0;padding:0;border-radius:50%;color:var(--gold);background:radial-gradient(circle at 50% 35%,#1d3027,#0a130f 70%);box-shadow:0 0 0 1px var(--gold-line-strong),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(201,168,106,.28),0 4px 10px rgba(0,0,0,.5);font-size:0;line-height:0;transition:box-shadow .2s,color .2s}
.table-demo .medallion-ring .emblem,#overlay .medallion-ring .emblem{width:22px;height:22px}

/* Tile buttons: lift and a gold ring when chosen. */
.table-demo .demo-hand-tile{position:relative;box-sizing:border-box;display:block;flex:none;width:auto;min-width:0;min-height:0;margin:0;padding:0;border:0;border-radius:6px;background:none;box-shadow:none;color:inherit;cursor:pointer;transform:none;outline:0;transition:transform .16s var(--ease-out),box-shadow .16s}
.table-demo .demo-hand-tile .tile{display:block;pointer-events:none}
.table-demo .demo-hand-tile.chosen{transform:translateY(-7px);box-shadow:0 0 0 2.5px var(--gold-bright),0 0 16px 3px rgba(240,200,120,.5)}
.table-demo .demo-hand-tile:focus{outline:0}
.table-demo .demo-hand-tile:focus-visible{outline:2px solid var(--ivory);outline-offset:4px}
.table-demo .demo-hand-tile:disabled{cursor:default;opacity:1;background:none;border:0}
.table-demo .demo-hand-tile:disabled:not(.chosen){filter:saturate(.7) brightness(.82)}
@media (hover:hover) and (pointer:fine){.table-demo .demo-hand-tile:not(:disabled):not(.chosen):hover{transform:translateY(-3px)}}

/* ---------- Table demonstrations ---------- */
/* A demonstration comes in three parts (tutorial-view.js). The step text (label,
   heading, what to do) opens the lesson's text box; the table alone is the
   felt's scene, zoomed to fill it; answers and feedback follow the step text.
   What the example leaves out is in Lesson Notes. Inner areas are marked with a
   gold hairline, never a second walnut rail. */
.table-demo{box-sizing:border-box;min-width:0;max-width:none;margin:0;padding:0;color:var(--ivory);text-align:left}
/* Legacy landscape rules place many of these parts by grid line; reset them. */
.table-demo *{grid-area:auto}
.table-demo.demo-text{display:grid;gap:10px;margin:0}
/* The scene keeps the box of its tallest step (step-fit.js), its table at the top. */
.table-demo.demo-table{--fit-max:1.7;display:flex;flex-direction:column;justify-content:flex-start;min-height:0}
.table-demo.demo-table>.demo-felt{flex:1 1 auto}
.table-demo.demo-side{display:flex;flex-direction:column;align-items:stretch;gap:10px}
.table-demo.demo-side:not(:has(.demo-feedback:not(:empty),.demo-controls:not(:empty),fieldset,.wonder-score)){display:none}

.table-demo .demo-intro{display:grid;gap:6px;min-height:0;margin:0;padding:0;text-align:left}
/* The step's label with Restart on the same line, a row as tall as Restart's
   44 px target on every step, so the text below never moves. */
.table-demo .demo-label{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:44px;margin:-12px 0 -3px}
.table-demo .demo-intro .small-label{display:block;margin:0;font:600 .68rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.table-demo .demo-label>button.demo-restart{flex:none;min-height:44px;margin:0 -10px 0 0;padding:0 10px;border:0;background:none;box-shadow:none;font:500 .86rem/1 var(--sans);color:var(--gold)}
@media (hover:hover) and (pointer:fine){.table-demo .demo-label>button.demo-restart:hover{color:var(--gold-bright);text-decoration:underline;text-underline-offset:4px}}
.table-demo .demo-intro h2{display:block;min-height:0;margin:0;padding:0;font:500 1.4rem/1.14 var(--serif);letter-spacing:.005em;color:var(--ivory);text-align:left}
.table-demo .demo-intro h2:focus{outline:none}
.table-demo .demo-intro p{min-height:0;max-width:62ch;margin:0;font:400 .96rem/1.5 var(--sans);color:var(--ivory-2)}

.table-demo .demo-feedback{position:relative;display:block;box-sizing:border-box;min-height:0;max-width:none;margin:0;padding:0;border:0;border-radius:12px;background:none;font:500 .92rem/1.45 var(--sans);color:var(--ivory);text-align:left}
.table-demo .demo-feedback:focus{outline:none}
.table-demo .demo-feedback:empty{display:none}
.table-demo .demo-feedback:not(:empty){padding:11px 14px 11px 40px;border:1px solid var(--gold-line);background:linear-gradient(180deg,rgba(28,44,36,.9),rgba(14,24,19,.9))}
.table-demo .demo-feedback:not(:empty):before{content:'';position:absolute;left:15px;top:15px;width:11px;height:11px;border-radius:50%;box-shadow:0 0 0 1.5px var(--gold)}
.table-demo .demo-feedback.success:not(:empty){border-color:rgba(143,208,162,.5);background:linear-gradient(180deg,rgba(30,64,44,.92),rgba(16,36,25,.92))}
.table-demo .demo-feedback.success:not(:empty):before{left:17px;top:12px;width:5px;height:11px;border-radius:0;border:solid var(--positive);border-width:0 2px 2px 0;box-shadow:none;transform:rotate(45deg)}

.table-demo .demo-controls{display:flex;flex-wrap:wrap;justify-content:flex-start;gap:8px;min-height:0;margin:0;padding:0}
.table-demo .demo-controls:empty{display:none}
.table-demo .demo-controls button{min-height:44px;font-size:.9rem}
.table-demo .demo-controls button.quiet{padding:0 10px;margin-left:-10px;color:var(--gold)}
/* Kong forms: a segmented choice. The selected form is outlined in bright
   gold; the one filled gold action stays in the dock. */
.table-demo .kong-forms{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;justify-content:stretch}
.table-demo .kong-forms button{width:100%;min-width:0;min-height:44px;margin:0;padding:4px 8px;font-size:.82rem;line-height:1.15;white-space:normal;text-align:center}
.table-demo .kong-forms button.primary{border:1px solid var(--gold-bright);background:linear-gradient(180deg,rgba(40,70,52,.96),rgba(18,35,26,.96));box-shadow:inset 0 0 0 1px rgba(230,200,143,.35),0 0 14px rgba(230,190,110,.16);color:var(--gold-bright)}
.table-demo .kong-forms button.primary:after{content:none}

/* The table. It lies on the lesson felt; tiles and seats are sized from its
   width (container units). */
.table-demo .demo-felt{container-type:inline-size;position:relative;box-sizing:border-box;display:flex;flex-direction:column;align-items:stretch;gap:14px;width:100%;min-width:0;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;color:var(--ivory);text-align:center;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.table-demo .demo-felt:before{content:none}
.demo-felt{--gap:4px;--dt:38px;--dt-max:46px}
@container (min-width:1px){.demo-felt>*{--dt:min(var(--dt-max),calc((100cqw - 6 * var(--gap)) / 7))}}
/* Seat sizes follow the table's width. */
.demo-felt>*{--plaque:clamp(100px,30cqw,150px);--cg:14px;--ring:clamp(34px,8cqw,48px);--bw:clamp(7px,calc((100cqw - var(--plaque) - 2 * var(--cg) - 54px) / 14),13px);--name:clamp(1rem,3.2cqw,1.22rem)}

/* Seats around the centre plaque: the table's edge is a gold hairline; East
   sits on your left, South (you) at the near rail. Top and bottom seats span
   the table so their words never meet the side seats. */
.demo-felt .demo-compass{box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr) var(--plaque) minmax(0,1fr);grid-template-rows:auto auto auto;grid-template-areas:"t t t" "l c r" "b b b";gap:12px var(--cg);align-items:center;justify-items:center;width:100%;max-width:none;margin:0;padding:14px 10px;border:1px solid rgba(201,168,106,.3);border-radius:18px;background:radial-gradient(80% 70% at 50% 45%,rgba(255,230,180,.06),transparent 70%) center/100% 100% no-repeat padding-box;box-shadow:inset 0 0 0 1px rgba(0,0,0,.18);color:inherit;flex-wrap:nowrap}
.demo-felt .demo-seat-0{grid-area:l}.demo-felt .demo-seat-1{grid-area:b}.demo-felt .demo-seat-2{grid-area:r}.demo-felt .demo-seat-3{grid-area:t}
.demo-felt .demo-seat{position:relative;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:6px;flex:none;width:auto;min-width:0;max-width:100%;min-height:0;margin:0;padding:4px;border:0;border-radius:14px;background:none;box-shadow:none;color:var(--ivory);font:inherit;text-align:center;opacity:1;transform:none;cursor:default}
.demo-felt button.demo-seat{min-width:44px;min-height:44px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.demo-felt .medallion-ring{width:var(--ring);height:var(--ring)}
.demo-felt .medallion-ring .emblem{width:calc(var(--ring) * .55);height:calc(var(--ring) * .55)}
/* Side seats stack: medallion, name, count, place, then the standing tiles. */
.demo-felt .demo-seat-copy{display:grid;grid-template-columns:minmax(0,auto);justify-items:center;align-items:baseline;row-gap:2px;min-width:0;max-width:100%;font-size:inherit;line-height:1.2;color:inherit}
.demo-felt .demo-seat strong{display:block;margin:0;font:500 var(--name)/1.15 var(--serif);letter-spacing:.01em;color:var(--ivory);white-space:nowrap}
.demo-felt .demo-count{display:block;margin:0;font:500 calc(var(--name) * 1.06)/1.1 var(--serif);white-space:nowrap;color:var(--gold-bright);font-variant-numeric:tabular-nums}
.demo-felt .demo-count small{display:inline;margin-left:.2em;font:600 .58rem/1 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
/* Place labels keep a minimum width, so "On Your Left" never breaks word by word. */
.demo-felt .demo-seat-copy>span{display:block;box-sizing:border-box;min-width:min(6.6em,100%);max-width:100%;font:500 .68rem/1.3 var(--sans);letter-spacing:.03em;color:var(--sage);white-space:normal;text-wrap:balance}
/* Top and bottom seats sit side-on: medallion, then the words; the standing
   tiles face the centre. */
.demo-felt :is(.demo-seat-1,.demo-seat-3){display:grid;grid-template-columns:auto auto;align-items:center;justify-content:center;column-gap:10px;row-gap:8px}
.demo-felt :is(.demo-seat-1,.demo-seat-3) .demo-seat-copy{grid-template-columns:auto auto;justify-content:start;justify-items:start;column-gap:8px;text-align:left}
.demo-felt :is(.demo-seat-1,.demo-seat-3) .demo-seat-copy>strong{grid-column:1;grid-row:1}
.demo-felt :is(.demo-seat-1,.demo-seat-3) .demo-seat-copy>.demo-count{grid-column:2;grid-row:1}
.demo-felt :is(.demo-seat-1,.demo-seat-3) .demo-seat-copy>span{grid-column:1/-1;grid-row:2;min-width:0;white-space:nowrap}
.demo-felt :is(.demo-seat-1,.demo-seat-3) .demo-backs{grid-column:1/-1;max-width:calc(14 * var(--bw) + 14px)}
.demo-felt .demo-seat-1 .demo-backs{order:-1}
.demo-felt .demo-seat.demo-active .medallion-ring,.demo-felt .demo-seat.demo-picked .medallion-ring{color:var(--gold-bright);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(230,200,143,.55),0 0 20px rgba(240,200,120,.6)}
.demo-felt .demo-seat.demo-active strong,.demo-felt .demo-seat.demo-picked strong{color:var(--gold-bright)}
.demo-felt .demo-seat.demo-picked{background:radial-gradient(closest-side,rgba(240,200,120,.16),transparent)}
.demo-felt button.demo-seat:disabled{opacity:1;background:none;border:0}
.demo-felt button.demo-seat.demo-picked:disabled{background:radial-gradient(closest-side,rgba(240,200,120,.16),transparent)}
.demo-felt button.demo-seat:not(:disabled) .medallion-ring{box-shadow:0 0 0 1.5px var(--gold),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(201,168,106,.4),0 4px 10px rgba(0,0,0,.5)}
@media (hover:hover) and (pointer:fine){.demo-felt button.demo-seat:not(:disabled):hover .medallion-ring{color:var(--gold-bright);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(230,200,143,.5),0 0 14px rgba(240,200,120,.4)}}
.demo-felt button.demo-seat:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px}

/* Concealed hands stand face down: the same jade-backed tile portraits as the
   table, large enough to read as tiles. Four a row beside a narrow table, seven
   beside a wide one; one row at the top and bottom. */
.demo-felt>*{--bw:clamp(12px,5.8cqw,21px)}
.demo-felt .demo-backs{display:flex;flex-wrap:wrap;justify-content:center;align-content:flex-start;gap:3px 1px;max-width:calc(4 * (var(--bw) + 1px))}
@container (min-width:520px){.demo-felt .demo-backs{max-width:calc(7 * (var(--bw) + 1px))}}
.demo-felt :is(.demo-seat-1,.demo-seat-3) .demo-backs{max-width:calc(14 * (var(--bw) + 1px))}
.demo-felt .demo-backs:empty{display:none}
.demo-felt .demo-deal .demo-backs,.demo-felt .demo-deal .demo-backs:empty{display:flex;min-height:calc(var(--rows,1) * (var(--bw) * 1.52 + 3px) - 3px)}
.demo-felt .demo-deal :is(.demo-seat-0,.demo-seat-2) .demo-backs{--rows:4}
@container (min-width:520px){.demo-felt .demo-deal :is(.demo-seat-0,.demo-seat-2) .demo-backs{--rows:2}}
.demo-felt .demo-backs i{display:block;flex:none;box-sizing:border-box;width:var(--bw);aspect-ratio:1/1.52;border-radius:2px;background:linear-gradient(180deg,#2f8a5d,#1d6b46 64%,#0f4a2f 76%,#e9dfc8 76%,#cfc3a8);box-shadow:0 1.5px 1.5px rgba(0,0,0,.5)}
html[data-portraits] .demo-felt .demo-backs i{border-radius:0;background:var(--portrait-back) center/contain no-repeat;box-shadow:none;filter:drop-shadow(0 1.5px 1px rgba(0,0,0,.5))}

/* Centre plaque: black lacquer, gold hairline, as on the game table. */
.demo-felt .demo-centre{grid-area:c;box-sizing:border-box;display:grid;justify-items:center;align-content:center;gap:5px;width:100%;max-width:none;height:auto;min-height:100px;margin:0;padding:10px 8px;border:0;border-radius:12px;background:linear-gradient(180deg,#19241e,#070c0a);box-shadow:0 0 0 1px rgba(201,168,106,.5),0 0 0 3px rgba(5,9,7,.85),0 0 0 4px rgba(201,168,106,.16),0 10px 22px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,240,210,.08);color:var(--ivory);text-align:center;text-shadow:none;flex-direction:column;flex-basis:auto}
.demo-felt .demo-centre>span,.demo-felt .demo-centre>small{display:block;margin:0;font:600 .58rem/1.25 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.demo-felt .demo-centre>small{font-weight:500;font-size:.68rem;letter-spacing:.04em;text-transform:none;color:var(--sage)}
.demo-felt .demo-centre>strong{display:block;margin:0;font:500 calc(var(--name) * .96)/1.3 var(--serif);letter-spacing:.01em;word-spacing:normal;color:var(--ivory)}
.demo-felt .demo-centre>strong.demo-wall-total{font:500 2.1rem/1 var(--serif);color:var(--ivory)}
/* The turn order breaks only after its second arrow: "East → South →" / "West → North". */
.demo-seat-winds .demo-felt>*{--plaque:clamp(132px,40cqw,184px)}
.demo-felt .demo-centre>strong.demo-order{font-size:calc(var(--name) * .92);white-space:nowrap}
/* Until a seat is right, the dock names the move: a prompt, not a dead button. */
.app-lesson .lesson-dock>.demo-prompt{display:flex;align-items:center;gap:10px;min-height:48px;margin:0 0 0 auto;padding:0 6px;font:500 .98rem/1.2 var(--sans);letter-spacing:.01em;color:var(--gold-bright);white-space:nowrap}
.app-lesson .lesson-dock>.demo-prompt .icon{width:20px;height:20px;color:var(--gold)}
.demo-felt .demo-centre .tile{--w:clamp(34px,9cqw,48px)}
.demo-felt .demo-centre br{display:revert}
/* The wall on the plaque: stacks two tiles high, built from the same tile backs. */
/* The wall's stacks narrow to fit the centre box rather than run out of it (director, 26 Sep). */
.demo-felt .demo-stacks{display:flex;flex-wrap:nowrap;gap:1px;justify-content:center;max-width:100%;margin-top:10px}
.demo-felt .demo-stacks i{position:relative;display:block;flex:0 1 clamp(9px,3.2cqw,15px);width:clamp(9px,3.2cqw,15px);min-width:0;height:auto;aspect-ratio:1/1.52;border:0;border-radius:1.5px;background:linear-gradient(180deg,#2f8a5d,#1d6b46 64%,#0f4a2f 76%,#e9dfc8 76%,#cfc3a8);box-shadow:0 1px 1px rgba(0,0,0,.5)}
.demo-felt .demo-stacks i:before{content:'';position:absolute;inset:0;transform:translateY(-42%);background:inherit;border-radius:inherit;filter:inherit}
.demo-felt .demo-stacks i:nth-child(n+7){display:none}
@container (min-width:520px){.demo-felt .demo-stacks i:nth-child(n+7){display:block}}
html[data-portraits] .demo-felt .demo-stacks i{border-radius:0;background:var(--portrait-back) center/contain no-repeat;box-shadow:none;filter:drop-shadow(0 1px 1px rgba(0,0,0,.5))}

/* Your hand along the near rail, below the table's edge. */
.demo-felt .demo-rack-label{display:flex;justify-content:space-between;align-items:baseline;gap:10px;max-width:none;margin:0 2px -4px;padding:0;border:0;font:inherit}
.demo-felt .demo-rack-label strong{font:600 .64rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.demo-felt .demo-rack-label span{font:500 .74rem/1.2 var(--sans);color:var(--sage)}
.demo-felt .demo-hand{box-sizing:border-box;display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;gap:8px var(--gap);width:100%;max-width:none;margin:0;padding:0;border:0;background:none;grid-template-columns:none;grid-template-rows:none}
.demo-felt .demo-hand .tile{--w:var(--dt)}
.demo-felt .demo-hand-tile .tile{--w:var(--dt)}

/* Rows of example tiles, each labelled underneath as on the result felt. */
.demo-felt :is(.wonder-family,.kong-focus,.kong-hand){display:grid;grid-template-columns:minmax(0,1fr);gap:8px;justify-items:center;max-width:none;margin:0;padding:0;border:0;border-radius:0;background:none;color:inherit}
.demo-felt :is(.wonder-family,.kong-focus,.kong-hand)>figcaption{margin:0;font:600 .62rem/1.3 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold);text-align:center}
.demo-felt .wonder-family .demo-hand{padding:0;margin:0;border:0}
/* Rows of one tile pair up side by side. */
.table-demo:is(.wonder-demo,.bao-demo) .demo-felt{flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:flex-start;align-content:flex-start;column-gap:28px}
.table-demo:is(.wonder-demo,.bao-demo) .demo-felt>*{flex:1 1 100%}
.table-demo:is(.wonder-demo,.bao-demo) .demo-felt>.wonder-family:has(.demo-hand>.tile:only-child){flex:0 1 auto}
.demo-felt .wonder-options,.demo-felt .bao-offer{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;gap:14px;min-width:0;margin:2px 0 0;padding:12px 0 2px;border:0;border-top:1px solid rgba(230,200,143,.2);border-radius:0;background:none}
.demo-felt .wonder-options legend{float:left;width:100%;margin:0 0 12px;padding:0;font:500 1.05rem/1.2 var(--serif);color:var(--ivory);text-align:center}
.demo-felt .wonder-options .tile{--w:max(44px,min(56px,calc(var(--dt) * 1.2)))}
.demo-felt .bao-melds{display:flex;flex-wrap:wrap;justify-content:center;gap:10px 16px}
.demo-felt .bao-melds .demo-hand{width:auto;flex-wrap:nowrap;gap:2px}
.demo-felt .bao-offer{display:grid;justify-items:center;gap:8px}
.demo-felt .bao-offer figcaption{font:600 .62rem/1.25 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.demo-felt .bao-offer .tile{--w:max(44px,min(56px,calc(var(--dt) * 1.2)))}
.demo-felt .bonus-rows{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;gap:12px 28px;padding-top:12px;border-top:1px solid rgba(230,200,143,.2)}
/* Short captions let the bonuses and the discard share one row. */
.demo-felt .bonus-rows figcaption{max-width:17em;text-wrap:balance}
.demo-felt .replacement-trace{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:0;padding:0}
.demo-felt .replacement-trace>div{position:relative;display:grid;justify-items:center;align-content:start;gap:6px;min-width:0;flex:none}
.demo-felt .replacement-trace>div+div:before{content:'';position:absolute;left:-4px;top:calc(var(--trace) * 1.52 / 2);width:10px;height:10px;border:solid var(--gold);border-width:1.5px 1.5px 0 0;transform:translate(-50%,-50%) rotate(45deg);opacity:.8}
.demo-felt .replacement-trace strong{min-height:0;font:600 .58rem/1.25 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold);text-align:center}
.demo-felt .replacement-trace span{font:500 .8rem/1.25 var(--sans);color:var(--ivory-2);text-align:center}
.demo-felt .replacement-trace{--trace:min(56px,calc(var(--dt) * 1.3))}
.demo-felt .replacement-trace .tile{--w:var(--trace)}

/* Chow and Pong examples. */
.demo-felt .claim-examples{display:grid;gap:14px;justify-items:center;min-width:0;margin:0;padding:4px 0;text-align:center}
.demo-felt .claim-examples h3{margin:0;font:600 .64rem/1.25 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.demo-felt .claim-example-sets{display:flex;flex-wrap:wrap;justify-content:center;gap:18px 30px}
.demo-felt .claim-example{display:grid;justify-items:center;gap:10px;flex:none;margin:0}
.demo-felt .claim-example figcaption{display:grid;gap:3px;margin:0;font:inherit}
.demo-felt .claim-example figcaption strong{font:500 1.3rem/1.1 var(--serif);color:var(--ivory)}
.demo-felt .claim-example figcaption span{font:400 .8rem/1.3 var(--sans);color:var(--ivory-2)}
.demo-felt .claim-example-tiles{display:flex;justify-content:center;gap:3px}
.demo-felt .claim-example-tiles .tile{--w:min(60px,calc(var(--dt) * 1.3))}
.demo-felt .claim-order{margin:2px 0 0;padding:8px 14px;border-radius:999px;border:1px solid rgba(230,200,143,.3);background:rgba(6,14,10,.45);font:500 .82rem/1.3 var(--sans);letter-spacing:.02em;color:var(--ivory)}

/* Kong: the set in focus, then your hand. */
.demo-felt .kong-hand{padding-top:12px;border-top:1px solid rgba(230,200,143,.2)}
.demo-felt .kong-tiles{display:flex;justify-content:center;align-items:flex-end;gap:3px}
.demo-felt .kong-tiles .tile{--w:min(60px,calc(var(--dt) * 1.25))}
.demo-felt .kong-offered{display:grid;justify-items:center;gap:6px;margin-left:14px;padding-left:14px;border-left:1px dashed rgba(230,200,143,.4)}
.demo-felt .kong-offered small{font:600 .56rem/1.2 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}

/* Money-style summaries: a card with a serif head and hairline rows. */
.table-demo .wonder-score{box-sizing:border-box;max-width:none;margin:0;padding:14px 18px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:var(--panel-fill);box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 10px 26px rgba(0,0,0,.28);text-align:left}
.table-demo .wonder-score h3{margin:0 0 8px;padding-bottom:10px;border-bottom:1px solid rgba(201,168,106,.2);font:500 1.3rem/1.15 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
.table-demo .wonder-score p{margin:8px 0;font:400 .88rem/1.5 var(--sans);color:var(--ivory-2)}
.table-demo .wonder-score dl{display:grid;margin:10px 0 4px;padding:0}
.table-demo .wonder-score dl>div{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:8px 0;border-bottom:1px solid rgba(201,168,106,.12);font-weight:400;color:var(--ivory-2)}
.table-demo .wonder-score dt{font:400 .9rem/1.3 var(--sans);color:var(--ivory-2)}
.table-demo .wonder-score dd{margin:0;font:500 1.08rem/1.2 var(--serif);color:var(--ivory);font-variant-numeric:tabular-nums}
.table-demo .wonder-score dl>div:last-child{border-bottom:0;padding-top:10px}
.table-demo .wonder-score dl>div:last-child :is(dt,dd){color:var(--gold-bright)}
.table-demo .wonder-score dl>div:last-child dt{font:500 1.02rem/1.2 var(--serif)}
.bao-demo .wonder-score dl>div:last-child :is(dt,dd){color:var(--ivory)}
.bao-demo .wonder-score dl>div:last-child dt{font:400 .9rem/1.3 var(--sans);color:var(--ivory-2)}

/* Who pays? Three outlined answers. */
.table-demo .bao-payers{display:grid;grid-template-columns:minmax(0,1fr);justify-content:stretch;justify-items:stretch;align-items:stretch;gap:8px;min-width:0;margin:0;padding:0;border:0}
.table-demo .bao-payers legend{margin:0 0 8px;padding:0;font:500 1.15rem/1.2 var(--serif);color:var(--ivory)}
.table-demo .bao-payers button{justify-content:flex-start;width:100%;min-height:48px;outline:0}
.table-demo .bao-payers button.chosen{border-color:var(--gold-bright);box-shadow:inset 0 0 0 1px var(--gold-bright),0 0 16px rgba(240,200,120,.25);color:var(--gold-bright)}
.table-demo .bao-payers button:disabled{color:var(--sage)}
.table-demo .bao-payers button.chosen:disabled{color:var(--gold-bright);border-color:var(--gold-bright);background:linear-gradient(180deg,rgba(38,58,47,.95),rgba(18,30,24,.95))}

.demo-felt .wonder-family:has(.demo-hand-tile),.demo-felt .kong-hand:has(.demo-hand-tile){gap:14px;padding-top:8px}
/* Turn demo: the seats carry only name and count; your hand is on the rail. */
.demo-turn .demo-seat-copy>span{display:none}
/* Seven tiles a row on phones, all fourteen in one row on a wide table. */
.demo-felt .demo-turn ~ .demo-hand,.bonus-demo .demo-felt>.wonder-family .demo-hand,.kong-demo .demo-felt .demo-hand{display:grid;grid-template-columns:repeat(7,var(--dt));justify-content:center;gap:8px var(--gap)}
@container (min-width:560px){
  .demo-felt .demo-turn ~ .demo-hand{grid-template-columns:repeat(14,var(--dt))}
  .demo-turn ~ .demo-hand{--dt:min(48px,calc((100cqw - 13 * var(--gap)) / 14))}
}

/* Landscape: wider tables hold larger tiles before the felt's zoom. */
@media (orientation:landscape) and (min-width:700px){
  .demo-felt{--dt-max:60px}
}
/* Tablets: larger seats and tiles. */
@media (orientation:landscape) and (min-width:700px) and (min-height:621px){
  .demo-felt>*{--ring:clamp(40px,8cqw,52px);--bw:clamp(12px,3.4cqw,22px);--name:clamp(1.05rem,3cqw,1.3rem)}
  .demo-felt .demo-centre{min-height:130px}
}
/* Tablets and desktop: the table fills a large felt, so tiles, labels and the
   step text grow with it (bounded by the felt's height as well as its width). */
@media (orientation:landscape) and (min-width:1000px) and (min-height:621px){
  html:not([data-expanded-text=true]) .demo-felt{--dt-max:78px;--gap:5px}
  @container (min-width:1px){html:not([data-expanded-text=true]) .demo-felt>*{--dt:min(var(--dt-max),calc((100cqw - 6 * var(--gap)) / 7))}}
  /* Your hand in the turn demo stays one row of fourteen. */
  @container (min-width:1px){html:not([data-expanded-text=true]) .demo-felt .demo-turn ~ .demo-hand{--dt:min(56px,calc((100cqw - 13 * var(--gap)) / 14))}}
  html:not([data-expanded-text=true]) .demo-felt :is(.wonder-options,.bao-offer) .tile,html:not([data-expanded-text=true]) .demo-felt .claim-example-tiles .tile,html:not([data-expanded-text=true]) .demo-felt .kong-tiles .tile{--w:calc(var(--dt) * 1.2)}
  html:not([data-expanded-text=true]) .demo-felt .replacement-trace{--trace:calc(var(--dt) * 1.3)}
  html:not([data-expanded-text=true]) .demo-felt :is(.wonder-family,.kong-focus,.kong-hand)>figcaption,html:not([data-expanded-text=true]) .demo-felt .bao-offer figcaption{font-size:.72rem}
  html:not([data-expanded-text=true]) .demo-felt .wonder-options legend{font-size:1.25rem}
  html:not([data-expanded-text=true]) .table-demo .demo-intro .small-label{font-size:.74rem}
  html:not([data-expanded-text=true]) .table-demo .demo-intro h2{font-size:1.85rem}
  html:not([data-expanded-text=true]) .table-demo .demo-intro p{font-size:1.1rem}
  html:not([data-expanded-text=true]) .table-demo .demo-feedback{font-size:1.02rem}
  html:not([data-expanded-text=true]) .table-demo .kong-forms button{min-height:50px;font-size:.95rem}
}
/* Tablet portrait: the demonstrations scale with the lesson (about 1.2), and
   the seats spread to fill the felt. */
@media (orientation:portrait) and (min-width:700px){
  html:not([data-expanded-text=true]) .table-demo .demo-intro .small-label{font-size:.8rem}
  html:not([data-expanded-text=true]) .table-demo .demo-intro h2{font-size:2rem}
  html:not([data-expanded-text=true]) .table-demo .demo-intro p{font-size:1.2rem}
  html:not([data-expanded-text=true]) .table-demo .demo-feedback{font-size:1.08rem}
  html:not([data-expanded-text=true]) .table-demo .demo-controls button{min-height:52px;font-size:1rem}
  html:not([data-expanded-text=true]) .demo-felt{--dt-max:64px}
  html:not([data-expanded-text=true]) .demo-felt>*{--ring:clamp(44px,8cqw,58px);--bw:clamp(14px,3.2cqw,22px);--name:clamp(1.1rem,3cqw,1.4rem);--plaque:clamp(150px,30cqw,210px)}
  html:not([data-expanded-text=true]) .demo-felt .demo-centre{min-height:130px}
  html:not([data-expanded-text=true]) .demo-felt .demo-seat-copy>span{font-size:.8rem}
}
/* Short landscape phones and phones held upright: a smaller step text. */
@media (max-height:620px),(orientation:portrait) and (max-width:699px){
  .table-demo .demo-intro h2{font-size:1.28rem}
  .table-demo .demo-intro p{font-size:.93rem;line-height:1.45}
  .table-demo .demo-feedback{font-size:.88rem}
  .table-demo .demo-feedback:not(:empty){padding:8px 12px 8px 36px}
  .table-demo .demo-feedback:not(:empty):before{left:13px;top:12px}
  .table-demo .demo-feedback.success:not(:empty):before{left:15px;top:9px}
}
/* A short felt (a phone, either way up) holds a compact table: smaller seats,
   face-down tiles seven to a row and smaller, and in the turn the seats in two
   rows with your hand below (each seat still shows its count). The felt's zoom
   then fits it; anything you can tap stays at least 44 px. */
@container felt (max-height:460px){
  .table-demo .demo-felt{gap:10px}
  .demo-felt>*{--ring:32px;--name:1rem;--plaque:clamp(104px,28cqw,140px)}
  .demo-felt .demo-compass{row-gap:6px;padding:8px 10px}
  .demo-felt .demo-seat{row-gap:3px;padding:2px}
  .demo-felt .demo-seat-copy>span{font-size:.7rem}
  .demo-felt .demo-centre{min-height:80px;padding:6px 8px}
  .demo-felt .demo-centre>strong.demo-wall-total{font-size:1.8rem}
  .demo-felt .demo-centre .tile{--w:32px}
  .demo-felt>.demo-deal{--bw:clamp(9px,2.8cqw,13px)}
  .demo-felt .demo-deal :is(.demo-seat-0,.demo-seat-2) .demo-backs{--rows:2;max-width:calc(7 * (var(--bw) + 1px))}
  .demo-felt .demo-turn .demo-backs,.demo-felt .demo-turn .demo-seat-1{display:none}
  .demo-felt .demo-turn{grid-template-rows:auto auto;grid-template-areas:"t t t" "l c r"}
  .demo-felt .demo-turn :is(.demo-seat-0,.demo-seat-2){flex-direction:row;gap:6px}
  .demo-felt .demo-turn :is(.demo-seat-0,.demo-seat-2) .demo-seat-copy{justify-items:start}
  .demo-felt .demo-turn .demo-centre{height:76px;min-height:0;padding:4px 6px;gap:3px;overflow:hidden}
  .demo-felt .demo-turn .demo-centre .tile{--w:30px}
  .demo-felt .demo-turn .demo-centre>strong{font-size:.85rem;line-height:1.15}
  .table-demo .demo-felt .demo-turn ~ .demo-hand{gap:4px 2px}
  /* Rows of example tiles share a line where they fit: smaller tiles to look at,
     larger ones to choose, and short captions wrap under their tile. */
  .table-demo.wonder-demo:not(.bonus-demo) .demo-felt>.wonder-family{flex:0 1 auto}
  .table-demo.wonder-demo:not(.bonus-demo) .demo-felt>.wonder-family{--dt:40px}
  .table-demo.wonder-demo:not(.bonus-demo) .demo-felt .wonder-options .demo-hand-tile .tile{--w:56px}
  .table-demo.wonder-demo .demo-felt>.wonder-family>figcaption{max-width:22em;text-wrap:balance}
  .table-demo.wonder-demo .demo-felt>.wonder-family:has(.demo-hand>.tile:only-child)>figcaption{max-width:8em}
  .table-demo:is(.wonder-demo,.bao-demo) .demo-felt{row-gap:10px}
  .demo-felt .wonder-options legend{margin-bottom:8px}
  .demo-felt .kong-hand{padding-top:8px}
  /* The Kong itself is never smaller than the hand you choose from. */
  .demo-felt .kong-tiles .tile{--w:max(44px,var(--dt),min(50px,calc(var(--dt) * 1.1)))}
  .demo-felt .wonder-family:has(.demo-hand-tile),.demo-felt .kong-hand:has(.demo-hand-tile){gap:10px}
  /* Hands you choose from keep seven 44 px tiles to a row on the narrowest felt. */
  .demo-felt :is(.kong-hand .demo-hand,.wonder-family .demo-hand:has(.demo-hand-tile)){column-gap:2px}
  /* The turn's closing Chow and Pong examples share one line. */
  .demo-felt .claim-examples{gap:10px}
  .demo-felt .claim-example-sets{gap:12px 22px}
  .demo-felt .claim-example-tiles .tile{--w:max(42px,min(50px,calc(var(--dt) * 1.1)))}
  .demo-felt .claim-example figcaption span{max-width:11em;text-wrap:balance}
  .demo-felt .claim-example figcaption strong{font-size:1.12rem}
}
/* The shortest felts (a small phone on its side): your hand's label gives way; the
   step's text says whose hand it is. */
@container felt (max-height:300px){
  .demo-felt .demo-turn ~ .demo-rack-label{display:none}
}
/* The narrowest felt (a 320 px phone) takes your hand five to a row; 13 and 14
   tiles still need the same rows, so the draw moves nothing. */
@container felt (max-width:300px){
  .lesson-stage .table-demo .demo-felt .demo-turn ~ .demo-hand{grid-template-columns:repeat(auto-fill,var(--pick))}
  /* The side seats stack again beside a smaller plaque. */
  .demo-felt>.demo-turn{--plaque:84px;--cg:8px}
  .demo-felt .demo-turn :is(.demo-seat-0,.demo-seat-2){flex-direction:column;gap:3px}
  .demo-felt .demo-turn :is(.demo-seat-0,.demo-seat-2) .demo-seat-copy{justify-items:center}
}

/* ---------- Count This Hand ---------- */
/* A worked hand fits the screen like a lesson: the heading and the hand's story,
   the hand on felt (zoomed to fill it, step-fit.js), the working in a box as
   tall as its longest state (count or payment, discard or self-draw, before and
   after checking) and the actions, so checking an answer never moves the felt.
   A long count scrolls inside its box. The table's limits are in Table Rules. */
/* The surface already keeps clear of the home indicator (safe-area padding). */
.surface>main.scoring-screen{--felt-room:calc(var(--app-frame-height,100dvh) - var(--safe-top) - var(--safe-bottom) - 58px);--felt-min:clamp(170px,calc(var(--felt-room) * .34),320px);--text-max:calc(var(--felt-room) * .4);
  box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto auto auto minmax(var(--felt-min),1fr) minmax(0,min(var(--text-h,9999px),var(--text-max))) auto;
  grid-template-areas:"hud" "heading" "story" "felt" "work" "dock";align-items:stretch;gap:0;
  flex:1 1 auto;width:100%;max-width:720px;min-height:0;margin:0 auto;padding:0 16px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;color:var(--ivory);text-align:left}
.scoring-screen *{grid-area:auto}
.scoring-screen :is(.scoring-scroll,.score-table){display:contents}
.scoring-screen>.lesson-hud{grid-area:hud;display:flex;align-self:stretch;align-items:center;justify-content:space-between;gap:8px;min-height:44px;margin:0 -6px;padding:0;font:600 .68rem/1 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--sage)}
.scoring-screen>.lesson-hud button{min-height:44px;padding:0 6px;border:0;border-radius:8px;background:none;box-shadow:none;font:500 .88rem/1 var(--sans);letter-spacing:0;text-transform:none;color:var(--gold)}
.scoring-screen .score-heading{grid-area:heading;display:grid;justify-items:center;gap:4px;margin:0;padding:0;text-align:center}
.scoring-screen .score-heading h1{margin:0;font:500 clamp(1.6rem,6.6vw,2rem)/1.05 var(--serif);letter-spacing:0;color:var(--ivory)}
.scoring-screen .score-heading p{display:grid;max-width:none;margin:0;font:600 .64rem/1.35 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
/* The hand's name and its step share a line box as tall as the longer step's, so
   moving on to the payment never moves the felt. */
.scoring-screen .score-heading p>span{grid-area:1/1}
.scoring-screen .score-heading p>.score-stage-size{visibility:hidden}
.scoring-screen .score-description{grid-area:story;max-width:none;margin:6px 0 0;font:400 .9rem/1.45 var(--sans);color:var(--ivory-2);text-align:center}
.scoring-screen .score-felt{grid-area:felt;align-self:stretch;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);place-items:center;min-height:0;margin:10px 0 0;padding:10px;overflow:hidden;container:felt/size}
/* The hand at its natural size; the felt's zoom fills the felt with it. */
.score-fit{--fit-max:2.2;--st:40px;box-sizing:border-box;display:grid;gap:12px;justify-items:center}
.score-fit .score-context{display:flex;flex-wrap:wrap;justify-content:center;gap:5px;margin:0;font:inherit;color:inherit}
.score-fit .score-context span{padding:4px 9px;border-radius:999px;border:1px solid rgba(230,200,143,.3);background:rgba(6,14,10,.5);font:500 .68rem/1.2 var(--sans);letter-spacing:0;white-space:nowrap;color:var(--sage);text-shadow:none}
.score-fit .score-context strong{font-weight:600;color:var(--ivory)}
/* Sets and the pair with tracked labels, as on the result felt. */
:is(.score-felt,#overlay .winning-felt) .scoring-hand{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;gap:12px 18px;margin:0;padding:0}
:is(.score-felt,#overlay .winning-felt) .score-group{display:grid;justify-items:center;gap:6px;width:auto;margin:0;padding:0}
:is(.score-felt,#overlay .winning-felt) .score-group>div{display:flex;flex-wrap:nowrap;justify-content:center;gap:2px;margin:0}
:is(.score-felt,#overlay .winning-felt) .score-group>span{display:block;margin:0;font:600 .58rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold);text-align:center;text-shadow:0 1px 3px rgba(0,0,0,.6)}
.score-felt .tile{--w:var(--st)}
:is(.score-felt,#overlay .winning-felt) .score-bonuses{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;margin:0;padding:12px 0 0;border-top:1px solid rgba(230,200,143,.18)}
:is(.score-felt,#overlay .winning-felt) .score-bonuses>span,.score-felt .score-no-bonus{display:block;max-width:none;margin:0;font:600 .6rem/1.2 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold);text-align:center}
:is(.score-felt,#overlay .winning-felt) .score-bonuses>div{display:flex;flex-wrap:wrap;justify-content:center;gap:4px}
.score-felt .score-bonuses .tile{--w:calc(var(--st) * .8)}
.score-felt .score-no-bonus{padding-top:12px;border-top:1px solid rgba(230,200,143,.18);color:var(--sage)}
.score-fit :is(.score-bonuses,.score-no-bonus){justify-self:stretch}

/* The working: the question and its totals, or the verdict and the count.
   Sizing copies (.step-size) lay out exactly like it. */
.scoring-screen :is(.score-work,.step-size){display:flex;flex-direction:column;gap:10px;min-width:0}
.scoring-screen .score-work{grid-area:work;position:relative;box-sizing:border-box;align-self:stretch;min-height:0;margin:0;padding:12px 0 4px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}
.scoring-screen .score-work.has-more{-webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 24px),transparent);mask-image:linear-gradient(180deg,#000 calc(100% - 24px),transparent)}
.scoring-screen .score-prompt{margin:0;font:500 1.3rem/1.2 var(--serif);letter-spacing:0;color:var(--ivory);text-align:center}
.scoring-screen .score-payment-hint{max-width:none;margin:0;font:400 .88rem/1.45 var(--sans);color:var(--ivory-2);text-align:center}
.scoring-screen .score-choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;width:100%;max-width:520px;margin:0 auto}
.scoring-screen .score-choices>button{box-sizing:border-box;display:grid;justify-items:center;align-content:center;gap:4px;flex:none;min-width:0;min-height:66px;margin:0;padding:6px 4px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:linear-gradient(180deg,rgba(30,48,39,.94),rgba(14,24,19,.94));box-shadow:inset 0 1px 0 rgba(255,240,210,.06),0 6px 16px rgba(0,0,0,.3);color:var(--ivory);cursor:pointer;transform:none;transition:border-color .18s,background .18s,box-shadow .18s,transform .12s}
.scoring-screen .score-choices>button strong{font:500 1.8rem/1 var(--serif);color:var(--ivory)}
.scoring-screen .score-choices>button span{font:600 .58rem/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.scoring-screen .score-choices>button.chosen{border-color:var(--gold-bright);background:linear-gradient(180deg,rgba(54,76,54,.96),rgba(24,40,30,.96));box-shadow:inset 0 0 0 1px var(--gold-bright),0 0 22px rgba(240,200,120,.28)}
.scoring-screen .score-choices>button.chosen strong{color:var(--gold-bright)}
.scoring-screen .score-choices>button:active{transform:translateY(1px)}
@media (hover:hover) and (pointer:fine){.scoring-screen .score-choices>button:not(.chosen):hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(38,58,47,.95),rgba(18,30,24,.95))}}
.scoring-screen .score-cue{min-height:1.3em;margin:0;font:500 .8rem/1.3 var(--sans);letter-spacing:.02em;color:var(--sage);text-align:center}

/* Answer: the shared answer mark (learn.css), then a summary card with
   hairline rows. */
.scoring-screen .score-feedback:focus{outline:none}
.scoring-screen .feedback-mark{box-sizing:border-box;display:grid;place-items:center;border-radius:50%;background:radial-gradient(circle at 50% 35%,#1d3228,#0b1511 72%)}
.scoring-screen .feedback-mark .icon{width:18px;height:18px}
.scoring-screen .score-feedback>h2{font-size:1.45rem}
.scoring-screen .score-feedback>p{font-size:.94rem;line-height:1.45}
.score-card{box-sizing:border-box;margin:0;padding:12px 18px 14px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:var(--panel-fill);box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 10px 26px rgba(0,0,0,.28);text-align:left}
.score-card-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:0 0 2px;padding-bottom:10px;border-bottom:1px solid rgba(201,168,106,.2)}
.score-card-head h3{margin:0;font:500 1.38rem/1.1 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
.score-card-head strong{font:500 1.38rem/1 var(--serif);color:var(--gold-bright);white-space:nowrap}
/* Tai lines: award and plain explanation on the left, tai on the right. */
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown{max-width:none;margin:0;padding:0;border:0;list-style:none}
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown li{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;margin:0;padding:10px 0;border:0;border-bottom:1px solid rgba(201,168,106,.12);font:400 .9rem/1.45 var(--sans);color:var(--ivory-2)}
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown li:last-child{border-bottom:0}
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown li>div{min-width:0}
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown strong{display:block;font:500 .95rem/1.3 var(--sans);color:var(--ivory)}
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown p{margin:3px 0 0;font:400 .82rem/1.45 var(--sans);color:var(--sage)}
:is(.scoring-screen,#overlay .dialog-body) .tai-breakdown li>span{flex:none;white-space:nowrap;font:500 1.08rem/1.25 var(--serif);color:var(--ivory)}
.scoring-screen .score-rule-result{max-width:none;margin:2px 0 0;padding-top:10px;border-top:1px solid rgba(201,168,106,.2);font:400 .86rem/1.5 var(--sans);color:var(--ivory-2)}
/* Key and value rows (payments, point changes). */
:is(.scoring-screen,#overlay .dialog-body) .payment-breakdown{display:grid;grid-template-columns:minmax(0,1fr);justify-content:stretch;gap:0;margin:4px 0 10px;padding:0}
:is(.scoring-screen,#overlay .dialog-body) .payment-breakdown>div{display:flex;flex-direction:row;align-items:baseline;justify-content:space-between;gap:12px;margin:0;padding:9px 0;border-bottom:1px solid rgba(201,168,106,.12)}
:is(.scoring-screen,#overlay .dialog-body) .payment-breakdown>div:last-child{border-bottom:0}
:is(.scoring-screen,#overlay .dialog-body) .payment-breakdown span{font:400 .92rem/1.3 var(--sans);color:var(--ivory-2)}
:is(.scoring-screen,#overlay .dialog-body) .payment-breakdown strong{font:500 1.1rem/1.2 var(--serif);color:var(--ivory)}

.scoring-screen>.lesson-dock{grid-area:dock;display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);justify-content:stretch;gap:10px;margin:0;padding:8px 0 10px}
.scoring-screen>.lesson-dock button{width:100%;min-width:0;min-height:48px;padding:0 12px;font-size:.92rem}

/* Landscape: the hand on felt fills the height on the left; the heading, the
   story, the working and the actions share the column beside it. */
@media (orientation:landscape) and (min-width:700px){
  html:not([data-expanded-text=true]) .surface>main.scoring-screen{max-width:1180px;height:100%;padding:0 18px 8px;overflow:hidden;
    grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);grid-template-rows:auto auto auto minmax(0,1fr) auto;
    grid-template-areas:"hud hud" "felt heading" "felt story" "felt work" "felt dock";column-gap:24px}
  html:not([data-expanded-text=true]) .scoring-screen .score-felt{grid-row:2/6;margin:4px 0 0}
  html:not([data-expanded-text=true]) .scoring-screen .score-heading{justify-items:start;margin-top:6px;text-align:left}
  html:not([data-expanded-text=true]) .scoring-screen .score-description{text-align:left}
  html:not([data-expanded-text=true]) .scoring-screen :is(.score-prompt,.score-payment-hint,.score-cue){text-align:left}
  html:not([data-expanded-text=true]) .scoring-screen .score-choices{max-width:none;margin:0}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-dock{padding:8px 0 0}
}
/* Short landscape phones: the header floats over the first row (learn.css), and
   the navigation shares that row between its buttons. */
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .surface>main.scoring-screen{grid-template-rows:58px auto auto minmax(0,1fr) auto}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-hud{margin:0;padding:0 44px}
  html:not([data-expanded-text=true]) .scoring-screen .score-felt{margin:0;padding:8px}
  html:not([data-expanded-text=true]) .scoring-screen .score-heading{margin-top:0}
  html:not([data-expanded-text=true]) .scoring-screen .score-heading h1{font-size:1.5rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-description{margin-top:4px;font-size:.84rem;line-height:1.4}
  html:not([data-expanded-text=true]) .scoring-screen .score-work{padding-top:8px;gap:8px}
  html:not([data-expanded-text=true]) .scoring-screen .step-size{gap:8px}
  html:not([data-expanded-text=true]) .scoring-screen .score-prompt{font-size:1.15rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-payment-hint{font-size:.84rem;line-height:1.4}
  html:not([data-expanded-text=true]) .scoring-screen .score-choices>button{min-height:54px}
  html:not([data-expanded-text=true]) .scoring-screen .score-choices>button strong{font-size:1.5rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-feedback>h2{font-size:1.25rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-feedback>p{font-size:.86rem}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-dock{padding-top:6px}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-dock button{min-height:46px}
}
/* The smallest phones: one page that scrolls, as for lessons (learn.css). */
@media (orientation:portrait) and (max-height:620px){
  .surface>main.scoring-screen{grid-template-rows:auto auto auto auto auto auto}
  .scoring-screen .score-felt{height:clamp(240px,calc(var(--felt-room) * .62),400px)}
  .scoring-screen .score-work{min-height:var(--text-h,0px);overflow:visible;-webkit-mask-image:none;mask-image:none}
  .scoring-screen>.lesson-dock{position:sticky;bottom:0;z-index:4;margin:0 -16px;padding:8px 16px 10px;background:#090e0c}
}
/* Short portrait phones: a tighter heading and working. */
@media (orientation:portrait) and (max-height:760px){
  .scoring-screen .score-heading h1{font-size:1.5rem}
  .scoring-screen .score-description{font-size:.85rem;line-height:1.4}
  .scoring-screen .score-felt{margin-top:8px;padding:8px}
  .scoring-screen .score-prompt{font-size:1.15rem}
  .scoring-screen .score-choices>button{min-height:54px}
  .scoring-screen .score-choices>button strong{font-size:1.5rem}
}
/* Tablets and desktop: the lessons' composition. Capped and centred on the
   same gutter, starting 24 px under the header; above 1700 x 940 it scales up
   with the lessons. */
@media (orientation:landscape) and (min-width:1000px) and (min-height:621px){
  html:not([data-expanded-text=true]) .surface>main.scoring-screen{max-width:none;height:auto;padding:24px var(--learn-gutter) 32px;column-gap:40px}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-hud{min-height:44px;margin:0 0 10px;font-size:.72rem}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-hud button{min-height:44px;padding:0 10px;font-size:.95rem}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-hud button:first-child{margin-left:-10px}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-hud button:last-child{margin-right:-10px}
  html:not([data-expanded-text=true]) .scoring-screen .score-felt{margin:0;padding:22px 14px 24px}
  html:not([data-expanded-text=true]) .score-fit .score-context span{font-size:.78rem;padding:5px 11px}
  html:not([data-expanded-text=true]) .score-fit .score-group>span{font-size:.64rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-heading{gap:8px;margin:0}
  html:not([data-expanded-text=true]) .scoring-screen .score-heading h1{font-size:2.6rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-heading p{font-size:.72rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-description{margin-top:14px;font-size:1.02rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-work{gap:14px;padding:18px 0 12px}
  html:not([data-expanded-text=true]) .scoring-screen .step-size{gap:14px}
  html:not([data-expanded-text=true]) .scoring-screen .score-prompt{font-size:1.6rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-payment-hint{font-size:.98rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-choices{gap:10px}
  html:not([data-expanded-text=true]) .scoring-screen .score-choices>button{min-height:86px}
  html:not([data-expanded-text=true]) .scoring-screen .score-choices>button strong{font-size:2.2rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-feedback>h2{font-size:1.9rem}
  html:not([data-expanded-text=true]) .scoring-screen .score-feedback>p{font-size:1.05rem}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-dock{margin:12px 0 0;padding:0}
  html:not([data-expanded-text=true]) .scoring-screen>.lesson-dock button{min-height:52px;font-size:1rem}
}

/* ---------- Dialog contents ---------- */
/* Small felt trays hold tiles inside dialogs; the full railed felt is kept
   for the winning hand. */
#overlay :is(.guide-offered,.guide-tiles,.public-tray,.inspected-sets,.inspected-tiles,.review-hand,.review-offer){box-sizing:border-box;border:0;border-radius:14px;background:radial-gradient(90% 80% at 50% 30%,rgba(255,226,170,.1),transparent 70%),radial-gradient(140% 120% at 50% 40%,transparent 50%,rgba(2,10,6,.5) 100%),url('/felt-v1.webp') center/300px,#1b4a31;box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 4px 12px rgba(0,0,0,.4),0 0 0 1px rgba(201,168,106,.2)}
#overlay .dialog-body .dialog-note{margin:0 0 12px;font:400 .82rem/1.5 var(--sans);color:var(--sage)}
#overlay .dialog-body .positive{color:var(--positive)}
#overlay .dialog-body .negative{color:var(--negative)}
#overlay .medallion-ring{width:34px;height:34px}
#overlay .medallion-ring .emblem{width:19px;height:19px}

/* Hand guide. */
#overlay .guide-pause-note{display:inline-flex;align-items:center;gap:9px;max-width:100%;margin:0 0 14px;padding:5px 13px 5px 11px;border-radius:999px;border:1px solid rgba(201,168,106,.28);background:rgba(8,15,12,.6);font:500 .74rem/1.3 var(--sans);letter-spacing:.01em;color:var(--sage)}
#overlay .guide-pause-note:before{content:'';flex:none;box-sizing:border-box;width:8px;height:10px;border:solid var(--gold);border-width:0 2.5px}
#overlay .dialog-body .hand-guide h3.guide-title{margin:0 0 6px;font:500 1.55rem/1.15 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
#overlay .hand-guide>h3:not(.guide-title){margin:22px 0 8px}
#overlay div.guide-offered{display:flex;align-items:center;gap:14px;margin:14px 0;padding:10px 16px}
#overlay .guide-offered .tile{--w:44px}
#overlay .guide-offered>span{display:block;min-width:0;font:400 .9rem/1.3 var(--sans);color:var(--ivory);text-shadow:0 1px 3px rgba(0,0,0,.55)}
#overlay .guide-offered>span strong{display:block;font:500 1.2rem/1.2 var(--serif);color:var(--ivory)}
#overlay .guide-offered>span br{display:none}
#overlay .guide-offered>span small{display:block;margin-top:3px;font:600 .6rem/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
#overlay .guide-claim{margin:14px 0 0;padding:14px 16px;border:1px solid var(--gold-line);border-top:1px solid var(--gold-line);border-radius:var(--radius-card);background:var(--panel-fill)}
#overlay .dialog-body .guide-claim h3{margin:0 0 10px;font:500 1.3rem/1.1 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
#overlay .guide-tiles{display:flex;justify-content:center;gap:3px;margin:0 0 10px;padding:12px}
#overlay .guide-tiles .tile{--w:42px}
#overlay .dialog-body .guide-claim p{margin:0;font-size:.9rem}
#overlay .guide-detail{margin:14px 0 0;padding:8px 0 0;border:0;border-top:1px solid rgba(201,168,106,.14)}
#overlay .guide-detail p{margin:0 0 8px}
#overlay .guide-links{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:18px 0 0}
#overlay .guide-links button{width:100%;min-width:0;min-height:46px;padding:0 10px;font-size:.88rem}
#overlay .dialog-body :is(.guide-scope,.glossary-scope){margin:14px 0 0;font:400 .8rem/1.5 var(--sans);color:var(--sage)}
#overlay .hand-guide .dialog-actions>*{flex:1 1 100%}
/* The hand hint's suggested tile: a felt chip that selects it. */
#overlay button.guide-offered{position:relative;display:flex;align-items:center;justify-content:flex-start;gap:14px;width:100%;min-height:76px;margin:4px 0 14px;padding:10px 44px 10px 16px;border:1px solid var(--gold-line-strong);border-radius:14px;color:var(--ivory);font:500 1.02rem/1.3 var(--sans);text-align:left;text-shadow:0 1px 3px rgba(0,0,0,.6);cursor:pointer}
#overlay button.guide-offered .tile{--w:40px}
#overlay button.guide-offered:after{content:'';position:absolute;right:20px;top:50%;width:8px;height:8px;border-top:1.5px solid var(--gold-bright);border-right:1.5px solid var(--gold-bright);transform:translateY(-50%) rotate(45deg)}
@media (hover:hover) and (pointer:fine){#overlay button.guide-offered:hover{box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 4px 12px rgba(0,0,0,.4),0 0 0 1px var(--gold-bright),0 0 18px rgba(240,200,120,.25)}}
/* Choose Your Move: one full-width outlined row per legal claim. */
#overlay .claim-choices{display:grid;grid-template-columns:minmax(0,1fr);gap:10px;margin:6px 0 4px}
#overlay .claim-choices>button{width:100%;min-height:54px;justify-content:flex-start;padding:0 18px;font:500 1.02rem/1.2 var(--sans)}
/* Each choice shows the set it makes: your tiles, and the discard in a gold ring. */
#overlay .claim-choice{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:14px;min-height:72px;padding:10px 16px;border:1px solid var(--gold-line);border-radius:14px;background:linear-gradient(180deg,rgba(28,44,36,.9),rgba(14,24,19,.9));color:var(--ivory);text-align:left;cursor:pointer}
#overlay .claim-choice:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}
@media (hover:hover){#overlay .claim-choice:hover{border-color:var(--gold-line-strong)}}
#overlay .claim-choice.is-win{border-color:#f0d9a8;background:var(--primary-fill);color:var(--ink-on-gold)}
#overlay .claim-tiles{display:flex;gap:2px}
#overlay .claim-tile{position:relative;display:block;border-radius:6px}
#overlay .claim-tile .tile{--w:34px;width:34px;height:auto;aspect-ratio:1/1.52;margin:0}
#overlay .claim-tile.from-discard{box-shadow:0 0 0 2px var(--gold-bright),0 0 12px rgba(230,200,143,.45)}
#overlay .claim-seal{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;background:#7c1a14;box-shadow:0 0 0 2px #f0d9a8;color:#f7e6c0;font:600 1.3rem/1 'Songti SC','Noto Serif CJK TC',serif}
#overlay .claim-text{display:grid;gap:3px;min-width:0}
#overlay .claim-text strong{font:600 1.02rem/1.2 var(--sans)}
#overlay .claim-text small{font:400 .84rem/1.3 var(--sans);color:var(--sage)}
#overlay .claim-choice.is-win .claim-text small{color:#4a3a1c}

/* Glossary. */
#overlay .glossary-search{display:grid;gap:8px;margin:16px 0 10px;font:600 .66rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
#overlay .glossary-search input{box-sizing:border-box;width:100%;min-height:48px;margin:0;padding:0 14px 0 42px;border-radius:12px;border:1px solid var(--gold-line);background:#0a1410 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c9a86a' stroke-width='1.7' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='m15.5 15.5 5 5'/%3E%3C/svg%3E") 14px center/18px no-repeat;box-shadow:inset 0 2px 6px rgba(0,0,0,.4);color:var(--ivory);font:400 1rem/1.2 var(--sans);letter-spacing:0;text-transform:none;outline:none;-webkit-appearance:none;appearance:none}
#overlay .glossary-search input:focus{border-color:var(--gold-bright);box-shadow:inset 0 2px 6px rgba(0,0,0,.4),0 0 0 3px rgba(230,200,143,.18)}
#overlay .glossary-search input::placeholder{color:var(--sage-2);opacity:1}
#overlay .dialog-body .glossary-count{margin:0 0 2px;font:600 .62rem/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--sage)}
#overlay details.glossary-term{margin:0;padding:0;border:0;border-bottom:1px solid rgba(201,168,106,.14)}
#overlay .glossary-term>summary{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:12px;min-height:58px;padding:8px 4px 8px 2px;cursor:pointer;list-style:none;font:500 1.22rem/1.2 var(--serif);color:var(--ivory)}
#overlay .glossary-term>summary:before{content:none;display:none}
#overlay .glossary-term>summary:after{content:'';grid-column:2;grid-row:1/3;width:8px;height:8px;margin-right:6px;border-right:1.5px solid var(--gold);border-bottom:1.5px solid var(--gold);transform:rotate(45deg);transition:transform .2s}
#overlay .glossary-term[open]>summary:after{transform:rotate(-135deg)}
#overlay .glossary-term>summary small{display:block;grid-column:1;margin:2px 0 0;font:400 .78rem/1.3 var(--sans);letter-spacing:0;color:var(--sage)}
#overlay .dialog-body .glossary-term p{margin:0 0 10px;padding:0 2px;font:400 .93rem/1.55 var(--sans);color:var(--ivory-2)}
#overlay .glossary-term button{min-height:40px;margin:0 0 14px;padding:0 14px;font-size:.86rem}

/* Lesson notes and rules: a lead paragraph, gold bullets, ruled section heads. */
#overlay .dialog-body .reference-copy>p:first-child{font:400 1.04rem/1.55 var(--sans);color:var(--ivory)}
#overlay .dialog-body .reference-copy h3{display:flex;align-items:center;gap:12px}
#overlay .dialog-body .reference-copy h3:after{content:'';flex:1;height:1px;background:rgba(201,168,106,.2)}
#overlay .dialog-body .reference-copy ul{padding:0;list-style:none}
#overlay .dialog-body .reference-copy li{position:relative;padding-left:18px}
#overlay .dialog-body .reference-copy li:before{content:'';position:absolute;left:3px;top:.62em;width:5px;height:5px;border-radius:50%;background:var(--gold)}
#overlay .lesson-reference-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:18px 0 4px}
#overlay .lesson-reference-actions button{width:100%;min-width:0;min-height:46px;padding:0 10px;font-size:.88rem}

/* Table details: the wall count as a lacquer plaque, then each seat. */
#overlay .dialog-body .public-wall{margin:0 0 4px;padding:11px 16px;border-radius:12px;background:linear-gradient(180deg,#19241e,#070c0a);box-shadow:0 0 0 1px rgba(201,168,106,.45),0 0 0 3px rgba(5,9,7,.8),inset 0 1px 0 rgba(255,240,210,.08);text-align:center}
#overlay .dialog-body .public-wall strong{font:500 1.12rem/1.3 var(--serif);color:var(--ivory)}
#overlay .dialog-body .seat-points{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:4px 0 10px}
#overlay .dialog-body .seat-points>div{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto auto;align-items:center;column-gap:10px;row-gap:1px;padding:10px 12px;border:1px solid rgba(201,168,106,.26);border-radius:12px;background:var(--panel-fill)}
#overlay .dialog-body .seat-points>div:last-child{border-bottom:1px solid rgba(201,168,106,.26)}
#overlay .dialog-body .seat-points .medallion-ring{grid-row:1/3}
#overlay .dialog-body .seat-points span:not(.medallion-ring){font:500 .82rem/1.2 var(--sans);color:var(--ivory-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#overlay .dialog-body .seat-points strong{font:500 1.4rem/1 var(--serif);color:var(--ivory)}
#overlay .dialog-body .seat-points strong.positive{color:var(--positive)}
#overlay .dialog-body .seat-points strong.negative{color:var(--negative)}
#overlay .dialog-body .seat-points .is-you{border-color:var(--gold-line-strong)}
#overlay .dialog-body .seat-points .is-you:last-child{border-bottom-color:var(--gold-line-strong)}
#overlay .public-seat{margin:18px 0 0;padding:16px 0 0;border:0;border-top:1px solid rgba(201,168,106,.16)}
#overlay .public-seat-head{display:flex;align-items:center;gap:12px;margin:0 0 10px}
#overlay .dialog-body .public-seat h3{margin:0;font:500 1.28rem/1.15 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
#overlay .dialog-body .public-seat-head p{margin:2px 0 0;font:400 .8rem/1.3 var(--sans);color:var(--sage)}
#overlay .public-tray{display:grid;gap:8px;padding:12px;text-shadow:0 1px 3px rgba(0,0,0,.55)}
#overlay .public-melds{display:flex;flex-wrap:wrap;gap:8px 12px;margin:0}
#overlay .public-melds>span{font:500 .78rem/1.3 var(--sans);color:var(--ivory-2)}
#overlay .live-meld{display:flex;gap:2px;--w:30px}
#overlay .live-meld .tile{--w:30px}
#overlay .dialog-body .public-bonuses{margin:0;font:400 .8rem/1.4 var(--sans);color:var(--ivory-2)}
#overlay .public-tray .small-label{display:block;margin:2px 0 0;font:600 .58rem/1.2 var(--sans);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
#overlay .public-river{display:flex;flex-wrap:wrap;gap:6px 3px;margin:0}
#overlay .river-entry{display:grid;justify-items:center;align-content:start;gap:2px;opacity:1}
#overlay .river-entry.claimed .tile{opacity:.45}
#overlay .river-entry small{font:600 .48rem/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--gold)}
#overlay .public-river .tile{--w:28px}
#overlay .dialog-body .public-river>p{margin:0;font-size:.8rem;color:var(--ivory-2)}

/* A seat's tiles, each with its name. */
#overlay .dialog-body .seat-inspection h3{margin:18px 0 8px}
#overlay .dialog-body .seat-inspection h3:first-child{margin-top:0}
#overlay .seat-inspection h3 small{margin-left:8px;font:500 .72rem/1 var(--sans);letter-spacing:.02em;text-transform:none;color:var(--sage)}
#overlay :is(.inspected-sets,.inspected-tiles){display:flex;flex-wrap:wrap;gap:12px 6px;margin:0;padding:12px}
#overlay .inspected-sets{gap:14px 18px}
#overlay .inspected-set{display:grid;gap:6px;justify-items:center}
#overlay .inspected-set>span{display:block;margin:0;font:600 .58rem/1.2 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
#overlay .inspected-set>div{display:flex;gap:2px}
#overlay .inspected-piece{display:grid;justify-items:center;align-content:start;gap:4px;width:auto;min-width:60px;max-width:88px;margin:0;font:500 .62rem/1.2 var(--sans);color:var(--ivory-2);text-align:center;text-shadow:0 1px 3px rgba(0,0,0,.6);overflow-wrap:break-word}
/* Inspection is for reading: tiles stay large (52 px) and wrap. */
#overlay .inspected-piece .tile{--w:52px}
#overlay .inspected-piece .tile-back{--w:52px}
#overlay .inspected-piece small{font:600 .5rem/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--gold)}
#overlay .dialog-body :is(.inspected-sets,.inspected-tiles)>p{margin:0;font-size:.84rem;color:var(--ivory-2)}

/* How the hand scored: the winning hand on railed felt, then summary cards. */
#overlay .winning-tiles{margin:0 0 14px}
#overlay .dialog-body h3+.winning-tiles>h3{margin-top:4px}
#overlay .winning-felt{container-type:inline-size;display:grid;gap:12px;margin:0 0 10px;padding:14px 8px 16px}
#overlay .winning-felt .tile{--w:min(40px,calc((100cqw - 34px) / 6.3))}
#overlay .winning-felt .score-bonuses .tile{--w:30px}
#overlay .winning-felt .loose-tiles>div{flex-wrap:wrap;justify-content:center;gap:4px 2px}
#overlay .dialog-body .winning-reveal{margin:0;font:400 .8rem/1.5 var(--sans);color:var(--sage)}
#overlay .score-card{margin:0 0 12px}
#overlay .dialog-body .score-card-head h3{margin:0;font:500 1.3rem/1.15 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
#overlay .dialog-body .score-card-head strong{font:500 1.3rem/1 var(--serif);color:var(--gold-bright)}
#overlay .dialog-body .score-card>p{margin:10px 0 2px;font:400 .88rem/1.5 var(--sans);color:var(--ivory-2)}
#overlay .dialog-body .score-card .payment-breakdown{margin:4px 0 0}

/* Decisions, payments and match hands: hairline cards. */
#overlay .decision-entry{margin:10px 0 0;padding:14px 16px;border:1px solid rgba(201,168,106,.24);border-radius:var(--radius-card);background:var(--panel-fill)}
#overlay .dialog-body .decision-entry>h3{margin:0 0 6px;font:500 1.14rem/1.25 var(--serif);letter-spacing:0;text-transform:none;color:var(--ivory)}
#overlay .dialog-body .decision-entry p{margin:0 0 8px;font:400 .88rem/1.5 var(--sans);color:var(--ivory-2)}
#overlay .dialog-body .decision-entry p:last-child{margin-bottom:0}
#overlay .dialog-body .decision-guide strong{color:var(--gold-bright)}
#overlay .decision-entry details{margin:8px 0 0;padding:6px 0 0;border-top:1px solid rgba(201,168,106,.14)}
#overlay .decision-entry summary{min-height:40px;padding:0}
#overlay .review-hand{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 3px;margin:4px 0 10px;padding:12px 10px}
#overlay .review-hand .tile{--w:34px}
#overlay .review-offer{display:flex;justify-content:center;margin:4px 0 10px;padding:12px}
#overlay .review-offer .tile{--w:44px}
#overlay .decision-entry .public-melds{margin:4px 0 10px;padding:10px;border-radius:12px;background:rgba(6,14,10,.45)}
#overlay .ledger-entry{padding:10px 14px}
#overlay .dialog-body .ledger-entry>h3{margin:0 0 2px;font:600 .9rem/1.3 var(--sans);color:var(--ivory)}
#overlay .dialog-body .ledger-entry p{font-size:.82rem;color:var(--sage)}
#overlay .dialog-body .match-status strong{font:500 1.3rem/1.3 var(--serif);color:var(--ivory)}
#overlay .match-history-points{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 0}
#overlay .match-history-points span{padding:3px 9px;border-radius:999px;border:1px solid rgba(201,168,106,.22);background:rgba(6,14,10,.4);font:500 .74rem/1.3 var(--sans);color:var(--ivory-2)}
#overlay .match-history-points span.positive{color:var(--positive)}
#overlay .match-history-points span.negative{color:var(--negative)}
#overlay .dialog-body>button.outline{margin-top:4px}
@media (max-width:360px){#overlay .dialog-body .seat-points{grid-template-columns:1fr}}

/* ---------- Touch targets ---------- */
/* A tile you can choose is at least 44 px wide. Hands with choosable tiles
   wrap to another row rather than shrinking them. */
.demo-felt :is(.kong-hand .demo-hand,.wonder-family .demo-hand:has(.demo-hand-tile)){--pick:max(44px,var(--dt));display:grid;grid-template-columns:repeat(auto-fill,var(--pick));justify-content:center}
.demo-felt :is(.kong-hand .demo-hand,.wonder-family .demo-hand:has(.demo-hand-tile)) .tile{--w:var(--pick)}
.demo-felt .demo-hand-tile .tile{--w:max(44px,var(--dt))}
/* Your hand in the turn demo holds 13 tiles, then 14 after the draw: two rows
   of seven, or one row of fourteen when fourteen 44 px tiles fit, so the draw
   never adds a row and moves the table. */
.table-demo .demo-felt .demo-turn ~ .demo-hand{--pick:max(44px,var(--dt));display:grid;grid-template-columns:repeat(7,var(--pick));justify-content:center;gap:4px}
.table-demo .demo-felt .demo-turn ~ .demo-hand .tile{--w:var(--pick)}
@container (min-width:680px){.table-demo .demo-felt .demo-turn ~ .demo-hand{grid-template-columns:repeat(14,var(--pick))}}

/* ---------- At The Movies (src/movie-scene-view.js) ---------- */
/* The lesson layout with a demonstration's felt: our table for every step, one zoom
   for all of them (step-fit.js), and the step's words in the text box. */
.movie-screen .movie-text{display:grid;gap:6px;margin:0}
.movie-screen .movie-kicker{margin:0;font:600 .66rem/1.2 var(--sans);letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.movie-screen .movie-text h2{margin:0;font:500 1.4rem/1.14 var(--serif);letter-spacing:.005em;color:var(--ivory)}
.movie-screen .movie-text h2:focus{outline:none}
.movie-screen .movie-text p:not(.movie-kicker){max-width:62ch;margin:0;font:400 .96rem/1.5 var(--sans);color:var(--ivory-2)}
/* Portrait: the heading shares its row with Scene Notes (the dots in the actions
   say where you are), so the felt and the step's words keep the room. */
@media (orientation:portrait){
  .app-lesson>.teaching-table.movie-scene{grid-template-columns:minmax(0,1fr) auto;grid-template-rows:auto minmax(var(--felt-min),1fr) minmax(0,min(var(--text-h,9999px),var(--text-max))) auto;grid-template-areas:"title hud" "stage stage" "body body" "dock dock"}
  .movie-scene>.lesson-hud{align-self:end;min-height:44px;margin:0;padding:0 0 0 8px}
  .movie-scene>.lesson-title{margin-top:6px}
}
/* The step's kicker says where you are, so the heading's place gives way everywhere. */
.movie-scene>.lesson-hud>.lesson-place{display:none}
@media (orientation:landscape) and (min-width:700px) and (max-height:400px){
  html:not([data-expanded-text=true]) .movie-screen .lesson-title .lesson-eyebrow{display:block}
}
@media (orientation:portrait) and (max-width:429px){
  .movie-scene>.lesson-hud>button.quiet{position:relative;width:44px;padding:0;gap:0;justify-content:center}
  .movie-scene>.lesson-hud>button.quiet>span{width:0;height:0;margin:0;overflow:hidden;font-size:0;line-height:0;white-space:nowrap}
}
/* The table, seen from behind Rachel: Eleanor across the felt, the aunties either side
   of the plaque, Rachel at the near rail. Every step shows the same four places, so
   only the tiles change: the 8 Bamboo leaves Rachel's rail for the plaque, then
   joins Eleanor's Pong. Nothing on it is tapped; it zooms to fill the felt. */
.movie-screen .lesson-stage{padding:8px}
.table-demo.movie-felt{--fit-max:2.4}
.demo-felt.movie-table{--mt:30px;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-areas:"tag tag tag" "across across across" "left plaque right" "near near near";align-items:center;justify-items:center;gap:10px 10px;padding:2px 0}
.movie-table .movie-reconstructed{grid-area:tag;justify-self:start;margin:0;padding:3px 9px;border:1px solid rgba(230,200,143,.35);border-radius:999px;background:rgba(6,14,10,.5);font:600 .54rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-bright);text-shadow:none}
.movie-table .movie-across{grid-area:across}
.movie-table .movie-near{grid-area:near;flex-direction:column-reverse}
.movie-table .movie-side.is-left{grid-area:left}
.movie-table .movie-side.is-right{grid-area:right}
.movie-table .movie-seat{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0;max-width:100%}
.movie-table :is(.movie-across,.movie-near){width:100%}
.movie-table .movie-tiles{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-end;gap:5px 8px;max-width:100%}
.movie-table .movie-set{display:flex;flex:none;gap:1px}
.movie-table .tile{--w:var(--mt)}
.movie-table .movie-back{display:block;box-sizing:border-box;flex:none;width:var(--mt);aspect-ratio:1/1.52;border-radius:2px;background:linear-gradient(180deg,#2f8a5d,#1d6b46 64%,#0f4a2f 76%,#e9dfc8 76%,#cfc3a8);box-shadow:0 1.5px 1.5px rgba(0,0,0,.5)}
html[data-portraits] .movie-table .movie-back{border-radius:0;background:var(--portrait-back) center/contain no-repeat;box-shadow:none;filter:drop-shadow(0 1.5px 1px rgba(0,0,0,.5))}
.movie-table .movie-side .movie-backs{--mt:12px;display:grid;grid-template-columns:repeat(7,var(--mt));justify-content:center;gap:2px 1px}
.movie-table .movie-bonus{margin-left:6px}
/* The 8 Bamboo, wherever it is. */
.movie-table .is-key>.tile[data-tile-id=s8]:last-child,.movie-table .movie-plaque .tile[data-tile-id=s8]{border-radius:4px;outline:2px solid var(--gold-bright);outline-offset:1px;box-shadow:0 0 14px rgba(240,200,120,.45)}
/* Names: the medallion, the name and the seat's wind. */
.movie-table .movie-name{position:relative;display:flex;align-items:center;gap:8px;margin:0;text-align:left}
.movie-table .movie-name .medallion-ring{width:32px;height:32px}
.movie-table .movie-name .medallion-ring .emblem{width:18px;height:18px}
.movie-table .movie-name>span{display:grid;gap:1px}
.movie-table .movie-name strong{font:500 1.05rem/1.1 var(--serif);color:var(--ivory)}
.movie-table .movie-name small{font:600 .56rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--sage)}
.movie-table .movie-side .movie-name{flex-direction:column;gap:4px;text-align:center}
.movie-table .movie-name.is-lit .medallion-ring{color:var(--gold-bright);box-shadow:0 0 0 1.5px var(--gold-bright),0 0 0 3px rgba(10,19,15,.9),0 0 0 4px rgba(230,200,143,.55),0 0 18px rgba(240,200,120,.55)}
.movie-table .movie-name.is-lit strong{color:var(--gold-bright)}
/* A call, as at the table: gold for the win, quieter for the Chow it beats. */
.movie-table .movie-call{padding:2px 8px;border-radius:999px;background:rgba(6,14,10,.7);box-shadow:0 0 0 1px var(--gold-bright);font:italic 500 1rem/1.2 var(--serif);color:var(--gold-bright);white-space:nowrap}
.movie-table .movie-side .movie-call{box-shadow:0 0 0 1px rgba(201,168,106,.4);font-size:.86rem;color:var(--sage);text-decoration:line-through;text-decoration-thickness:1px}
/* The plaque: black lacquer and a gold hairline, as on the game table. */
.movie-table .movie-plaque{grid-area:plaque;box-sizing:border-box;display:grid;justify-items:center;align-content:center;gap:6px;width:120px;min-height:100px;padding:10px 8px;border-radius:12px;background:linear-gradient(180deg,#19241e,#070c0a);box-shadow:0 0 0 1px rgba(201,168,106,.5),0 0 0 3px rgba(5,9,7,.85),0 0 0 4px rgba(201,168,106,.16),0 10px 22px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,240,210,.08);text-shadow:none}
.movie-table .movie-plaque>span:last-child{font:600 .56rem/1.3 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--gold);text-align:center;text-wrap:balance}
.movie-table .movie-plaque-tiles{display:flex;justify-content:center;gap:4px}
.movie-table .movie-plaque .tile{--w:34px}
.movie-table .movie-plaque-ask{font:500 2.4rem/1 var(--serif);color:var(--gold-bright)}
/* Very large text: the page scrolls as a lesson does, and the actions wrap inside their buttons. */
html[data-expanded-text=true] .movie-screen .lesson-dock>button{flex:1 1 0;min-width:0;white-space:normal;line-height:1.15;text-align:center;text-wrap:balance}
/* Desktop: the words beside the table read at a comfortable size (the text box still
   holds the longest step, so nothing moves). */
@media (orientation:landscape) and (min-width:1100px) and (min-height:700px){
  html:not([data-expanded-text=true]) .movie-screen .movie-kicker{font-size:.74rem}
  html:not([data-expanded-text=true]) .movie-screen .movie-text h2{font-size:1.85rem}
  html:not([data-expanded-text=true]) .movie-screen .movie-text p:not(.movie-kicker){font-size:1.1rem;line-height:1.55}
}
/* Short landscape phones: a little more width for the words and a smaller size, so
   the longest step fits beside the table; Tamil's script sets large, so a step less. */
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .app-lesson>.teaching-table.demo-lesson.movie-scene{grid-template-columns:minmax(0,1.04fr) minmax(0,1fr)}
  html:not([data-expanded-text=true]) .movie-screen .movie-text{gap:4px}
  html:not([data-expanded-text=true]) .movie-screen .movie-text h2{font-size:1.25rem}
  html:not([data-expanded-text=true]) .movie-screen .movie-text p:not(.movie-kicker){font-size:.88rem;line-height:1.42}
  html:not([data-expanded-text=true]):lang(ta) .movie-screen .movie-text h2{font-size:1.05rem}
  html:not([data-expanded-text=true]):lang(ta) .movie-screen .movie-text p:not(.movie-kicker){font-size:.78rem;line-height:1.5}
}
/* A story step says more than a lesson's caption: on a portrait phone its words get a
   little more of the screen (the felt still keeps two fifths). */
@media (orientation:portrait){
  .app-lesson>.teaching-table.demo-lesson.movie-scene{--felt-min:clamp(200px,calc(var(--felt-room) * .4),340px);--text-max:calc(var(--felt-room) * .39)}
}
/* Short portrait phones: Tamil's script sets large, so its words take a step down there too. */
@media (orientation:portrait) and (max-height:760px){
  html:not([data-expanded-text=true]):lang(ta) .movie-screen .movie-text h2{font-size:1.2rem}
  html:not([data-expanded-text=true]):lang(ta) .movie-screen .movie-text p:not(.movie-kicker){font-size:.86rem;line-height:1.5}
}
/* Short landscape phones: the kicker says where you are, so the dots give way, and the
   two actions share the row, a long label wrapping inside its button. */
@media (orientation:landscape) and (min-width:700px) and (max-height:620px){
  html:not([data-expanded-text=true]) .movie-screen .lesson-dots{display:none}
  html:not([data-expanded-text=true]) .movie-screen .lesson-dock>button{flex:1 1 0;min-width:0;margin:0;padding:0 12px;white-space:normal;line-height:1.15;text-align:center;text-wrap:balance}
  html:not([data-expanded-text=true]) .movie-screen .lesson-dock>button.primary{flex-grow:1.3}
}

/* src/solitaire.css */
/* Gwai Lou Mode: the board picker and the solitaire board. The board is the table's world (felt,
   walnut, lamplight, the same 3D tiles); the controls are the table's (gm-button, the message line).
   src/solitaire-board.js draws the tiles and places the accessible tile buttons over them. */

/* ---------- The picker ---------- */
.sol-shape{display:block;width:100%;height:100%}
.sol-shape .e{fill:var(--theme-back,#124b3c)}
.sol-shape .f{fill:var(--theme-face,#f5efe2)}
.sol-shape .f.l1{fill:color-mix(in srgb,var(--theme-face,#f5efe2) 88%,#fff)}
.sol-shape .f.l2{fill:color-mix(in srgb,var(--theme-face,#f5efe2) 76%,#fff)}
.sol-shape .f.l3,.sol-shape .f.l4,.sol-shape .f.l5{fill:color-mix(in srgb,var(--theme-face,#f5efe2) 64%,#fff)}

.surface>main.sol-pick{width:100%;max-width:none;margin:0;padding:6px max(16px,var(--safe-right)) calc(28px + var(--safe-bottom)) max(16px,var(--safe-left));overflow:auto;overscroll-behavior:contain}
.sol-pick>*{width:100%;max-width:1080px;margin-inline:auto}
.sol-pick-head{display:grid;justify-items:start;gap:6px;margin-bottom:18px}
.sol-pick-head h1{margin:0;font:500 min(2.3rem,46px)/1.05 var(--serif);letter-spacing:.005em;color:var(--ivory)}
.sol-pick-head .home-rule{display:block;width:54px;height:1px;margin:4px 0 2px;background:linear-gradient(90deg,var(--gold),transparent)}
.sol-lead{max-width:62ch;margin:0;font:400 .95rem/1.5 var(--sans);color:var(--ivory-2)}
.sol-featured{display:grid;gap:10px;margin-bottom:22px}
.sol-boards>h2{margin:0 0 10px}
.sol-grid{display:grid;gap:10px}

.sol-card{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px;width:100%;min-height:88px;padding:10px 14px 10px 10px;border-radius:var(--radius-card);border:1px solid var(--gold-line);background:linear-gradient(180deg,rgba(25,45,35,.92),rgba(14,27,21,.92));color:var(--ivory);text-align:left;box-shadow:inset 0 1px 0 rgba(255,240,210,.05),0 8px 22px rgba(0,0,0,.25);cursor:pointer;transition:border-color .2s,background .2s,transform .15s}
.sol-card-art{display:block;box-sizing:border-box;width:96px;height:74px;padding:6px;border-radius:10px;background:radial-gradient(90% 90% at 50% 30%,rgba(255,226,170,.14),transparent 70%),linear-gradient(rgb(26,62,44),rgb(18,46,33));box-shadow:inset 0 0 0 1px rgba(0,0,0,.35),inset 0 0 14px rgba(0,0,0,.35),0 0 0 3px rgba(74,46,28,.9),0 0 0 4px rgba(201,168,106,.25)}
.sol-card-copy{display:grid;gap:3px;min-width:0}
.sol-card-copy strong{font:500 1.36rem/1.1 var(--serif);color:var(--ivory)}
.sol-card-copy small{font:400 .82rem/1.3 var(--sans);color:var(--sage)}
.sol-card-copy .eyebrow{font-size:.64rem}
.sol-card .sol-blurb{color:var(--ivory-2)}
.sol-card>.icon:last-child{width:18px;height:18px;color:var(--gold)}
.sol-best{justify-self:start;margin-top:2px;padding:2px 9px;border-radius:999px;border:1px solid var(--gold-line-strong);font:500 .68rem/1.4 var(--sans);letter-spacing:.06em;color:var(--gold-bright)}
.sol-best.none{border-color:transparent;padding-inline:0;color:var(--sage-2);letter-spacing:.02em}
.sol-zoom-note{display:inline-flex;align-items:center;gap:5px;font:400 .72rem/1.3 var(--sans);color:var(--sage-2)}
.sol-zoom-note .icon{width:13px;height:13px;color:var(--gold)}
.sol-card.sol-continue,.sol-card.sol-daily{min-height:96px;border-color:var(--gold-line-strong)}
.sol-card.sol-continue{background:linear-gradient(180deg,rgba(35,62,47,.95),rgba(17,33,25,.95))}
.sol-card.sol-daily.is-done .sol-card-copy small{color:var(--positive)}
.sol-card :is(.eyebrow){color:var(--gold)}
@media (hover:hover) and (pointer:fine){
  .sol-card:hover{border-color:var(--gold-line-strong);background:linear-gradient(180deg,rgba(34,60,46,.96),rgba(17,33,25,.96));box-shadow:inset 0 1px 0 rgba(255,240,210,.08),0 0 0 1px rgba(214,182,120,.08),0 14px 30px rgba(0,0,0,.34);transform:translateY(-1px)}
  .sol-card:hover>.icon:last-child{transform:translateX(3px);color:var(--gold-bright)}
}
.sol-card>.icon:last-child{transition:transform .22s var(--ease-out)}
.sol-card:active{transform:translateY(1px)}
.sol-card:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}
/* Fresh Boards: three cards (Easy, Normal, Hard), each showing the very board it deals. */
.sol-fresh{margin-bottom:22px}
.sol-fresh>h2{margin:0 0 4px}
.sol-fresh-lead{margin:0 0 10px;font:400 .86rem/1.4 var(--sans);color:var(--sage)}
.sol-fresh-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.sol-fresh-grid .sol-card{grid-template-columns:minmax(0,1fr);grid-template-rows:auto 1fr;align-items:start;justify-items:stretch;gap:8px;min-height:0;padding:8px 8px 10px}
.sol-fresh-grid .sol-card-art{width:100%;height:auto;aspect-ratio:1/1.05;padding:6px}
.sol-fresh-grid .sol-card-copy strong{font-size:1.18rem}
.sol-fresh-grid .sol-blurb{font-size:.76rem}
.sol-fresh-grid .sol-best{font-size:.62rem;letter-spacing:.03em;padding-inline:7px}
.sol-fresh-grid .sol-best.none{display:none}
.sol-card[data-level=e] .sol-card-copy strong{color:#bfe3c2}
.sol-card[data-level=h] .sol-card-copy strong{color:var(--gold-bright)}
.sol-upright-note:before{content:'';width:8px;height:13px;border:1.5px solid var(--gold);border-radius:2px;box-sizing:border-box}
.sol-pick-links{display:flex;flex-wrap:wrap;gap:4px 14px}
/* Statistics: the numbers in a grid, then each board cleared. */
.sol-stats{display:grid;gap:16px}
.sol-stats-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px 8px;margin:0}
.sol-stats-grid div{display:grid;gap:2px;min-width:0;padding:8px 6px;border-radius:10px;background:rgba(255,240,210,.04);text-align:center}
.sol-stats-grid dt{font:500 .6rem/1.25 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--sage)}
.sol-stats-grid dd{margin:0;font:500 1.35rem/1.1 var(--serif);color:var(--ivory);font-variant-numeric:tabular-nums}
.sol-stats-table{width:100%;border-collapse:collapse;font:400 .9rem/1.3 var(--sans);color:var(--ivory-2)}
.sol-stats-table caption{text-align:left;margin-bottom:6px;color:var(--gold)}
.sol-stats-table th,.sol-stats-table td{padding:7px 4px;border-bottom:1px solid var(--gold-line);text-align:right;font-variant-numeric:tabular-nums}
.sol-stats-table th:first-child{text-align:left;font-weight:500;color:var(--ivory)}
.sol-stats-table thead th{font:500 .62rem/1.3 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--sage)}
.sol-pick-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 16px;margin-top:22px;padding-top:14px;border-top:1px solid var(--gold-line)}
.sol-pick-foot p{margin:0;font:400 .88rem/1.4 var(--sans);color:var(--sage)}
@media (max-width:374px){
  .sol-card{gap:10px;padding-right:10px}
  .sol-card-art{width:78px;height:62px}
  .sol-card .sol-blurb{display:none}
}
@media (min-width:700px){
  .sol-featured{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
  .sol-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (min-width:1100px){
  .surface>main.sol-pick{padding-top:18px}
  .sol-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
  .sol-grid .sol-card{grid-template-columns:minmax(0,1fr);grid-template-rows:auto 1fr;align-items:start;gap:12px;padding:12px 12px 14px}
  .sol-grid .sol-card-art{width:100%;height:132px;padding:12px}
  .sol-card-copy strong{font-size:1.5rem}
}
/* Landscape phones: two short columns so a whole row of boards shows at once. */
@media (orientation:landscape) and (max-height:620px){
  .sol-pick-head{grid-template-columns:auto minmax(0,1fr);align-items:end;column-gap:18px;margin-bottom:12px}
  .sol-pick-head .eyebrow,.sol-pick-head h1,.sol-pick-head .home-rule{grid-column:1}
  .sol-pick-head .sol-lead{grid-column:2;grid-row:1/4;font-size:.86rem}
  .sol-featured{grid-template-columns:repeat(auto-fit,minmax(280px,1fr));margin-bottom:14px}
  .sol-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .sol-fresh-grid .sol-card{grid-template-columns:auto minmax(0,1fr);grid-template-rows:none;align-items:center}
  .sol-fresh-grid .sol-card-art{width:72px;height:66px;aspect-ratio:auto}
}
@media (min-width:1100px){.sol-fresh-grid .sol-card-art{height:150px;aspect-ratio:auto}}

/* ---------- The board screen ---------- */
html[data-screen=solitaire] .surface{background:radial-gradient(120% 80% at 50% 42%,#16271f 0%,var(--room) 62%,#070c0a 100%)}
html[data-screen=solitaire] .surface>header{position:relative;z-index:6;display:grid;grid-template-columns:48px minmax(0,1fr) 48px;align-items:center;gap:4px;height:58px;min-height:58px;padding:0 8px;border:0;background:linear-gradient(#0a110ee6,#0a110e00)}
html[data-screen=solitaire] .app-header .header-actions{justify-self:end;display:flex}
html[data-screen=solitaire] .app-header .save-status{position:absolute;right:56px;top:9px}
.sol-title .sol-clock{font-variant-numeric:tabular-nums}
/* The title can sit over the far rail: a soft shadow keeps it readable on the wood. */
.sol-title h1,.sol-title p{text-shadow:0 1px 2px rgba(0,0,0,.85),0 0 14px rgba(0,0,0,.7)}
.surface>main.sol-screen{display:grid;grid-template-rows:minmax(0,1fr) auto;overflow:hidden;width:100%;max-width:none;margin:-58px 0 0;padding:0}
/* --fit-*: the part of the board area clear of the header and the controls, where the tiles must fit. */
.sol-board{position:relative;min-height:0;overflow:hidden;isolation:isolate;touch-action:none;--fit-top:68px;--fit-bottom:8px;--fit-left:var(--safe-left,0px);--fit-right:var(--safe-right,0px)}
.sol-canvas{position:absolute;inset:0;z-index:0}
.sol-canvas canvas{display:block;width:100%;height:100%}
.sol-board:after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(130% 95% at 50% 46%,transparent 58%,rgba(3,8,6,.55) 100%)}
.sol-tiles{position:absolute;inset:0;z-index:2;pointer-events:none}
/* Each tile's button lies over the tile as drawn (left, top, width, height set by solitaire-board.js). */
.sol-tile{position:absolute;left:0;top:0;width:0;height:0;min-width:0;min-height:0;margin:0;padding:0;border:0;border-radius:5px;background:transparent;box-shadow:none;color:inherit;cursor:pointer;pointer-events:auto;-webkit-tap-highlight-color:transparent}
.sol-tile[data-free=false]{cursor:default}
.sol-board:not([data-placed]) .sol-tile{visibility:hidden}
.sol-tile:focus-visible{outline:2px solid var(--gold-bright);outline-offset:1px;border-radius:5px}
.sol-tile:focus:not(:focus-visible){outline:none}

/* The flat board, when WebGL is missing: the tiles themselves, stacked with each layer up and to the left, each tile's side (ivory, then the backing) as wide as the 3D board's band (--band, in tile pitches, from solitaire-board.js). */
.sol-board[data-flat] .sol-tile{display:block;border-radius:calc(var(--u,40px) * .12);background:linear-gradient(160deg,color-mix(in srgb,var(--theme-face,#fff5e2) 92%,#fff),var(--theme-face,#fff5e2));box-shadow:inset 0 0 0 1px rgba(120,100,70,.35),calc(var(--u,40px) * var(--band,.15) * .62) calc(var(--u,40px) * var(--band,.15) * .62) 0 0 color-mix(in srgb,var(--theme-face,#fff5e2) 62%,#6f6250),calc(var(--u,40px) * var(--band,.15)) calc(var(--u,40px) * var(--band,.15)) 0 0 var(--theme-back,#124b3c),calc(var(--u,40px) * .2) calc(var(--u,40px) * .24) calc(var(--u,40px) * .14) rgba(0,0,0,.42);transition:transform .16s var(--ease-out),filter .16s}
.sol-board[data-flat] .sol-face{position:absolute;inset:6.6% 8.8%;display:block}
.sol-board[data-flat] .sol-face svg{display:block;width:100%;height:100%}
.sol-board[data-flat] .sol-tile[aria-pressed=true]{transform:translate(-2px,-4px);box-shadow:inset 0 0 0 2px var(--gold-bright),0 0 0 2px rgba(230,200,143,.55),calc(var(--u,40px) * var(--band,.15)) calc(var(--u,40px) * var(--band,.15)) 0 0 var(--theme-back,#124b3c),0 8px 16px rgba(0,0,0,.5)}
.sol-board[data-flat][data-show-free=true] .sol-tile[data-free=false]{filter:brightness(.62) saturate(.7)}
.sol-board[data-flat] .sol-tile[data-hint]{animation:sol-hint 1.2s ease-in-out 3}
@keyframes sol-hint{50%{box-shadow:inset 0 0 0 2px #fff4d8,0 0 0 3px rgba(255,226,168,.8),0 0 16px rgba(255,226,168,.7)}}
html[data-motion=off] .sol-board[data-flat] .sol-tile[data-hint]{animation:none;box-shadow:inset 0 0 0 2px #fff4d8,0 0 0 3px rgba(255,226,168,.8)}
@media (prefers-reduced-motion:reduce){.sol-board[data-flat] .sol-tile[data-hint]{animation:none;box-shadow:inset 0 0 0 2px #fff4d8,0 0 0 3px rgba(255,226,168,.8)}}
.sol-board[data-flat]{background:radial-gradient(80% 70% at 50% 45%,rgba(255,226,170,.12),transparent 70%),linear-gradient(rgba(28,74,51,.94),rgba(28,74,51,.94)),url('/felt-v1.webp') center/240px}

/* Panels over the board: no pairs left (near the top, so the board still shows), and the cleared board. */
.sol-scrim{position:absolute;inset:0;z-index:4;pointer-events:none;background:radial-gradient(70% 60% at 50% 46%,rgba(4,8,6,.35),rgba(4,8,6,.15) 60%,rgba(4,8,6,.5))}
html[data-motion=on] .sol-scrim{animation:fade-in .6s ease both}
.sol-panel{position:absolute;left:50%;z-index:5;display:grid;justify-items:center;gap:8px;box-sizing:border-box;width:min(calc(100% - 24px),420px);padding:18px 20px 16px;border-radius:var(--radius-sheet);border:1px solid var(--gold-line-strong);background:linear-gradient(180deg,rgba(21,39,31,.96),rgba(11,20,16,.97));box-shadow:0 24px 60px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,240,210,.07);text-align:center;transform:translateX(-50%)}
.sol-panel h2{margin:0;font:500 min(1.7rem,34px)/1.1 var(--serif);color:var(--gold-bright)}
.sol-panel p{margin:0;font:400 .92rem/1.45 var(--sans);color:var(--ivory-2)}
.sol-panel-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-top:6px}
.sol-panel-actions>button{min-height:46px}
.sol-stuck{top:calc(var(--fit-top) + 4px)}
.sol-panel-close{position:absolute;top:6px;right:6px}
.sol-stuck h2{padding:0 34px}
html[data-motion=on] .sol-stuck{animation:sol-drop .5s var(--ease-out) both}
@keyframes sol-drop{from{opacity:0;transform:translate(-50%,-12px)}}
.sol-win{top:50%;transform:translate(-50%,-50%);padding-top:22px}
html[data-motion=on] .sol-win{animation:sol-rise .7s var(--ease-out) .9s both}
@keyframes sol-rise{from{opacity:0;transform:translate(-50%,calc(-50% + 18px)) scale(.98)}}
.sol-win .rs-seal{width:62px;height:62px;margin:0 0 4px}
.sol-win .rs-seal span{font-size:1.9rem}
.sol-win h2{font-size:min(2.1rem,40px)}
.sol-ribbon{padding:3px 12px;border-radius:999px;background:var(--primary-fill);color:var(--ink-on-gold)!important;font:600 .66rem/1.5 var(--sans)!important;letter-spacing:.14em;text-transform:uppercase}
.sol-facts{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:4px;width:100%;margin:8px 0 2px;padding:10px 0;border-block:1px solid var(--gold-line)}
.sol-facts.is-relaxed{grid-template-columns:repeat(3,minmax(0,1fr))}
.sol-facts div{display:grid;gap:2px;justify-items:center;min-width:0}
.sol-facts dt{font:500 .58rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--sage)}
.sol-facts dd{margin:0;font:500 1.2rem/1.1 var(--serif);color:var(--ivory)}
.sol-facts .is-best dd{color:var(--gold-bright)}
.sol-note{color:var(--gold)!important;font-weight:500!important}
/* The board menu: its one switch runs the width of the sheet. */
.settings-list.sol-menu-settings{grid-template-columns:minmax(0,1fr);margin-top:6px}

/* Controls: the message line, then Hint, Undo and Shuffle (and Zoom on a big board). */
.sol-controls{position:relative;z-index:5;display:grid;gap:6px;padding:4px 10px calc(10px + var(--safe-bottom,0px));background:#070d0b}
.sol-status{display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:100%;max-width:none;min-height:40px;margin:0;font:400 min(.82rem,17px)/1.3 var(--sans);color:var(--ivory-2);text-align:center;text-wrap:balance}
.sol-actions{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:8px;width:100%;max-width:620px;margin:0 auto}
.sol-button[data-key=""]::after{display:none}
/* Zoom (big boards on small screens) is a square icon beside the three moves; its name is its label. */
.sol-actions:has([data-action=sol-zoom]){grid-auto-flow:row;grid-template-columns:repeat(3,minmax(0,1fr)) 52px}
.sol-actions [data-action=sol-zoom]{padding:0}
.sol-actions [data-action=sol-zoom] span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.sol-actions [data-action=sol-zoom][aria-pressed=true]{border-color:var(--gold-line-strong);background:rgba(201,168,106,.14)}
.sol-actions:has([data-action=sol-zoom]) .sol-button{padding:0 6px;gap:5px}
/* A label that cannot fit (a long language, large text) leaves its icon; the name stays for screen readers. */
.sol-actions[data-icons=true] .sol-button{padding:0}
.sol-actions[data-icons=true] .sol-button>span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
@media (max-width:374px){.sol-actions .sol-button{padding:0 6px;gap:5px}}

/* Landscape phones: the header floats over the board, the buttons stand in a column on the right and
   the message sits at the bottom left, so the tiles get the full height. */
@media (orientation:landscape) and (max-height:620px){
  html[data-screen=solitaire] .surface:has(>.sol-screen)>header{position:absolute;left:0;right:0;top:var(--safe-top,0px);height:52px;min-height:52px;padding:0 max(8px,var(--safe-right,0px)) 0 max(8px,var(--safe-left,0px));background:linear-gradient(#0a110ecc,#0a110e00);pointer-events:none}
  html[data-screen=solitaire] .surface:has(>.sol-screen)>header button{pointer-events:auto}
  .surface:has(>.sol-screen) .sol-title{text-align:left}
  .surface>main.sol-screen{position:relative;margin:0;grid-template-rows:minmax(0,1fr)}
  .sol-board{--fit-top:calc(var(--safe-top,0px) + 50px);--fit-bottom:max(6px,var(--safe-bottom));--fit-right:calc(max(10px,var(--safe-right)) + 132px);--fit-left:max(12px,var(--safe-left))}
  .sol-controls{position:absolute;top:calc(var(--safe-top,0px) + 50px);bottom:max(8px,var(--safe-bottom,0px));right:max(10px,var(--safe-right));width:122px;padding:0;background:none;display:flex;flex-direction:column;justify-content:center;gap:10px}
  .sol-actions{grid-auto-flow:row;grid-auto-columns:auto;width:100%;margin:0}
  .sol-actions .sol-button{min-height:46px;justify-content:flex-start;padding:0 12px}
  .sol-actions:has([data-action=sol-zoom]){grid-template-columns:minmax(0,1fr)}
  .sol-actions [data-action=sol-zoom]{padding:0 12px}
  .sol-actions [data-action=sol-zoom] span{position:static;width:auto;height:auto;overflow:hidden;clip:auto}
  /* The message sits in the column above the buttons, clear of the tiles. */
  .sol-status{display:block;min-height:0;max-height:7.2em;overflow:hidden;padding:0 2px;font-size:min(.74rem,15px);line-height:1.3;text-align:left;color:var(--ivory-2)}
  .sol-status:empty{display:none}
  /* Panels centre on the board's part of the screen (left of the buttons) and stay inside its height. */
  .sol-panel{left:calc((100% - 132px - max(10px,var(--safe-right))) / 2);width:min(calc(100% - 172px),600px);max-height:calc(100% - 58px);overflow:auto;padding:10px 16px 12px;gap:5px}
  .sol-win{top:calc(50% + 22px)}
  .sol-win .rs-seal{display:none}
  .sol-win h2{font-size:min(1.55rem,30px)}
  .sol-facts{margin:2px 0 0;padding:5px 0}
  .sol-facts dd{font-size:1.05rem}
  .sol-panel-actions{margin-top:2px}
  .sol-panel-actions>button{min-height:44px;white-space:nowrap}
  .sol-stuck{top:auto;bottom:10px}
}
@media (min-width:1100px) and (min-height:700px){
  html[data-screen=solitaire] .surface>header{grid-template-columns:minmax(150px,auto) minmax(0,1fr) minmax(150px,auto);padding:0 max(clamp(16px,2.4vw - 6px,52px),var(--safe-right)) 0 max(clamp(16px,2.4vw - 6px,52px),var(--safe-left))}
  html[data-screen=solitaire] .app-header :is(.app-back,.table-menu){display:inline-flex;align-items:center;gap:8px;width:auto;padding:0 18px 0 12px;border:1px solid transparent;border-radius:999px;font:500 .9rem/1 var(--sans);letter-spacing:.02em;justify-self:start}
  html[data-screen=solitaire] .app-header .table-menu{flex-direction:row-reverse;padding:0 12px 0 18px}
  html[data-screen=solitaire] .app-header :is(.app-back,.table-menu) span{position:static;width:auto;height:auto;overflow:visible;clip:auto;color:var(--ivory-2)}
  html[data-screen=solitaire] .app-header :is(.app-back,.table-menu) .icon{width:22px;height:22px}
  html[data-screen=solitaire] .app-header :is(.app-back,.table-menu):hover{border-color:var(--gold-line);background:rgba(201,168,106,.08)}
  .sol-board{--fit-top:84px;--fit-bottom:14px}
  .sol-status{font-size:min(.95rem,18px)}
  .sol-controls{padding-bottom:calc(16px + var(--safe-bottom,0px))}
  .sol-button{min-height:54px;font-size:min(1rem,20px)}
}
/* A board of big tiles on a phone held upright leaves room: the tiles sit a little lower, clear of the title. */
@media (orientation:portrait) and (max-width:599px){.sol-board{--fit-top:66px}}

/* src/tables.css */
/* More Tables (docs/more-tables-ui-plan.md): a table's What's Different course page and the
   comparison of the tables (table-courses-view.js, table-compare.js). The course page borrows the
   Learn library's rows and tray, but not its chapter-deck grid: it is one centred column at every
   size, so :root raises these rules above the library's size-specific layouts. */
:root .surface>main.curriculum-screen.course-page{display:flex;flex-direction:column;width:100%;max-width:760px;height:100%;max-height:none;margin:0 auto;padding:clamp(0px,2vh,20px) 16px 0;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;contain:none}
:root .curriculum-screen.course-page .learning-hud{display:grid;gap:6px;justify-items:start;margin:6px 0 0;padding:0;align-self:stretch}
:root .curriculum-screen.course-page .learning-hud h1{order:0;margin:0;font:500 clamp(1.9rem,1.25rem + 2.2vw,2.8rem)/1.05 var(--serif)}
:root .curriculum-screen.course-page .chapter-tray{display:block;flex:none;min-height:auto;margin:18px 0 0;padding:0;overflow:visible;contain:none}
:root .curriculum-screen.course-page .topic-drawer{flex:none;min-height:auto;overflow:visible}
:root .curriculum-screen.course-page .tutorial-row{min-height:64px}
:root .curriculum-screen.course-page .tutorial-row small{white-space:normal;overflow:visible}
:root .curriculum-screen.course-page .learning-dock{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0 0;padding:0}
:root .curriculum-screen.course-page .learning-dock>button{flex:1 1 200px;min-height:44px}
:root .curriculum-screen.course-page .learning-next{position:sticky;bottom:0;z-index:3;display:grid;margin:auto -16px 0;padding:18px 16px 16px;background:linear-gradient(180deg,rgba(9,14,12,0),var(--dock-fill) 34%)}

/* A course lesson: the hand, then the bonus tiles on a row of their own. */
.app-lesson .course-objects .course-break{flex:0 0 100%;height:0}

/* The comparison: one hand at every table, then the rules row by row. */
.surface>main.compare-screen{display:block;width:100%;max-width:1080px;height:100%;margin:0 auto;padding:clamp(0px,2vh,20px) 16px 0;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}
.compare-screen .learning-hud{display:grid;gap:6px;justify-items:start;margin:6px 0 0}
.compare-screen .learning-hud h1{margin:0;font:500 clamp(1.9rem,1.25rem + 2.2vw,2.8rem)/1.05 var(--serif);color:var(--ivory)}
.compare-lead{max-width:62ch;margin:0;font:400 .95rem/1.45 var(--sans);color:var(--sage)}
.compare-hands,.compare-rules{container-type:inline-size;margin:20px 0 0;padding:18px clamp(14px,3cqi,22px);border:1px solid rgba(201,168,106,.22);border-radius:18px;background:linear-gradient(180deg,rgba(24,40,32,.7),rgba(12,22,17,.7))}
.compare-hand-head h2,.compare-rules h2{margin:0;font:500 1.45rem/1.15 var(--serif);color:var(--ivory)}
.compare-hand-head p,.compare-tap,.compare-context{margin:4px 0 0;font:400 .88rem/1.4 var(--sans);color:var(--sage)}
.compare-hand{display:flex;flex-wrap:wrap;align-items:flex-end;gap:3px;margin:14px 0 0}
.compare-hand .tile{--t:clamp(19px,calc((100cqi - 72px) / 16.5),46px)}
/* A phone: the hand in two rows of seven larger tiles, the bonus tiles on a third. */
@container (max-width:560px){.compare-hand .tile{--t:calc((100cqi - 20px) / 7)}.compare-bonus{margin-left:0;padding-left:0;border-left:0}}
.compare-bonus{display:flex;gap:3px;margin-left:8px;padding-left:8px;border-left:1px solid rgba(201,168,106,.3)}
.compare-controls{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 0}
.compare-controls>button{flex:1 1 150px;min-height:44px}
.compare-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr));gap:12px;margin:16px 0 0}
.compare-card{display:flex;flex-direction:column;gap:6px;min-width:0;padding:14px 16px;border:1px solid rgba(201,168,106,.18);border-radius:14px;background:rgba(6,12,9,.46)}
.compare-card.is-win{border-color:rgba(201,168,106,.5);box-shadow:inset 0 1px 0 rgba(240,200,120,.1)}
.compare-card h3{margin:0;font:500 1.22rem/1.2 var(--serif);color:var(--ivory)}
.compare-verdict{margin:0;font:600 .92rem/1.35 var(--sans);color:var(--gold-bright)}
.compare-card.is-no-win .compare-verdict{color:var(--sage)}
.compare-items{display:grid;gap:4px;margin:4px 0 0;padding:0;list-style:none}
.compare-items li{display:flex;justify-content:space-between;gap:10px;font:400 .86rem/1.3 var(--sans);color:var(--ivory-2)}
.compare-items strong{flex:none;font-weight:600;color:var(--ivory);white-space:nowrap}
.compare-pay{margin:auto 0 0;padding-top:8px;border-top:1px solid rgba(201,168,106,.16);font:500 .84rem/1.35 var(--sans);color:var(--ivory-2)}
.compare-note{margin:0;font:400 .8rem/1.3 var(--sans);color:var(--sage)}
/* Rule by rule: a table on wide screens; on narrow ones each rule stacks its three answers. */
.compare-grid{display:grid;margin:10px 0 0}
.compare-row{display:grid;grid-template-columns:minmax(130px,.8fr) repeat(3,minmax(0,1fr));gap:0 16px;align-items:start;padding:6px 0 10px;border-top:1px solid rgba(201,168,106,.14)}
.compare-head{padding:0 0 8px;border-top:0;font:600 .7rem/1.2 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
.compare-screen .compare-row-head{display:flex;align-items:center;justify-content:space-between;gap:6px;min-height:44px;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;font:500 1.04rem/1.2 var(--serif);color:var(--ivory);text-align:left;cursor:pointer}
.compare-row-head .icon{width:14px;height:14px;flex:none;opacity:.7;transition:transform .2s}
.compare-row.is-open .compare-row-head .icon{transform:rotate(90deg)}
.compare-cell{padding-top:12px;font:400 .88rem/1.4 var(--sans);color:var(--ivory-2)}
.compare-cell-table{display:none}
.compare-why{grid-column:1/-1;margin:8px 0 0;padding:10px 12px;border-radius:10px;background:rgba(201,168,106,.08);font:400 .88rem/1.4 var(--sans);color:var(--ivory-2)}
.compare-screen .learning-next{display:flex;flex-wrap:wrap;gap:8px;margin:18px 0 0;padding:0 0 28px}
.compare-screen .learning-next>button{flex:1 1 240px;min-height:44px}
@media (hover:hover) and (pointer:fine){.compare-screen .compare-row-head:hover{color:var(--gold-bright)}}
@media (max-width:720px){
  .compare-head{display:none}
  .compare-row{grid-template-columns:minmax(0,1fr);gap:4px;padding:4px 0 10px}
  .compare-cell{display:grid;grid-template-columns:minmax(92px,.42fr) minmax(0,1fr);gap:10px;padding-top:0}
  .compare-cell-table{display:block;font:500 .78rem/1.4 var(--sans);color:var(--gold)}
}
@media (prefers-reduced-motion:reduce){.compare-row-head .icon{transition:none}}

/* ---------- One game only (25 Sep 2026): Which Game Brings You Here?, and a course's two paths ---------- */
.welcome-games{margin-top:6px}
.welcome-games .mode-card{text-align:left;cursor:pointer}
@media (max-height:720px){.welcome-games{gap:8px}.welcome-games .mode-card{min-height:56px;padding-block:6px}.welcome-games .mode-card .tile{--w:32px;width:32px}}
/* A short landscape phone: three games to a row, so all five and Skip fit without scrolling. */
@media (max-height:500px) and (min-width:700px){.welcome-game h1{font-size:clamp(1.5rem,7vh,1.9rem);margin-bottom:2px}.welcome-game .welcome-lead{margin-block:2px 4px;font-size:.86rem}.welcome-games{grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.welcome-games .mode-card{gap:10px;min-height:52px;padding:6px 10px}.welcome-games .mode-card strong{font-size:1.02rem}.welcome-games .mode-card small{font-size:.74rem;line-height:1.25}}
.course-page .course-part{margin:14px 0 6px;font:500 .72rem/1.3 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold)}
.course-page .course-part:first-child{margin-top:0}
.course-page .course-path{display:block;margin:12px auto 0;min-height:44px}
/* A course demonstration's 3D table fills the lesson felt, as Learn Riichi's does (riichi-learn.css). */
.app-lesson .course-table3d{position:absolute;inset:0;border-radius:inherit;overflow:hidden}
.app-lesson .course-table3d .physical-table{position:absolute;inset:0;--table-top:6px}
.app-lesson .course-table3d .physical-table canvas{display:block;width:100%;height:100%}
.app-lesson .course-table3d .course-demo-fallback{display:none;position:absolute;inset:0;place-items:center}
.app-lesson .course-table3d:has(.physical-table[data-ready=false]) .course-demo-fallback{display:grid}
/* A demonstration's dock holds Skip To Question, Back and Next: Skip wraps rather than running into Back. */
.course-lesson .lesson-dock .rl-skip{white-space:normal;line-height:1.15;max-width:7.5em;flex:0 1 auto}
/* A small phone: the demonstration's tiles beside the words are smaller, so they are never cut short. */
@media (max-height:700px) and (max-width:600px){.course-lesson .rl-demo-tiles .tile{--t:30px}}
/* Short screens: a demonstration's words stay whole in their box. The words are a touch smaller, and
   on a landscape phone the tiles beside them give way (the 3D table shows the same moment). */
@media (max-height:700px){.course-lesson .course-demo-text>p:last-child{font-size:.9rem;line-height:1.42}}
@media (max-height:500px){.course-lesson .has-table-demo .rl-demo-tiles{display:none}.course-lesson .course-demo-text>p:last-child{font-size:.84rem;line-height:1.38}}
/* As Learn Riichi's demonstrations (riichi-learn.css): no hand strip, so the table takes the whole stage,
   and an upright stage takes the deep cloth instead of the wide cloth letterboxed small. */
.app-lesson .course-table3d .physical-table{--hand-reserve:4px}
@media (orientation:portrait){.app-lesson .course-table3d .physical-table{--table-cloth:deep}}

