/* App-side additions to the Claude Design export. pikafish.css is kept as exported (only image paths point at
   the WebP copies); anything the running app needs beyond the design lives here. */

/* The export's "new user" hero has two stacked full-width buttons on mobile; the torn paper band (margin-top
   -20px) and the foreground leaves (bottom -52px) then cover the second one. Give that hero room below its CTA. */
@media (max-width: 760px) {
  .hero__in { padding-bottom: 104px; }
}

/* Vertical eval number: in vertical writing mode text-align works along the column, so the glyphs hugged one edge
   of the bar. Centre the column horizontally instead. */
.evalbar:not(.evalbar--h) .evalbar__v { left: 50%; right: auto; transform: translateX(-50%) rotate(180deg); }

/* Vietnamese stacks diacritics above and below (ố, ậ, ỵ), so display headings that wrap need more than ~1.0 line
   height or the marks of one line touch the letters of the next. */
.display, .land-hero__t, .hero__t, .h-page, .sheet__t, .tray__t, .pz-rush__t, .result-card__t, .success__t, .auth__t { line-height: 1.15; }

/* Brand mark: the carp-and-chariot logo replaces the export's empty placeholder square. */
.brand__logo { width: 48px; height: 48px; border-radius: 0; box-shadow: none; background: url(/design/assets/logo.webp) center / contain no-repeat; }
.brand { gap: 10px; }
.footer .brand__logo { width: 64px; height: 64px; }
@media (max-width: 760px) { .brand__logo { width: 44px; height: 44px; } }

/* Landing headline: at 72px in a 540px column "học như có thầy." overflowed by a few pixels, so the headline broke
   into four uneven lines and pushed the buttons down. Size it so each half sits on one line, and let the subline
   run the full column width so both blocks share one right edge. */
.land-hero__copy { max-width: 600px; }
.land-hero__t { font-size: 56px; text-wrap: balance; }
.land-hero__sub { max-width: none; }
@media (max-width: 1240px) and (min-width: 761px) { .land-hero__copy { max-width: 480px; } .land-hero__t { font-size: 44px; } }
@media (max-width: 760px) { .land-hero__t { font-size: 40px; } }

/* Landing hero bottom: the dó-paper and the banyan art ended in a ruler-straight cut beside the board tray (very
   visible on wide screens). Lay a torn sheet of page colour over the edge, with the same soft shadow the bands use. */
.land-hero::before, .land-hero::after { content: ""; position: absolute; left: 0; right: 0; pointer-events: none; z-index: 1;
  -webkit-mask: url(../assets/torn-top.svg) top / 100% 32px no-repeat; mask: url(../assets/torn-top.svg) top / 100% 32px no-repeat; }
.land-hero::before { bottom: -4px; height: 44px; background: rgba(48, 30, 16, .2); filter: blur(7px); }
.land-hero::after { bottom: -1px; height: 32px; background: var(--bg); }
@media (max-width: 760px) { .land-hero__in { padding-bottom: 56px; } }

/* The dark board tray used to ride 200px up into the hero and covered the painting (the board, both old men, the
   dog). Keep the painting whole: the tray starts just below the hero's torn edge, and the hero drops the bottom
   padding that only existed to make room for that overlap. */
@media (min-width: 761px) {
  .tray { margin-top: 24px; }
  .land-hero__in { padding-bottom: 104px; }
}

/* Live screens -------------------------------------------------------------------------------------------- */
/* Close button on the end-of-game sheet (the sheet can be dismissed to look at the final position). */
.sheet__close { position: absolute; top: 12px; right: 12px; z-index: 2; }
/* "Đi / Hủy" under the board when tap-to-confirm is on. */
.confirm-move { gap: 8px; margin-top: 8px; }
/* On phones .game turns into a flex column but keeps the desktop "align-items: start", so the side column sizes
   to its widest child (the horizontal move strip) and the page overflows sideways. Stretch it to the screen. */
@media (max-width: 760px) {
  .game > .side, .game > .stage { align-self: stretch; width: 100%; min-width: 0; }
}
/* Real VietQR image (the export drew a placeholder grid). */
img.qr { display: block; width: 220px; height: 220px; object-fit: contain; background: #fff; border-radius: 12px; }
@media print { .topbar, .tabbar, .sheet__actions { display: none !important; } .invoice-sheet { box-shadow: none; } }
/* Live board: the SVG sits in .xq-base; legal-move dots are an overlay on top that ignores the pointer. */
.xq-base, .xq-overlay-wrap { position: absolute; inset: 0; }
.xq-overlay-wrap { pointer-events: none; }
.xq-overlay { display: block; width: 100%; height: 100%; overflow: visible; }
/* The export shadows the whole board with filter: drop-shadow on the SVG, which makes the browser re-filter the
   entire board whenever a piece changes. The board is a rounded rectangle, so a box-shadow looks the same and is
   cheap. Live boards only; the demo pages keep the export's rendering. */
.xq-board[data-live] .xq-svg { filter: none; }
.xq-board[data-live]:not([data-mini]) .xq-base { border-radius: 2.34% / 2.12%; box-shadow: 0 28px 26px rgba(0, 0, 0, .5), 0 6px 5px rgba(0, 0, 0, .35); }
html[data-theme="light"] .xq-board[data-live]:not([data-mini]) .xq-base { box-shadow: 0 24px 32px rgba(72, 40, 12, .22), 0 2px 4px rgba(72, 40, 12, .18); }
.xq-board[data-live][data-mini] .xq-base { border-radius: 2.34% / 2.12%; box-shadow: 0 6px 10px rgba(48, 30, 16, .2); }
@media (max-width: 760px) { .xq-board[data-live]:not([data-mini]) .xq-base { box-shadow: 0 12px 16px rgba(0, 0, 0, .45); } }
/* In-browser engine: install banner progress and the "running on your device" badge. */
.engine-banner .bar { display: block; margin-top: 6px; }
.engine-badge { display: inline-flex; align-items: center; gap: 6px; font: 600 12px var(--f-ui); color: var(--text-2); }
.engine-badge .ic { width: 14px; height: 14px; color: #D9B26A; }
/* Policy page: plain bullet lists inside cards (the export's .ticks expects an icon per item). */
.policy .ticks li { display: list-item; list-style: disc; margin-left: 20px; padding-left: 2px; }
.policy code { font: 500 13px var(--f-mono); }
/* The export sets html { overflow-x: clip } and body { overflow-x: hidden }. With html no longer "visible", the
   body's overflow is not passed to the viewport, so body became its own scroll box: two scrollbars on tall
   pages. clip hides sideways overflow the same way without making a scroll container. */
body { overflow-x: clip; }
/* Result sheet: the close button sits top-left so the win/draw seal (top-right) stays clear; plain note in place
   of the Elo row for bot games; a progress bar while the review runs instead of empty stat boxes. */
.sheet__close { right: auto; left: 12px; }
.sheet__note { margin: 12px 0 0; font-size: 14px; color: var(--text-2); }
.sheet__grading { margin: 20px 0 20px; display: grid; gap: 8px; text-align: center; }

/* The warm light behind the board (.stage::before) reaches 140px past the stage. On desktop the game screen fits the
   window, so that decorative overflow must not count as page height (it made the page scroll and the board shrink). */
@media (min-width: 761px) {
  body.page--game .game { overflow-y: clip; overflow-x: visible; }
}

/* Under the board the stepper sits in a content-sized row, where the export's 1fr columns collapse to icon width. */
.stage__col .stepper { grid-template-columns: repeat(4, 44px); }
.stage__col .legend { flex-wrap: nowrap; white-space: nowrap; }
/* When the board column is narrower than legend + stepper, keep them on one line centred under the board instead of
   wrapping (a second line takes height from the board). There is free space beside the board column on desktop. */
@media (min-width: 761px) {
  .stage__col > .row--between { flex-wrap: nowrap; gap: 24px; align-self: center; width: max-content; min-width: 100%; }
}

/* Horizontal card rows with a mouse: grab to drag (see hrow-mouse-scroll.tsx). Snapping waits until the drag ends,
   and the wider left gutter keeps the selected card's ring and shadow from being cut at the row's edge. */
@media (hover: hover) and (pointer: fine) {
  .hrow { cursor: grab; }
  .hrow.is-dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }
  .hrow.is-dragging > * { pointer-events: none; }
  .hrow img { -webkit-user-drag: none; }
}
@media (min-width: 761px) {
  .hrow { padding-left: 16px; margin-left: -16px; scroll-padding-left: 16px; }
}

/* Board file numbers (xq-board.tsx): a row above (Black's files) and below (Red's), centred on each file. */
.xq-frame { position: relative; width: 100%; }
.xq-files { position: relative; height: 18px; font: 600 12px/18px var(--f-mono); color: var(--text-2); }
.xq-files span { position: absolute; top: 0; transform: translateX(-50%); }
.xq-files--top { margin-bottom: 4px; }
.xq-files--bottom { margin-top: 4px; }

/* Chrome on Android sizes 100vh as if the address bar were hidden, so a page that just fits could still scroll
   by the bar's height. svh is the height actually visible. */
@supports (min-height: 100svh) {
  body { min-height: 100svh; }
  .auth { min-height: calc(100svh - 56px); }
}
a.mini-review { text-decoration: none; }
/* Four tabs since the puzzle tab was removed. */
@media (max-width: 760px) { .tabbar { grid-template-columns: repeat(5, 1fr); } }

/* Bot picker on desktop: all characters in one wrapping row (nothing hidden behind the setup card, no sideways
   scrolling), and the setup card underneath in three columns. Phones keep the swipe row and stacked setup. */
@media (min-width: 761px) {
  .bots-layout { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .bots.hrow { grid-auto-flow: row; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-columns: auto; overflow: visible; margin: 0; padding: 16px 0 0; cursor: auto; }
  .setup { position: static; }
  .setup__cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 40px; align-items: start; }
  .setup__col > :first-child { margin-top: 0; }
  .setup__cta { margin-top: 24px; }
}
@media (min-width: 1100px) { .bots.hrow { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 12px; } }
/* Ladder: characters already beaten. */
.botcard__won { position: absolute; top: 16px; right: 16px; padding: 2px 8px !important; border-radius: 999px; background: var(--gold, #D9A441); color: #2A1B0E; font-size: 11px; font-weight: 700; }
.sheet__ladder { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 12px 0 4px; padding: 12px 14px; border-radius: 12px; background: rgba(217, 164, 65, .14); font-weight: 600; }
.sheet__ladder.is-muted { background: var(--surface-2, rgba(0, 0, 0, .05)); font-weight: 500; }

/* Landing hero: the copy sits in the middle of the painting's height (the tray no longer rides up into the hero),
   with the free characters under the buttons. */
@media (min-width: 761px) {
  .land-hero__in { min-height: 680px; display: flex; align-items: center; padding-top: 56px; padding-bottom: 88px; }
}
.land-hero__bots { display: flex; align-items: center; gap: 16px; margin-top: 16px; padding-top: 20px; border-top: 1px solid rgba(72, 40, 12, .14); font-size: 15px; line-height: 1.45; }
.land-hero__faces { display: flex; flex: none; }
.land-hero__faces a { display: block; margin-left: -10px; border-radius: 50%; box-shadow: 0 0 0 3px #EEE2CB, 0 4px 10px rgba(72, 40, 12, .18); transition: transform .15s var(--ease); }
.land-hero__faces a:first-child { margin-left: 0; }
.land-hero__faces a:hover { transform: translateY(-3px); }
.land-hero__faces img { display: block; width: 48px; height: 48px; border-radius: 50%; background: #F6EEDD; }
/* Clock digits centred: right-aligned, a short time ("9:38") left a gap on the left of a box sized for "10:00". */
.clock { text-align: center; }

/* Result sheet: always in the middle of the window, never scrolling. The overlay covers the whole window (its
   centre is the window's centre) and on short windows the sheet gets tighter instead of running off the bottom.
   The top margin is exactly the koi art's overhang. */
@media (min-width: 761px) {
  .overlay { inset: 0; z-index: 60; }
  .sheet { margin-top: 64px; }
  .sheet .stat3 { margin: 20px 0 16px; }
  .sheet__ladder { margin: 0 0 12px; }
}
@media (min-width: 761px) and (max-height: 820px) {
  .sheet { margin-top: 44px; padding: 24px 28px 18px; }
  .sheet__art { width: 150px; height: 118px; margin-top: -68px; }
  .sheet__t { font-size: 26px; }
  .sheet__sub { margin-top: 4px; }
  .sheet__note { margin-top: 4px; }
  .sheet .stat3 { margin: 12px 0 10px; }
  .sheet__grading { margin: 12px 0; }
  .sheet__ladder { padding: 8px 12px; margin-bottom: 8px; }
  .sheet__actions { gap: 6px; }
  .sheet__actions .btn--lg { min-height: 48px; }
}
@media (min-width: 761px) and (max-height: 640px) {
  .sheet { margin-top: 0; }
  .sheet__art { display: none; }
  .sheet__seal { top: -14px; }
}
/* Nothing behind an open sheet scrolls either. */
@media (min-width: 761px) { html:has(.overlay .sheet), body:has(.overlay .sheet) { overflow: hidden; } }
/* Locked coach panel: the text under the lock is hidden, so the panel is short; keep it tall enough for the
   upsell card that sits over it (it spilled over the eval graph). */
.coach:has(> .coach__lock) { min-height: 380px; }
@media (max-width: 760px) { .coach:has(> .coach__lock) { min-height: 400px; } }
/* A result sheet with a single action in the row (online games: no rematch) — it takes the full width. */
.sheet__row > :only-child { grid-column: 1 / -1; }
.sheet__elo { margin-bottom: 16px; }
/* Lobby on phones: the single column may not grow past the screen to fit its widest child (the room pace
   switch), which pushed the whole page 17px past the right edge. */
@media (max-width: 760px) { .lobby { grid-template-columns: minmax(0, 1fr); } .room-act .seg { max-width: 100%; overflow-x: auto; } }
/* The room card's pace switch (five buttons) may not widen the card past the screen either. */
@media (max-width: 760px) { .room-actions { grid-template-columns: minmax(0, 1fr); } .room-act, .room-act .grow { min-width: 0; } }
/* Side dot next to a player's name: the name box clips overflow (ellipsis), which cut the dot's 1px ring. */
.pstrip__side, .rv-p__name .pstrip__side { margin-left: 2px; }
/* Landing hero: 40px more paper under the painting, so the torn edge no longer runs into the dog's paws. */
@media (min-width: 761px) {
  .land-hero { min-height: 720px; }
  .land-hero__in { min-height: 720px; }
  .land-hero__art { height: calc(100% - 40px); }
}
@media (max-width: 1240px) and (min-width: 761px) { .land-hero__art { height: 72%; bottom: 40px; } }
/* Signed-in home hero: the next band's torn top rides up over the hero's bottom edge; end the painting above it
   (same room as the landing hero) so the dog's paws are not cut. */
@media (min-width: 761px) {
  .hero { min-height: 584px; }
  .hero__art { height: calc(100% - 44px); }
}

/* Account menu under the avatar (app.js). */
.topbar__acct { position: relative; }
.topbar__avatar { border: 0; cursor: pointer; font: inherit; }
.topbar__acctmenu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 70; min-width: 180px; display: grid; padding: 6px; border-radius: 12px; background: var(--surface); box-shadow: var(--sh-3), 0 0 0 1px var(--hair); }
.topbar__acctmenu[hidden] { display: none; }
.topbar__acctmenu a, .topbar__acctmenu button { display: block; width: 100%; padding: 10px 12px; border: 0; border-radius: 8px; background: none; color: var(--text); font: 500 14px var(--f-ui, inherit); text-align: left; cursor: pointer; }
.topbar__acctmenu a:hover, .topbar__acctmenu button:hover { background: var(--surface-2); }
.topbar__acctmenu .topbar__logout { color: var(--son); border-top: 1px solid var(--hair); border-radius: 0 0 8px 8px; margin-top: 4px; }
/* Game screens: the move list shows five rows (it scrolls inside, the current move kept in view), so the side
   column fits the window and its buttons are not cut off. */
@media (min-width: 761px) { .panel--ml-m .ml-scroll { max-height: 162px; } }
/* Settings on desktop: every tab fits the window (the Bàn cờ tab was the only one tall enough to scroll, and its
   scrollbar shifted the layout between tabs). Tighter swatches and rows. */
@media (min-width: 761px) {
  .settings .theme__sw { height: 52px; }
  .settings .themes { padding: 4px 0 10px; }
  .settings .srow { min-height: 54px; padding: 6px 0; }
  .settings .sgroup__t { padding: 14px 0 6px; }
  .page-main:has(.settings) { padding-bottom: 16px; }
}

/* Home quick-play tiles: surface-2 on the paper band made them nearly invisible (phones especially). Resting
   state now reads as a card — lighter face, hairline and a soft shadow; hover lifts a little more. */
.qtile:not(.qtile--up) { background: var(--surface); box-shadow: 0 0 0 1px var(--hair-2, var(--hair)), 0 2px 6px rgba(72, 40, 12, .08); }
.qtile:not(.qtile--up):hover { box-shadow: 0 0 0 1px var(--hair-2, var(--hair)), var(--sh-2); }
.qtile__bots img { box-shadow: 0 0 0 2px var(--surface); }

/* Game screens on phones: back · title · right as three columns, so the title stays centred even when the right
   side is empty (signed in: avatar hidden here; the export's right-hand menu button is not used). */
@media (max-width: 760px) {
  .page--game .topbar__in { display: grid; grid-template-columns: minmax(44px, 1fr) minmax(0, auto) minmax(44px, 1fr); align-items: center; }
  .page--game .topbar__back { justify-self: start; }
  .page--game .topbar__title { grid-column: 2; }
  .page--game .topbar__right { grid-column: 3; justify-self: end; }
}
/* Coach actions: two equal columns that may not grow past the panel; long labels wrap instead of spilling. */
.coach__actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.coach__actions > .btn { min-width: 0; white-space: normal; line-height: 1.2; text-align: center; }
/* Coordinate notation: a rank column (0–9) on the left of the board; the file rows shift to stay over the files. */
.xq-frame__mid { position: relative; }
.xq-frame--uci { --rank-w: 16px; }
.xq-frame--uci .xq-frame__mid { display: grid; grid-template-columns: var(--rank-w) minmax(0, 1fr); column-gap: 4px; }
.xq-frame--uci .xq-files { margin-left: calc(var(--rank-w) + 4px); }
.xq-ranks { position: relative; font: 600 12px/1 var(--f-mono); color: var(--text-2); }
.xq-ranks span { position: absolute; left: 0; right: 0; text-align: center; transform: translateY(-50%); }

/* Wallet: the balance line, the top-up chooser inside the dark "Theo ván" card, the topbar chip, the lobby price note. */
.wallet-now { margin: 0; font-size: 15px; color: var(--text-2); }
.wallet-now b { color: var(--text); font-variant-numeric: lining-nums tabular-nums; }
.plan__note { margin: 0; font-size: 14px; line-height: 1.5; color: var(--text-2); }
.topup { display: flex; flex-direction: column; gap: 12px; margin-top: auto; }
.topup .seg { background: rgba(255, 240, 220, .08); flex-wrap: wrap; }
.topup .seg > button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 56px; min-width: 0; padding: 6px 8px; color: #CDBFAA; font-variant-numeric: lining-nums tabular-nums; }
.topup .seg > button small { font-size: 12px; font-weight: 500; color: #A39581; }
.topup .seg > button:hover { color: #F3EADB; }
.topup .seg > button.is-active, html[data-theme="dark"] .topup .seg > button.is-active { background: rgba(217, 178, 106, .2); color: #F3EADB; box-shadow: 0 0 0 1px rgba(217, 178, 106, .55); }
.topup .field__l { color: #CDBFAA; }
.topup .input { background: rgba(255, 240, 220, .06); border-color: rgba(255, 240, 220, .18); color: #F3EADB; }
.topup .input::placeholder { color: #8C7F6D; }
.topbar__wallet { font-variant-numeric: lining-nums tabular-nums; }
.lobby__price { margin: -8px 0 16px; }
@media (max-width: 560px) {
  .topup .seg > button { flex: 1 1 calc(50% - 2px); }
  .topbar__wallet .ic { display: none; }
}
.botcard__price { position: absolute; top: 12px; left: 12px; padding: 0 !important; }
.wrap > [data-live] + .faq { margin-top: 56px; }

/* Game lists: our side under the opponent's name; on phones each game is a two-line card
   (opponent + result, then date / accuracy / Elo and the review link) instead of cells placed by odd/even order. */
.gtable__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gtable__me { display: block; font: 400 12px/1.4 var(--f-ui); color: var(--text-3); }
.gtable__me .pstrip__side { margin-right: 6px; vertical-align: 1px; }
@media (max-width: 760px) {
  .gtable--m-cards tr { grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px 16px; }
  .gtable--m-cards td:nth-child(even) { text-align: left !important; justify-self: auto; }
  .gtable--m-cards .gt-opp { grid-column: 1 / 3; grid-row: 1; }
  .gtable--m-cards .gt-res { grid-column: 3; grid-row: 1; justify-self: end; }
  .gtable--m-cards .gt-date { grid-column: 1; grid-row: 2; }
  .gtable--m-cards .gt-acc { grid-column: 2; grid-row: 2; }
  .gtable--m-cards .gt-act { grid-column: 3; grid-row: 2; justify-self: end; }
  .gtable--recent .gt-acc { grid-column: 1; }
  .gtable--recent .gt-elo { grid-column: 2; grid-row: 2; }
  .gtable--m-cards .gt-date, .gtable--m-cards .gt-acc, .gtable--m-cards .gt-elo { font-size: 13px; color: var(--text-2); }
  .gtable--m-cards .gt-acc::before { content: 'Chính xác '; font-family: var(--f-ui); color: var(--text-3); }
  .gtable--recent .gt-elo::before { content: 'Elo '; font-family: var(--f-ui); color: var(--text-3); }
  .gtable--m-cards .gtable__me { font-size: 13px; }
}

/* Site navigation: drop-down groups in the top bar, the phone menu sheet and the site footer (app.js draws them). */
.topnav__grp { position: relative; }
.topnav__grp > button { border: 0; background: none; cursor: pointer; font: inherit; gap: 4px; }
.topnav__caret { width: 14px; height: 14px; transform: rotate(90deg); opacity: .6; transition: transform .15s var(--ease); }
.topnav__panel { position: absolute; left: -8px; top: 100%; z-index: 70; display: none; width: 320px; padding: 8px; margin-top: 6px; border-radius: 14px; background: var(--surface); box-shadow: 0 0 0 1px var(--hair-2), var(--sh-3); }
.topnav__panel::before { content: ''; position: absolute; left: 0; right: 0; top: -10px; height: 10px; }
.topnav__grp:hover .topnav__panel, .topnav__grp:focus-within .topnav__panel, .topnav__grp.is-open .topnav__panel { display: grid; gap: 2px; }
.topnav__grp:hover .topnav__caret, .topnav__grp.is-open .topnav__caret { transform: rotate(-90deg); }
.topnav__it { display: grid; gap: 2px; padding: 10px 12px; border-radius: 10px; color: var(--text); }
.topnav__it:hover, .topnav__it:focus-visible { background: var(--surface-2); color: var(--text); }
.topnav__it b { font-weight: 600; font-size: 14px; }
.topnav__it span { font-size: 13px; line-height: 1.4; color: var(--text-3); }
.topbar__acctmenu a small { float: right; margin-left: 16px; color: var(--text-3); font-variant-numeric: lining-nums tabular-nums; }
@media (min-width: 761px) and (max-width: 1100px) {
  .topbar__in { gap: 16px; }
  .topbar .brand__name { display: none; }
  .topnav__a { padding: 0 8px; }
}
.tabbar__menu { border: 0; background: none; font-family: inherit; cursor: pointer; }
.navsheet { position: fixed; inset: 0; z-index: 80; display: flex; align-items: flex-end; background: rgba(18, 12, 9, .45); }
.navsheet[hidden] { display: none; }
.navsheet__in { width: 100%; max-height: 88svh; overflow-y: auto; padding: 8px 16px calc(24px + env(safe-area-inset-bottom)); border-radius: 20px 20px 0 0; background: var(--surface); }
.navsheet__hd { position: sticky; top: 0; display: flex; align-items: center; justify-content: space-between; padding: 8px 0; background: var(--surface); font-size: 17px; }
.navsheet__g { padding: 8px 0; border-top: 1px solid var(--hair); }
.navsheet__t { padding: 8px 0 4px; font: 600 12px var(--f-ui); letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.navsheet__g a { display: block; padding: 10px 0; color: var(--text); font-weight: 500; font-size: 16px; }
.navsheet__g a small { display: block; margin-top: 2px; font-weight: 400; font-size: 13px; color: var(--text-3); }
html.has-navsheet, html.has-navsheet body { overflow: hidden; }
.sitefoot { margin-top: 80px; padding: 48px 0 32px; border-top: 1px solid var(--hair); color: var(--text-2); font-size: 14px; }
body.page--game .sitefoot { display: none; }
.sitefoot__in { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(5, minmax(0, 1fr)); gap: 32px; }
.sitefoot__brand p { margin: 12px 0 0; max-width: 280px; line-height: 1.5; color: var(--text-3); }
.sitefoot__brand .brand__logo { width: 48px; height: 48px; }
.sitefoot__col { display: grid; align-content: start; gap: 10px; }
.sitefoot__t { font: 600 12px var(--f-ui); letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.sitefoot a { color: var(--text-2); } .sitefoot a:hover { color: var(--text); }
.sitefoot__bot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 24px; margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--hair); font-size: 13px; color: var(--text-3); }
.sitefoot__bot a { color: var(--text-3); }
@media (max-width: 1100px) { .sitefoot__in { grid-template-columns: repeat(3, minmax(0, 1fr)); } .sitefoot__brand { grid-column: 1 / -1; } }
@media (max-width: 760px) {
  .sitefoot { margin-top: 48px; padding: 32px 0 24px; }
  .sitefoot__in { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 16px; }
  .sitefoot .brand__name { display: inline; }
}

/* Rank avatars: the ring (--ring) and seal colours climb with the rank — wood, bronze, silver, jade, gold, lacquer red.
   Higher ranks add an outer rim and, at the top, a glow. The seal carries the rank's Hán character. */
.ravatar { --sz: 40px; --bw: 3px; position: relative; display: inline-grid; place-items: center; flex: none; width: var(--sz); height: var(--sz); padding: var(--bw); border: 0; border-radius: 50%; background: var(--ring); box-shadow: var(--rim, none); }
.ravatar__in { display: grid; place-items: center; width: 100%; height: 100%; overflow: hidden; border-radius: 50%; background: var(--surface-3); color: var(--text); font: 700 calc(var(--sz) * .34)/1 var(--f-ui); letter-spacing: -.02em; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12); }
.ravatar__in img { width: 100%; height: 100%; object-fit: cover; }
.ravatar__seal { position: absolute; right: -2px; bottom: -2px; display: grid; place-items: center; width: calc(var(--sz) * .36); height: calc(var(--sz) * .36); min-width: 16px; min-height: 16px; border-radius: 50%; background: var(--seal); color: var(--seal-ink, #FFF8EC); font: 700 calc(max(16px, var(--sz) * .36) * .6)/1 var(--f-han); box-shadow: 0 0 0 2px var(--surface), 0 1px 3px rgba(0, 0, 0, .25); }
.ravatar--sm { --sz: 32px; --bw: 2px; }
.ravatar--md { --sz: 44px; }
.ravatar--lg { --sz: 64px; --bw: 4px; }
.ravatar--xl { --sz: 104px; --bw: 5px; }
.ravatar--sm .ravatar__seal { right: -4px; bottom: -3px; }
.ravatar[data-rank="0"] { --ring: linear-gradient(145deg, #D9BE94, #9A7447); --seal: #8A6A42; }
.ravatar[data-rank="1"] { --ring: linear-gradient(145deg, #E2A36B, #8E4F22); --seal: #9A5728; }
.ravatar[data-rank="2"] { --ring: linear-gradient(145deg, #E7AE78, #7A3F17); --rim: 0 0 0 1.5px #B87333; --seal: #7A3F17; }
.ravatar[data-rank="3"] { --ring: linear-gradient(145deg, #F4F6F8, #9CA3AB 55%, #D5D9DE); --seal: #6E7780; }
.ravatar[data-rank="4"] { --ring: linear-gradient(145deg, #F4F6F8, #9CA3AB 55%, #D5D9DE); --rim: 0 0 0 2px #3F8F7C; --seal: #2F7A68; }
.ravatar[data-rank="5"] { --ring: linear-gradient(145deg, #FBE7A6, #C9962F 50%, #F1D27A); --seal: #A87718; --seal-ink: #2A1B0E; }
.ravatar[data-rank="6"] { --ring: linear-gradient(145deg, #FBE7A6, #C9962F 50%, #F1D27A); --rim: 0 0 0 2px #B3261E, 0 0 0 3.5px #E9C66A; --seal: #B3261E; }
.ravatar[data-rank="7"] { --ring: conic-gradient(from 200deg, #F6D77F, #B3261E, #F6D77F, #8E1B15, #F6D77F); --rim: 0 0 0 2px #F1D27A, 0 0 14px 2px rgba(233, 180, 60, .55); --seal: #8E1B15; }
.rank-name { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: 999px; background: var(--surface-2); font-weight: 600; font-size: 14px; }
.ranks { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.ranks li { display: flex; align-items: center; gap: 12px; opacity: .55; }
.ranks li.is-done, .ranks li.is-now { opacity: 1; }
.ranks li.is-now b { color: var(--son); }
.ranks li span:last-child { display: grid; font-size: 14px; }
.ranks li small { color: var(--text-3); font-size: 12px; }
.avatar-row { align-items: center; gap: 16px; }
.avatar-row__err { color: var(--son) !important; }
@media (max-width: 760px) { .avatar-row { flex-wrap: wrap; } .avatar-row__acts { width: 100%; } }
.ravatar__stars { position: absolute; left: 50%; bottom: calc(var(--sz) * -0.16); display: flex; gap: 2px; transform: translateX(-50%); padding: 2px 6px; border-radius: 999px; background: var(--surface); box-shadow: 0 0 0 1px var(--hair-2); }
.ravatar__stars i { width: calc(var(--sz) * .11); height: calc(var(--sz) * .11); min-width: 9px; min-height: 9px; background: var(--hair-3); clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
.ravatar__stars i.is-on { background: #E0A92E; }
.ravatar--xl { margin-bottom: 10px; }
.lg__who { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }

/* Leaderboard */
.lb-tabs { align-self: flex-start; }
.lb-tabs > a { display: inline-flex; align-items: center; min-height: 32px; padding: 0 14px; border-radius: 8px; color: var(--text-2); font-weight: 500; font-size: 14px; }
.lb-tabs > a.is-active { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: 0 1px 2px rgba(48, 30, 16, .1), 0 0 0 1px var(--hair); }
.lb { list-style: none; margin: 0; padding: 0; }
.lb li { display: grid; grid-template-columns: 36px auto minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--hair); }
.lb li:last-child { border-bottom: 0; }
.lb__pos { font: 700 15px var(--f-mono); color: var(--text-3); text-align: center; }
.lb__top--1 .lb__pos { color: #C9962F; } .lb__top--2 .lb__pos { color: #8E98A2; } .lb__top--3 .lb__pos { color: #B87333; }
.lb__name { display: grid; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.lb__name small { font-weight: 400; color: var(--text-3); font-size: 12px; }
.lb__elo { font: 700 16px var(--f-mono); font-variant-numeric: tabular-nums; }
.rating__pos { font-size: 12px; color: var(--son); }

/* Daily missions (home) */
.missions__list { list-style: none; margin: 8px 0 12px; padding: 0; display: grid; gap: 8px; }
.missions__list li { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: center; gap: 8px; font-size: 14px; }
.missions__ic { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--hair-3); }
.missions__list li.is-done .missions__ic { background: var(--dong); box-shadow: none; color: #fff; }
.missions__ic .ic { width: 14px; height: 14px; }
.missions__list li.is-done .missions__t { color: var(--text-3); text-decoration: line-through; }
.missions__n { color: var(--text-3); font-size: 13px; }

/* Friends */
.friends { display: grid; gap: 4px; }
.friend { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; padding: 8px 0; border-bottom: 1px solid var(--hair); }
.friend:last-child { border-bottom: 0; }
.friend__who { display: flex; align-items: center; gap: 12px; min-width: 0; }
.friend__id { display: grid; min-width: 0; }
.friend__id b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.friend__id small { font-size: 12px; color: var(--text-3); }
.friend__st::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 5px; border-radius: 50%; background: var(--hair-3); vertical-align: 1px; }
.friend__st.is-on::before { background: #3F9A5B; } .friend__st.is-playing::before { background: var(--son); }
.friend__acts { display: flex; align-items: center; gap: 6px; }
.friend__pools { width: 100%; flex-wrap: wrap; }
.invite-toast { position: fixed; left: 50%; bottom: calc(84px + env(safe-area-inset-bottom)); z-index: 90; transform: translateX(-50%); display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; width: min(520px, calc(100vw - 32px)); padding: 12px 14px; border-radius: 16px; background: var(--surface); box-shadow: 0 0 0 1px var(--hair-2), var(--sh-3); }
.invite-toast__t { flex: 1 1 200px; font-size: 14px; }
.invite-toast__acts { display: flex; gap: 8px; margin-left: auto; }
@media (min-width: 761px) { .invite-toast { bottom: 24px; } }
.name-prompt { flex-wrap: wrap; gap: 8px 10px; margin-bottom: 16px; }
.name-prompt .input { flex: 1 1 160px; min-width: 0; height: 36px; }

/* Home and profile: the Elo pools fill the row; the missions tile has no mini board column. */
.ratings, .tiles4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Profile: three Elo pools (cờ tướng, cờ úp, với máy) side by side, also on a phone. */
.tiles4.tiles4--elo { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tile.missions { display: block; }
.tile.missions .tile__bd { align-items: stretch; }
.tile.missions .tile__bd > .row--between { flex-wrap: nowrap; align-items: center; }

/* Painted rank frames at every size: the picture fills the frame's opening (55–58 % of the art, so 59 % hides the
   edge under the ring); the frame, the ribbon name and the stars are laid over it and take room around it. */
.ravatar--framed { --fr: calc(var(--sz) / .59); padding: 0; background: none !important; box-shadow: none !important; border: 0; margin: calc((var(--fr) - var(--sz)) / 2); }
.ravatar--framed .ravatar__in { box-shadow: none; }
.ravatar--sm.ravatar--framed { --sz: 28px; }
.ravatar--md.ravatar--framed { --sz: 38px; }
.ravatar--lg.ravatar--framed { --sz: 64px; margin-bottom: calc((var(--fr) - var(--sz)) / 2 + var(--fr) * .14); }
.ravatar--xl.ravatar--framed { --sz: 140px; margin-bottom: calc((var(--fr) - var(--sz)) / 2 + var(--fr) * .16); }
.ravatar__frame { position: absolute; left: 50%; top: 50%; width: var(--fr); height: var(--fr); transform: translate(-50%, -50%); background: center / 100% 100% no-repeat; pointer-events: none; }
.ravatar--framed[data-rank="0"] .ravatar__frame { background-image: url(/design/ranks/frame-0-tan-thu.webp); }
.ravatar--framed[data-rank="1"] .ravatar__frame { background-image: url(/design/ranks/frame-1-ky-sinh.webp); }
.ravatar--framed[data-rank="2"] .ravatar__frame { background-image: url(/design/ranks/frame-2-ky-thu.webp); }
.ravatar--framed[data-rank="3"] .ravatar__frame { background-image: url(/design/ranks/frame-3-ky-si.webp); }
.ravatar--framed[data-rank="4"] .ravatar__frame { background-image: url(/design/ranks/frame-4-ky-hiep.webp); }
.ravatar--framed[data-rank="5"] .ravatar__frame { background-image: url(/design/ranks/frame-5-ky-tuong.webp); }
.ravatar--framed[data-rank="6"] .ravatar__frame { background-image: url(/design/ranks/frame-6-ky-vuong.webp); }
.ravatar--framed[data-rank="7"] .ravatar__frame { background-image: url(/design/ranks/frame-7-ky-thanh.webp); }
/* Rank name on the ribbon, styled after the frame's material: a metal gradient cut out by the letters, an edge in the
   ribbon's darkest tone below them and a small cast shadow (drop-shadow filters: a text-shadow would sit on the
   gradient). A full outline would swallow the metal at this size on ordinary screens. */
.ravatar__name { position: absolute; left: 50%; top: var(--ribbon, 83%); transform: translate(-50%, -50%); white-space: nowrap; font: 900 calc(var(--fr) * .06)/1 "Playfair Display", "Noto Serif", Georgia, serif; letter-spacing: .03em; color: transparent;
  background: var(--tx-fill); -webkit-background-clip: text; background-clip: text;
  filter: drop-shadow(0 1px 0 var(--tx-line)) drop-shadow(0 1px 1.5px rgba(0, 0, 0, .5)); }
.ravatar[data-rank="0"] .ravatar__name { --tx-fill: linear-gradient(180deg, #8A5A2B 0%, #5C3814 55%, #3E230A 100%); --tx-line: #F1DDB8; }
.ravatar[data-rank="1"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFE0B8 0%, #E7A268 45%, #A85A26 100%); --tx-line: #4E1410; }
.ravatar[data-rank="2"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFD9A6 0%, #D98E4A 45%, #8C4518 100%); --tx-line: #3E0F0B; }
.ravatar[data-rank="3"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFFFFF 0%, #D9DEE6 45%, #8E97A6 100%); --tx-line: #0B1C4A; }
.ravatar[data-rank="4"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFFFFF 0%, #DCE6E0 45%, #8FA89C 100%); --tx-line: #083324; }
.ravatar[data-rank="5"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFF7C8 0%, #F6CF5A 45%, #B8791A 100%); --tx-line: #5A1E06; }
.ravatar[data-rank="6"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFF6C4 0%, #F4C94E 45%, #B07416 100%); --tx-line: #4A0808; }
.ravatar[data-rank="7"] .ravatar__name { --tx-fill: linear-gradient(180deg, #FFFBE0 0%, #FFD968 40%, #C98A1E 100%); --tx-line: #4A0606; }
.ravatar--framed .ravatar__stars { left: 50%; top: calc(100% - var(--fr) * .005); bottom: auto; transform: translateX(-50%); gap: calc(var(--fr) * .055); padding: 0; background: none; box-shadow: none; align-items: flex-start; }
.ravatar--framed .ravatar__stars i { width: calc(var(--fr) * .12); height: calc(var(--fr) * .12); min-width: 0; min-height: 0; clip-path: none; background: url(/design/ranks/star-off.webp) center / contain no-repeat; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .35)); }
.ravatar--framed .ravatar__stars i.is-on { background-image: url(/design/ranks/star-on.webp); }
.ravatar--framed .ravatar__stars i:nth-child(2) { transform: translateY(calc(var(--fr) * .025)) scale(1.12); }
.topbar__avatar.ravatar--framed { margin: 0 10px; }

/* Home: six tiles in the Elo band (three Elo pools, online rank, ladder rank, accuracy); the band ends closer to its content. */
.band--last .ratings { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.band--last .band__sheet { padding-bottom: 64px; }
.rating--rank { color: inherit; text-decoration: none; }
.rating--rank:hover { background: #231813; }
.rating__rank { display: flex; align-items: center; gap: 4px; }
.rating__rank .rating__v { font-size: 26px; }
@media (max-width: 1100px) {
  .band--last .ratings { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .band--last .ratings > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
/* Landing hero: the copy sits in the middle of the painting's visible part (the torn band covers the bottom). */
@media (min-width: 761px) { .land-hero__in { padding-top: 32px; padding-bottom: 120px; } }
/* Wide screens (from 1241px, i.e. a 1920px screen at 125–150 % scaling too): the home hero grows with the painting and its copy takes more of the row, so the middle stays full. */
@media (min-width: 1241px) {
  .hero { min-height: 640px; }
  .hero__copy { max-width: min(760px, 52vw); }
  .hero__t { font-size: clamp(56px, 4.4vw, 68px); }
}
@media (min-width: 1400px) { .land-hero, .land-hero__in { min-height: 780px; } }
/* A rank portrait (no own picture): the character's bust sits on paper, head near the top of the circle. */
.ravatar__in--art { background: #F3E8D4; }
.ravatar__in--art img { object-fit: cover; object-position: 50% 18%; transform: scale(1.08); }

/* Player strips: the framed avatar takes the same 44px as the old portrait (the frame spills a little around it), the
   name shrinks before the Elo does, and the clock keeps room inside its box. */
.pstrip__av.ravatar--framed { --sz: 32px; width: var(--sz); height: var(--sz); margin: 6px; flex: none; }
@media (max-width: 760px) { .pstrip__av.ravatar--framed { --sz: 28px; margin: 4px; } }
.pstrip__name { overflow: visible; min-width: 0; }
.pstrip__nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pstrip__elo { flex: none; }
.pstrip .clock { min-width: 0; padding: 8px 16px; font-size: 24px; flex: none; }
.pstrip .clock.is-low { font-size: 26px; }
@media (max-width: 760px) { .pstrip .clock { font-size: 22px; padding: 7px 12px; } }

/* Wordmark: "Cờ" in the text colour, "Vũ Môn" in turmeric gold (the frames' gold), a metal gradient cut by the letters. */
.brand__gold { background: linear-gradient(180deg, #E9B03A 0%, #D0901A 55%, #A96F0C 100%); -webkit-background-clip: text; background-clip: text; color: transparent; }
html[data-theme="dark"] .brand__gold { background-image: linear-gradient(180deg, #F6D77F 0%, #E3B04A 55%, #C08A24 100%); }

/* Player strip, two lines: the name alone on top; below it the Elo, captured pieces and the status (the bot thinking,
   your turn). The clock is a fixed box at the end, so nothing pushes it out of the strip. */
.pstrip { gap: 12px; padding: 8px 10px; }
.pstrip__id { gap: 3px; }
.pstrip__name { font-size: 15px; }
.pstrip__sub { flex-wrap: nowrap; gap: 8px; min-height: 22px; overflow: hidden; }
.pstrip__sub .pstrip__elo { padding: 1px 7px; border-radius: 6px; background: rgba(217, 178, 106, .12); color: var(--text-2); font-size: 12px; flex: none; }
.pstrip__status { min-width: 0; overflow: hidden; }
.pstrip__status .thinking { padding: 2px 8px; font-size: 12px; }
.pstrip .clock { width: 96px; padding: 8px 0; text-align: center; font-size: 22px; }
.pstrip .clock.is-low { font-size: 24px; }
.page--game .game > .side { align-self: start; }
@media (max-width: 760px) { .pstrip .clock { width: 84px; font-size: 20px; } }
/* Captured pieces: one chip per kind, side by side (no overlap), with a count. Status sits right of the name. */
.caps { gap: 6px; flex-wrap: nowrap; }
.capg { display: inline-flex; align-items: center; gap: 1px; }
.pstrip .cap { width: 20px; height: 20px; margin-right: 0; font-size: 11px; }
.capg__n { font: 600 11px var(--f-mono); color: var(--text-3); }
.pstrip__name { gap: 8px; }
.pstrip__name .pstrip__status { margin-left: auto; flex: none; font-weight: 500; }
@media (min-width: 761px) { .page--game .game { column-gap: 72px; } }

/* Heroes: the pale area behind the copy (it keeps the text clear of the painting) is the same giấy dó as the hero,
   pinned to the viewport like the hero's own paper so the grain lines up, and faded out by a mask — no longer a flat
   paper-coloured glow that smoothed the texture away. */
@media (min-width: 761px) {
  .hero, .land-hero { background-attachment: fixed; background-position: 0 0; }
  .hero__copy::before, .land-hero__copy::before {
    background: #EEE2CB url(../assets/texture-giay-do.webp) 0 0 / 520px fixed;
    -webkit-mask-image: radial-gradient(ellipse 70% 75% at 35% 50%, rgba(0, 0, 0, .9) 30%, transparent 75%);
    mask-image: radial-gradient(ellipse 70% 75% at 35% 50%, rgba(0, 0, 0, .9) 30%, transparent 75%);
  }
}

/* Phone analysis: one slim eval strip under the board (the engine panel right below shows the number). */
.evalbar--strip { width: calc(100% - 32px); height: 8px; margin: 12px 16px 4px; align-self: center; border-radius: 999px; background: #0B0705; box-shadow: 0 0 0 1px var(--hair-2); }
.evalbar--strip .evalbar__red { border-radius: 999px 0 0 999px; background: linear-gradient(90deg, #E9DCC3, #F6EEDF); }
.evalbar--strip .evalbar__mid { width: 2px; margin-left: -1px; background: var(--gold); opacity: .8; }
.evalbar--strip .evalbar__v { display: none; }
/* The vertical eval bar spans the board itself, not the file-letter rows above and below it. */
.stage__row:has(.xq-files) > .evalbar:not(.evalbar--h) { margin-block: 22px; }

/* Lesson path (/hoc) */
.lp-lead { max-width: 60ch; margin: -8px 0 24px; font-size: 16px; }
.lp-next { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px 24px; padding: 24px; margin-bottom: 24px; color: inherit; text-decoration: none; transition: box-shadow .2s var(--ease), transform .2s var(--ease); }
.lp-next:hover { box-shadow: var(--sh-2); transform: translateY(-1px); }
.lp-next__bar { grid-column: 1 / -1; order: 3; }
.lp-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; padding-bottom: 48px; }
.lp-ch { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.lp-ch__hd { display: grid; gap: 8px; padding: 20px 20px 16px; border-bottom: 1px solid var(--hair); }
.lp-ch__hd .muted { margin: 0; }
.lp-list { list-style: none; margin: 0; padding: 6px; }
.lp-item { display: grid; grid-template-columns: 28px 1fr 16px; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--r-sm); color: var(--text); text-decoration: none; }
.lp-item:hover { background: var(--surface-2); }
.lp-item > .ic:last-child { width: 16px; height: 16px; color: var(--text-3); }
.lp-item__n { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--surface-3); font: 600 12px/1 var(--f-mono); color: var(--text-2); }
.lp-item.is-done .lp-item__n { background: var(--dong); color: #fff; }
.lp-item.is-done .lp-item__n .ic { width: 14px; height: 14px; }
.lp-item__t { font-weight: 500; }
@media (max-width: 760px) {
  .lp-grid { grid-template-columns: 1fr; gap: 16px; }
  .lp-next { grid-template-columns: 1fr; padding: 20px; }
  .lp-next .btn { justify-self: start; }
}
/* One lesson */
.lesson p { margin: 0; line-height: 1.6; color: var(--text-2); }
.lesson__t { margin: 0; font: 700 20px/1.3 var(--f-display); color: var(--text); }
.lesson .lesson__task { display: flex; gap: 10px; align-items: flex-start; padding: 12px 14px; border-radius: var(--r-sm); background: rgba(217, 178, 106, .1); box-shadow: inset 0 0 0 1px rgba(217, 178, 106, .3); color: var(--text); font-weight: 600; }
.lesson__task .ic { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--gold); }
.lesson__next { margin: -4px 0 0; text-align: center; }
/* Opening library (/khai-cuoc) */
.oc-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; padding-bottom: 48px; }
.oc-card { display: grid; grid-template-columns: 148px 1fr; gap: 20px; align-items: start; padding: 20px; color: inherit; text-decoration: none; transition: box-shadow .2s var(--ease), transform .2s var(--ease); }
.oc-card:hover { box-shadow: var(--sh-2); transform: translateY(-1px); }
.oc-card .minib { width: 148px; }
.oc-card__bd { gap: 6px; min-width: 0; }
.oc-card__bd .muted { margin: 0; }
.oc-keys { margin: 0; padding-left: 18px; display: grid; gap: 6px; color: var(--text-2); line-height: 1.55; }
@media (max-width: 900px) { .oc-grid { grid-template-columns: 1fr; } }
@media (max-width: 480px) { .oc-card { grid-template-columns: 104px 1fr; gap: 14px; padding: 16px; } .oc-card .minib { width: 104px; } }
/* Bot picker started from a chosen position */
.from-pos { display: grid; grid-template-columns: 120px 1fr; gap: 20px; align-items: center; padding: 16px 20px; margin-bottom: 20px; }
.from-pos .minib { width: 120px; }
.from-pos .stack { gap: 4px; }
.from-pos p { margin: 0; }
@media (max-width: 480px) { .from-pos { grid-template-columns: 88px 1fr; gap: 14px; padding: 14px; } .from-pos .minib { width: 88px; } }
/* Master games library (/van-cao-thu) */
.mg-top { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.chip.is-active { background: var(--than); color: #FCFAF6; }
.chip__n { font: 500 12px var(--f-mono); color: var(--text-2); }
.mg-filter { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) auto; gap: 12px; align-items: end; padding: 16px 20px; }
.mg-filter .field { margin: 0; }
.mg-count { margin: 16px 0 8px; }
.mg-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.mg-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 16px; padding: 14px 18px; color: inherit; text-decoration: none; transition: box-shadow .2s var(--ease); }
.mg-row:hover { box-shadow: var(--sh-2); }
.mg-row__who { display: flex; align-items: center; gap: 8px; font-weight: 600; min-width: 0; flex-wrap: wrap; }
.mg-row__vs { color: var(--text-3); font-weight: 400; }
.mg-row__p { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.mg-row__res { grid-row: span 2; align-self: center; }
.mg-row__ev, .mg-row__op { min-width: 0; }
.mg-pages { justify-content: space-between; align-items: center; margin: 20px 0; }
.mg-source { margin: 24px 0 48px; }
.mg-players { display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px; align-items: center; font-weight: 600; color: var(--text); }
.mg-players > span:last-child { justify-self: end; }
.mg-players .pstrip__side { margin-right: 6px; }
.mg-flip { justify-self: start; }
@media (max-width: 760px) {
  .mg-top { flex-wrap: nowrap; overflow-x: auto; margin: 0 -16px 12px; padding: 0 16px 4px; scrollbar-width: none; }
  .mg-top .chip { flex: none; }
  .mg-filter { grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px; }
  .mg-filter .field:first-child, .mg-filter .btn { grid-column: 1 / -1; }
  .mg-row { padding: 12px 14px; }
  .mg-players { grid-template-columns: 1fr; }
  .mg-players > span:last-child { justify-self: start; }
}
/* Lobby: quiet pool offer while searching */
.seek__quiet { display: grid; gap: 12px; max-width: 520px; margin: 4px auto 8px; padding: 16px; border-radius: var(--r); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--hair); text-align: left; }
.seek__quiet p { margin: 0; line-height: 1.55; color: var(--text-2); }
.seek__quiet p b { color: var(--text); }
.pool__elo { font-size: 12px; }
/* Owner tools (/quan-tri) */
.adm-nums { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 16px; }
.adm-num { font: 600 20px/1.2 var(--f-ui); font-variant-numeric: tabular-nums; margin-top: 4px; }
@media (max-width: 760px) { .adm-nums { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Links inside running text are underlined, so they do not depend on colour alone (WCAG 1.4.1). */
p a:not(.btn), li a:not(.btn), .meta a:not(.btn), .muted a:not(.btn), .field__l a:not(.btn), .banner__grow a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }

/* Footer: the page in every language, one line of small links under the columns. */
.sitefoot__langs { display: flex; flex-wrap: wrap; gap: 6px 16px; padding-top: 16px; padding-bottom: 8px; border-top: 1px solid var(--hair); font-size: 13px; }
.sitefoot__langs a { color: inherit; opacity: .78; text-decoration: none; white-space: nowrap; }
.sitefoot__langs a b { font-weight: 600; font-size: 11px; letter-spacing: .04em; opacity: .7; margin-right: 2px; }
.sitefoot__langs a:hover, .sitefoot__langs a[aria-current] { opacity: 1; }
.sitefoot__langs a[aria-current] { text-decoration: underline; text-underline-offset: 3px; }

/* Settings tabs on a phone scroll sideways: no scrollbar drawn over the tabs' hover/active background (swipe still
   scrolls), and a little room under the pills. */
@media (max-width: 760px) {
  .snav { scrollbar-width: none; padding-bottom: 2px; }
  .snav::-webkit-scrollbar { display: none; }
}

/* Top menu: a group opened by a click (it keeps focus / is-open) must not stay open under the one the pointer is on:
   while the pointer is over the menu, only the hovered group shows its panel. */
.topnav:hover .topnav__grp:not(:hover) .topnav__panel { display: none; }
.topnav:hover .topnav__grp:not(:hover) .topnav__caret { transform: none; }

/* Top-up page: gift card code under the two plans (one row: field, button; the result on its own line). */
.voucher-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-top: 16px; padding: 16px 20px; }
.voucher-form .field { flex: 1 1 260px; margin: 0; }
.voucher-form__ok, .voucher-form__err { flex-basis: 100%; margin: 0; font-size: 14px; }
.voucher-form__ok { color: var(--tg-good); }
.voucher-form__err { color: var(--tg-blunder); }

/* Engine still loading: a small spinner in the middle of the board (no banner). */
.xq-busy { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.xq-busy__spin { width: 36px; height: 36px; border-radius: 50%; border: 3px solid rgba(60, 36, 18, .18); border-top-color: var(--son); background: rgba(255, 248, 236, .55); animation: spin .9s linear infinite; }
