/* HORO-BEAT sim: the play lane's screens (setup, the night board, the match bar, the fan hands, the dock with the
   decision panel, the side panel, game over).
   Owner: play lane. Spec: reports/polish/DESIGN.md §4.4 / §4.5, identity-3 mockup "03 board".
   The board is the playmat at night, its zones placed as on the official board (reference/board-example-video.webp):
   on my mat, from the line rail outwards, the five lines (line 5 left … line 1 right), the わざぞ〜ん bar (one cell per
   line), the えなぞ〜ん bar; は〜とぞ〜ん in the left column; やまふだ beside the battle line and ぼち beside the two bars
   in the right column. The opponent's mat is mine turned round (its えなぞ〜ん at the top, its hearts on the right, its
   deck / grave on the left) except the line order, so line N faces line N; the rail between the two carries the 人魂
   line marks and the power compare. Every size comes from play.js fit() as px custom properties on #g-main (--cw card
   width, --slot, --colw the side columns, --lineh, --wzh, --enh, --hw hand card, --wk / --ek / --pk / --hk zone cards,
   --matcols the mat's columns, --dockh the dock, --fanw / --fantop / --fanlow / --fanhov my fan, --ofan* the opponent's).
   Flat paint here; every gradient / pattern / glow / idle loop is in the @layer hb-fx block at the end, scoped to
   body:not(.hb-perf) (DESIGN §7). Transforms the cue queue animates (play-fx.js) are kept off the elements it moves:
   centring uses the `translate` property, the down / used turns are the only `transform`s. */

@layer hb-screens {
  /* ================================================================== setup */
  #scr-play.in-game .hb-playsetup { display: none; }
  #scr-play:not(.in-game) .hb-game { display: none; }
  .hb-playsetup { position: absolute; inset: 0; overflow: auto; background-color: var(--hb-ink-1); }
  .hb-playsetup__scene { position: absolute; inset: 0; z-index: 0; min-height: 560px; overflow: hidden; pointer-events: none; opacity: .5; }
  .hb-playsetup__col { position: relative; z-index: 1; display: grid; align-content: center; gap: 14px; width: min(700px, 100%); min-height: 100%; margin: 0 auto; padding: 28px var(--hb-gutter) 32px; box-sizing: border-box; }
  .hb-resume__body { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 12px; padding: 12px 14px 12px 16px; }
  .hb-resume { box-shadow: inset 0 0 0 1px var(--hb-tama-deep), var(--hb-e1); }
  .hb-resume__dama { width: 22px; height: 22px; color: var(--hb-tama); }
  .hb-resume__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .hb-resume__text b { font: 800 var(--hb-fs-16)/1.2 var(--hb-font-display); letter-spacing: .04em; }
  .hb-resume__text span { color: var(--hb-text-3); font-size: var(--hb-fs-12); }
  .hb-setup { overflow: hidden; }
  .hb-setup__head { display: flex; flex-direction: column; gap: 6px; padding: 18px 20px 4px; }
  .hb-setup__head .hb-crest { width: 22px; height: 22px; font-size: 11px; }
  .hb-setup__title { margin: 0; color: var(--hb-text); font: 800 var(--hb-fs-28)/1.15 var(--hb-font-display); letter-spacing: .06em; }
  .hb-setup__body { display: flex; flex-direction: column; gap: 18px; padding: 14px 20px 18px; }
  .hb-setup__mode > button { height: 40px; font-size: var(--hb-fs-13); }
  .hb-setup__vs { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: end; gap: 14px; }
  .hb-setup__side { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
  .hb-setup__side .hb-label { margin: 0; }
  .hb-setup__who { font: 800 var(--hb-fs-18)/1.2 var(--hb-font-display); letter-spacing: .04em; }
  .hb-setup__tai { display: grid; place-items: center; width: 42px; height: 42px; margin-bottom: 14px; border-radius: 3px; background-color: var(--hb-shu); color: #fff;
    font: 800 22px/1 var(--hb-font-display); transform: rotate(-6deg); box-shadow: inset 0 0 0 2px rgba(255,220,190,.35), 0 6px 16px rgba(0,0,0,.5); }
  .hb-deckpick { width: 100%; margin: 0; border: 0; color: var(--hb-text); font: inherit; text-align: left; grid-template-columns: auto minmax(0, 1fr) auto; min-height: 64px; }
  .hb-deckpick .hb-deck__art { width: 46px; height: 46px; object-fit: cover; object-position: 50% 18%; }
  .hb-deck__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .hb-deck__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .hb-deck__meta { display: flex; align-items: center; gap: 2px; }
  .hb-deck__meta .hb-dot { width: 8px; height: 8px; }
  .hb-deck__text .hb-comp { height: 4px; margin-top: 2px; }
  .hb-deckpick__chev, .hb-deck__on { color: var(--hb-kin); }
  .hb-deck__on { color: var(--hb-shu-hi); }
  .hb-deckpick[aria-pressed="true"] { box-shadow: inset 0 0 0 1px var(--hb-kin); }
  .hb-decklist { display: flex; flex-direction: column; gap: 6px; }
  .hb-deckpickwin .hb-window__body { gap: 6px; }
  .hb-setup__opts { display: grid; grid-template-columns: 1fr 1.4fr; gap: 14px; }
  .hb-setup__opt { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
  .hb-setup__opt .hb-label { margin: 0; }
  .hb-setup__opt .hb-seg > button { padding: 0 6px; }
  .hb-setup__foot { display: flex; justify-content: flex-end; padding: 12px 20px 16px; border-top: 1px solid var(--hb-line); }
  .hb-setup__foot .hb-btn { min-width: 180px; }

  /* ================================================================== the game: main column + side panel */
  .hb-game { position: absolute; inset: 0; display: grid; grid-template-columns: minmax(0, 1fr) var(--sidepanel, 340px); background-color: var(--hb-ink-1); }
  .hb-game__main {
    --cw: 70px; --slot: 90px; --hw: 80px; --ohw: 16px; --colw: 60px; --lineh: 120px; --wzh: 60px; --enh: 56px;
    --wk: 40px; --ek: 36px; --pk: 44px; --hk: 38px; --gap: 5px; --cg: 8px; --rg: 5px; --matpad: 10px; --matpady: 8px; --railh: 32px; --downscale: 1;
    --slottop: 9px; --matcols: 60px 450px 60px; --tabley: 4px; --dockh: 72px; --fanw: 480px; --fantop: -100px; --fanlow: 110px; --fanhov: 10px;
    --ofanw: 250px; --ofantop: -10px; --ofanlow: 20px;
    /* (overflow CLIP, not hidden: a hidden box can still be scrolled, and the keyboard focus on a card of the lowered fan -
       mostly under the bottom edge - would scroll the whole board up to show it) */
    position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: clip; }

  /* ---- the match bar: round / phase | the opponent's name and fan | speed · language · settings · Concede · leave.
     During a match it is the only bar (the app bar is hidden: body.hb-match, shell.css), 40 px high */
  .hb-phasebar { position: relative; z-index: 6; flex: none; flex-direction: row; align-items: center; gap: 10px; height: 40px; margin: 4px 8px 0; padding: 0 5px 0 2px; }
  .hb-phasebar__info { flex: 1 1 0; display: flex; align-items: center; gap: 10px; min-width: 0; overflow: hidden; white-space: nowrap; margin-block: -6px; padding-block: 6px; }   /* (room for the italic numerals' descenders under the clip) */
  .hb-round { display: flex; align-items: baseline; gap: 6px; padding: 0 12px 0 10px; border-right: 1px solid var(--hb-line); }
  .hb-round small { color: var(--hb-kin-text); font: 800 10px/1 var(--hb-font-ui); letter-spacing: .26em; }
  .hb-round b { color: var(--hb-text); font: italic 900 24px/1 var(--hb-font-num); }
  /* The phase's NAME is not cut for the detail's sake. The detail (who · which step; online it holds a player's own
     name, up to 16 characters) takes the room that is left, with an ellipsis; when this side of the bar is too narrow
     to leave it about 6em (the round 96 px + a name up to 115 + the gaps = 300 px), it is not shown at all.
     (Shrinking both cut the name, "Summon pha…"; shrinking the detail alone left a 2 px sliver of its first letter.)
     The side's width does not depend on its text (flex-basis 0), so it can be the query's container. */
  .hb-phasebar__info { container: hb-phinfo / inline-size; }
  .hb-phase { display: flex; align-items: baseline; gap: 8px; min-width: 0; overflow: hidden; }
  .hb-phasebar__info > .hb-phase:first-child { padding-left: 14px; }   /* "Setup": no round yet */
  .hb-phase b { min-width: 0; overflow: hidden; font: 800 var(--hb-fs-14)/1.45 var(--hb-font-display); letter-spacing: .06em; text-overflow: ellipsis; }
  .hb-phase span { flex: 0 1000000 auto; min-width: 4em; overflow: hidden; color: var(--hb-text-3); font: 600 var(--hb-fs-12)/1.45 var(--hb-font-ui); text-overflow: ellipsis; }
  @container hb-phinfo (max-width: 300px) { .hb-phase span { display: none; } }
  /* the controls keep their width; the round / phase text gives way (ellipsis). Equal sides keep the fan in the middle */
  .hb-phasebar__ctl { flex: 1 1 0; display: flex; align-items: center; justify-content: flex-end; gap: 6px; min-width: max-content; }
  .hb-phasebar__ctl > * { flex: none; }
  .hb-speed > button { min-width: 32px; height: 26px; padding: 0 7px; }
  .hb-matchlang > button { min-width: 0; height: 26px; padding: 0 8px; font-size: var(--hb-fs-11); }
  .is-bar-s .hb-matchlang { display: none; }   /* a narrow bar: the language is in Settings (the gear beside it) */
  .is-bar-s .hb-concede > span { display: none; }
  .is-bar-s .hb-concede { width: var(--hb-h-sm); padding: 0; }
  .hb-logbtn { display: none; }
  /* the replay transport sits in the decision panel (the match bar has the opponent's fan) */
  .hb-replay { display: flex; align-items: center; gap: 6px; flex: 1 1 100%; min-width: 0; }
  .hb-replay__bar { width: auto; min-width: 60px; flex: 1 1 150px; }
  .hb-replay__pos { min-width: 54px; color: var(--hb-text-3); font: 400 var(--hb-fs-11)/1 var(--hb-font-num); white-space: nowrap; }
  .hb-replay__pos b { color: var(--hb-text); font: italic 900 var(--hb-fs-14)/1 var(--hb-font-num); }
  .hb-icon--end { transform: rotate(-90deg); }

  /* ---- the table: the two mats, the full width of the play area (sized to fill it: fit()) */
  .hb-table { flex: 1 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; display: flex; flex-direction: column; align-items: center; justify-content: safe center; padding: var(--tabley) 8px; }
  .hb-handwrap { flex: none; }
  .hb-board { flex: none; display: flex; flex-direction: column; gap: var(--gap); max-width: 100%; }

  /* ---- a card on the table (the real printing, the printed corner) */
  .hb-c { position: relative; flex: none; box-sizing: border-box; width: var(--w, var(--cw)); aspect-ratio: 600 / 838; border-radius: var(--hb-r-print); overflow: hidden;
    background-color: var(--hb-ink-0); box-shadow: 0 0 0 1px rgba(0,0,0,.7), 0 3px 8px rgba(0,0,0,.45); }
  .hb-c > .hb-cimg { width: 100%; height: 100%; }
  .hb-c--back { box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 3px 8px rgba(0,0,0,.45); }   /* (the official back: its own black frame, no keyline over it) */
  .hb-c--none { background-color: transparent; box-shadow: inset 0 0 0 1.5px var(--hb-line-2); }
  #play-game [data-uid] { cursor: help; }
  #play-game [data-opt], #play-game .is-human [data-hand].is-act { cursor: pointer; }

  /* ---- THE NIGHT MAT */
  .hb-mat { position: relative; isolation: isolate; display: grid; grid-template-columns: var(--matcols); column-gap: var(--cg); row-gap: var(--rg); padding: var(--matpady) var(--matpad);
    border-radius: var(--hb-r-mat); background-color: var(--hb-mat-bg); box-shadow: inset 0 0 0 1px var(--hb-mat-edge), 0 6px 18px rgba(0,0,0,.35); }
  /* the official board: from the rail outwards the battle line, the ワザ bar, the エナ bar; my hearts left, my deck
     beside the battle line and my grave beside the bars right. The opponent's mat is mine turned round (the lines'
     order is not: play.js lineOrder()), so both mats have the same three columns and the lines stay in line */
  .hb-mat--me { grid-template-areas: "hearts lines deck" "hearts waza grave" "hearts ena grave"; grid-template-rows: var(--lineh) var(--wzh) var(--enh); }
  .hb-mat--opp { grid-template-areas: "grave ena hearts" "grave waza hearts" "deck lines hearts"; grid-template-rows: var(--enh) var(--wzh) var(--lineh); }
  .hb-zone { position: relative; min-width: 0; min-height: 0; border-radius: var(--hb-r-zone); }
  /* zone tags (the playmat's black hex in a gold one; hiragana in 日本語) */
  .hb-ztag { position: absolute; z-index: 4; pointer-events: none; }
  .hb-ztag.hb-tag--v.hb-tag--sm { width: 17px; font-size: 10px; letter-spacing: .1em; }

  /* は〜とぞ〜ん: the face-down hearts, the top one (last) in front; down = turned sideways */
  .hb-hearts { grid-area: hearts; display: flex; flex-direction: column; align-items: center; padding: 0 0 6px; background-color: var(--hb-mat-hearts); }
  /* the tag is in the column's flow (poking over its top edge), so the pile always starts under it, in both languages */
  .hb-hearts > .hb-ztag { position: relative; flex: none; margin: -7px 0 2px; }
  /* a column too short for the tag, the pile and the count (a small desktop; play.js fit() sets .is-edgehearts): the
     tag stands on the column's outer edge from its top, as the DECK / GRAVE tags do, the pile beside it 4 px toward
     the board */
  .is-edgehearts .hb-hearts > .hb-ztag { position: absolute; margin: 0; top: -7px; left: -9px; }
  .is-edgehearts .hb-mat--opp .hb-hearts > .hb-ztag { left: auto; right: -9px; }
  .is-edgehearts .hb-hearts__pile { padding-top: 6px; translate: 4px 0; }
  .is-edgehearts .hb-mat--opp .hb-hearts__pile { translate: -4px 0; }
  .hb-hearts__pile { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; align-items: center; width: 100%; padding: 4px 0; }
  .hb-hearts__pile > * + * { margin-top: var(--ov, -64%); }
  /* the opponent's pile, turned round: its top heart (the last) is the whole card at the top of the stack */
  .hb-mat--opp .hb-hearts__pile { flex-direction: column-reverse; justify-content: flex-end; }
  .hb-mat--opp .hb-hearts__pile > * + * { margin-top: 0; margin-bottom: var(--ov, -64%); }
  .hb-heart { display: block; flex: none; width: var(--hk); }
  .hb-heart > .hb-c { --w: var(--hk); }
  .hb-heart.is-down { transform: rotate(90deg); }
  .hb-heart.is-down > .hb-c { filter: brightness(.7) saturate(.7); }
  .hb-zone__count { flex: none; display: flex; flex-direction: column; align-items: center; gap: 1px; padding-top: 4px; }
  .hb-hearts .hb-zone__count { position: relative; z-index: 3; }   /* above the heart pile's top card, never under it */
  .hb-zone__count .hb-count { font-size: var(--hb-fs-22); }
  .hb-zone__count span { color: var(--hb-text-3); font-size: var(--hb-fs-11); white-space: nowrap; }
  /* the check zone: a vermilion chip in the column's flow under the count (never over it), only while it holds cards */
  .hb-checkchip { position: relative; z-index: 3; flex: none; display: inline-flex; align-items: center; gap: 3px; height: 18px; margin-top: 4px; padding: 0 7px; border-radius: 2px;
    background-color: var(--hb-shu); color: #fff; font: 700 10px/1 var(--hb-font-ui); white-space: nowrap; box-shadow: 0 2px 6px rgba(0,0,0,.5); }
  .hb-checkchip b { font: italic 900 12px/1 var(--hb-font-num); }
  .hb-checkchip.is-empty { display: none; }

  /* the five lines: ホロビト slots split by faint gold rules; the battle line lit */
  .hb-lines { grid-area: lines; display: grid; grid-template-columns: repeat(5, var(--slot)); }
  .hb-line { position: relative; min-width: 0; border-left: 1px solid var(--hb-mat-rule); }
  .hb-line:first-child { border-left-color: transparent; }
  .hb-line.is-battle { border-radius: 8px; background-color: var(--hb-mat-battle); box-shadow: inset 0 0 0 1px var(--hb-kin-line); border-left-color: transparent; }
  .hb-line.is-battle + .hb-line { border-left-color: transparent; }
  .hb-slot { position: relative; width: 100%; height: 100%; border-radius: 8px; }
  .hb-slot__empty { position: absolute; left: 50%; top: var(--slottop); translate: -50% 0; width: var(--cw); aspect-ratio: 600 / 838; box-sizing: border-box; border-radius: var(--hb-r-print); border: 1.5px dashed var(--hb-line-2); }
  .hb-slot.is-target { box-shadow: inset 0 0 0 2px var(--hb-tama); }
  .hb-slot.is-target .hb-slot__empty { border-color: var(--hb-tama); border-style: solid; background-color: rgba(120,236,214,.08); }
  .hb-unit { position: absolute; left: 50%; top: var(--slottop); width: var(--cw); translate: -50% 0; }
  .hb-unit.is-down { scale: var(--downscale); }
  .hb-unit__turn { position: relative; }
  .hb-unit.is-down .hb-unit__turn { transform: rotate(90deg); }
  .hb-unit.is-down .hb-c--unit > .hb-cimg { filter: saturate(.55) brightness(.72); }
  .hb-c--unit { position: relative; z-index: 1; }
  .hb-stack__under { position: absolute; left: 0; top: 0; z-index: 0; width: 100%; aspect-ratio: 600 / 838; overflow: hidden; border-radius: var(--hb-r-print); box-shadow: 0 0 0 1px rgba(0,0,0,.7); }
  .hb-stack__under > .hb-cimg { width: 100%; height: 100%; }
  .hb-stack__under--1 { translate: 0 calc(var(--cw) * -.06); filter: brightness(.8); }
  .hb-stack__under--2 { translate: 0 calc(var(--cw) * -.12); filter: brightness(.6); }
  .hb-stackn { position: absolute; z-index: 4; left: calc(50% + var(--cw) / 2 - 8px); top: calc(var(--slottop) - 9px); }
  .hb-unitcost { position: absolute; z-index: 4; left: calc(50% - var(--cw) / 2 - 4px); top: calc(var(--slottop) - 4px); }
  .hb-unitcost .hb-gem { box-shadow: 0 0 0 1.5px var(--hb-glyph-edge), 0 0 0 3px var(--hb-warn); }
  .hb-kwbs { position: absolute; z-index: 4; left: calc(50% + var(--cw) / 2 - 3px); top: calc(var(--slottop) + var(--cw) * .32); translate: -100% 0; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
  .hb-kwb { display: grid; place-items: center; min-width: 18px; height: 15px; padding: 0 3px; background-color: var(--hb-ink-0); color: var(--hb-text); font: 900 9px/1 var(--hb-font-gemtext); font-style: normal; font-synthesis: none;
    clip-path: polygon(4px 0, calc(100% - 4px) 0, 100% 50%, calc(100% - 4px) 100%, 4px 100%, 0 50%); }
  .hb-kwb--dd { background-color: var(--hb-red-deep-2); color: var(--hb-red-text); }
  .hb-kwb--bar { background-color: var(--hb-blue-deep-2); color: var(--hb-blue-text); }
  .hb-kwb--lost { background-color: var(--hb-ink-4); color: var(--hb-text-3); }
  /* the power plate (lacquer, colour-edged, Playfair, the modifier in gold) on the slot's bottom edge */
  .hb-pow { position: absolute; z-index: 5; left: 50%; bottom: 0; translate: -50% 0; display: flex; align-items: baseline; gap: 3px; padding: 2px 7px 3px; border: 1px solid var(--c, var(--hb-line-2)); border-radius: 2px;
    background-color: #0e0806; white-space: nowrap; box-shadow: 0 3px 8px rgba(0,0,0,.6); }
  .hb-pow .hb-num { margin: 0; padding: 0; font-size: max(12px, calc(var(--cw) * .17)); -webkit-text-stroke: 0; color: #fff; }
  .hb-pow .hb-num--up { color: var(--hb-kin-hi); }
  .hb-pow .hb-num--down { color: var(--hb-text-3); }
  .hb-pow small { color: var(--hb-kin-hi); font: 400 max(9px, calc(var(--cw) * .11))/1 var(--hb-font-boostnum); font-synthesis: none; }

  /* わざぞ〜ん: one cell per line (the playmat's peach band) */
  .hb-wazarow { grid-area: waza; display: grid; grid-template-columns: repeat(5, var(--slot)); background-color: var(--hb-mat-waza); }
  /* the わざぞ〜ん / えなぞ〜ん tags stand at their bar's right end, as on the playmat: on a desktop in the column gap
     beside it (the gap is a tag wide), on a phone across the bar's edge. play.js placeTags() sets their height: each
     centred on its bar, the two kept apart where a bar is lower than its tag */
  .hb-wazarow > .hb-ztag, .hb-ena > .hb-ztag { top: 0; bottom: auto; left: calc(100% + (var(--cg) - 17px) / 2); right: auto; }
  .hb-waza { position: relative; display: flex; align-items: center; justify-content: center; min-width: 0; border-radius: 6px; }
  .hb-waza + .hb-waza::before { content: ""; position: absolute; left: 0; top: 12%; bottom: 12%; border-left: 1px dashed var(--hb-mat-waza-line); }
  .hb-waza.is-battle { background-color: rgba(255,138,64,.14); box-shadow: inset 0 0 0 1px var(--hb-kin-line); }
  .hb-waza > .hb-c { --w: var(--wk); }
  .hb-waza > .hb-c + .hb-c { margin-left: var(--ov, 4px); }
  .hb-wzplus { position: absolute; left: 0; right: 0; bottom: 0; padding: 2px 0 1px; background-color: rgba(10,6,4,.82); color: var(--hb-kin-hi); font: 400 max(9px, calc(var(--wk, 45px) * .2))/1 var(--hb-font-boostnum); font-synthesis: none; text-align: center; }
  .hb-wzplus.is-boost { color: var(--hb-green-hi); }

  /* えなぞ〜ん: the count (unused / all) + colour pips, the cards overlapped; used = turned sideways */
  .hb-ena { grid-area: ena; display: flex; align-items: center; gap: 10px; padding: 4px 10px; background-color: var(--hb-mat-ena); }
  .hb-enacount { flex: none; display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
  .hb-enacount .hb-count { font-size: var(--hb-fs-20); white-space: nowrap; }
  .hb-enacount .hb-count small { font-size: var(--hb-fs-11); }
  .hb-pips { display: flex; gap: 6px; }
  .hb-pip { display: inline-flex; align-items: center; gap: 3px; }
  .hb-pip .hb-gem { --s: 13px; }
  .hb-pip b { font: italic 900 var(--hb-fs-12)/1 var(--hb-font-num); }
  .hb-ena__cards { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; height: 100%; }
  .hb-ena__cards > * + * { margin-left: var(--ov, 4px); }
  .hb-c--e { --w: var(--ek); }
  .hb-c--e.is-used { transform: rotate(90deg); }
  .hb-c--e.is-used > .hb-cimg { filter: brightness(.62) saturate(.7); }
  .hb-ena__cards > .hb-c--e.is-used { margin-right: calc(var(--ek) * .2); }
  .hb-ena__cards > .hb-c--e.is-used:not(:first-child) { margin-left: max(var(--ov, 4px), calc(var(--ek) * .2)); }
  .hb-ena__cards > .hb-c--e.is-used:first-child { margin-left: calc(var(--ek) * .2); }   /* (its sideways overhang clear of the count) */
  /* many エナ overlap like a hand (play.js overlap(), the sideways cards counted): the used ones drop their side
     margins, and the row keeps one sideways card's overhang free at its two ends */
  .hb-ena__cards.is-ov { padding: 0 calc(var(--ek) * .2); }
  .hb-ena__cards.is-ov > .hb-c--e.is-used, .hb-ena__cards.is-ov > .hb-c--e.is-used:not(:first-child) { margin-right: 0; margin-left: var(--ov); }
  .hb-ena__cards.is-ov > .hb-c--e.is-used:first-child { margin-left: 0; }

  /* やまふだ beside the battle line, ぼち beside the two bars: on a desktop the DECK / GRAVE tags stand on the column's
     outer edge (my mat's right, the opponent's left), the pile sits a little toward the board and its count badge on
     the board side, kept inside the zone (the bars' tags stand in the gap beyond it) */
  .hb-pilezone { position: relative; display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; border-radius: var(--hb-r-zone); background-color: var(--hb-mat-side); box-shadow: inset 0 0 0 1px var(--hb-mat-side-line); }
  .hb-pilezone[data-zone="deck"] { grid-area: deck; }
  .hb-pilezone[data-zone="grave"] { grid-area: grave; }
  .hb-pilezone > .hb-ztag { right: -9px; top: 50%; translate: 0 -50%; }
  .hb-mat--opp .hb-pilezone > .hb-ztag { right: auto; left: -9px; }
  .hb-pilezone--grave { cursor: pointer; }
  .hb-pilezone--grave:hover { box-shadow: inset 0 0 0 1px var(--hb-kin); }
  .hb-pile { position: relative; flex: none; width: var(--pk); translate: -4px 0; }
  .hb-mat--opp .hb-pile { translate: 4px 0; }
  .hb-pile > .hb-c { --w: var(--pk); position: relative; z-index: 1; }
  .hb-pile.is-thick::before, .hb-pile.is-thick::after { content: ""; position: absolute; inset: 0; border-radius: var(--hb-r-print); background-color: #0f0705; box-shadow: 0 0 0 1px var(--hb-kin-lo); }
  .hb-pile.is-thick::before { transform: translate(4px, 4px); }
  .hb-pile.is-thick::after { transform: translate(2px, 2px); }
  .hb-mat--opp .hb-pile.is-thick::before { transform: translate(-4px, 4px); }   /* (the turned mat: the stack's edges mirrored, clear of its badge) */
  .hb-mat--opp .hb-pile.is-thick::after { transform: translate(-2px, 2px); }
  .hb-pile > .hb-badge { position: absolute; z-index: 2; left: max(-9px, calc((var(--pk) - var(--colw)) / 2 + 4px)); bottom: -6px; }
  .hb-mat--opp .hb-pile > .hb-badge { left: auto; right: max(-9px, calc((var(--pk) - var(--colw)) / 2 + 4px)); }

  /* ---- the line rail between the mats: each line's 人魂 mark, the battle compare plate */
  .hb-center { display: grid; grid-template-columns: var(--matcols); column-gap: var(--cg); height: var(--railh); padding: 0 var(--matpad); }
  .hb-center__lines { display: grid; grid-template-columns: repeat(5, var(--slot)); }
  .hb-center__pad--r { grid-column: 3 / -1; }
  .hb-rail { position: relative; display: flex; align-items: center; justify-content: center; gap: 6px; min-width: 0; border-radius: 4px; }
  .hb-rail .hb-lmark--rail { --s: 22px; }
  .hb-rail__lab { overflow: hidden; color: var(--hb-text-3); font: 700 var(--hb-fs-11)/1.3 var(--hb-font-ui); letter-spacing: .04em; white-space: nowrap; text-overflow: ellipsis; }
  .hb-rail__note { color: var(--hb-text-4); font-size: var(--hb-fs-10); white-space: nowrap; }
  .hb-rail.has-info .hb-rail__lab { display: none; }
  .hb-rail.is-battle { background-color: var(--hb-mat-battle); box-shadow: inset 0 0 0 1px var(--hb-kin-line); }
  .hb-rail.is-target { box-shadow: inset 0 0 0 2px var(--hb-tama); background-color: rgba(120,236,214,.08); }
  /* the compare plate: my power big, the tilted vermilion 対 hanko, the opponent's power smaller; the winner gold */
  .hb-compare { position: relative; z-index: 6; display: flex; align-items: center; gap: 7px; padding: 3px 9px; white-space: nowrap; background-color: #0e0806; border: 1px solid var(--hb-kin); border-radius: 3px; box-shadow: 0 6px 16px rgba(0,0,0,.6); }
  .hb-compare__me { color: #fff; font: italic 900 22px/1 var(--hb-font-num); }
  .hb-compare__op { color: var(--hb-text-3); font: italic 900 16px/1 var(--hb-font-num); }
  .hb-compare .is-win { color: var(--hb-kin-hi); }
  .hb-compare .is-lose { color: var(--hb-text-4); }
  .hb-compare__vs { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 2px; background-color: var(--hb-shu); color: #fff; font: 800 11px/1 var(--hb-font-display); transform: rotate(-6deg); }

  /* ---- the players' tags: the opponent's beside its fan in the match bar, mine left of my fan in the dock */
  .hb-ptag { flex: none; display: flex; flex-direction: column; gap: 4px; width: 118px; font-size: var(--hb-fs-12); line-height: 1.25; }
  .hb-ptag__who { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: var(--hb-fs-14); }
  .hb-ptag__who .hb-first { height: 17px; padding: 0 9px; font-size: 9px; letter-spacing: .1em; }
  .hb-ptag__meta { display: flex; flex-direction: column; gap: 1px; color: var(--hb-text-3); }
  .hb-ptag__deck { overflow: hidden; font-size: var(--hb-fs-11); text-overflow: ellipsis; white-space: nowrap; }
  .hb-who { color: var(--hb-text); font-weight: 700; }
  .hb-who--me { color: var(--hb-seat-me); }
  .hb-who--opp { color: var(--hb-seat-opp); }
  .hb-none { color: var(--hb-text-4); font-size: var(--hb-fs-12); }

  /* ---- THE FAN (play.js fanGeom): a hand's cards on an arc about one pivot. Each SLOT is moved to its place on the
     arc and turned (--x, --y, --a); the CARD in it turns back upright and lifts while the pointer is over the slot,
     while it has the focus or is selected, and comes to the front (the slot itself never moves, so the pointer stays
     on the card it lifted) */
  .hb-hfan { position: relative; flex: none; }
  .hb-hfan > .hb-none { position: absolute; left: 50%; top: 50%; translate: -50% -50%; white-space: nowrap; }
  /* (the slot is the card's VISIBLE STRIP, --sw wide: the part its right neighbour leaves in sight. The pointer picks
     cards by their strips; the card itself takes no pointer, so the one that is lifted and brought to the front never
     takes its neighbours' place under the pointer) */
  .hb-hfan__slot { position: absolute; left: 50%; width: var(--sw, var(--fw)); height: calc(var(--fw) * 838 / 600); margin-left: calc(var(--fw) / -2);
    transform-origin: calc(var(--fw) / 2) 50%; cursor: help;
    /* --low: the whole fan lowered by this much; --yk / --ak: how much of the arc's drop and of the cards' turn shows (a
       lowered fan is half closed, so the visible strip of every card still reaches above the edge; it opens as it rises) */
    transform: translate(var(--x), calc(var(--y) * var(--yk, 1) + var(--low, 0px))) rotate(calc(var(--a) * var(--ak, 1))); transition: transform .22s var(--hb-ease-out); }
  .hb-hfan__slot > .hb-c { position: absolute; left: 0; top: 0; --w: var(--fw); pointer-events: none; transition: transform var(--hb-dur-hover) var(--hb-ease-out), box-shadow var(--hb-dur-hover); }
  .is-human .hb-hfan--me > .hb-hfan__slot.is-act { cursor: pointer; }
  /* my fan: on the bottom edge. LOWERED (only its top shows in the dock) until the pointer is over it / it has the
     focus / a card of it is selected (#g-hand.is-up: play.js fanApply) */
  .hb-handwrap--me { grid-area: hand; justify-self: center; }
  .hb-hfan--me { --fw: var(--hw); --low: var(--fanlow); --yk: .3; --ak: .5; width: var(--fanw); height: var(--dockh); }
  .hb-hfan--me > .hb-hfan__slot { top: var(--fantop); }
  #g-hand.is-up .hb-hfan--me { --low: 0px; --yk: 1; --ak: 1; }
  .hb-hfan--me > .hb-hfan__slot.is-sel { z-index: 60 !important; }
  .hb-hfan--me > .hb-hfan__slot:focus-within { z-index: 65 !important; }
  .hb-hfan--me > .hb-hfan__slot.is-sel > .hb-c, .hb-hfan--me > .hb-hfan__slot:focus-within > .hb-c { transform: rotate(calc(var(--a) * var(--ak) * -1)) translateY(calc(var(--y) * var(--yk) * -1 - var(--fanhov))); }
  @media (hover: hover) {
    .hb-hfan--me > .hb-hfan__slot:hover { z-index: 70 !important; }
    .hb-hfan--me > .hb-hfan__slot:hover::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 34%; }   /* (the strip reaches up with the lifted card) */
    .hb-hfan--me > .hb-hfan__slot:hover > .hb-c { transform: rotate(calc(var(--a) * var(--ak) * -1)) translateY(calc(var(--y) * var(--yk) * -1 - var(--fanhov))) scale(1.04); }
  }
  .hb-c--hand { box-shadow: 0 0 0 1px rgba(0,0,0,.7), -3px 2px 8px rgba(0,0,0,.4); }
  .is-human .hb-c--hand.is-act { box-shadow: 0 0 0 2px var(--hb-tama), 0 -4px 12px -2px var(--hb-tama-glow); }   /* (a legal pick: its glow shows on the lowered fan too) */
  .hb-c--hand.is-sel, .is-human .hb-c--hand.is-act.is-sel { box-shadow: 0 0 0 3px var(--hb-kin-hi), 0 10px 22px rgba(0,0,0,.6); }
  .is-human .hb-c--hand:not(.is-act):not(.hb-c--back) > .hb-cimg { filter: brightness(.66) saturate(.7); }
  #g-hand.is-look .hb-c--hand > .hb-cimg { filter: none; }   /* the opening hand: every card is looked at, none is a pick */
  /* the opponent's fan: backs hanging from the top edge into the match bar. AI vs AI / a replay show its faces: it
     slides down while the pointer is over it (#g-opphand.is-up) */
  .hb-handwrap--opp { flex: none; align-self: stretch; display: flex; min-width: 0; }
  .hb-hand--opp { display: flex; align-items: center; gap: 10px; min-width: 0; }
  .hb-hand--opp .hb-ptag { flex-direction: row; align-items: center; gap: 8px; width: auto; min-width: 0; }
  /* (a player's own name, online: up to 16 characters. It gives way with an ellipsis; the hand count and the fan keep their room) */
  .hb-hand--opp .hb-ptag__who { min-width: 0; }
  .hb-hand--opp .hb-who { min-width: 0; max-width: 10em; overflow: hidden; text-overflow: ellipsis; }
  .is-bar-s .hb-hand--opp .hb-who { max-width: 7em; }
  .is-bar-l .hb-hand--opp .hb-who { max-width: 16em; }
  .hb-hand--opp .hb-ptag__meta { flex: none; flex-direction: row; gap: 8px; }
  .hb-hand--opp .hb-ptag__deck { display: none; max-width: 150px; }
  .is-bar-l .hb-hand--opp .hb-ptag__deck { display: block; }
  .hb-hfan--opp { --fw: var(--ohw); align-self: stretch; width: var(--ofanw); pointer-events: none; }
  .hb-hfan--opp > .hb-hfan__slot { top: var(--ofantop); }
  .hb-hfan--opp .hb-c--hand { box-shadow: 0 0 0 1px rgba(0,0,0,.6), 0 2px 5px rgba(0,0,0,.4); }
  .is-watch .hb-hfan--opp { pointer-events: auto; }
  #g-opphand.is-up .hb-hfan--opp { --low: var(--ofanlow); }
  @media (hover: hover) {
    .is-watch .hb-hfan--opp > .hb-hfan__slot:hover { z-index: 70 !important; }
    .is-watch .hb-hfan--opp > .hb-hfan__slot:hover > .hb-c { transform: rotate(calc(var(--a) * -1)) translateY(calc(var(--y) * -1 + 4px)) scale(1.04); }
  }

  /* ---- the dock: the strip on the bottom edge. My name | my fan | the decision panel: beside the fan, none of them
     a row of its own (the fan rises over the dock and my mat's bars; the panel stays in the dock: what a decision
     needs more than the dock's height it finds sideways, play.js fitDecide) */
  .hb-dock { position: relative; z-index: 7; flex: none; display: grid; grid-template: "me hand decide" var(--dockh) / minmax(0, 1fr) var(--fanw) minmax(0, 1fr); pointer-events: none; }
  .hb-dock > * { pointer-events: auto; }
  .hb-dock__me { grid-area: me; align-self: end; min-width: 0; padding: 0 10px 8px 14px; pointer-events: none; }
  /* a desktop without the side panel (.is-noside: a window under 1,100 px): the panel has nowhere to run on to, so my
     fan stands left of the middle and the panel has the larger share of the dock */
  .is-noside .hb-dock { grid-template-columns: minmax(0, 1fr) var(--fanw) minmax(0, 2.4fr); }

  /* ---- the decision panel (your move: a tama border that breathes; the default action is the vermilion primary) */
  /* (its height is the dock's, 2 px under the dock's top edge: it never reaches my mat, whatever it holds) */
  .hb-decide { grid-area: decide; position: relative; z-index: 80; align-self: end; display: flex; flex-direction: column; box-sizing: border-box;
    min-height: calc(var(--dockh) - 8px); max-height: calc(var(--dockh) - 8px); overflow: hidden; margin: 0 8px 6px 6px; padding: 7px 10px 7px 14px;
    border-radius: var(--hb-r-panel); background-color: var(--hb-ink-2); box-shadow: inset 0 0 0 1px var(--hb-line), 0 -6px 18px rgba(0,0,0,.35); }
  .hb-decide.is-live { box-shadow: inset 0 0 0 1px var(--hb-tama), 0 -6px 18px rgba(0,0,0,.35); }
  .hb-decide:empty { display: none; }
  /* its content is centred while it fits (auto margins: a taller content starts at the top and scrolls, never cut above) */
  .hb-decide > :first-child { margin-top: auto; }
  .hb-decide > :last-child { margin-bottom: auto; }
  .hb-decide__row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
  .hb-decide__prompt { flex: 1 1 9em; min-width: 0; color: var(--hb-text); font: 700 var(--hb-fs-14)/1.35 var(--hb-font-ui); }
  .hb-decide__result { font: 800 var(--hb-fs-16)/1.3 var(--hb-font-display); letter-spacing: .04em; }
  .hb-decide--wait .hb-decide__prompt { color: var(--hb-text-3); font-weight: 500; }
  .hb-decide__dama { width: 16px; height: 16px; color: var(--hb-text-4); }
  .hb-decide__opts { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px 8px; margin-left: auto; }
  /* (a hand card is selected: the decision's own buttons - End summon, Pass - after the card's plays) */
  .hb-decide__more { display: flex; align-items: center; flex: none; gap: 6px 8px; }
  .hb-decide__more:empty { display: none; }
  /* ---- the steps of play.js fitDecide(), each only when the one before does not fit the dock's height:
     .is-snug: two tight lines (the prompt over one row of 32 px buttons; the cards that are the choices 33 px wide;
       a card that is only shown stands at the left end over both lines) */
  .hb-decide.is-snug { padding: 4px 10px 4px 12px; }
  .hb-decide.is-snug .hb-decide__row { gap: 4px 8px; }
  /* (the prompt takes its own width, not 9em: "Check", the card and To hand are one line. With a hand card selected
     the prompt is the first line by itself, one line: the card's name gives way with an ellipsis - the card is lifted
     in the fan - and its plays and the decision's own button are the row under it) */
  .hb-decide.is-snug .hb-decide__prompt { flex-basis: auto; line-height: 1.3; }
  .hb-decide.is-snug .hb-decide__row.has-sel > .hb-decide__prompt { display: flex; align-items: center; flex-basis: 100%; min-width: 0; white-space: nowrap; }
  .hb-decide.is-snug .hb-decide__row.has-sel .hb-decide__sel { flex: 0 1 auto; min-width: 0; }
  .hb-decide.is-snug .hb-btn { height: 32px; }
  .hb-decide.is-snug .hb-optgrp { padding: 2px; }
  .hb-decide.is-snug .hb-optgrp .hb-btn { height: 28px; }
  .hb-decide.is-snug .hb-c--t { --w: 33px; }
  .hb-decide.is-snug .hb-thumb { gap: 8px; padding: 3px 9px 3px 3px; }
  .hb-decide.is-snug .hb-thumb.is-bare { padding-right: 3px; }
  .hb-decide.is-snug .hb-thumb__side { gap: 3px; }
  .hb-decide.is-snug .hb-thumb__opts .hb-btn { height: 26px; }
  .hb-decide.is-snug .hb-decide__thumbs { margin-top: 0; padding: 0; }
  .hb-decide.is-snug .hb-decide__row.has-lead { position: relative; padding-left: 46px; }
  .hb-decide.is-snug .hb-decide__lead { position: absolute; left: 0; top: 50%; translate: 0 -50%; }
  .hb-decide.is-snug .hb-decide__lead .hb-c--t { --w: 32px; }
  /* .is-wide: the panel runs on to the right, over the foot of the side panel, which ends above the dock meanwhile
     (the log is shorter by the dock's height; nothing of it is under the panel) */
  .hb-decide.is-wide { justify-self: start; width: max-content; min-width: calc(100% - 14px); max-width: calc(100% - 14px + var(--sidepanel, 0px)); }
  .hb-game.is-decwide > .hb-game__main { overflow-x: visible; overflow-y: clip; }
  .hb-game.is-decwide > .hb-game__side { padding-bottom: calc(var(--dockh) + 2px); }
  /* .is-tight: no key hints, nothing wraps, a unit's name and a group's word give way with an ellipsis (the line mark
     names the unit, and it is lit on the board) */
  .hb-decide.is-tight .hb-btn kbd { display: none; }
  .hb-decide.is-tight .hb-decide__prompt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .hb-decide.is-tight .hb-decide__opts, .hb-decide.is-tight .hb-optgrp { flex-wrap: nowrap; min-width: 0; }
  .hb-decide.is-tight .hb-decide__opts { max-width: 100%; }
  .hb-decide.is-tight .hb-opt { flex: 0 1 auto; min-width: 0; padding: 0 9px; }
  .hb-decide.is-tight .hb-opt--line, .hb-decide.is-tight .hb-opt--plan { flex: none; }
  .hb-decide.is-tight .hb-opt--line { gap: 3px; padding: 0 6px 0 5px; }
  .hb-decide.is-tight .hb-opt > .hb-lmark, .hb-decide.is-tight .hb-opt > .hb-gem, .hb-decide.is-tight .hb-opt > .hb-opt__pw { flex: none; }
  .hb-decide.is-tight .hb-opt__name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.5; }
  .hb-decide.is-tight .hb-optgrp__w { flex: 0 1 auto; min-width: 0; overflow: hidden; padding: 0 4px 0 5px; text-overflow: ellipsis; line-height: 1.5; }
  .hb-decide.is-tight .hb-thumb__note { max-width: 96px; }
  /* .is-scroll, the last resort (a narrow window, many choices): one line; the choices scroll sideways in it */
  .hb-decide.is-scroll .hb-decide__row { flex-wrap: nowrap; }
  .hb-decide.is-scroll .hb-decide__prompt { flex: 0 1 auto; min-width: 2.5em; max-width: 36%; }
  .hb-decide.is-scroll .hb-decide__opts, .hb-decide.is-scroll .hb-decide__thumbs.is-inline { flex: 0 1 auto; min-width: 0; justify-content: flex-start; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
  .hb-decide.is-scroll .hb-opt, .hb-decide.is-scroll .hb-optgrp { flex: none; }
  /* (the pay picker's row of my エナ keeps its width through the steps - a row that gave way was cut at its end, and
     fitDecide could not see it - and scrolls like the choices in the last one) */
  .hb-game__main:not(.is-phone) .hb-decide__ena { flex: none; }
  .hb-game__main:not(.is-phone) .hb-decide.is-scroll .hb-decide__ena { flex: 0 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
  .hb-decide__sel { display: inline-flex; align-items: center; max-width: 100%; margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--hb-line-2); overflow: hidden; font-size: var(--hb-fs-14); white-space: nowrap; vertical-align: bottom; }
  .hb-decide__sel .hb-cn { overflow: hidden; text-overflow: ellipsis; }
  .hb-opt .hb-lmark--btn + .hb-gem { margin-left: -3px; }
  .hb-opt { gap: 7px; }
  .hb-opt .hb-gem { --s: 20px; }
  .hb-opt__pw { color: var(--hb-kin-hi); font: italic 900 var(--hb-fs-14)/1 var(--hb-font-num); }
  .hb-btn--primary .hb-opt__pw { color: #fff3d6; }
  .hb-opt .hb-lmark--btn { --s: 26px; margin: -4px -2px -4px -3px; color: var(--hb-kin); }
  .hb-opt .hb-lmark--btn > b { color: #1b0c0a; font: 400 calc(var(--s) * .48)/1 var(--hb-font-gemnum); font-synthesis: none; }   /* (the cost numeral is upright: an italic 4 reads as 1 at this size) */
  /* several plays of one kind (overbeat targets): the word once, then compact line-mark + cost buttons in a well */
  .hb-optgrp { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px; padding: 3px; border-radius: var(--hb-r-ctl); background-color: var(--hb-well); box-shadow: inset 0 0 0 1px var(--hb-line); }
  .hb-optgrp__w { padding: 0 6px 0 7px; color: var(--hb-text-2); font: 700 var(--hb-fs-13)/1 var(--hb-font-ui); white-space: nowrap; }
  .hb-opt--line { gap: 5px; padding: 0 9px 0 7px; }
  .hb-opt .hb-lmark--btn.is-theirs { color: var(--hb-seat-opp); }
  .hb-opt .hb-lmark--btn.is-mine { color: var(--hb-seat-me); }
  .hb-opt--plan { padding: 0 10px; gap: 4px; }
  .hb-plan { display: inline-flex; }
  .hb-plan .hb-gem { --s: 24px; }
  .hb-decide .hb-btn kbd { margin-left: 2px; }
  .hb-decide__thumbs { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding: 2px 0; overflow-x: auto; }
  .hb-decide__thumbs.is-inline { flex: 0 1 auto; min-width: 0; margin: 0; }
  /* a card that is only shown (the trigger being placed): a small chip in the prompt's row; the full card is in the side panel */
  .hb-decide__lead { display: flex; align-items: center; gap: 6px; flex: none; }
  .hb-decide__lead .hb-thumb { padding: 2px; }
  .hb-decide__lead .hb-c--t { --w: 27px; }
  /* a card chip: the card, then its note over its buttons (lacquer, like a secondary control) */
  .hb-thumb { position: relative; display: flex; align-items: center; gap: 9px; flex: none; padding: 4px 10px 4px 4px; border-radius: var(--hb-r-panel); background-color: var(--hb-ink-3); box-shadow: inset 0 0 0 1px var(--hb-line); }
  .hb-thumb.is-bare { padding-right: 4px; }
  .hb-thumb__side { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
  .hb-c--t { --w: 44px; }
  .hb-thumb__state { position: absolute; left: 2px; right: 2px; bottom: 2px; padding: 2px; border-radius: 2px; background: rgba(10,6,4,.85); color: var(--hb-text); font: 700 var(--hb-fs-10)/1.2 var(--hb-font-ui); text-align: center; }
  .hb-thumb.is-unused .hb-thumb__state { color: var(--hb-tama); }
  .hb-thumb.is-used .hb-c--t > .hb-cimg { filter: brightness(.55) saturate(.6); }
  .hb-thumb__note { max-width: 160px; overflow: hidden; color: var(--hb-text-3); font-size: var(--hb-fs-11); line-height: 1.25; text-overflow: ellipsis; white-space: nowrap; }
  .hb-thumb__opts { display: flex; gap: 4px; }
  .hb-thumb__opts .hb-btn { height: 28px; }
  .hb-thumb__opts .hb-trig { margin-left: -4px; }
  /* the pay picker: my エナ inline (used ones turned and dimmed), then one button per colour plan */
  .hb-decide__ena { display: flex; align-items: center; gap: 5px; flex: 0 1 auto; min-width: 0; overflow: hidden; padding: 1px 12px; border-left: 1px solid var(--hb-line); border-right: 1px solid var(--hb-line); }
  .hb-c--mini { --w: 24px; }
  .hb-c--mini.is-used { transform: rotate(90deg); margin: 0 6px; }
  .hb-c--mini.is-used > .hb-cimg { filter: brightness(.5) saturate(.6); }
  .hb-err { color: var(--hb-danger-text); }

  /* ---- side panel: the card (compact, carddetail.js) on top, the log below */
  .hb-game__side { display: flex; flex-direction: column; gap: 8px; min-height: 0; min-width: 0; padding: 6px 8px 8px 0; }
  .hb-side__detail { flex: 0 0 auto; max-height: 58%; min-height: 0; overflow: auto; border-radius: var(--hb-r-panel); background-color: var(--hb-ink-2); box-shadow: inset 0 0 0 1px var(--hb-line); }
  .hb-side__detail:empty { display: none; }
  .hb-side__log { flex: 1 1 0; min-height: 160px; display: flex; flex-direction: column; border-radius: var(--hb-r-panel); background-color: var(--hb-ink-2); box-shadow: inset 0 0 0 1px var(--hb-line); overflow: hidden; }
  .hb-side__loghead { flex: none; display: flex; align-items: center; justify-content: space-between; height: 42px; padding: 0 6px 0 12px; border-bottom: 1px solid var(--hb-line); }
  .hb-log { flex: 1 1 auto; min-height: 0; overflow: auto; margin: 0; padding: 2px 12px 10px; list-style: none; color: var(--hb-text-2); font-size: var(--hb-fs-13); line-height: 1.5; }
  .hb-log__e { display: flex; gap: 8px; padding: 5px 0; border-bottom: 1px dashed rgba(201,154,58,.13); }
  .hb-log__ic { flex: none; display: inline-flex; justify-content: center; width: 20px; padding-top: 1px; color: var(--hb-text-4); }
  .hb-log__tx { min-width: 0; }
  .hb-log__sec { padding: 12px 0 4px; color: var(--hb-kin-text); font: 800 var(--hb-fs-11)/1.2 var(--hb-font-ui); letter-spacing: .2em; text-align: center; text-transform: uppercase; }
  :lang(ja) .hb-log__sec { letter-spacing: .12em; }
  .hb-log .hb-lmark--log { --s: 19px; }
  .hb-log .hb-trig--log { width: 18px; height: 18px; font-size: 10px; }
  .hb-icon--log { width: 15px; height: 15px; margin-top: 2px; }
  .hb-log__ena { width: 14px; height: 14px; margin-top: 3px; color: var(--hb-blue-hi); }
  .hb-log__first { display: grid; place-items: center; min-width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--hb-kin); color: var(--hb-kin-text); font: 800 9px/1 var(--hb-font-display); font-family: "HB Cost", var(--hb-font-display); font-style: normal; font-synthesis: none; }
  .hb-log--dmg .hb-log__ic { color: var(--hb-danger-text); }
  .hb-log--dmg .hb-log__tx { color: var(--hb-text-2); }
  .hb-log--heal .hb-log__ic { color: var(--hb-green-hi); }
  .hb-log--trig .hb-log__tx { color: var(--hb-text); }
  .hb-log--muted .hb-log__tx { color: var(--hb-text-3); font-size: var(--hb-fs-12); }
  .hb-log--battle .hb-log__tx { color: var(--hb-text); }
  .hb-log--over { border-bottom: 0; }
  .hb-log--over .hb-log__ic { color: var(--hb-shu-hi); }
  .hb-log--over .hb-log__tx { color: var(--hb-text); font: 800 var(--hb-fs-14)/1.4 var(--hb-font-display); }
  .hb-log__line { color: var(--hb-kin-text); font-weight: 700; }
  .hb-log__by { color: var(--hb-text-3); }
  .hb-log__pw { margin-left: 4px; color: var(--hb-text); font: italic 900 var(--hb-fs-13)/1 var(--hb-font-num); white-space: nowrap; }
  .hb-log__pw i { margin: 0 4px; color: var(--hb-shu-hi); font: 800 10px/1 var(--hb-font-display); font-style: normal; }
  .hb-log .hb-plan .hb-gem { --s: 16px; vertical-align: -3px; }
  .hb-cn { font-weight: 700; color: var(--c-text, var(--hb-kin-text)); cursor: help; }
  .hb-logwin .hb-window__body { padding: 4px 14px 12px; }
  .hb-logwin .hb-log { max-height: none; padding: 0; overflow: visible; }

  /* ---- game over (a hanging scroll after the brush banner), the record, the graveyard */
  .hb-result { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 4px 0 6px; text-align: center; }
  .hb-result__word { color: var(--hb-kin-hi); font: 800 44px/1.05 var(--hb-font-display); letter-spacing: .24em; }
  :lang(ja) .hb-result__word { letter-spacing: .3em; }
  .hb-result--lose .hb-result__word { color: var(--hb-text-3); }
  .hb-result--draw .hb-result__word { color: var(--hb-text-2); }
  .hb-result__line { color: var(--hb-text-3); font-size: var(--hb-fs-13); }
  .hb-result__sides { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 10px; width: 100%; margin-top: 6px; }
  .hb-result__vs { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 2px; background-color: var(--hb-shu); color: #fff; font: 800 15px/1 var(--hb-font-display); transform: rotate(-6deg); }
  .hb-result__side { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 10px 12px; border-radius: var(--hb-r-panel); background-color: var(--hb-ink-3); box-shadow: inset 0 0 0 1px var(--hb-line); }
  .hb-result__side.is-win { box-shadow: inset 0 0 0 1px var(--hb-kin); }
  .hb-result__who { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 22px; font-size: var(--hb-fs-16); }
  .hb-result__deck { overflow: hidden; color: var(--hb-text-3); font-size: var(--hb-fs-12); text-overflow: ellipsis; white-space: nowrap; }
  .hb-result__stats { display: flex; justify-content: center; gap: 18px; }
  .hb-result__stats span { display: flex; flex-direction: column; align-items: center; gap: 2px; }
  .hb-result__stats small { color: var(--hb-text-3); font-size: var(--hb-fs-10); letter-spacing: .1em; text-transform: uppercase; }
  .hb-result__stats .hb-count { font-size: var(--hb-fs-22); }
  .hb-gameover .hb-window__foot { flex-wrap: wrap; }
  .hb-record { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 4px 0; }
  .hb-record__head { margin: 0; color: var(--hb-text); font: 800 var(--hb-fs-16)/1.35 var(--hb-font-display); letter-spacing: .03em; }
  .hb-record__sub { margin: 0; color: var(--hb-text-2); font-size: var(--hb-fs-13); }
  .hb-gravegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 10px; }
  .hb-gravecard { margin: 0; padding: 0; border: 0; background: none; cursor: pointer; }
  .hb-gravecard .hb-cimg { box-shadow: 0 0 0 1px rgba(0,0,0,.7), 0 4px 10px rgba(0,0,0,.45); }

  /* ---- the cue queue's overlays (play-fx.js; they exist only while cues play, never in Performance mode) */
  .hb-pfx { position: fixed; inset: 0; z-index: 690; pointer-events: none; overflow: hidden; }
  .hb-ph { position: fixed; pointer-events: none; }
  .hb-ph > *, .hb-pfx .hb-c, .hb-fxlayer .hb-c, .hb-ghost > .hb-heart { display: block; width: 100%; height: 100%; margin: 0; }
  .hb-ph .hb-heart > .hb-c, .hb-ghost .hb-heart > .hb-c { width: 100%; }
  /* a unit's copy is its whole slot (or its card alone, flying to a pile) inside display:contents copies of its
     ancestors, so the board's own rules style it: the down turn, scale and dim, the plate, the phone sizes */
  .hb-phctx { display: contents !important; }
  .hb-phslot { position: absolute !important; inset: 0 !important; width: auto !important; height: auto !important; margin: 0 !important; }
  .hb-phunit { position: absolute !important; inset: 0 !important; width: auto !important; height: auto !important; margin: 0 !important; translate: none !important; }
  /* a card held invisible until its cue takes no pointer (hovering what is drawn there never shows the hidden card) */
  .hb-held { pointer-events: none !important; }
  .hb-spot { position: fixed; z-index: 2; pointer-events: none; border-radius: 5%; box-shadow: 0 0 0 2px var(--c, var(--hb-kin)), 0 0 0 4px #0b0604, 0 24px 50px rgba(0,0,0,.7); }
  .hb-spot > .hb-cimg { width: 100%; height: 100%; }
  .hb-clash { position: fixed; z-index: 3; translate: -50% -50%; display: flex; align-items: center; gap: 10px; padding: 6px 14px; white-space: nowrap; pointer-events: none;
    background-color: #0e0806; border: 1.5px solid var(--hb-kin); border-radius: 3px; box-shadow: 0 10px 28px rgba(0,0,0,.7); }
  .hb-clash__me { color: #fff; font: italic 900 34px/1 var(--hb-font-num); }
  .hb-clash__op { color: var(--hb-text-2); font: italic 900 26px/1 var(--hb-font-num); }
  .hb-clash .is-win { color: var(--hb-kin-hi); }
  .hb-clash .is-lose { color: var(--hb-text-4); }
  .hb-clash__vs { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 2px; background-color: var(--hb-shu); color: #fff; font: 800 16px/1 var(--hb-font-display); transform: rotate(-6deg); }
}

@layer hb-phone {
  /* no side panel: the log is a sheet from the phase bar, the card a sheet on tap / long-press */
  @media (max-width: 1099px) {
    .hb-game { grid-template-columns: minmax(0, 1fr); }
    .hb-game__side { display: none; }
    .hb-logbtn { display: inline-flex; }
  }
  @media (max-width: 760px) {
    .hb-playsetup__col { padding-top: 16px; }
    .hb-setup__head { padding: 14px 14px 2px; }
    .hb-setup__title { font-size: var(--hb-fs-22); }
    .hb-setup__body { gap: 14px; padding: 12px 14px 14px; }
    .hb-setup__vs { grid-template-columns: minmax(0, 1fr); gap: 8px; }
    .hb-setup__tai { justify-self: center; width: 32px; height: 32px; margin: 0; font-size: 17px; }
    .hb-setup__opts { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .hb-setup__foot { padding: 10px 14px 14px; }
    .hb-setup__foot .hb-btn { flex: 1 1 auto; }
  }
  /* the phone board (fit() sets .is-phone when the board column is under 640 px) */
  /* the match bar: its controls' row, then the opponent's name and fan (whole, small) in a row of their own */
  .is-phone .hb-phasebar { display: grid; grid-template: "info ctl" 42px "opp opp" auto / minmax(0, 1fr) auto; gap: 0 6px; height: auto; margin: 4px 4px 0; padding: 0 4px 0 0; }
  .is-phone .hb-phasebar__info { grid-area: info; }
  .is-phone .hb-phasebar__ctl { grid-area: ctl; min-width: 0; }
  .is-phone .hb-handwrap--opp { grid-area: opp; height: 28px; padding-left: 10px; }
  .is-phone.is-watch .hb-handwrap--opp { height: 46px; }
  .is-phone .hb-matchlang { display: none; }   /* (Settings, the gear beside it, has the language) */
  .is-phone .hb-round { padding: 0 8px; }
  .is-phone .hb-round small { display: none; }
  .is-phone .hb-round b { font-size: 20px; }
  .is-phone .hb-phase b { font-size: var(--hb-fs-12); }
  .is-phone .hb-phase span { display: none; }
  .is-phone .hb-phasebar__ctl { gap: 3px; }
  .is-phone .hb-speed > button { min-width: 28px; padding: 0 5px; font-size: 11px; }
  .is-phone .hb-speed > button[data-speed="0"], .is-phone .hb-speed > button[data-speed="2"] { display: none; }
  .is-phone .hb-concede > span { display: none; }
  .is-phone .hb-concede { width: var(--hb-h-sm); padding: 0; }
  .is-phone .hb-table { padding: var(--tabley) 3px; }
  .is-phone .hb-ztag.hb-tag--v.hb-tag--sm { width: 13px; font-size: 8px; letter-spacing: .02em; --tip: 5px; padding: 8px 0; }
  .is-phone .hb-hearts > .hb-ztag { margin-top: -5px; }
  .is-phone .hb-zone__count .hb-count { font-size: 15px; }
  .is-phone .hb-zone__count span { font-size: 9px; text-align: center; white-space: normal; line-height: 1.1; }
  .is-phone .hb-checkchip { height: 15px; margin-top: 2px; padding: 0 4px; font-size: 8px; }
  /* a phone's column gap is 3 px: the bars' tags stand across the bar's right edge, ending at the next column (the
     ena bar's right padding and line 1's ワザ cell keep its inner part free) */
  .is-phone .hb-wazarow > .hb-ztag, .is-phone .hb-ena > .hb-ztag { left: auto; right: calc(-1 * var(--cg)); }
  .is-phone .hb-wazarow > .hb-waza.is-many:nth-child(5) { padding-right: 11px; }
  /* bars lower than their two tags (a 320 px phone, fit() .is-tighttags): the tags' ends tighten to the hex's tips */
  .is-phone.is-tighttags .hb-wazarow > .hb-ztag.hb-tag--v.hb-tag--sm, .is-phone.is-tighttags .hb-ena > .hb-ztag.hb-tag--v.hb-tag--sm { padding: 5px 0; }
  .is-phone .hb-optgrp { flex: 1 1 100%; justify-content: flex-end; }
  .is-phone .hb-optgrp__w { margin-right: auto; }
  .is-phone .hb-opt--line { padding: 0 6px 0 5px; gap: 3px; }
  .is-phone .hb-decide__sel { font-size: var(--hb-fs-13); }
  .is-phone .hb-decide__ena { padding: 1px 4px 1px 1px; border: 0; }
  .is-phone .hb-c--mini { --w: 20px; }
  .is-phone .hb-ena { gap: 5px; padding: 3px 12px 3px 4px; }
  .is-phone .hb-enacount { gap: 3px; }
  .is-phone .hb-enacount .hb-count { font-size: 14px; }
  .is-phone .hb-enacount .hb-count small { font-size: 9px; }
  .is-phone .hb-pips { flex-direction: column; gap: 2px; }
  .is-phone .hb-pip .hb-gem { --s: 10px; }
  .is-phone .hb-pip b { font-size: 10px; }
  /* やまふだ / ぼち: horizontal on the zone's top edge (the selector outranks the phone's vertical tag size) */
  .is-phone .hb-pilezone > .hb-ztag.hb-tag--v.hb-tag--sm, .is-phone .hb-mat--opp .hb-pilezone > .hb-ztag.hb-tag--v.hb-tag--sm { right: auto; left: 50%; top: -6px; translate: -50% 0; writing-mode: horizontal-tb; width: auto; height: 14px; padding: 0 7px; }
  .is-phone .hb-pilezone > .hb-ztag::before, .is-phone .hb-pilezone > .hb-ztag::after { clip-path: polygon(var(--tip) 0, calc(100% - var(--tip)) 0, 100% 50%, calc(100% - var(--tip)) 100%, var(--tip) 100%, 0 50%); }
  .is-phone .hb-pilezone { padding-top: 6px; }
  .is-phone .hb-pile { translate: 0 0; }
  /* the phone's pile badge: on the column's outer side (the tag is on top, the bars' tags on the board side), kept
     inside the zone */
  .is-phone .hb-pile > .hb-badge { left: auto; right: max(-6px, calc((var(--pk) - var(--colw)) / 2)); min-width: 16px; height: 16px; font-size: 10px; }
  .is-phone .hb-mat--opp .hb-pile > .hb-badge { right: auto; left: max(-6px, calc((var(--pk) - var(--colw)) / 2)); }
  .is-phone .hb-stackn { min-width: 16px; height: 16px; font-size: 10px; top: calc(var(--slottop) - 7px); }
  .is-phone .hb-pow { padding: 1px 3px 2px; gap: 1px; }
  .is-phone .hb-pow small { display: none; }
  .is-phone .hb-kwb { min-width: 13px; height: 12px; font-size: 7px; }
  .is-phone .hb-rail .hb-lmark--rail { --s: 18px; }
  /* (and a desktop line too narrow for its mark and the whole label, fit() .is-raillabs-off: the mark names the line) */
  .is-phone .hb-rail__lab, .is-raillabs-off .hb-rail__lab { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .is-phone .hb-compare { gap: 3px; padding: 2px 5px; }
  .is-phone .hb-compare__me { font-size: 14px; }
  .is-phone .hb-compare__op { font-size: 11px; }
  .is-phone .hb-compare__vs { width: 14px; height: 14px; font-size: 8px; }
  .is-phone .hb-rail.is-battle .hb-lmark--rail { display: none; }
  /* any width: the battle's info chip names the line, and the lit mark beside it sat on the next line's label */
  .hb-rail.is-battle.has-info > .hb-lmark--rail { display: none; }
  /* narrow slots (fit() sets .is-narrowslots): the compare plate is wider than its line, so what it would cover in the
     neighbours steps aside while it is up, as on a phone: the right neighbour's mark (its leading end), the left
     neighbour's label (its trailing end) */
  .is-narrowslots .hb-center.has-battle .hb-rail.is-battle.has-info + .hb-rail:not(.is-target) > .hb-lmark--rail,
  .is-narrowslots .hb-center.has-battle .hb-rail:not(.is-target):has(+ .hb-rail.is-battle.has-info) > .hb-rail__lab { visibility: hidden; }
  /* (labels off, .is-raillabs-off: the left neighbour's mark stands in its cell's middle, under the plate's end) */
  .is-narrowslots.is-raillabs-off .hb-center.has-battle .hb-rail:not(.is-target):has(+ .hb-rail.is-battle.has-info) > .hb-lmark--rail { visibility: hidden; }
  /* the compare plate is wider than a phone's line: during a battle the other lines' marks step aside (the lit
     column names the line) instead of showing half-covered */
  .is-phone .hb-center.has-battle .hb-rail:not(.is-battle):not(.is-target) > .hb-lmark--rail { visibility: hidden; }
  /* the dock: my name line, the decision bar, the fan's room (the RAISED fan's: play.js fit()). Raised, the three stand
     as laid out: nothing reaches over my mat. Lowered, the fan sinks by --fanlow and the bar and my name line ride
     DOWN on it (the band they leave under my mat is the room a taller bar grows into, my name line moving up by as
     much: --dover, play.js fitDecide) */
  .is-phone .hb-dock { grid-template: "me" 22px "decide" 84px "hand" var(--dockh) / minmax(0, 1fr); }
  .is-phone .hb-dock__me { align-self: center; padding: 0 8px; }
  .is-phone .hb-dock__me .hb-ptag { flex-direction: row; align-items: center; gap: 10px; width: auto; }
  .is-phone .hb-dock__me .hb-ptag__meta { flex-direction: row; gap: 8px; }
  .is-phone .hb-ptag__deck { display: none; }
  .is-phone .hb-hand--opp .hb-ptag__who { font-size: var(--hb-fs-12); }
  .is-phone .hb-hand--opp .hb-ptag { flex: 0 1 auto; }
  .is-phone .hb-hand--opp .hb-who { max-width: none; }
  /* the bar is its row high (80 px: the prompt + a row of choices, or the two lines of a selected card's plays); a
     taller one (cards to choose from, many units) grows into the band over the lowered fan, and scrolls inside past
     that (the choices are lit on the board too) */
  .is-phone .hb-decide { min-height: 54px; max-height: 80px; overflow: hidden auto; margin: 0 4px 4px; padding: 6px 8px; transition: translate .22s var(--hb-ease-out); }
  .is-phone:not(.is-fanup) .hb-decide { max-height: calc(80px + var(--fanlow)); translate: 0 var(--fanlow); }
  .is-phone .hb-dock__me { translate: 0 calc(var(--dover, 0px) * -1); transition: translate .22s var(--hb-ease-out); }
  .is-phone:not(.is-fanup) .hb-dock__me { translate: 0 calc(var(--fanlow) - var(--dover, 0px)); }
  .is-phone.is-talldec .hb-decide, .is-phone.is-talldec .hb-dock__me { transition: none; }   /* (a bar taller than its row: no ride, play.js fitDecide) */
  /* a hand card is selected (the fan is up, the bar has its row and no more): two lines. The prompt and the card's
     name with the decision's own button (End summon, Pass); under them the card's plays in one row, a group's word
     giving way first */
  .is-phone .hb-decide:has(.has-sel) { padding: 4px 8px; }
  .is-phone .hb-decide__row.has-sel { gap: 4px 8px; }
  .is-phone .hb-decide__row.has-sel > .hb-decide__prompt { order: 0; display: flex; align-items: center; flex: 1 1 0; min-width: 0; white-space: nowrap; }
  .is-phone .hb-decide__row.has-sel .hb-decide__sel { flex: 0 1 auto; min-width: 0; }
  .is-phone .hb-decide__row.has-sel > .hb-decide__more { order: 1; }
  .is-phone .hb-decide__row.has-sel > .hb-decide__opts { order: 2; flex: 1 1 100%; flex-wrap: nowrap; min-width: 0; }
  .is-phone .hb-decide__row.has-sel .hb-btn { flex: none; height: 34px; }
  .is-phone .hb-decide__row.has-sel .hb-optgrp { flex: 0 1 auto; flex-wrap: nowrap; min-width: 0; padding: 2px; }
  .is-phone .hb-decide__row.has-sel .hb-optgrp .hb-btn { height: 30px; }
  .is-phone .hb-decide__row.has-sel .hb-optgrp__w { flex: 0 1 auto; min-width: 0; margin-right: 0; overflow: hidden; text-overflow: ellipsis; line-height: 1.5; }
  .is-phone .hb-decide__row { gap: 6px 8px; }
  .is-phone .hb-decide__prompt { flex: 1 1 100%; font-size: var(--hb-fs-13); }
  .is-phone .hb-decide--wait .hb-decide__prompt { flex: 1 1 auto; }
  .is-phone .hb-decide__row.has-lead .hb-decide__prompt, .is-phone .hb-decide__row:has(> .hb-decide__thumbs.is-inline) .hb-decide__prompt { flex: 1 1 0; min-width: 4em; }
  .is-phone .hb-decide__row > .hb-decide__thumbs.is-inline { flex: 0 1 auto; }
  .hb-decide__opts:empty { display: none; }
  .is-phone .hb-opt__name { max-width: 8.5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.5; }   /* the line mark tells two of a name apart */
  .is-phone .hb-decide__opts { flex: 1 1 100%; justify-content: flex-end; gap: 6px; }
  .is-phone .hb-decide .hb-btn kbd { display: none; }
  .is-phone .hb-c--t { --w: 40px; }
  /* (one or two cards that are the choices, beside the decision's one button - a check's To hand: the row's last) */
  .is-phone .hb-decide__row:has(> .hb-decide__thumbs.is-inline) > .hb-decide__opts { flex: 0 1 auto; order: 3; }
  .is-phone .hb-decide__thumbs.is-inline { flex: 1 1 100%; justify-content: flex-end; }
  @media (pointer: coarse) { .hb-decide .hb-btn kbd { display: none; } }
  @media (max-width: 600px) {
    .hb-result__word { font-size: 34px; }
    .hb-result__sides { grid-template-columns: minmax(0, 1fr); }
    .hb-result__vs { justify-self: center; }
  }
}

@layer hb-screens {
  /* toasts clear the decision bar on the play screen (components.css reads --hb-toast-b) */
  body[data-screen="play"] { --hb-toast-b: 96px; }
}

/* ===================================================================== DECORATION (Performance mode strips it) */
@layer hb-fx {
  @keyframes hb-play-pulse { from { opacity: .25; } to { opacity: 1; } }
  @keyframes hb-play-flicker { 0%, 100% { opacity: 1; } 10% { opacity: .82; } 13% { opacity: .97; } 41% { opacity: .88; } 63% { opacity: .78; } 67% { opacity: .95; } }
  /* the setup: a lantern-lit panel over the dimmed night street */
  body:not(.hb-perf) .hb-playsetup { background-image: radial-gradient(70% 60% at 50% 40%, rgba(255,140,60,.07), transparent 70%); }
  body:not(.hb-perf) .hb-setup__head { background-image: var(--pat-seigaiha); background-size: 16px 8px; background-repeat: repeat-x; background-position: 0 100%; padding-bottom: 14px; }
  body:not(.hb-perf) .hb-setup__tai, body:not(.hb-perf) .hb-result__vs { box-shadow: inset 0 0 0 2px rgba(255,220,190,.35), 0 0 18px var(--hb-shu-glow); }
  body:not(.hb-perf) .hb-resume__dama { filter: drop-shadow(0 0 6px var(--hb-tama-glow)); }
  /* the night playmat: dyed sumi with grain, the playmat's 菱 corner top-left and 市松 corner bottom-right, zone washes */
  body:not(.hb-perf) .hb-mat { background-image: var(--tex-grain), var(--tex-sumi); }
  body:not(.hb-perf) .hb-mat::before { content: ""; position: absolute; z-index: -1; left: 0; top: 0; width: 220px; height: 140px; border-top-left-radius: var(--hb-r-mat); pointer-events: none; opacity: .6;
    background: var(--pat-hishi) 0 0 / 30px 30px; -webkit-mask-image: radial-gradient(120% 120% at 0 0, #000 20%, transparent 70%); mask-image: radial-gradient(120% 120% at 0 0, #000 20%, transparent 70%); }
  body:not(.hb-perf) .hb-mat::after { content: ""; position: absolute; z-index: -1; right: 0; bottom: 0; width: 220px; height: 150px; border-bottom-right-radius: var(--hb-r-mat); pointer-events: none; opacity: .13;
    background: var(--pat-ao) 0 0 / 36px 36px; -webkit-mask-image: radial-gradient(120% 120% at 100% 100%, #000 15%, transparent 70%); mask-image: radial-gradient(120% 120% at 100% 100%, #000 15%, transparent 70%); }
  body:not(.hb-perf) .hb-mat--opp::before { left: auto; right: 0; border-radius: 0 var(--hb-r-mat) 0 0; -webkit-mask-image: radial-gradient(120% 120% at 100% 0, #000 20%, transparent 70%); mask-image: radial-gradient(120% 120% at 100% 0, #000 20%, transparent 70%); }
  body:not(.hb-perf) .hb-mat--opp::after { right: auto; left: 0; border-radius: 0 0 0 var(--hb-r-mat); -webkit-mask-image: radial-gradient(120% 120% at 0 100%, #000 15%, transparent 70%); mask-image: radial-gradient(120% 120% at 0 100%, #000 15%, transparent 70%); }
  body:not(.hb-perf) .hb-hearts { background-image: linear-gradient(180deg, rgba(109,184,44,.16), rgba(109,184,44,.05)); }
  body:not(.hb-perf) .hb-wazarow { background-image: linear-gradient(90deg, rgba(240,140,90,.03), rgba(240,140,90,.11)); }
  body:not(.hb-perf) .hb-ena { background-image: linear-gradient(90deg, rgba(13,155,220,.05), rgba(13,155,220,.14)); }
  /* lantern light on the battle line: a warm wash falling down the lit column of both mats and the rail */
  body:not(.hb-perf) .hb-line.is-battle { background-image: linear-gradient(180deg, rgba(255,138,64,.16), rgba(255,138,64,.03) 80%); box-shadow: inset 0 0 0 1px var(--hb-kin-line), inset 0 40px 50px -30px rgba(255,150,70,.22); }
  body:not(.hb-perf) .hb-mat--opp .hb-line.is-battle { background-image: linear-gradient(0deg, rgba(255,138,64,.16), rgba(255,138,64,.03) 80%); box-shadow: inset 0 0 0 1px var(--hb-kin-line), inset 0 -40px 50px -30px rgba(255,150,70,.22); }
  body:not(.hb-perf) .hb-rail.is-battle { background-image: radial-gradient(70% 120% at 50% 50%, rgba(255,150,70,.24), transparent 70%); }
  body:not(.hb-perf) .hb-compare { box-shadow: 0 6px 16px rgba(0,0,0,.6), 0 0 22px rgba(255,120,48,.32); }
  body:not(.hb-perf) .hb-compare__me:not(.is-lose) { text-shadow: 0 0 12px rgba(255,170,90,.8); animation: hb-play-flicker 3.4s linear infinite; }
  body:not(.hb-perf) .hb-clash { box-shadow: 0 10px 28px rgba(0,0,0,.7), 0 0 34px rgba(255,120,48,.4); }
  body:not(.hb-perf) .hb-clash__me:not(.is-lose) { text-shadow: 0 0 16px rgba(255,170,90,.85); }
  body:not(.hb-perf) .hb-clash .is-win, body:not(.hb-perf) .hb-compare .is-win { text-shadow: 0 0 16px rgba(255,200,110,.75); }
  /* your move: the decision bar breathes (an overlay's opacity), legal cards and targets pulse */
  body:not(.hb-perf) .hb-decide.is-live::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    box-shadow: inset 0 0 0 1px var(--hb-tama), inset 0 0 22px rgba(120,236,214,.12); animation: hb-play-pulse 2.6s var(--hb-ease-sway) infinite alternate; }
  body:not(.hb-perf) .is-human .hb-c--hand.is-act::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    box-shadow: inset 0 0 0 2px var(--hb-tama), inset 0 0 16px rgba(120,236,214,.45); animation: hb-play-pulse 1.9s ease-in-out infinite alternate; }
  body:not(.hb-perf) .hb-slot.is-target::after, body:not(.hb-perf) .hb-rail.is-target::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    box-shadow: inset 0 0 0 2px var(--hb-tama), inset 0 0 18px rgba(120,236,214,.35); animation: hb-play-pulse 1.4s ease-in-out infinite alternate; }
  body:not(.hb-perf) .hb-hfan--me > .hb-hfan__slot:hover > .hb-c--hand:not(.is-sel) { box-shadow: 0 0 0 1.5px var(--hb-kin), 0 14px 24px rgba(0,0,0,.55), var(--glow-lantern); }
  body:not(.hb-perf) .hb-spot { box-shadow: 0 0 0 2px var(--c, var(--hb-kin)), 0 0 0 4px #0b0604, 0 24px 50px rgba(0,0,0,.7), 0 0 50px color-mix(in srgb, var(--c, #ff8a40) 55%, transparent); }
  body:not(.hb-perf) .hb-side__detail, body:not(.hb-perf) .hb-side__log, body:not(.hb-perf) .hb-decide { background-image: var(--tex-grain); }
  body:not(.hb-perf) .hb-result--win .hb-result__word { text-shadow: 0 0 22px rgba(255,190,90,.45); }
}
