/* The table: the tarp, ten hand-ruled slots, cards that jab, scrape and turn sideways. */
.table-screen { background: var(--paper-2); }
.table-host { position: absolute; inset: 0; }
.tbl { position: absolute; inset: 0; overflow: hidden; background: var(--paper-2); font-family: var(--serif); }
.tbl-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tbl-slots, .tbl-stack, .tbl-units, .tbl-fx { position: absolute; inset: 0; pointer-events: none; }
.tbl-fx { z-index: 20; } /* crit: JOB-036: the layer of the numbers and the marks lies above the cards (z-index 2); under them the burst of a critical hit, and every number that leaves a card, were hidden (probe: the burst shows once the layer is raised) */
.slot { fill: rgba(244, 241, 232, .14); stroke: var(--ink); stroke-width: 1.7; stroke-linejoin: round; opacity: .75; }

/* health plates and piles */
.plate {
  position: absolute; display: flex; flex-direction: column; justify-content: center; gap: 3px; padding: 4px 10px; overflow: hidden;
  background: var(--paper); color: var(--ink); border: 2px solid var(--ink);
  box-shadow: inset 0 0 0 3px var(--paper), inset 0 0 0 4px var(--ink), 2px 3px 0 rgba(27, 26, 23, .3);
}
.plate-label { font-size: clamp(.68rem, calc(var(--sw) * .06), 1.05rem); letter-spacing: .18em; text-transform: uppercase; font-weight: 700; line-height: 1; }
.plate-row { display: flex; align-items: center; gap: 6px; font-size: clamp(1.1rem, calc(var(--sw) * .12), 1.9rem); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.plate-row .sym { width: .72em; height: .72em; } /* B: rule 160, the icon is smaller than the number */
.plate[data-side="enemy"] .plate-row .sym { color: var(--red); }
.plate-bar { display: block; height: clamp(9px, calc(var(--sw) * .06), 15px); border: 1.5px solid var(--ink); background: rgba(27, 26, 23, .16); overflow: hidden; }
.plate-bar i { display: block; height: 100%; background: var(--ink); transform-origin: 0 50%; transition: transform .35s ease-out; }
.plate.is-low .plate-bar i { background: var(--red); }
.pile { position: absolute; }
.pile-imgs { position: absolute; inset: 0; }
.pile-img { position: absolute; left: calc(var(--i, 0) * 2.2px); top: calc(var(--i, 0) * -2.2px); width: calc(100% - 5px); height: calc(100% - 5px); object-fit: cover; border-radius: 3.6% / 2.4%; box-shadow: 0 1px 3px rgba(27, 26, 23, .5); }
.pile.is-empty { border: 2px dashed rgba(27, 26, 23, .55); border-radius: 4px; }
.pile-count {
  position: absolute; right: -7px; top: -9px; min-width: 25px; height: 25px; padding: 0 6px; border-radius: 13px; z-index: 2;
  background: var(--ink); color: var(--paper); font-weight: 700; font-size: .88rem; display: grid; place-items: center;
  font-variant-numeric: tabular-nums;
}
.pile-count:empty { display: none; }

/* the middle strip: the fight clock and the route bar */
.tbl-mid { position: absolute; display: flex; flex-direction: column; justify-content: center; gap: 22px; pointer-events: none; padding: 0 6px; }
.clock, .route { position: relative; height: 4px; background: rgba(27, 26, 23, .24); }
.clock i { display: block; height: 100%; background: var(--ink); transform-origin: 0 50%; transform: scaleX(0); }
.route-fill { position: absolute; inset: 0; background: var(--red); transform-origin: 0 50%; transform: scaleX(0); transition: transform .3s ease-out; }
.route-truck { position: absolute; top: -14px; left: 0; width: 28px; height: 28px; padding: 3px; transform: translateX(-50%); color: var(--ink); background: var(--paper); border: 2px solid var(--ink); border-radius: 50%; transition: left .3s ease-out; }
.route-truck .sym { width: 100%; height: 100%; }
.route-mark { position: absolute; right: 0; top: -9px; width: 3px; height: 22px; background: var(--ink); }

/* the units */
.tc { position: absolute; left: 0; top: 0; width: var(--sw); height: var(--sh); z-index: 2; will-change: transform; }
.tc.is-down { z-index: 1; }
.tc-move, .tc-shake, .tc-tap, .tc-card { position: absolute; inset: 0; }
.tc-card { border-radius: 3.6% / 2.4%; background: var(--paper); box-shadow: 0 1px 0 rgba(27, 26, 23, .5), 0 4px 9px rgba(27, 26, 23, .32); cursor: pointer; pointer-events: auto; outline: none; user-select: none; -webkit-user-select: none; touch-action: manipulation; }
.tc-card:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.tc-card > .tw-face { pointer-events: none; }
.tc-card > .tw-face .tw-art { pointer-events: none; }
/* a tapped card is turned sideways and scaled so that its rotated width fits its own slot (never onto a neighbour) */
.tc-tap.is-tapped { transform: rotate(90deg) scale(var(--tapk, .62)); }
.tc-tap.is-tapped .tc-badge { transform: rotate(-90deg) scale(1.25); }
.tc-tap.is-tapped .tc-hparc, .tc-tap.is-tapped .tc-arcwrap { display: none; }
/* a fallen card: the picture goes gray and fades; the numbers stay solid ink so they stay readable */
/* T2: JOB-048 (rule 175): a fallen card lies on its side in its own colours (it was greyscale at 72 %): the mark of the state is .tc-fallen */
.tc-chips { position: absolute; left: 4%; top: 8%; display: flex; gap: 2px; pointer-events: none; z-index: 3; }
.tc-chips .chip { min-width: 0; min-height: 0; padding: 1px 4px; border: 0; border-radius: 999px; background: var(--ink); color: var(--paper); font-size: calc(var(--sw) * .13); font-weight: 700; display: flex; align-items: center; gap: 1px; letter-spacing: 0; cursor: default; box-shadow: none; }
.tc-chips .chip .sym { width: calc(var(--sw) * .15); height: calc(var(--sw) * .15); }
.tc-badge {
  --bd: max(19px, calc(var(--sw) * .17));
  position: absolute; bottom: calc(var(--bd) * -.5); width: var(--bd); height: var(--bd); border-radius: 50%; z-index: 3;
  background: var(--ink); color: var(--paper); border: 1.5px solid var(--paper);
  display: grid; place-items: center; font-weight: 700; font-size: calc(var(--bd) * .6); line-height: 1; pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.tc-atk { left: 6%; }
.tc-hp { right: 6%; }
.tc-atk, .tc-hp { width: auto; min-width: var(--bd); padding: 0 calc(var(--bd) * .16); border-radius: 999px; display: flex; align-items: center; justify-content: center; gap: 1px; } /* B: rule 164: the symbol beside its number, in a pill */
.tc-atk .sym, .tc-hp .sym { width: calc(var(--bd) * .5); height: calc(var(--bd) * .5); flex: none; }
.tc[data-side="enemy"] .tc-badge { background: #8F2B22; }
.tc .tc-card.is-fallen .tc-badge { background: var(--ink); }
.tc-arcwrap { --bd: max(19px, calc(var(--sw) * .17)); position: absolute; left: calc(6% - var(--bd) * .16); bottom: calc(var(--bd) * -.66); width: calc(var(--bd) * 1.32); height: calc(var(--bd) * 1.32); pointer-events: none; z-index: 3; }
.tc-hparc { left: auto; right: calc(6% - var(--bd) * .16); }
.tc-hparc .arc-fill { transition: stroke-dashoffset .35s ease-out; stroke: var(--ink); }
.tc[data-side="enemy"] .tc-hparc .arc-fill { stroke: var(--red); }
.tc-arc { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.arc-track { fill: none; stroke: rgba(244, 241, 232, .8); stroke-width: 2; }
.arc-fill { fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; }
.tc[data-side="enemy"] .arc-fill { stroke: var(--red); }
.tc-stamp { position: absolute; left: 50%; top: 38%; width: calc(var(--sw) * .44); height: calc(var(--sw) * .44); transform: translate(-50%, -50%); border: 2px solid var(--red); border-radius: 50%; background: rgba(244, 241, 232, .94); color: var(--red); display: grid; place-items: center; pointer-events: none; }
.tc-stamp .sym { width: 66%; height: 66%; }

/* Gear stays above its owner in a reserved shelf, with the host's face fully exposed. */
.tc-gear { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.tc-gear[data-placement="above"].has-gear::after { content: ''; position: absolute; left: 50%; top: -6px; height: 6px; border-left: 1px solid var(--ink); pointer-events: none; }
.tc-tap { z-index: 1; }
.gear { position: absolute; transform-origin: 50% 8%; pointer-events: auto; cursor: pointer; transition: transform .32s cubic-bezier(.2,.8,.25,1); border-radius: 3.6% / 2.4%; box-shadow: 0 1px 4px rgba(27, 26, 23, .5); outline: none; }
.tc-gear[data-placement="above"] .gear { transform-origin: 50% 50%; }
.tc-gear[data-placement="above"] .gear:focus-visible { z-index: 10 !important; }
.gear > .tw-face { pointer-events: none; }
.gear:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.gear.is-dropped { pointer-events: none; } /* T2: JOB-048 (rule 175): a dropped card keeps its colours */
.gear-badge { position: absolute; bottom: calc(var(--sw) * .02); min-width: max(15px, calc(var(--sw) * .15)); height: max(15px, calc(var(--sw) * .15)); padding: 0 3px; border-radius: 999px; background: var(--ink); color: var(--paper); border: 1px solid var(--paper); display: grid; place-items: center; font-weight: 700; font-size: max(9px, calc(var(--sw) * .09)); line-height: 1; pointer-events: none; }
.gb-atk { left: 4%; }
.gb-hp { right: 4%; }
.gear-sym { position: absolute; right: 5%; top: 46%; width: 22%; aspect-ratio: 1; background: var(--paper); border: 1.5px solid var(--ink); border-radius: 50%; display: grid; place-items: center; color: var(--ink); pointer-events: none; }
.gear-sym .sym { width: 68%; height: 68%; }
.gear-rounds { position: absolute; left: 24%; right: 24%; bottom: calc(var(--sw) * .03); display: flex; gap: 1.5px; justify-content: center; pointer-events: none; }
.gear-rounds i { flex: 0 1 3px; height: max(4px, calc(var(--sh) * .04)); background: var(--ink); box-shadow: 0 0 0 .8px var(--paper); border-radius: 1px; }
.gear-more { position: absolute; left: 50%; top: 100%; transform: translate(-50%, 2px); padding: 0 6px; border-radius: 999px; background: var(--ink); color: var(--paper); font-weight: 700; font-size: 12px; z-index: 5; }
.tc-gear[data-placement="above"] .gear-more { top: 0; transform: translate(-50%, -100%); }

/* the tactic card that rises to the middle */
.tc-tactic { pointer-events: none; z-index: 30; }
.tc-tactic .tc-card { pointer-events: none; }

/* damage and heal numbers */
.fx-num {
  position: absolute; font-weight: 800; font-size: clamp(1.25rem, 4.6vw, 2rem); line-height: 1; color: var(--ink); pointer-events: none; transform: translate(-50%, -70%);
  text-shadow: -1.5px -1.5px 0 var(--paper), 1.5px -1.5px 0 var(--paper), -1.5px 1.5px 0 var(--paper), 1.5px 1.5px 0 var(--paper), 0 0 10px var(--paper);
  font-variant-numeric: tabular-nums;
}
.fx-num.is-heavy { color: var(--red); font-size: clamp(1.6rem, 5.6vw, 2.5rem); }
/* crit: JOB-036 (rule 180): a critical hit leaves the target larger than any other number, in the game's red, with its burst beside it */
.fx-num.is-crit { color: var(--red); font-size: clamp(2.1rem, 7.4vw, 3.3rem); letter-spacing: .02em; }
.fx-num.is-crit .sym { display: inline-block; width: .72em; height: .72em; margin-right: .12em; vertical-align: -.04em; stroke-width: 2; filter: drop-shadow(1px 0 0 var(--paper)) drop-shadow(-1px 0 0 var(--paper)) drop-shadow(0 1px 0 var(--paper)) drop-shadow(0 -1px 0 var(--paper)); } /* rule 160: the icon is never taller than the number beside it; the paper outline the number has */
.fx-num .sym, .fx-num .sym * { pointer-events: none; } /* crit: JOB-036: nothing the fx layer draws takes the pointer or the hover from a card, whatever the symbol's own rect says */

/* the objective stamp */
.tbl-stamp { position: absolute; display: none; pointer-events: none; max-width: 88%; z-index: 40; }
.tbl-stamp.is-on { display: block; }
.stamp-text {
  display: inline-block; padding: 9px 18px; border: 3px double var(--red); color: var(--red); background: var(--paper);
  font-weight: 700; letter-spacing: .14em; text-transform: uppercase; text-align: center; line-height: 1.25;
  font-size: clamp(.85rem, 3.7vw, 1.35rem); text-wrap: balance;
}

/* the result */
.tbl-veil { position: absolute; inset: 0; display: none; place-items: center; background: rgba(27, 26, 23, .22); z-index: 50; cursor: pointer; }
.tbl-veil.is-on { display: grid; }
.veil-banner { background: var(--ink); color: var(--paper); padding: 14px 30px; border: 3px double var(--paper); outline: 3px solid var(--ink); font-size: clamp(1.4rem, 7vw, 2.8rem); font-weight: 700; letter-spacing: .2em; text-transform: uppercase; text-align: center; }
.veil-banner.is-lost { background: var(--red); outline-color: var(--red); }

/* controls: symbols only */
.tbl-ctl { position: absolute; left: 0; right: 0; display: flex; justify-content: center; align-items: center; gap: 18px; z-index: 45; pointer-events: none; }
.tbl-ctl .ctl {
  pointer-events: auto; appearance: none; cursor: pointer; width: 50px; height: 50px; border-radius: 50%;
  color: var(--ink); background: var(--paper); border: 2px solid var(--ink); display: grid; place-items: center; padding: 0;
  box-shadow: 2px 3px 0 rgba(27, 26, 23, .35);
}
.tbl-ctl .ctl-speed { width: auto; min-width: 74px; padding: 0 14px; border-radius: 26px; display: flex; gap: 6px; }
.tbl-ctl .ctl-speed b { font-size: 1rem; font-variant-numeric: tabular-nums; }
.tbl-ctl .ctl:hover, .tbl-ctl .ctl:focus-visible { background: var(--ink); color: var(--paper); outline: none; }
.tbl.is-paused .tbl-slots { opacity: .5; }

@media (prefers-reduced-motion: reduce) {
  .plate-bar i, .route-fill, .route-truck { transition: none; }
  .tc-jam { animation: none; }
}

/* phone: each health plate is one slim line */
.tbl[data-layout="portrait"] .plate { flex-direction: row; align-items: center; gap: 8px; padding: 0 8px; box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); border-width: 1.5px; }
.tbl[data-layout="portrait"] .plate-label { display: none; }
.tbl[data-layout="portrait"] .plate-row { font-size: 1rem; flex: none; }
.tbl[data-layout="portrait"] .plate-bar { flex: 1; height: 7px; }

/* ------------------------------------------------------------ kill cutscenes, moments, stills, loot */
.tbl-fin { position: absolute; inset: 0; pointer-events: none; z-index: 46; overflow: hidden; }
.fin-panel { position: absolute; left: 6%; right: 6%; top: 18%; bottom: 20%; transform: rotate(var(--tilt, 0deg)); filter: drop-shadow(0 8px 14px rgba(27, 26, 23, .5)); }
.fin-frame { position: absolute; inset: 0; border: 4px solid var(--ink); background: var(--paper-2); overflow: hidden; box-shadow: 5px 6px 0 var(--ink); }
.fin-img { width: 100%; height: 100%; object-fit: contain; display: block; will-change: transform; }
.fin-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; }
.fin-thumb { position: absolute; bottom: -4%; width: clamp(48px, 15%, 92px); aspect-ratio: 2 / 3; z-index: 2; }
.fin-thumb .tw-face { position: absolute; inset: 0; }
.fin-thumb.is-killer { left: 3%; }
.fin-thumb.is-victim { right: 3%; }
.fin-fx { position: absolute; inset: 0; pointer-events: none; }
.fin-fx-flame { background: rgba(232, 112, 32, .3); animation: fin-wash .5s ease-out both; }
@keyframes fin-wash { from { opacity: 0; } 25% { opacity: 1; } to { opacity: 0; } }
.fin-svg { width: 100%; height: 100%; }
/* every effect is a thin ink mark: stroke at most 0.6 % of the panel width, drawn in under .25 s, gone by .5 s */
.fin-slash { fill: none; stroke: var(--ink); stroke-width: .5; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; animation: fin-draw .2s ease-out forwards, fin-gone .15s .35s linear forwards; }
@keyframes fin-gone { to { opacity: 0; } }
@keyframes fin-draw { to { stroke-dashoffset: 0; } }
.fin-ring { fill: none; stroke: var(--paper); stroke-width: .5; opacity: 0; transform-box: fill-box; transform-origin: center; animation: fin-ring .45s ease-out forwards; }
.fin-ring.r2 { animation-delay: .12s; } .fin-ring.r3 { animation-delay: .24s; }
@keyframes fin-ring { from { transform: scale(.4); opacity: 1; } to { transform: scale(7); opacity: 0; } }
.fin-speed { stroke: var(--paper); stroke-width: .4; opacity: .85; animation: fin-run .3s linear both, fin-gone .1s .4s linear forwards; }
@keyframes fin-run { from { transform: translateX(-60%); opacity: 0; } to { transform: translateX(120%); opacity: .9; } }
.fin-arc { fill: none; stroke: var(--ink); stroke-width: .5; stroke-linejoin: round; stroke-dasharray: 100; stroke-dashoffset: 100; animation: fin-draw .22s ease-out forwards, fin-gone .15s .35s linear forwards; }
.fin-still { position: absolute; inset: 0; display: grid; place-items: center; container-type: size; background: rgba(27, 26, 23, .78); }
/* Fit the complete portrait within the overlay's width AND height; a height cap after grid sizing lets the card overflow. */
.fin-still-card { width: min(92cqw, calc(86cqh * 2 / 3)); aspect-ratio: 2 / 3; position: relative; }
.fin-still-card .tw-face { position: absolute; inset: 0; }
.fin-still-card .tw-art { object-fit: contain; }
.fx-deflect { position: absolute; width: calc(var(--sw) * .4); height: calc(var(--sw) * .4); color: var(--ink); background: var(--paper); border: 2px solid var(--ink); border-radius: 50%; display: grid; place-items: center; pointer-events: none; z-index: 5; }
.fx-deflect .sym { width: 68%; height: 68%; }
.tc-loot { z-index: 30; pointer-events: none; }
.tc-loot .tc-card { pointer-events: none; }
.pile.loot .pile-img { left: 0; top: 0; width: 100%; height: 100%; }
.pile.loot.is-empty { display: none; }
/* T2: JOB-048 (rule 175): the fallen of the convoy are NOT dimmed when the last man stands: he carries a thicker outline and a mark */
.tc-card.is-last-one { box-shadow: 0 0 0 4px var(--ink), 0 4px 9px rgba(27, 26, 23, .32); }
.tbl-ctl .ctl-fin.is-off { background: rgba(244, 241, 232, .6); color: rgba(27, 26, 23, .55); border-style: dashed; }

.table-radio { position: absolute; left: 10px; bottom: 16px; z-index: 47; padding: 6px 10px; background: var(--paper); border: 2px solid var(--ink); box-shadow: 2px 3px 0 rgba(27, 26, 23, .35); }
.table-radio .fx { display: inline-flex; align-items: center; }

/* Phone: names are in the enlarged card; geometry contains each whole gear fan within its owner's column. */
.tbl[data-layout="portrait"] .tc .cf-name, .tbl[data-layout="portrait"] .tc .cf-sub { display: none; }
.tbl[data-layout="portrait"] .tc .tc-gear:not([data-placement="above"]) { clip-path: inset(-10% 0 -120% 0); }

.tbl[data-layout="portrait"] .table-radio { top: auto; bottom: 74px; left: auto; right: 10px; }
/* a moment on the phone: the painting whole, in landscape, across the full width, paper above and below */
.tbl-fin.is-whole { background: var(--paper); }
.tbl-fin.is-whole .fin-panel { left: 0; right: 0; }
.tbl-fin.is-whole .fin-img { object-fit: contain; background: var(--paper-2); }

/* ------------------------------------------------------------ the mechanics (brief 07): armour, wear, restart, away, hacks, and the small flights */
.tc-arm { top: calc(var(--bd) * -.42); bottom: auto; right: 6%; gap: 0; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); width: auto; min-width: var(--bd); padding: 0 3px; border-radius: 999px; font-size: calc(var(--bd) * .66); font-weight: 800; display: inline-flex; align-items: center; justify-content: center; }
.tc-arm .sym { width: calc(var(--bd) * .6); height: calc(var(--bd) * .6); }
.tc[data-side="enemy"] .tc-arm { background: var(--paper); color: var(--ink); border-color: #8F2B22; } /* the red rim says whose it is; the numeral stays ink (red at 10px on the phone read 4.4:1 in the pixel check) */
/* the objective stamp: the text in the darker red of the enemy badges (the light red read 4.0 to 4.7:1 on the tarp in the pixel check); the double rim keeps the stamp red */
.stamp-text { color: #8F2B22; }
.gear-wear { position: absolute; left: 12%; right: 12%; bottom: calc(var(--sh) * .1); height: max(5px, calc(var(--sh) * .045)); background: rgba(244, 241, 232, .9); border: 1px solid var(--ink); border-radius: 2px; pointer-events: none; overflow: hidden; }
.gear-wear i { display: block; height: 100%; background: var(--ink); }
.gear.is-worn .gear-wear i { background: var(--red); }
.gear-crack { display: none; position: absolute; inset: 8% 14%; color: var(--ink); pointer-events: none; }
.gear-crack .sym { width: 100%; height: 100%; stroke-width: 2.4; }
/* T2: JOB-048 (rule 175): a broken piece keeps its colours: the crack mark and the red 0 say so */
.gear.is-broken .gear-crack { display: block; }
.tc-backface { display: none; position: absolute; inset: 0; border-radius: inherit; background: var(--paper) center / cover no-repeat; z-index: 5; pointer-events: none; }
.tc-card.is-restarting > .tw-face, .tc-card.is-restarting > .tc-scr, .tc-card.is-restarting > .tc-chips { visibility: hidden; }
.tc-card.is-restarting > .tc-backface { display: block; }
.tc.has-window { transition: translate .45s ease; } /* T2: JOB-048 (rules 175, 182): no opacity here any more */
.tc.is-away { translate: 0 var(--away-dy, 0px); } /* T2: JOB-048: solid, full colour, a step back toward its own side (the step is computed in index.js so that the card stays whole inside the board); the mark is the nerve chip */
/* T2: JOB-048 (rule 175): the ring of a stopped machine is in full colour and holds still; the pause chip says why */
.tc-card.is-glitch { animation: tc-glitch .22s steps(2, end) infinite; box-shadow: 0 0 0 3px var(--red), 0 4px 9px rgba(27, 26, 23, .32); } /* T2: JOB-048 (rule 175): a red outline, no dark lines over the face */
@keyframes tc-glitch { 0% { transform: translate(-3px, 1px) skewX(4deg); } 50% { transform: translate(3px, -1px) skewX(-5deg); } 100% { transform: translate(-2px, 0) skewX(2deg); } }
.tc-card.is-burning { box-shadow: 0 0 0 3px #E0702A, 0 0 16px 3px rgba(224, 112, 42, .6); } /* T2: JOB-048 (rule 175): full colour with an orange rim; it was darkened */
.tc-stamp.is-fin { border-color: var(--ink); color: var(--ink); }
.fx-fly { position: absolute; width: calc(var(--sw) * .3); aspect-ratio: 1; border: 2px solid var(--ink); border-radius: 50%; background: var(--paper); color: var(--ink); display: grid; place-items: center; pointer-events: none; transform: translate(-50%, -50%); z-index: 20; }
.fx-fly .sym { width: 62%; height: 62%; }
.fx-fly.is-card { width: calc(var(--sw) * .42); aspect-ratio: 2 / 3; border-radius: 3px; border: 1.5px solid var(--ink); overflow: hidden; background: transparent; }
.fx-fly.is-card > .tw-face { position: absolute; inset: 0; }
.fx-line { position: absolute; height: 3px; transform-origin: 0 50%; pointer-events: none; z-index: 19; background: repeating-linear-gradient(90deg, var(--ink) 0 7px, transparent 7px 11px); }
.plate-parts { display: inline-flex; align-items: center; gap: 3px; margin-left: 8px; font-size: .85em; font-weight: 700; }
.plate-parts[hidden] { display: none; }
.plate-parts .sym { width: .72em; height: .72em; }
@media (prefers-reduced-motion: reduce) { .tc-card.is-glitch { animation: none; } .tc.has-window { transition: none; } }

/* what a card carries with the mechanics on: its tattoo stars and its installs (top left, the armour is top right) */
.tc-tat { top: calc(var(--bd) * -.42); bottom: auto; left: 6%; right: auto; gap: 1px; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); width: auto; min-width: var(--bd); padding: 0 3px; border-radius: 999px; font-size: calc(var(--bd) * .52); display: inline-flex; align-items: center; justify-content: center; }
.tc-tat .sym { width: calc(var(--bd) * .6); height: calc(var(--bd) * .6); }
.tc[data-side="enemy"] .tc-tat { color: #8F2B22; border-color: #8F2B22; }
/* a fallen card carries no armour or mark any more (and its rotated badges would sit over its neighbours) */
.tc-tap.is-tapped .tc-arm, .tc-tap.is-tapped .tc-tat { display: none; }
/* rule 160: the symbols of the table name themselves on hover too (their elements let the pointer through so the cards under them keep their taps; the symbol alone takes the hover) */
.tc-badge .sym, .tc-chips .sym, .plate-row .sym, .plate-parts .sym, .gear-sym .sym, .route-truck .sym { pointer-events: auto; }

/* T: JOB-047: the battlefield (data-board on the table). Off, none of this matches anything. */
.tbl[data-board] .tbl-mid { gap: 14px; }
.tbl[data-board] .route-truck { width: 24px; height: 24px; top: -12px; padding: 2px; }
.tbl-trail { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.tc.is-truck { --sw: var(--tsw); --sh: var(--tsh); }
.tc.is-walking { z-index: 4; }
.tc-exposed { display: none; bottom: auto; top: calc(var(--bd) * -.5); right: 6%; width: auto; min-width: var(--bd); padding: 0 calc(var(--bd) * .16); border-radius: 999px; align-items: center; justify-content: center; gap: 1px; }
.tc-exposed.is-on { display: flex; }
.tc-exposed .sym { width: calc(var(--bd) * .5); height: calc(var(--bd) * .5); flex: none; }
.fx-dust { position: absolute; border-radius: 50%; background: rgba(27, 26, 23, .32); pointer-events: none; }
.trail-line { position: absolute; height: 14px; margin-top: -7px; transform-origin: 0 50%; pointer-events: auto; z-index: 3; }
.trail-line::before { content: ''; position: absolute; left: 0; right: 0; top: 6px; height: 2px; background: repeating-linear-gradient(90deg, var(--ink) 0 5px, transparent 5px 9px); }

.feat:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.feat-shake { position: absolute; inset: 0; will-change: transform; }
.tc[data-side] .tc-badge.tc-cover { display: none; top: 24%; bottom: auto; left: auto; right: calc(var(--bd) * -.46); width: auto; min-width: var(--bd); padding: 0 calc(var(--bd) * .16); border-radius: 999px; align-items: center; justify-content: center; gap: 1px; background: #3E5B3A; color: var(--paper); }
.tc[data-side] .tc-badge.tc-cover.is-on { display: flex; }
.tc-cover .sym { width: calc(var(--bd) * .5); height: calc(var(--bd) * .5); flex: none; }
.fx-num.fx-cover-note { display: flex; align-items: center; gap: .15em; font-size: clamp(.95rem, 3.2vw, 1.4rem); color: #3E5B3A; text-shadow: 1px 0 0 var(--paper), -1px 0 0 var(--paper), 0 1px 0 var(--paper), 0 -1px 0 var(--paper); }
.fx-num.fx-cover-note .sym { width: .85em; height: .85em; stroke-width: 2.2; }
.fx-num.fx-cover-note.is-stop { color: var(--red); }
.fx-blast { position: absolute; border-radius: 50%; pointer-events: none; z-index: 6; background: radial-gradient(circle, var(--blast, #E0702A) 0 38%, rgba(224, 112, 42, 0) 72%); }
.fx-blast.is-ring { background: none; border: 3px solid var(--blast, #E0702A); box-shadow: 0 0 0 1.5px var(--ink), inset 0 0 0 1.5px var(--ink); }
.fx-chip { position: absolute; border: 1px solid var(--ink); border-radius: 1px; pointer-events: none; z-index: 6; }

/* T2: JOB-048 (rules 209 and 211): the obstacles are CARDS standing on their spot in front of the man behind them; JEV-202610080216: each is a small card in the band just above its spot, in the row of the card that stands there, and on the board itself when nobody stands there; the ground layer lies above the standing cards and below a card that runs. */
.feat.is-burning .feat-shake { animation: feat-jitter .16s linear infinite; }
@keyframes feat-jitter { 0% { transform: translate(0, 0); } 25% { transform: translate(-1.5px, .5px); } 50% { transform: translate(1.5px, -.5px); } 75% { transform: translate(-1px, -.5px); } 100% { transform: translate(0, 0); } }
.feat-smoke { position: absolute; bottom: 55%; width: 22%; aspect-ratio: 1; border-radius: 50%; background: radial-gradient(circle, rgba(42, 40, 37, .75) 0 35%, rgba(42, 40, 37, 0) 70%); pointer-events: none; animation: feat-smoke 1.7s ease-out infinite; }
@keyframes feat-smoke { 0% { transform: translateY(0) scale(.6); opacity: .9; } 100% { transform: translateY(-120%) scale(1.7); opacity: 0; } }
.tc-why { position: absolute; left: 50%; top: calc(var(--sh) * -.2); transform: translateX(-50%); white-space: nowrap; z-index: 6; padding: 1px 7px; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); border-radius: 3px; font-size: clamp(.62rem, calc(var(--sw) * .13), .95rem); font-weight: 700; letter-spacing: .02em; box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); pointer-events: none; transition: opacity .4s ease-out; }
.tc-why.is-gone { opacity: 0; }
.walk-ghost { position: absolute; pointer-events: none; --c: 16%; background:
  linear-gradient(var(--ink), var(--ink)) 0 0 / var(--c) 2px no-repeat, linear-gradient(var(--ink), var(--ink)) 0 0 / 2px var(--c) no-repeat,
  linear-gradient(var(--ink), var(--ink)) 100% 0 / var(--c) 2px no-repeat, linear-gradient(var(--ink), var(--ink)) 100% 0 / 2px var(--c) no-repeat,
  linear-gradient(var(--ink), var(--ink)) 0 100% / var(--c) 2px no-repeat, linear-gradient(var(--ink), var(--ink)) 0 100% / 2px var(--c) no-repeat,
  linear-gradient(var(--ink), var(--ink)) 100% 100% / var(--c) 2px no-repeat, linear-gradient(var(--ink), var(--ink)) 100% 100% / 2px var(--c) no-repeat; }
.walk-line { position: absolute; height: 3px; margin-top: -1px; transform-origin: 0 50%; background: var(--ink); border-radius: 2px; pointer-events: none; }
.tc.is-walking .tc-card { box-shadow: 0 2px 0 rgba(27, 26, 23, .5), 0 12px 16px rgba(27, 26, 23, .34); }
/* a fallen card on the board lies in its own colours (rule 175) and carries its mark */
.tc-fallen { display: none; position: absolute; left: 50%; top: 50%; width: calc(var(--sw) * .3); aspect-ratio: 1; transform: translate(-50%, -50%); z-index: 5; border-radius: 50%; background: var(--paper); border: 2px solid var(--ink); color: var(--ink); place-items: center; pointer-events: none; }
.tc-fallen.is-on { display: grid; }
.tc-fallen .sym { width: 68%; height: 68%; pointer-events: auto; }



.feat-mark { position: absolute; right: 7%; top: 8%; width: 20%; aspect-ratio: 1; border-radius: 50%; background: var(--paper); border: 1.5px solid var(--ink); color: var(--ink); display: grid; place-items: center; pointer-events: none; }
.feat-mark .sym { width: 70%; height: 70%; pointer-events: auto; }



/* T2: JOB-048 (rules 216 and 217): live numbers tick red when they go down; a rounds count (or the durability of a protection) on the shelf; armour at 0 in red */
@keyframes tw-tick { from { background-color: #D1382B; color: #fff; } }
.is-tick { animation: tw-tick .55s ease-out; }
.tc-arm.is-zero { color: #B03024; border-color: #B03024; }
.tc-arm.is-zero b { color: #B03024; }
.gear-n { position: absolute; left: 50%; bottom: calc(var(--sw) * .02); transform: translateX(-50%); display: flex; align-items: center; gap: 1px; padding: 0 calc(var(--sw) * .04); height: max(14px, calc(var(--sw) * .14)); border-radius: 999px; background: var(--ink); color: var(--paper); border: 1px solid var(--paper); font-weight: 700; font-size: max(9px, calc(var(--sw) * .095)); line-height: 1; font-variant-numeric: tabular-nums; z-index: 4; pointer-events: none; }
.gear-n .sym { width: max(9px, calc(var(--sw) * .1)); height: max(9px, calc(var(--sw) * .1)); flex: none; pointer-events: auto; }
.gear-n.is-zero { background: #B03024; }

/* T2: JOB-048 (JOB-061): the armour pool as a thin steel-grey bar above the health, the magazine of a natural shooter, the floating armour number */
.tc-mag { position: absolute; left: 50%; bottom: calc(var(--sw) * -.07); transform: translateX(-50%); display: flex; align-items: center; gap: 1px; padding: 0 calc(var(--sw) * .04); height: max(14px, calc(var(--sw) * .14)); border-radius: 999px; background: var(--ink); color: var(--paper); border: 1px solid var(--paper); font-weight: 700; font-size: max(9px, calc(var(--sw) * .095)); line-height: 1; font-variant-numeric: tabular-nums; z-index: 4; pointer-events: none; }
.tc-mag .sym { width: max(9px, calc(var(--sw) * .1)); height: max(9px, calc(var(--sw) * .1)); flex: none; pointer-events: auto; }
.tc-mag.is-zero { background: #B03024; }
.fx-num.is-armour { display: flex; align-items: center; gap: .15em; color: #4F5C69; font-size: clamp(1.1rem, 4vw, 1.7rem); text-shadow: 1px 0 0 var(--paper), -1px 0 0 var(--paper), 0 1px 0 var(--paper), 0 -1px 0 var(--paper); }
.fx-num.is-armour .sym { width: .85em; height: .85em; stroke-width: 2.2; }

/* T2: JOB-048 (rule 216, v6): the ammunition impossible to miss: the number is as large as the attack and health pills, a bar of the round pips under it, red at 0, green flash on a reload */
.gear-n { bottom: calc(var(--sw) * .075); height: max(22px, calc(var(--sw) * .17)); min-width: max(30px, calc(var(--sw) * .24)); justify-content: center; gap: 3px; padding: 0 calc(var(--sw) * .05); font-size: max(13px, calc(var(--sw) * .12)); border-width: 1.5px; }
.gear-n .sym { width: max(12px, calc(var(--sw) * .115)); height: max(12px, calc(var(--sw) * .115)); }
.gear-rounds { bottom: calc(var(--sw) * .02); left: 12%; right: 12%; }
.gear-rounds i { height: max(4px, calc(var(--sw) * .035)); }
.gear-n.is-up, .tc-mag.is-up { animation: tw-up .7s ease-out; }
@keyframes tw-up { from { background-color: #3E8E4A; color: #fff; } }
.tc-mag { height: max(22px, calc(var(--sw) * .17)); min-width: max(30px, calc(var(--sw) * .24)); justify-content: center; gap: 3px; padding: 0 calc(var(--sw) * .05); font-size: max(13px, calc(var(--sw) * .12)); border-width: 1.5px; bottom: calc(var(--sw) * -.09); --mf: 100%; }
.tc-mag .sym { width: max(12px, calc(var(--sw) * .115)); height: max(12px, calc(var(--sw) * .115)); }

.gear[data-fan="first"] .gear-n { left: -10%; transform: none; }
.gear[data-fan="last"] .gear-n { left: auto; right: 4%; transform: none; }


/* T2: JOB-048 (proposal B, rule 221): the cover card is a SMALL whole card in the row of small cards above the man who uses it: it is a .gear in the shelf (same size, frame and placement as a weapon card), nothing is ever laid over a card */
/* JEV-202610080216: the ground of a place is SEEN whether or not a card can use it. The card of a spot nobody stands on is drawn here, in the same band just above that spot, over the board; it lies over no card of a line (that band is a host's own shelf, and the spot is empty), so the layer may sit above them. `.tbl-feat` was `visibility: hidden` before: that is what hid the ground of the spots no user took. */
.tbl-feat { position: absolute; inset: 0; z-index: 3; pointer-events: none; } /* the ground cards of the spots nobody uses stand on the board here; a card the man on the spot does not use is in his row instead */
.feat.gear { pointer-events: auto; cursor: help; }
.tbl-feat .feat.gear { transform-origin: 50% 50%; } /* the same small card as a cover card of a row (the fan's own origin is for cards under a host) */
.feat-card { position: absolute; inset: 0; border-radius: 3.6% / 2.4%; overflow: hidden; background: var(--paper); }
.feat-card img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; user-select: none; }
.feat .feat-pill { z-index: 5; }
.feat .feat-pill b { font-variant-numeric: tabular-nums; }

/* T2: JOB-048 (rules 220, 222 and JOB-042f): no bar on a card; the armour badge as large as the attack and health pills; the kill tally; the reloads left of a firearm; at phone size the magazine pill goes under the card so that the three pills of a card never crowd */
.tc-arm { height: calc(var(--bd) * 1.15); min-width: calc(var(--bd) * 1.3); font-size: calc(var(--bd) * .72); padding: 0 calc(var(--bd) * .2); }
.tc-arm .sym { width: calc(var(--bd) * .64); height: calc(var(--bd) * .64); }
.tc-kills { top: calc(var(--bd) * -.42); bottom: auto; left: 50%; right: auto; transform: translateX(-50%); width: auto; min-width: var(--bd); padding: 0 calc(var(--bd) * .18); border-radius: 999px; display: flex; align-items: center; justify-content: center; gap: 1px; background: var(--ink); color: var(--paper); font-size: calc(var(--bd) * .62); }
.tc-kills .sym { width: calc(var(--bd) * .5); height: calc(var(--bd) * .5); flex: none; }
.gear-rl { position: absolute; top: calc(var(--sw) * .02); left: 4%; display: flex; align-items: center; gap: 2px; padding: 0 calc(var(--sw) * .035); height: max(15px, calc(var(--sw) * .12)); border-radius: 999px; background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); font-weight: 700; font-size: max(10px, calc(var(--sw) * .085)); line-height: 1; z-index: 4; pointer-events: none; }
.gear-rl .sym { width: max(10px, calc(var(--sw) * .09)); height: max(10px, calc(var(--sw) * .09)); flex: none; pointer-events: auto; }
.gear-rl.is-zero { background: #B03024; color: #fff; border-color: #B03024; }
.tbl[data-layout="portrait"] .tc-mag { bottom: calc(var(--sw) * -.3); }

/* T2: JOB-048 (rules 175, 182, 216): the ONE mark of a card whose nerve broke: an hourglass and the seconds left, as readable as the pills (paper and a red rim, ink on paper) */
.tc-chips.has-state { top: calc(var(--sw) * .17); }
.tc-chips .chip.is-state { order: -1; pointer-events: auto; cursor: help; height: max(18px, calc(var(--sw) * .17)); padding: 0 max(4px, calc(var(--sw) * .04)); gap: 2px; background: var(--paper); color: var(--ink); border: 2px solid var(--red); font-size: max(12px, calc(var(--sw) * .115)); line-height: 1; font-variant-numeric: tabular-nums; box-shadow: 1px 2px 0 rgba(27, 26, 23, .3); }
.tc-chips .chip.is-nerve { order: -1; }
.tc-chips .chip.is-last { border-color: var(--ink); }
.tc-chips .chip.is-burnt { border-color: #E0702A; }
.tc-tap.is-tapped .chip.is-state { display: none; } /* a fallen card carries only its own mark */
.tc-chips .chip.is-state .sym { width: max(11px, calc(var(--sw) * .1)); height: max(11px, calc(var(--sw) * .1)); flex: none; }

/* T2: JOB-048 (JOB-066, rule 228): the bubble belongs to the whole PILL of a symbol: the number and the rim of the attack, health, armour, kills, star and exposed badges, of a rounds / durability / reloads pill, of the disc of a gear card, of a chip, of the magazine pill and of the mark of a fallen card take the pointer.
   They are children of the card or of the gear card: a hover or a click on them still reaches it (the lift, the flip), as the symbol inside already did; nothing else of the table's taps changes. */
.tc-badge, .tc-chips .chip, .gear-n, .gear-rl, .gear-sym, .tc-mag, .tc-fallen { pointer-events: auto; }
/* A gear card is tilted in its fan, so the box of its rounds / durability / reloads pill (what a tool measures, and what a finger aims at) is larger than the painted pill: the pill's hit area reaches 5 px past its edge, drawn by nothing. */
.gear-n::after, .gear-rl::after { content: ''; position: absolute; inset: -5px; border-radius: inherit; }

/* Physical copies stay recognizable even when they share one card design. */
.tc-instance, .tc-optics { position: absolute; z-index: 7; right: 2%; top: 3%; display: flex; align-items: center; gap: 2px; padding: 2px 3px; border: 1px solid var(--ink); border-radius: 999px; background: var(--paper); color: var(--ink); font-size: max(9px, calc(var(--sw) * .075)); line-height: 1; }
.tc-instance .sym, .tc-optics .sym { width: 10px; height: 10px; }
.tc-optics { top: 24%; }
.tc-optics.is-disabled { border-color: var(--red); color: var(--red); }
.tbl.has-convoy .tc-mag { bottom: calc(var(--sw) * -.22); }
