/* =============================================================================
   GRAND SAGA TCG — STYLESHEET
   -----------------------------------------------------------------------------
   T5. Four rules run the sheet:

     1. CUT CORNERS ARE FOR BUTTONS. Bays and panels are whole rectangles with a
        small radius — clipping them was cutting the corners off the table.
     2. RAILS ARE TWO-TONE. Each bay carries one colour into grey: white/grey
        neutral, blue/grey defensive, red/grey aggressive. Never a rainbow.
     3. THE ART CARRIES THE CARD. Nothing is printed over a card face but the
        level, the name plate and a status chip. Numbers live beneath it.
     4. GLOW, NOT OUTLINE. Cards have no border at all — shadow for weight,
        coloured light for state.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   THE PALETTE — three colours, and they each mean something.

     CYAN     interactive, defensive, armour. "you may touch this"
     MAGENTA  aggression, damage, danger, HP. "this is a fight"
     GOLD     value, energy, rewards, what is next. "this is worth something"

   Everything else is white, grey or void. Nothing else earns a hue — a fourth
   colour is a fourth thing to learn, and the last pass had seven.

   The one exception is the energy orb, whose art is green: its glow keeps a
   green drop-shadow so the light matches the object. That is a property of the
   image, not a fourth palette entry.
   -------------------------------------------------------------------------- */
:root {
    --c-1:  #3ce8ff;   /* cyan   — interactive / armour / defence */
    --c-2:  #ff2bd6;   /* magenta — aggression / damage / danger  */
    --c-3:  #ffd43a;   /* gold   — value / energy / next          */

    --c-1-deep: #12718c;
    --c-2-deep: #8f1478;
    --c-3-deep: #8a6c10;
    --c-orb: var(--c-3);  /* the orb art only — never used for UI state */

    --c-void:    #06021a;
    --c-abyss:   #0b0426;
    --c-panel:   #150838;
    --c-panel-2: #200c4e;
    --c-line:    #35235e;
    --c-grey:    #8e88a8;
    --c-ash:     #b6a9df;
    --c-bone:    #f4f0ff;

    /* Aliases. Every old name now resolves onto one of the three. */
    --c-cyan: var(--c-1);     --c-blue: var(--c-1);
    --c-magenta: var(--c-2);  --c-violet: var(--c-2);   --c-danger: var(--c-2);
    --c-gold: var(--c-3);     --c-amber: var(--c-3);    --c-acid: var(--c-3);
    --color-void: var(--c-void);      --color-abyss: var(--c-abyss);
    --color-panel: var(--c-panel);    --color-panel-2: var(--c-panel-2);
    --color-line: var(--c-line);      --color-ash: var(--c-ash);
    --color-bone: var(--c-bone);      --color-accent: var(--c-1);
    --color-accent-dim: var(--c-1-deep);
    --color-gold: var(--c-3);         --color-danger: var(--c-2);
    --color-good: var(--c-3);

    --font-display: 'Orbitron', sans-serif;
    --font-body: 'Rajdhani', sans-serif;
    --font-mono: 'Share Tech Mono', monospace;

    --r: 10px;         /* EVERY container — bays, panels, piles, modals */
    --r-in: 10px;      /* inner containers and slots, same corner throughout */
    --cut: 8px;        /* corner cut, BUTTONS ONLY — the site chip notch (T16) */
    --rail: 3px;
    --gap: 26px;
    --board-max: 1900px;
    --card-w: clamp(120px, 10vw, 172px);
    --card-h: calc(var(--card-w) * 1.4);
    --detail-w: 400px;

    /* ── T16: THE SITE'S OWN TOKENS — CHROME ONLY ──────────────────────
       The top bar, buttons, header menus, the detail slider and the log
       tab now wear the site's language (globals.css). The --c-* palette
       above still runs the BODY — bays, cards, rails — untouched.
       Semantics on the site side:
         --s-accent  cyan   interactive / active     --s-gold  value
         --s-saga    green  income, growth           --s-orange attention
         --s-red     stop / danger                   bone/ash   text tiers
       The chip notch is the site's 8px; the notch-edge strokes on
       buttons and modals scale off --cut so every size variant keeps
       honest corners. */
    --s-accent:  #00d9ff;
    --s-signal:  #7fe7ff;
    --s-gold:    #ffd700;
    --s-saga:    #37ff8b;
    --s-orange:  #ff8c42;
    --s-red:     #ff0040;
    --s-violet:  #9370db;
    --s-white:   #ffffff;
    --s-void:    #060112;
    --s-abyss:   #0a0118;
    --s-panel:   #120826;
    --s-panel-2: #1a0b33;
    --s-line:    #2c1a52;
    --s-ash:     #9d92c2;
    --s-bone:    #eeeaff;
    --font-chrome: var(--font-body);   /* Rajdhani — the site's display face */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
    font-family: var(--font-body);
    background: var(--c-void) center/cover fixed no-repeat;
    color: var(--c-bone); min-height: 100vh; overflow-x: hidden;
}
/* Lighter than T4 — the backdrop art should read, not sit behind a curtain. */
body::before {
    content: ''; position: fixed; inset: 0; z-index: -1;
    background:
        radial-gradient(ellipse at 20% 0%, rgba(60,232,255,.10), transparent 55%),
        radial-gradient(ellipse at 84% 6%, rgba(255,43,214,.08), transparent 52%),
        linear-gradient(180deg, rgba(6,2,26,.30), rgba(6,2,26,.52));
}

/* T19: INNER rails scroll without drawing a bar — a strip inside a bay
   or panel gives its whole height to the cards. The page, the modal and
   the drawer keep the site scrollbar below. */
.tcg-bay-body, #tcg-log-body, .tcg-turnorder, .tcg-reserve-strip {
    scrollbar-width: none;
}
.tcg-bay-body::-webkit-scrollbar, #tcg-log-body::-webkit-scrollbar,
.tcg-turnorder::-webkit-scrollbar, .tcg-reserve-strip::-webkit-scrollbar {
    display: none;
}

/* T17: the site's own scrollbar — violet over abyss, copied from
   globals.css so the game and the site scroll identically. */
* { scrollbar-width: thin; scrollbar-color: var(--s-violet) var(--s-abyss); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--s-abyss); }
::-webkit-scrollbar-thumb { background: linear-gradient(180deg, var(--s-violet), #5c3ab8); border: 2px solid var(--s-abyss); }
::-webkit-scrollbar-thumb:hover { background: #b39bf5; }

.screen { display: none; min-height: 100vh; padding: 96px 24px 34px; }
.screen.active { display: block; }
.tcg-board {
    width: min(var(--board-max), 97vw); margin: 0 auto;
    display: flex; flex-direction: column; gap: var(--gap);
}
/* The panel OVERLAYS. Reserving board width for it re-laid out every bay on
   open, which made selecting a card feel like the table moved under your hand.
   It floats above instead, and the board never knows it is there. */

/* ── LOADING ───────────────────────────────────────────────────────────── */
#screen-loading { display: none; place-items: center; }
#screen-loading.active { display: grid; }
.tcg-loader { text-align: center; width: min(880px, 92vw); }
.tcg-loader-logo {
    width: min(520px, 78vw); margin-bottom: 22px;
    filter: drop-shadow(0 0 30px rgba(60,232,255,.6)) drop-shadow(0 0 70px rgba(255,43,214,.35));
    animation: logoBreathe 4s ease-in-out infinite;
}
@keyframes logoBreathe { 50% { filter: drop-shadow(0 0 48px rgba(60,232,255,.9)) drop-shadow(0 0 96px rgba(255,43,214,.5)); } }
.tcg-loader h2 { font-family: var(--font-display); font-size: .8rem; letter-spacing: 10px; color: var(--c-ash); margin-bottom: 40px; }
.tcg-load-bar { height: 10px; background: rgba(32,12,78,.8); border-radius: var(--r); overflow: hidden; box-shadow: 0 0 18px rgba(60,232,255,.3); }
.tcg-load-bar i { display: block; height: 100%; width: 0; transition: width .5s ease; background: linear-gradient(90deg, var(--c-cyan), var(--c-violet)); box-shadow: 0 0 20px rgba(60,232,255,.7); }
#tcg-load-text { font-family: var(--font-mono); font-size: 1.05rem; color: var(--c-cyan); text-transform: uppercase; letter-spacing: 2px; margin-top: 18px; text-shadow: 0 0 12px rgba(60,232,255,.7); }

/* ── TOP BAR ───────────────────────────────────────────────────────────── */
#tcg-topbar {
    /* T16: the site's header shell — flat void behind blur, one line
       border. The gradient rail is gone; the site never draws one. */
    position: fixed; top: 0; left: 0; right: 0; z-index: 60;
    display: flex; align-items: center; gap: 14px; padding: 9px 22px;
    background: rgba(6,1,18,.88);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--s-line);
    font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase;
    font-size: 13px; letter-spacing: .14em;   /* T17: was 11px — too small */
    overflow-x: auto; overflow-y: hidden;
}
.tcg-brand { flex: 0 0 auto; cursor: help; }
.tcg-brand img { height: 42px; display: block; filter: drop-shadow(0 0 12px rgba(0,217,255,.55)); }
.tcg-chapter { color: var(--s-accent); white-space: nowrap; }   /* T16: colour is the emphasis — the site never glows text */
.tcg-chapter b, .tcg-energy b { color: var(--s-bone); font-size: 17px; }
.tcg-spacer { flex: 1; min-width: 6px; }
/* T17: the verb strip. Desktop: the last flex run of the bar. Phones pin
   it to the bottom of the screen — see the 760px block. */
.tcg-actions { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.tcg-turnorder {
    display: flex; gap: 8px; align-items: center;
    /* T17: the pip cluster is the bar's only variable-width content —
       four seats of house names at the new type size could push END TURN
       off the right edge. The cluster scrolls INTERNALLY when tight; the
       verbs never move. */
    flex: 0 1 auto; min-width: 130px; max-width: 46vw;
    overflow-x: auto; scrollbar-width: none;
}
.tcg-turnorder::-webkit-scrollbar { display: none; }
.tcg-seatpip {
    display: flex; align-items: center; gap: 6px; padding: 6px 13px; border-radius: var(--r-in);
    background: rgba(26,11,51,.85); border: 1px solid var(--s-line);
    font-size: 10.5px; opacity: .62; cursor: pointer; white-space: nowrap; transition: .16s;
}
.tcg-seatpip:hover { opacity: 1; border-color: rgba(0,217,255,.6); box-shadow: inset 0 0 0 1px rgba(0,217,255,.22), inset 0 0 18px rgba(0,217,255,.1); }
.tcg-seatpip i { width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 9px currentColor; }
.tcg-seatpip em { font-style: normal; font-family: var(--font-mono); font-size: 10px; color: var(--s-ash); }
.tcg-seatpip.active { opacity: 1; border-color: rgba(0,217,255,.7); box-shadow: inset 0 0 0 1px rgba(0,217,255,.28), inset 0 0 22px rgba(0,217,255,.12); }
.tcg-seatpip.dead { text-decoration: line-through; opacity: .3; }
.tcg-energy { display: flex; align-items: center; gap: 9px; color: var(--s-gold); cursor: help; white-space: nowrap; }
/* The orb art is green, so its light is green — matching the object, not the
   palette. This is the single documented exception. */
.tcg-orb { display: inline-block; width: 26px; height: 26px; flex: 0 0 auto; background: center/contain no-repeat; filter: drop-shadow(0 0 11px rgba(57,255,136,.85)); animation: orbPulse 3s ease-in-out infinite; }
@keyframes orbPulse { 50% { filter: drop-shadow(0 0 20px rgba(57,255,136,1)); transform: scale(1.07); } }

/* ── BUTTONS — filled, cut corners. The only clipped things in the build. ─ */
.tcg-btn {
    /* T16: the site chip. Panel fill inside a line border; the two cut
       corners get their border back as rotated strokes (border-color:
       inherit, so they turn accent with the border on hover — the
       site's own technique). Outer glows are gone: box-shadow outside a
       clipped element never renders, which is why the old primary glow
       was invisible. The glow is INSET now, like every chip on the site. */
    font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase;
    font-size: 11.5px; letter-spacing: .14em;   /* T17: header verbs read bigger */
    padding: 10px 19px; cursor: pointer; white-space: nowrap;
    color: var(--s-bone); background: var(--s-panel);
    border: 1px solid var(--s-line); position: relative;
    clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
    transition: filter .16s, box-shadow .16s, transform .16s, border-color .16s;
}
.tcg-btn::before, .tcg-btn::after {
    content: ""; position: absolute; height: 0;
    border-top: 1px solid; border-color: inherit;
    width: calc(var(--cut) * 1.4142);
}
.tcg-btn::before { top: calc(var(--cut) * 0.44); left: calc(var(--cut) * -0.21); transform: rotate(-45deg); }
.tcg-btn::after  { bottom: calc(var(--cut) * 0.44); right: calc(var(--cut) * -0.21); transform: rotate(-45deg); }
.tcg-btn:hover:not(:disabled) {
    border-color: rgba(0,217,255,.6);
    box-shadow: inset 0 0 0 1px rgba(0,217,255,.22), inset 0 0 26px rgba(0,217,255,.12);
    transform: translateY(-1px);
}
.tcg-btn:focus-visible { outline: 2px solid var(--s-gold); outline-offset: 2px; }   /* T16: the site's focus ring */
.tcg-btn:disabled { filter: grayscale(.75) brightness(.55); cursor: not-allowed; }
.tcg-btn.primary { background: var(--s-accent); border-color: transparent; color: var(--s-void); }
.tcg-btn.good { background: var(--s-gold); border-color: transparent; color: var(--s-void); }
.tcg-btn.danger { background: var(--s-red); border-color: transparent; color: var(--s-white); }
/* Solid chips brighten instead of taking the cyan inset — a cyan ring on
   a gold or red fill is the wrong light. The lift still comes from base. */
.tcg-btn.primary:hover:not(:disabled), .tcg-btn.good:hover:not(:disabled),
.tcg-btn.danger:hover:not(:disabled), .tcg-btn.blocked:hover:not(:disabled),
.tcg-btn.ward:hover:not(:disabled) {
    border-color: transparent; box-shadow: none; filter: brightness(1.12);
}
.tcg-btn.ghost { padding: 10px 14px; font-size: 13px; letter-spacing: 0; }
.tcg-btn.tiny { font-size: 8.5px; padding: 6px 11px; letter-spacing: .1em; --cut: 6px; }
.tcg-btn.wide { width: 100%; margin-top: 10px; }
.tcg-btn.big { font-size: 13px; padding: 16px 38px; margin-top: 24px; --cut: 14px; }   /* T16: the site's PANEL notch — landing-CTA scale */

/* ── BAYS — whole rectangles, two-tone rail, name across the middle ────── */
/* ROW 1 assault | defence · ROW 2 bench | sigils | energy · ROW 3 hand | pool | deck.
   The two standing piles are stacks, not rows, so they only need a narrow
   column each — which is the width the bench was not using. */
.mat-row { display: grid; gap: var(--gap); grid-template-columns: 1fr 1fr; }
.mat-row.mid  { grid-template-columns: minmax(0,1fr) 250px 230px; }
.mat-row.dock { grid-template-columns: minmax(0,1.6fr) minmax(0,1.6fr) 230px; }

.mat-bay, .tcg-carousel {
    position: relative; padding: 22px; min-height: 190px; border-radius: var(--r);
    background: linear-gradient(165deg, rgba(21,8,56,.44), rgba(6,2,26,.58));
    border: none;
    box-shadow: inset 0 0 70px rgba(0,0,0,.5);
}
/* THE RING. border-image was doing this job and it CANNOT be rounded — a
   border-image always paints square corners and silently ignores
   border-radius. A masked gradient layer follows the corner instead, which is
   what lets every container carry the same 10px. */
.mat-bay::after, .tcg-carousel::after {
    content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
    border-radius: inherit; padding: var(--rail);
    /* T17: the two-tone gradient ring flattened — one solid colour per
       bay, the colour each bay already declared as --rail-a. */
    background: var(--rail-a, rgba(176,171,196,.42));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor; mask-composite: exclude;
}
.mat-bay::before {
    content: attr(data-label); position: absolute; inset: 0; z-index: 0;
    display: grid; place-items: center; pointer-events: none;
    font-family: var(--font-display); font-weight: 900;
    font-size: clamp(24px, 4.2vw, 62px); letter-spacing: clamp(5px, 1vw, 16px);
    color: #fff; opacity: .055; text-transform: uppercase;
}
.mat-bay > *, .tcg-carousel > * { position: relative; z-index: 1; }

/* ASSAULT is the only red rail on the mat and it was shouting — the red now
   fades to grey much earlier so it reads as a warning, not an alarm. */
.mat-bay.assault { --rail-a: rgba(255,0,64,.72); --rail-b: rgba(150,140,168,.28); }   /* T18: the site red — pink left the bay */
.mat-bay.defence { --rail-a: rgba(255,255,255,.8); }
.mat-bay.bench   { --rail-a: rgba(255,255,255,.8); min-height: 250px; }
.mat-bay.hand    { --rail-a: rgba(255,255,255,.8); }
.mat-bay.pool    { --rail-a: rgba(255,255,255,.8); }
.mat-bay.piles   { --rail-a: rgba(255,255,255,.8); }
/* The two standing piles are the exceptions: they carry their own card's
   colour so the bay and the thing inside it agree. */
.mat-bay.sigils  { --rail-a: var(--c-cyan); overflow: hidden; }
/* T19: the two standing piles sit centred — they hugged the left edge.
   The sigil bay's body is the rack, not a bay-body, so both get named. */
.mat-bay.energy .tcg-bay-body { justify-content: safe center; }
.mat-bay.sigils .tcg-rack { margin-inline: auto; }
.mat-bay.energy #tcg-energy-pile > * { margin-inline: auto; }
.mat-bay.energy  { --rail-a: #00bf63; --rail-b: rgba(0,191,99,.24); overflow: hidden; }
.tcg-carousel    { --rail-a: var(--c-blue); min-height: 0; }

.mat-bay h4 {
    font-family: var(--font-display); font-size: 10px; letter-spacing: 3px;
    /* T19: a bay's header wears its own border colour — the market reads
       gold, the exchange cyan, the ground the house you face. The sigil
       bay keeps its deliberate gold override below. */
    color: var(--rail-a, var(--c-bone)); margin-bottom: 16px; opacity: .9;
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.mat-bay.defence h4, .mat-bay.pool h4 { color: var(--c-1); }
.mat-bay.sigils h4, .mat-bay.sigils h4 span, .mat-bay.sigils::before { color: var(--c-gold); }
.mat-bay.energy h4, .mat-bay.energy h4 span { color: #00bf63; }
.mat-bay.energy::before { color: #00bf63; opacity: .085; }
.mat-bay h4 em { font-style: normal; font-family: var(--font-mono); font-size: 9px; letter-spacing: .5px; color: var(--c-ash); text-transform: none; }
.mat-bay h4 span { font-family: var(--font-mono); color: var(--c-ash); letter-spacing: 1px; }
.mat-bay h4 span.full { color: var(--c-gold); }
.mat-bay h5, .tcg-tray h5, .tcg-modal-body h5 { font-family: var(--font-display); font-size: 9px; letter-spacing: 2px; color: var(--c-ash); margin: 16px 0 9px; }
.tcg-bay-body { display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start; }
.tcg-bay-body.fanbody { display: block; }

/* ── UNITS: card on top, gear edges under it, stats under that ─────────── */
.tcg-unit { display: flex; flex-direction: column; width: var(--card-w); }
.tcg-unit.selected .tcg-tablecard { box-shadow: 0 12px 30px rgba(0,0,0,.75), 0 0 0 3px var(--c-cyan), 0 0 40px rgba(60,232,255,.55); }

.tcg-tablecard, .tcg-card {
    position: relative; width: var(--card-w); height: var(--card-h); flex: 0 0 auto;
    border: none; border-radius: var(--r-in); overflow: hidden;
    background: #0d0320 center/cover no-repeat;
    box-shadow: 0 12px 30px rgba(0,0,0,.72);
    transition: transform .2s cubic-bezier(.2,.9,.3,1.25), box-shadow .2s, filter .2s, opacity .18s;
}
.tcg-tablecard { cursor: pointer; }
.tcg-tablecard:hover, .tcg-card.clickable:hover, .tcg-card.pickable:hover {
    transform: translateY(-11px) rotate(-.8deg);
    box-shadow: 0 26px 50px rgba(0,0,0,.82), 0 0 34px rgba(60,232,255,.45);
}
.tcg-tablecard:focus-visible, .tcg-card:focus-visible {
    outline: none; box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 3px var(--c-cyan), 0 0 38px rgba(60,232,255,.7);
}
/* Dragging: much bigger shadow, hard glow. The card is off the table. */
.tcg-tablecard.lifted, .tcg-card.lifted {
    transform: translateY(-30px) scale(1.16) rotate(2deg);
    box-shadow: 0 56px 96px rgba(0,0,0,.92), 0 0 58px rgba(60,232,255,.8), 0 0 120px rgba(255,43,214,.45);
    z-index: 60;
}
.tcg-card.small { width: calc(var(--card-w) * .58); height: calc(var(--card-h) * .58); }
.tcg-card.clickable, .tcg-card.pickable { cursor: pointer; }
.tcg-card.dim { opacity: .3; filter: grayscale(.5); }
.tcg-card.locked { opacity: .5; filter: grayscale(.7); }
.tcg-card.broken, .tcg-tablecard.down { filter: grayscale(.85) brightness(.58); }
.tcg-tablecard.exposed { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 30px rgba(255,212,58,.72); }
.tcg-tablecard.pinned { cursor: default; }
.tcg-card.hidden-card { background-color: #14062c; }

.tc-status { position: absolute; top: 9px; left: 9px; z-index: 3; }
/* T17: the level hex left the face — the printed art carries its own.
   display:none rather than deletion so any straggler render is silent. */
.tc-rank, .tcg-card-lv { display: none; }
.tc-items {
    position: absolute; top: 9px; right: 9px; z-index: 3; min-width: 24px; height: 24px;
    display: grid; place-items: center; padding: 0 7px; border-radius: 999px;
    background: var(--c-gold); color: #06010f; box-shadow: 0 0 14px rgba(255,212,58,.6);
    font-family: var(--font-display); font-size: 10px; font-weight: 900;
}
.tc-garrison { position: absolute; bottom: 9px; right: 9px; z-index: 3; color: var(--c-cyan); font-size: 16px; text-shadow: 0 0 10px var(--c-cyan); }
.tc-pilecount {
    position: absolute; inset: 0; display: grid; place-items: center;
    font-family: var(--font-display); font-size: 30px; font-weight: 900;
    color: var(--c-bone); text-shadow: 0 0 20px rgba(0,0,0,.9); opacity: .92;
}
/* The name plate is the ONLY thing painted over the art — and since T17
   it appears on HOVER, carrying the die, damage and counts beside the
   name; the printed art already shows the name and level. Touch devices
   have no hover, so there the plate stays visible. */
.tc-plate, .tcg-card-plate {
    position: absolute; inset: auto 0 0 0; padding: 10px 11px 11px;
    background: linear-gradient(180deg, transparent, rgba(6,2,26,.94) 46%);
    opacity: 0; transform: translateY(4px); pointer-events: none;
    transition: opacity .18s, transform .18s;
}
.tcg-tablecard:hover .tc-plate, .tcg-tablecard:focus-visible .tc-plate,
.tcg-card:hover .tcg-card-plate, .tcg-fan-card:hover .tcg-card-plate {
    opacity: 1; transform: none;
}
.tc-sub { margin-top: 3px; font-family: var(--font-mono); font-size: 9px; color: var(--s-ash); }
.tc-sub b { color: var(--s-gold); font-weight: 700; }
@media (hover: none) {
    .tc-plate, .tcg-card-plate { opacity: 1; transform: none; }
}
.tc-name, .tcg-card-plate span {
    display: block; font-family: var(--font-display); font-size: clamp(9px, .78vw, 11.5px);
    letter-spacing: .5px; color: var(--c-bone); line-height: 1.2;
}
.tcg-card-body { position: absolute; inset: auto 0 0 0; padding: 8px 10px 10px; background: linear-gradient(180deg, transparent, rgba(6,2,26,.94) 38%);
    opacity: 0; transform: translateY(4px); pointer-events: none; transition: opacity .18s, transform .18s; }
.tcg-card:hover .tcg-card-body, .tcg-fan-card:hover .tcg-card-body { opacity: 1; transform: none; }
@media (hover: none) { .tcg-card-body { opacity: 1; transform: none; } }
.tcg-card-name { font-family: var(--font-display); font-size: 9.5px; color: var(--c-bone); line-height: 1.2; }
.tcg-card-stats { display: flex; gap: 8px; margin-top: 4px; font-family: var(--font-mono); font-size: 8.5px; }
.tcg-card-stats .ap { color: var(--c-cyan); }
.tcg-card-stats .dam { color: var(--s-red); }
.tcg-card-spine { position: absolute; top: 38px; left: 5px; z-index: 3; writing-mode: vertical-rl; font-family: var(--font-display); font-size: 8px; letter-spacing: 2px; color: var(--c-bone); opacity: .8; text-shadow: 0 0 6px #000; }
.tcg-apbar { height: 3px; margin-top: 4px; background: rgba(0,0,0,.65); border-radius: 2px; }
.tcg-apbar i { display: block; height: 100%; background: var(--c-cyan); box-shadow: 0 0 8px var(--c-cyan); }
.tcg-card-broken {
    position: absolute; top: 44%; left: 0; right: 0; text-align: center;
    font-family: var(--font-display); font-size: 10px; letter-spacing: 3px;
    color: var(--c-danger); background: rgba(6,2,26,.9); padding: 5px 0;
    text-shadow: 0 0 12px rgba(255,43,214,.9);
}
.tcg-loot-badge {
    position: absolute; top: 8px; left: 8px; z-index: 4; padding: 3px 8px; border-radius: 999px;
    background: var(--c-gold); color: #06010f; box-shadow: 0 0 16px rgba(255,212,58,.8);
    font-family: var(--font-display); font-size: 7px; font-weight: 900; letter-spacing: 1px;
}

/* Gear as real card edges tucked under the card. */
.tc-edges { position: relative; height: 15px; }
.tc-edge {
    position: absolute; left: calc(6px + var(--i) * 15%); top: 0;
    width: 26%; height: 14px; border-radius: 0 0 var(--r-in) var(--r-in);
    background: #200c4e center/cover no-repeat;
    box-shadow: 0 4px 9px rgba(0,0,0,.7);
}
.tc-edge.broken { box-shadow: 0 4px 9px rgba(0,0,0,.7), 0 0 0 1px var(--c-danger); }

/* THE STATS STRIP — under the card, where numbers can be read. */
.tcg-unitstats { margin-top: 8px; display: flex; flex-direction: column; gap: 4px; }
.tcg-unitline {
    display: flex; justify-content: space-between; align-items: baseline; gap: 8px;
    font-family: var(--font-mono); font-size: 11px; color: var(--c-ash);
}
.tcg-unitline b { font-family: var(--font-display); font-size: 11px; color: var(--c-bone); letter-spacing: 1px; }
.tcg-unitline .settling { color: var(--c-amber); }
.tcg-slotpips { display: flex; gap: 3px; }
.tcg-slotpips i { flex: 1; height: 5px; border-radius: 3px; background: rgba(255,255,255,.16); }
.tcg-slotpips i.on { background: var(--c-cyan); box-shadow: 0 0 8px rgba(60,232,255,.8); }

/* ── FANS — overlapping cards, hover pulls one forward whole ───────────── */
.tcg-fan { display: flex; padding: 6px 0 30px; min-height: calc(var(--card-h) + 34px); }
.tcg-fan-card {
    flex: 0 0 auto; width: calc(var(--card-w) * (1 - var(--overlap, .5)));
    transition: transform .22s cubic-bezier(.2,.9,.3,1.3);
}
.tcg-fan-card:last-child { width: var(--card-w); }
.tcg-fan-card .tcg-card { transition: transform .22s cubic-bezier(.2,.9,.3,1.3), box-shadow .2s; }
.tcg-fan-card:hover { z-index: 30; }
.tcg-fan-card:hover .tcg-card:not(.lifted) {
    transform: translateY(-26px) scale(1.1) rotate(-1deg);
    box-shadow: 0 30px 56px rgba(0,0,0,.85), 0 0 38px rgba(60,232,255,.5);
}
.tcg-fan-card:focus-within { z-index: 30; }

/* ── DROP PADS — nothing until a card is lifted ────────────────────────── */
.tcg-drop {
    display: none; width: var(--card-w); height: var(--card-h); border-radius: var(--r-in);
    place-items: center; text-align: center; padding: 12px;
    background: rgba(255,255,255,.055);
    box-shadow: inset 0 0 0 999px rgba(255,255,255,.012), inset 0 0 30px rgba(0,0,0,.4);
}
.tcg-drop.tall { height: calc(var(--card-h) * 1.2); }
.tcg-drop.slim { height: 54px; }
body.dragging .tcg-drop { display: grid; }
.tcg-drop-label { font-family: var(--font-display); font-size: 9px; letter-spacing: 2px; color: var(--c-ash); line-height: 1.6; }
.tcg-drop-verb {
    position: absolute; inset: auto 0 8px 0; z-index: 5; text-align: center; pointer-events: none;
    font-family: var(--font-display); font-size: 9px; letter-spacing: 2px; color: var(--c-cyan);
    text-shadow: 0 0 12px rgba(60,232,255,.9), 0 0 4px #000; opacity: 0; transition: opacity .18s;
}
body.dragging .legal .tcg-drop-verb { opacity: 1; }
.tcg-drop.legal, .dt-slot.legal {
    background: rgba(60,232,255,.14);
    box-shadow: inset 0 0 44px rgba(60,232,255,.3);
    animation: padPulse 1.4s ease-in-out infinite;
}
.tcg-drop.legal .tcg-drop-label { color: var(--c-cyan); text-shadow: 0 0 12px rgba(60,232,255,.8); }
@keyframes padPulse { 50% { background: rgba(60,232,255,.24); box-shadow: inset 0 0 60px rgba(60,232,255,.45); } }
/* A card that is a legal target lights up rather than growing an outline. */
body.dragging .tcg-tablecard.legal { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 3px var(--c-cyan), 0 0 46px rgba(60,232,255,.7); }
body.dragging .tcg-tablecard.illegal { filter: grayscale(.8) brightness(.5); }
.hovering { filter: brightness(1.2); }

/* ── SIGIL STACK ───────────────────────────────────────────────────────── */
/* CYAN, matching the bay's own rail. The bloom was violet, left over from the
   T4 palette, and it fought the cyan ring around it. */
.mat-sigils.charged {
    background:
        radial-gradient(ellipse at 50% 115%, rgba(60,232,255,.3), transparent 64%),
        linear-gradient(165deg, rgba(8,34,52,.5), rgba(6,2,26,.6));
    box-shadow: inset 0 0 80px rgba(60,232,255,.24);
}
.tcg-motes { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.tcg-mote {
    position: absolute; left: var(--x); bottom: -10px; width: var(--s); height: var(--s);
    border-radius: 50%; background: var(--c-cyan);   /* T19: blue, like the bay that breathes them */
    box-shadow: 0 0 10px var(--c-cyan), 0 0 22px rgba(60,232,255,.5);
    animation: mote var(--d) linear infinite; animation-delay: var(--delay); opacity: 0;
}
@keyframes mote {
    0% { transform: translateY(0) scale(.6); opacity: 0; }
    12% { opacity: .95; } 80% { opacity: .5; }
    100% { transform: translateY(-340px) translateX(16px) scale(1.25); opacity: 0; }
}
.tcg-sigil-stack {
    position: relative; width: var(--card-w);
    height: calc(var(--card-h) + var(--stack, 0) * 34px + 20px);
    transition: height .24s ease;
}
.tcg-rack:hover .tcg-sigil-stack { height: calc(var(--card-h) + var(--stack, 0) * 58px + 20px); }
.tcg-sigil-card {
    position: absolute; left: 0; right: 0;
    top: calc(var(--n) * 34px);
    transition: transform .24s cubic-bezier(.2,.9,.3,1.3), top .24s ease; z-index: var(--z, 1);
}
/* Enough of each card showing to read it and hit it. Hovering the stack fans
   it further so the ones underneath can be reached and taken back out. */
.tcg-rack:hover .tcg-sigil-card { top: calc(var(--n) * 58px); }
/* FULL SIZE, STACKED — the same shape as the energy pile. They used to be
   squashed to .62 height, which made racking one look like a downgrade. */
.tcg-sigil-card .tcg-card { width: 100%; height: var(--card-h); }
.tcg-sigil-card:hover { z-index: 40; transform: translateX(10px) scale(1.06); }
.tcg-sigil-card.next .tcg-card { box-shadow: 0 12px 30px rgba(0,0,0,.7), 0 0 0 2px var(--c-gold), 0 0 30px rgba(255,212,58,.5); }
.tcg-sigil-card.locked .tcg-card { filter: grayscale(.6) brightness(.72); }
.tcg-sigil-next {
    position: absolute; top: -8px; right: 6px; z-index: 5; padding: 3px 9px; border-radius: 999px;
    background: var(--c-gold); color: #06010f; box-shadow: 0 0 16px rgba(255,212,58,.8);
    font-family: var(--font-display); font-size: 7px; font-weight: 900; letter-spacing: 1.5px;
}

/* ── RESERVE & SPOILS ──────────────────────────────────────────────────── */
.tcg-reserve-strip { margin-top: 20px; display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
/* T19: on the desktop the reserve stands as a column at the bay's right
   edge, in the same row as the built outposts — mobile keeps the strip
   below, where a second row costs nothing. */
@media (min-width: 1081px) {
    .mat-bay.defence { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 20px; align-items: start; }
    .mat-bay.defence > h4 { grid-column: 1 / -1; }
    .mat-bay.defence > #tcg-bay-defence { grid-column: 1; }
    .mat-bay.defence > #tcg-reserve { grid-column: 2; margin-top: 0; flex-direction: column; align-items: stretch; flex-wrap: nowrap; }
    .mat-bay.defence > #tcg-reserve h5 { width: auto; }
}
.tcg-reserve-strip h5 { width: 100%; margin: 0 0 2px; }
.tcg-reserve-tile {
    position: relative; width: 178px; padding: 13px; border-radius: var(--r-in);
    background: rgba(11,4,38,.66);
}
.tcg-reserve-tile.waiting { opacity: .58; }
.tcg-reserve-tile.fresh { box-shadow: 0 0 0 2px var(--c-gold), 0 0 28px rgba(255,212,58,.3); }
.tcg-reserve-tile b { display: block; font-family: var(--font-display); font-size: 10px; margin-bottom: 10px; }
.tcg-new {
    position: absolute; top: -9px; right: 9px; padding: 3px 9px; border-radius: 999px;
    background: var(--c-gold); color: #06010f; box-shadow: 0 0 14px rgba(255,212,58,.8);
    font-family: var(--font-display); font-size: 7px; font-weight: 900; letter-spacing: 1px;
}
/* It used to be the board's first child, so an assault coming home pushed the
   whole mat down. It floats over the table instead. */
#tcg-spoils-host {
    position: fixed; top: 78px; left: 50%; transform: translateX(-50%);
    z-index: 130; width: min(760px, 92vw); pointer-events: none;
}
#tcg-spoils-host > * { pointer-events: auto; }
.tcg-spoils {
    position: relative; padding: 20px 22px; border-radius: var(--r);
    background: linear-gradient(165deg, rgba(46,32,10,.97), rgba(12,5,26,.97));
    box-shadow: 0 24px 60px rgba(0,0,0,.75);
    animation: spoilsIn .3s cubic-bezier(.2,.9,.3,1.1);
}
.tcg-spoils::after {
    content: ''; position: absolute; inset: 0; border-radius: inherit; padding: var(--rail);
    pointer-events: none;
    background: linear-gradient(150deg, var(--c-gold) 0%, var(--c-gold) 30%, rgba(142,136,168,.3) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor; mask-composite: exclude;
}
@keyframes spoilsIn { from { opacity: 0; transform: translateY(-14px); } }
.tcg-spoils h4 { font-family: var(--font-display); font-size: 11px; letter-spacing: 3px; color: var(--c-gold); margin-bottom: 13px; }
.tcg-spoils-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.tcg-spoils-tag { font-family: var(--font-display); font-size: 8px; letter-spacing: 1.5px; padding: 7px 14px; border-radius: 999px; color: currentColor; box-shadow: 0 0 0 1px currentColor; }
.tcg-spoils-tag.loot { color: var(--c-gold); }
.tcg-spoils-tag.ground { color: var(--c-cyan); }
.tcg-spoils-out { font-family: var(--font-mono); font-size: 11px; color: var(--c-bone); padding: 7px 14px; border-radius: 999px; background: rgba(60,232,255,.16); }

/* ── HOUSE FLAGS ───────────────────────────────────────────────────────── */
.tcg-flag {
    --house: var(--c-cyan); position: relative; flex: 0 0 auto;
    background: #0a0220 center/cover no-repeat;
    box-shadow: 0 12px 30px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.12);
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 16px), 50% 100%, 0 calc(100% - 16px));
}
.tcg-flag.tall { width: 92px; height: 210px; }
.tcg-flag.banner { width: 100%; height: 150px; margin-bottom: 16px; background-position: center 32%; }
.tcg-flag-name {
    position: absolute; inset: auto 0 22px 0; text-align: center;
    font-family: var(--font-display); font-size: 8px; letter-spacing: 2px;
    color: var(--c-bone); text-shadow: 0 0 8px #000, 0 0 18px var(--house);
}

/* ── THE DETAIL PANEL ──────────────────────────────────────────────────── */
.tcg-detail {
    /* T16: the site's panel voice — panel-over-abyss fill, one line
       border, and the 2px accent bar across the top (the site's
       accent-sweep: "this surface is live"). The gradient rail is gone.
       top: 66px clears the bar — the bar's padding did not change, so
       the offset still holds. */
    position: fixed; top: 66px; right: 0; bottom: 0; width: var(--detail-w); z-index: 120;
    padding: 22px; overflow-y: auto;
    background: linear-gradient(180deg, rgba(18,8,38,.98), rgba(10,1,24,.98));
    border-left: 1px solid var(--s-line);
    border-top: 1px solid var(--s-line);   /* T17: the accent bar read too loud here */
    transform: translateX(102%); transition: transform .28s cubic-bezier(.2,.9,.3,1.1);
}
body.detail-open .tcg-detail { transform: none; }
.dt-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 16px; }
.dt-title { flex: 1; min-width: 0; }
.dt-title h3 { font-family: var(--font-chrome); font-weight: 700; text-transform: uppercase; font-size: 17px; letter-spacing: .1em; color: var(--s-bone); line-height: 1.2; }
.dt-title span { font-family: var(--font-mono); font-size: 11px; color: var(--s-ash); }
.dt-back, .dt-close {
    width: 30px; height: 30px; border-radius: var(--r-in); cursor: pointer; font-size: 15px;
    background: rgba(26,11,51,.9); color: var(--s-ash); border: 1px solid var(--s-line);
}
.dt-back:hover, .dt-close:hover { color: var(--s-accent); border-color: rgba(0,217,255,.6); }
.dt-hero { display: flex; gap: 14px; margin-bottom: 18px; }
/* T19: EVERY portrait stands at true card proportions — T18 gave the
   outposts 5:7 and the character cards, which carry flags beside them the
   same way, now match. */
.dt-portrait { flex: 1; height: auto; aspect-ratio: 5 / 7; border-radius: var(--r-in); background: #12042a center/cover no-repeat; box-shadow: 0 12px 30px rgba(0,0,0,.7); }
.dt-portrait.outpost { background-size: cover; }   /* proportions come from the base rule now */
.dt-bigcard { width: 100%; height: auto; aspect-ratio: 5/7; margin-bottom: 18px; }
.dt-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 16px; }
.dt-stats div { text-align: center; padding: 10px 4px; border-radius: var(--r-in); background: rgba(10,1,24,.7); }
.dt-stats span { display: block; font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase; font-size: 8px; letter-spacing: .14em; color: var(--s-ash); margin-bottom: 5px; }
.dt-stats b { font-family: var(--font-mono); font-size: 19px; color: var(--s-bone); }
.dt-bars { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.dt-perk { padding: 13px 15px; border-radius: var(--r-in); background: rgba(26,11,51,.55); border-left: 3px solid var(--s-violet); margin-bottom: 14px; }   /* T16: the site violet */
.dt-perk b { display: block; font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase; font-size: 9px; letter-spacing: .14em; color: var(--s-gold); margin-bottom: 6px; }
.dt-perk p { font-family: var(--font-body); font-size: 14px; line-height: 1.45; color: var(--c-bone); }
.dt-lock { padding: 11px 14px; border-radius: var(--r-in); background: rgba(255,215,0,.12); color: var(--s-gold); font-family: var(--font-mono); font-size: 12px; margin-bottom: 14px; }
.dt-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
.dt-slot {
    position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px;
    padding: 22px 6px 9px; min-height: 128px; border-radius: var(--r-in);
    background: rgba(11,4,38,.62); border: 1px solid rgba(255,255,255,.12); transition: .18s;
}
.dt-slot-label { position: absolute; top: 7px; left: 0; right: 0; text-align: center; font-family: var(--font-display); font-size: 7.5px; letter-spacing: 1.2px; color: var(--c-ash); opacity: .85; }
.dt-slot-hint { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); opacity: .45; margin-top: 26px; }
.dt-slot-card { font-family: var(--font-mono); font-size: 9px; color: var(--c-bone); text-align: center; line-height: 1.25; }
.dt-slot .tcg-card { width: 62px; height: 87px; }
.dt-slot.filled { border-color: rgba(255,255,255,.26); }
.dt-slot.locked { opacity: .4; }
.dt-slot.security-slot { border-color: rgba(255,43,214,.45); }
.dt-slot.creature-slot { border-color: rgba(255,43,214,.5); }
.dt-slot.item-slot { border-color: rgba(255,212,58,.36); }
.dt-actions { display: flex; gap: 9px; flex-wrap: wrap; margin-bottom: 14px; }
.dt-hint { font-family: var(--font-body); font-size: 13px; color: var(--c-ash); line-height: 1.5; }

/* ── BARS ──────────────────────────────────────────────────────────────── */
.tcg-bar { position: relative; height: 14px; background: rgba(0,0,0,.6); border-radius: 7px; overflow: hidden; }
.tcg-bar.big { height: 24px; border-radius: var(--r-in); }
.tcg-bar i { display: block; height: 100%; transition: width .3s; }
.tcg-bar.hp i { background: linear-gradient(90deg, #7a0020, var(--s-red)); box-shadow: 0 0 12px rgba(255,0,64,.5); }   /* T17: red, not magenta */
.tcg-bar.ap i { background: linear-gradient(90deg, #0b5f74, var(--s-accent)); box-shadow: 0 0 12px rgba(0,217,255,.5); }
.tcg-bar span { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-mono); font-size: 9.5px; color: var(--c-bone); text-shadow: 0 0 5px #000; }
/* T17: under a card the bar is a thin strip like the outpost's 3px AP
   line, and the numbers live on the card's hover plate instead — the
   spans stay in the DOM for tests and screen readers. */
.tcg-unitstats .tcg-bar { height: 6px; border-radius: 3px; }
/* T19: an outpost's power reads at a glance — what it generates stands
   loud in gold, what its fitted gear draws hangs beside it in red. */
.tcg-powerline { display: inline-flex; gap: 9px; align-items: baseline; }
.tcg-powerline em { font-style: normal; font-family: var(--font-mono); }
.tcg-powerline .gen { font-size: 13.5px; font-weight: 700; color: var(--s-gold); text-shadow: 0 0 10px rgba(255,215,0,.35); }
.tcg-powerline .gen.settling { opacity: .55; text-shadow: none; }
.tcg-powerline .use { font-size: 10.5px; color: var(--s-red); }
.tcg-unitstats .tcg-bar span { display: none; }
.tcg-bar.big span { font-size: 12px; }
/* T17: the site's tag — angular clip-chip, command voice, colour ring
   without the glow. Pills left with the magenta. Green means GO. */
.tcg-status {
    font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase;
    font-size: 8px; letter-spacing: .12em; padding: 4px 9px; white-space: nowrap;
    color: currentColor; background: rgba(6,1,18,.92);
    box-shadow: 0 0 0 1px currentColor;
    clip-path: polygon(5px 0, 100% 0, 100% calc(100% - 5px), calc(100% - 5px) 100%, 0 100%, 0 5px);
}
.tcg-status.ready { color: var(--s-saga); }
.tcg-status.exposed { color: var(--s-orange); }
.tcg-status.engaged { color: var(--s-gold); }
.tcg-status.spent { color: var(--s-ash); }
.tcg-status.garrisoned { color: var(--s-accent); }
.tcg-status.down { color: var(--s-red); }

/* ══ THE FIELD ═════════════════════════════════════════════════════════ */
/* The exchange is where the dice land and the fight is read; the market is a
   list of four cards. It was the other way round. Two thirds / one third. */
.field-middle { display: grid; gap: var(--gap); grid-template-columns: minmax(0,2fr) minmax(0,1fr); }
.mat-bay.narrow, .mat-bay.roll { min-height: 280px; }
.tcg-carousel { display: flex; align-items: center; gap: 18px; padding: 16px 22px; }
.tcg-carousel-arrow { width: 46px; height: 46px; border-radius: var(--r-in); font-size: 15px; cursor: pointer; color: var(--c-bone); background: rgba(32,12,78,.9); border: 1px solid var(--c-line); }
.tcg-carousel-arrow:hover:not(:disabled) { color: var(--c-cyan); box-shadow: 0 0 22px rgba(60,232,255,.5); }
.tcg-carousel-arrow:disabled { opacity: .28; cursor: not-allowed; }
.tcg-carousel-face { flex: 1; text-align: center; }
.tcg-carousel-face b { font-family: var(--font-display); font-size: 18px; letter-spacing: 3px; }
.tcg-carousel-face span { display: block; font-family: var(--font-mono); font-size: 11px; color: var(--c-ash); margin-top: 5px; }
.tcg-lock { display: inline-block; margin-top: 6px; font-style: normal; font-family: var(--font-display); font-size: 8px; letter-spacing: 2px; color: var(--c-gold); }

.tcg-housepanel { display: flex; gap: 14px; margin-bottom: 18px; }
.tcg-housepanel .tcg-flag.banner { width: 116px; height: 168px; margin: 0; }
.tcg-housepanel-body { flex: 1; min-width: 0; }
.tcg-housepanel-body h5 { margin: 0 0 10px; color: var(--c-bone); }
.tcg-housefaces { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 12px; }
.tcg-housefac { width: 46px; height: 58px; border-radius: var(--r-in); background: #12042a center/cover no-repeat; box-shadow: 0 0 0 1px rgba(255,255,255,.16); }
.tcg-housefac.down { filter: grayscale(1) brightness(.45); }

.tcg-target { position: relative; width: var(--card-w); padding: 15px; cursor: pointer; border-radius: var(--r-in); background: rgba(11,4,38,.75); box-shadow: 0 12px 28px rgba(0,0,0,.6); transition: .18s; }
.tcg-target:hover { transform: translateY(-7px); box-shadow: 0 22px 40px rgba(0,0,0,.72), 0 0 28px rgba(60,232,255,.42); }
.tcg-target.selected { box-shadow: 0 0 0 3px var(--c-cyan), 0 0 38px rgba(60,232,255,.55); }
.tcg-outpost-tier { position: absolute; top: 7px; right: 7px; width: 26px; height: 26px; display: grid; place-items: center; font-family: var(--font-display); font-size: 12px; font-weight: 900; color: #06010f; background: var(--c-gold); box-shadow: 0 0 16px rgba(255,212,58,.7); clip-path: polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%); }
.tcg-outpost-name { font-family: var(--font-display); font-size: 10.5px; }
.tcg-outpost-meta { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); margin-top: 6px; }
.tcg-mystery { display: flex; gap: 5px; margin-top: 12px; flex-wrap: wrap; }
.tcg-mystery .myst { width: 22px; height: 30px; border-radius: 4px; background: #14062c center/cover no-repeat; box-shadow: 0 0 0 1px rgba(255,255,255,.2); }
.tcg-mystery .myst.empty { opacity: .22; background: none; }

.tcg-duel { display: grid; grid-template-columns: 1fr auto 1fr; gap: 18px; align-items: center; }
.tcg-fighter { text-align: center; }
.tcg-fighter-art { width: 108px; height: 138px; margin: 0 auto 10px; border-radius: var(--r-in); background: #12042a center/cover no-repeat; box-shadow: 0 12px 30px rgba(0,0,0,.7); }
.tcg-fighter b { font-family: var(--font-display); font-size: 11px; letter-spacing: 1px; }
.tcg-fighter-stats { display: flex; gap: 10px; justify-content: center; margin-top: 6px; font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); }
.tcg-fighter.revealing { animation: reveal .42s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes reveal { from { transform: rotateY(90deg) scale(.9); opacity: 0; } to { transform: none; opacity: 1; } }
.tcg-dice-stage { display: flex; align-items: center; gap: 10px; }
/* T19: the pre-roll face — the die each side brings, quiet until thrown. */
.tcg-orb-roll.pre i { opacity: .45; }
.tcg-orb-roll.pre b { font-size: 12.5px; letter-spacing: .04em; color: var(--s-bone); opacity: .9; }
.tcg-die { width: 66px; height: 66px; border-radius: var(--r-in); display: grid; place-items: center; background: rgba(11,4,38,.94); box-shadow: inset 0 0 0 2px rgba(255,255,255,.2); font-family: var(--font-display); font-size: 24px; font-weight: 900; }
.tcg-die em { display: block; font-style: normal; font-family: var(--font-mono); font-size: 8px; color: var(--c-ash); }
.tcg-die.won { color: var(--c-acid); box-shadow: inset 0 0 0 2px var(--c-acid), 0 0 34px rgba(255,212,58,.6); }
.tcg-die.bonus { color: var(--c-gold); box-shadow: inset 0 0 0 2px var(--c-gold), 0 0 34px rgba(255,212,58,.6); width: auto; padding: 0 20px; }
.tcg-dice-stage.rolling .tcg-die { animation: dieShake .13s linear infinite; }
@keyframes dieShake { 0%,100% { transform: none; } 25% { transform: translate(-2px,1px) rotate(-3deg); } 50% { transform: translate(2px,-1px) rotate(3deg); } 75% { transform: translate(-1px,-2px) rotate(-2deg); } }
.tcg-die-vs { font-family: var(--font-display); font-size: 11px; color: var(--c-ash); letter-spacing: 2px; }
.tcg-queue-note { text-align: center; margin-top: 14px; font-family: var(--font-mono); font-size: 11px; color: var(--c-ash); }
.tcg-roll-idle { text-align: center; padding: 54px 10px; color: var(--c-ash); }
.tcg-roll-idle h4 { font-family: var(--font-display); font-size: 12px; letter-spacing: 3px; color: rgba(255,255,255,.24); margin-bottom: 10px; }
.tcg-trays { display: flex; gap: 30px; flex-wrap: wrap; margin-top: 18px; }
.tcg-tray { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; }
.tcg-tray h5 { width: 100%; margin: 0 0 4px; }
.tcg-insp-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.tcg-insp-title { flex: 1; min-width: 0; }
.tcg-insp-title h4 { font-family: var(--font-display); font-size: 14px; letter-spacing: 2px; color: var(--c-bone); }
.tcg-insp-title span { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); }
.tcg-insp-stats { display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 14px; }
.tcg-insp-stats span { display: block; font-family: var(--font-display); font-size: 8px; letter-spacing: 1.4px; color: var(--c-ash); }
.tcg-insp-stats b { font-family: var(--font-mono); font-size: 18px; color: var(--c-bone); }
.tcg-insp-sub { font-family: var(--font-mono); font-size: 11px; color: var(--c-ash); margin-bottom: 14px; }
.tcg-insp-lock { font-family: var(--font-mono); font-size: 11px; color: var(--c-amber); background: rgba(255,212,58,.12); border-radius: var(--r-in); padding: 10px 13px; margin: 12px 0; }
.tcg-insp-perk, .tcg-insp-garrison, .tcg-mystery-note { font-family: var(--font-body); font-size: 13px; color: var(--c-ash); border-left: 3px solid var(--c-violet); padding-left: 12px; margin: 12px 0; line-height: 1.45; }
.tcg-insp-actions { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 16px; }
.tcg-inspector-idle { padding: 36px 8px; text-align: center; color: var(--c-ash); }
.tcg-inspector-idle h4 { font-family: var(--font-display); font-size: 11px; letter-spacing: 3px; color: rgba(255,255,255,.22); margin-bottom: 9px; }

.tcg-pick-list { display: flex; flex-direction: column; gap: 9px; margin: 16px 0; }
.tcg-pick { display: flex; gap: 12px; align-items: center; padding: 11px; border-radius: var(--r-in); background: rgba(11,4,38,.7); border: 1px solid rgba(255,255,255,.12); }
.tcg-pick.as-primary { border-color: var(--c-cyan); box-shadow: 0 0 24px rgba(60,232,255,.3); }
.tcg-pick.as-support { border-color: var(--c-gold); box-shadow: 0 0 24px rgba(255,212,58,.3); }
.tcg-pick-art { width: 56px; height: 70px; border-radius: var(--r-in); background: #12042a center/cover no-repeat; }
.tcg-pick-body { flex: 1; min-width: 0; }
.tcg-pick-body b { display: block; font-family: var(--font-display); font-size: 11px; }
.tcg-pick-body span { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); }
.tcg-pick-btns { display: flex; flex-direction: column; gap: 5px; }
.tcg-cost-ticker { font-family: var(--font-mono); font-size: 12px; color: var(--c-ash); text-align: center; padding: 13px; border-radius: var(--r-in); border: 1px solid rgba(255,255,255,.14); }
.tcg-cost-ticker b { color: var(--c-acid); font-size: 16px; }
.tcg-cost-ticker .short { display: block; color: var(--c-danger); font-style: normal; margin-top: 5px; }
.tcg-pile { display: flex; flex-direction: column; width: var(--card-w); }
.tcg-tablecard.pile { cursor: pointer; }

/* ── COMMS ─────────────────────────────────────────────────────────────── */
#tcg-comms { position: fixed; top: 72px; left: 50%; transform: translateX(-50%); z-index: 180; width: min(580px, 94vw); display: flex; flex-direction: column; gap: 9px; }
.tcg-comms-panel { --house: var(--c-cyan); border-radius: var(--r-in); background: linear-gradient(140deg, rgba(21,8,56,.98), rgba(6,2,26,.98)); box-shadow: 0 0 0 2px color-mix(in srgb, var(--house) 70%, transparent), 0 20px 44px rgba(0,0,0,.75), 0 0 44px color-mix(in srgb, var(--house) 34%, transparent); opacity: 0; transform: translateY(-18px); transition: .34s cubic-bezier(.2,.9,.3,1.2); cursor: pointer; }
.tcg-comms-panel.open { opacity: 1; transform: none; }
.tcg-comms-head { display: flex; align-items: center; gap: 9px; padding: 9px 15px; border-radius: var(--r-in) var(--r-in) 0 0; background: color-mix(in srgb, var(--house) 18%, transparent); font-family: var(--font-display); font-size: 8px; letter-spacing: 3px; color: var(--house); }
.tcg-comms-head em { margin-left: auto; font-style: normal; color: var(--c-ash); letter-spacing: 1.5px; }
.tcg-comms-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--house); box-shadow: 0 0 10px var(--house); animation: commsDot 1.1s ease-in-out infinite; }
@keyframes commsDot { 50% { opacity: .25; } }
.tcg-comms-body { display: flex; gap: 14px; align-items: center; padding: 14px 15px; }
.tcg-comms-face { width: 62px; height: 78px; flex: 0 0 auto; border-radius: var(--r-in); background: #12042a center/cover no-repeat; box-shadow: 0 0 0 1px color-mix(in srgb, var(--house) 60%, transparent); }
.tcg-comms-face.target { filter: grayscale(.6) brightness(.75); }
.tcg-comms-text { flex: 1; min-width: 0; }
.tcg-comms-text b { font-family: var(--font-display); font-size: 11px; letter-spacing: 1.5px; color: var(--house); }
.tcg-comms-text p { font-family: var(--font-body); font-size: 16px; color: var(--c-bone); margin-top: 6px; line-height: 1.35; }

/* ── NOTIFICATIONS — floating in the margin beside the mat ─────────────── */
#tcg-toasts { position: fixed; top: 84px; right: 20px; z-index: 300; width: min(320px, 88vw); display: flex; flex-direction: column; gap: 10px; pointer-events: none; }
body.detail-open #tcg-toasts { right: calc(var(--detail-w) + 20px); }
.tcg-toast {
    padding: 14px 18px; border-radius: var(--r-in); pointer-events: auto;
    background: linear-gradient(140deg, rgba(21,8,56,.98), rgba(8,3,28,.98));
    box-shadow: 0 0 0 2px var(--c-cyan), 0 16px 36px rgba(0,0,0,.7), 0 0 34px rgba(60,232,255,.28);
    font-family: var(--font-body); font-size: 14px; line-height: 1.4; color: var(--c-bone);
    opacity: 0; transform: translateX(24px); transition: .3s;
}
.tcg-toast.show { opacity: 1; transform: none; }
.tcg-toast.bad { box-shadow: 0 0 0 2px var(--s-red), 0 16px 36px rgba(0,0,0,.7), 0 0 34px rgba(255,0,64,.3); color: var(--s-red); }
.tcg-toast.good { box-shadow: 0 0 0 2px var(--s-gold), 0 16px 36px rgba(0,0,0,.7), 0 0 34px rgba(255,215,0,.3); color: var(--s-gold); }

/* ── MODALS · LOG ──────────────────────────────────────────────────────── */
.tcg-modal-back { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; background: rgba(6,1,18,.84); padding: 20px; }
.tcg-modal {
    /* T16: the site's clip-panel — 14px cut corners, one line border.
       The old drop shadow went with the radius: box-shadow outside a
       clipped shape never renders; the scrim does the separating. No
       notch-edge strokes here, deliberately: the modal is its own
       scroll container, and absolutely-positioned pseudos travel with
       scrolled content — the strokes would drift on a long standings
       sheet. The site runs borderless notches too (border-transparent). */
    width: min(880px, 96vw); max-height: 92vh; overflow: auto; padding: 28px;   /* T17: was 620px — too narrow */
    background: linear-gradient(160deg, rgba(18,8,38,.99), rgba(10,1,24,.99));
    border: 1px solid var(--s-line);
    clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
}
.tcg-modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.tcg-modal-head h3 { font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase; font-size: 15px; letter-spacing: .14em; color: var(--s-accent); }
.tcg-modal-x { background: none; border: none; color: var(--s-ash); font-size: 19px; cursor: pointer; }
.tcg-modal-x:hover { color: var(--s-accent); }   /* T16: the site hovers accent, not magenta */
.tcg-modal-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.tcg-kv { display: grid; grid-template-columns: 1fr 1fr; gap: 7px 20px; margin-bottom: 12px; }
.tcg-kv div { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 11px; }
.tcg-kv span { color: var(--s-ash); }
.tcg-opp-line { display: flex; justify-content: space-between; gap: 8px; padding: 7px 0; font-family: var(--font-mono); font-size: 11px; border-bottom: 1px dotted rgba(255,255,255,.1); }
.tcg-opp-line em { font-style: normal; color: var(--s-ash); }
.tcg-opp-line.dead { opacity: .38; text-decoration: line-through; }

#tcg-log { position: fixed; right: 0; bottom: 0; width: min(340px, 92vw); z-index: 90; background: rgba(6,1,18,.96); border-top-left-radius: var(--r-in); box-shadow: 0 0 0 1px var(--s-line); }
body.detail-open #tcg-log { right: var(--detail-w); }
#tcg-log-head { padding: 10px 15px; cursor: pointer; font-family: var(--font-chrome); font-weight: 600; text-transform: uppercase; font-size: 9px; letter-spacing: .14em; color: var(--s-accent); }
#tcg-log-body { max-height: 0; overflow: hidden auto; transition: max-height .3s; }
#tcg-log.open #tcg-log-body { max-height: 42vh; }
.tcg-log-line { padding: 6px 15px; font-family: var(--font-mono); font-size: 11px; color: var(--c-ash); border-top: 1px solid rgba(255,255,255,.06); }
.tcg-log-line.damage { color: var(--c-2); }
.tcg-log-line.capture, .tcg-log-line.victory, .tcg-log-line.loot { color: var(--c-gold); }
.tcg-log-line.energy, .tcg-log-line.build { color: var(--c-acid); }
.tcg-log-line.kill, .tcg-log-line.eliminated { color: var(--c-danger); }
.tcg-log-line.sigil { color: var(--c-violet); }

.tcg-float-card { position: fixed; z-index: 250; width: 84px; height: 118px; pointer-events: none; border-radius: var(--r-in); background: #14062c center/cover no-repeat; box-shadow: 0 0 0 1px var(--c-cyan), 0 0 30px rgba(60,232,255,.5); transition: transform .6s cubic-bezier(.2,.8,.3,1), opacity .6s; }

/* ── SHARED ────────────────────────────────────────────────────────────── */
.tcg-empty { font-family: var(--font-mono); font-size: 11px; color: var(--c-ash); opacity: .6; padding: 20px 4px; }
.tcg-empty.small { padding: 8px 2px; font-size: 10px; }
.tcg-hint { font-size: 13.5px; color: var(--c-ash); margin: 12px 0 0; line-height: 1.5; }
.tcg-warn { font-size: 14px; color: var(--c-amber); margin-bottom: 14px; }
.tcg-check { display: block; margin-top: 12px; font-size: 12px; color: var(--c-ash); }
.tcg-card-desc { font-size: 13px; color: var(--c-ash); margin-bottom: 12px; }
.tipped { cursor: help; }

/* ── RESULTS ───────────────────────────────────────────────────────────── */
#tcg-results { max-width: 820px; margin: 0 auto; text-align: center; }
.tcg-results-title { font-family: var(--font-display); font-size: 30px; letter-spacing: 8px; color: var(--c-gold); margin-bottom: 10px; text-shadow: 0 0 30px rgba(255,212,58,.55); }
.tcg-results-sub { color: var(--c-ash); margin-bottom: 30px; }
.tcg-results-table { border-radius: var(--r); border: var(--rail) solid rgba(255,215,0,.5); overflow: hidden; }   /* T17: flat — no border-image left in the sheet */
.tcg-results-row { display: grid; grid-template-columns: 38px 1fr 96px 1fr; gap: 14px; align-items: center; padding: 16px; border-bottom: 1px solid rgba(255,255,255,.09); text-align: left; }
.tcg-results-row.winner { background: rgba(255,212,58,.1); }
.tcg-results-row .rank { font-family: var(--font-display); font-size: 19px; color: var(--c-ash); }
.tcg-results-row .nm { font-family: var(--font-display); font-size: 13px; letter-spacing: 2px; }
.tcg-results-row .pts { font-family: var(--font-mono); font-size: 18px; color: var(--c-gold); }
.tcg-results-row .det { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); }

/* ── RESPONSIVE ────────────────────────────────────────────────────────── */
@media (max-width: 1500px) {
    .mat-row.dock { grid-template-columns: minmax(0,1fr) minmax(0,1fr); }
}
@media (max-width: 1200px) {
    :root { --gap: 20px; --detail-w: 340px; }
    .field-middle { grid-template-columns: 1fr; }
    .tcg-detail { top: auto; bottom: 0; left: 0; right: 0; width: 100%; max-height: 72vh; border-left: none; border-top: 1px solid var(--s-line); transform: translateY(102%); }
    body.detail-open .tcg-detail { transform: none; }
    /* T18: the sheet splits — the card art takes the left half, the stat
       boxes the right, and everything else keeps the full width. The flag
       drops under the portrait as a banner strip so the art keeps the
       column to itself. */
    .tcg-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; align-content: start; }
    .tcg-detail > * { grid-column: 1 / -1; }
    .tcg-detail .dt-hero { grid-column: 1; flex-direction: column; margin-bottom: 14px; }
    .tcg-detail .dt-stats { grid-column: 2; align-content: start; }
    .tcg-detail .dt-hero .tcg-flag.tall { width: 100%; height: 64px; }
    body.detail-open #tcg-toasts, body.detail-open #tcg-log { right: 20px; }
}
@media (max-width: 760px) {
    :root { --card-w: clamp(104px, 29vw, 138px); --gap: 15px; }
    .screen { padding: 82px 12px calc(84px + env(safe-area-inset-bottom)); }
    .mat-row, .mat-row.dock { grid-template-columns: 1fr; }
    .mat-bay { padding: 16px 14px; min-height: 0; }
    .mat-bay::before { font-size: 30px; letter-spacing: 7px; }
    .tcg-duel { grid-template-columns: 1fr; }
    .dt-grid { grid-template-columns: repeat(3, 1fr); }   /* T18: three across, like the desktop */
    .dt-stats { grid-template-columns: repeat(2, 1fr); }
    .tcg-housepanel { flex-direction: column; }
    .tcg-housepanel .tcg-flag.banner { width: 100%; height: 120px; }
    #tcg-topbar { font-size: 12px; gap: 10px; padding: 8px 13px; }   /* T17: 12px, not 10 */
    .tcg-brand img { height: 30px; }
    .tcg-seatpip em { display: none; }
    #tcg-toasts { right: 12px; left: 12px; width: auto; }
    .tcg-modal { width: calc(100vw - 20px); max-height: 92vh; padding: 20px 16px; }
}


/* ══════════════════════════════════════════════════════════════════════════
   T18 — THE GM ENGINE'S COMBAT PULSES, ON THE CARD
   -----------------------------------------------------------------------
   PORTED, NOT INVENTED — the same rule 13-elements.js lives by. The nine
   keyframes below are gm-engine/styles.css verbatim (the .fighter combat
   set: takeDamage, damageShake, and the seven element pulses). The classes
   that run them are the gm's element→class map from animation-manager.js,
   scoped to the table card; the durations in each `animation:` line are
   getAnimationDuration verbatim, and 09-fx holds the class for exactly
   that long, so the visual and the cleanup agree.

   The pulses are filter/transform work, so they ride the card art the way
   they ride the gm portrait — drop-shadow follows the card silhouette,
   no border dependence. --primary is the one gm variable takeDamage
   reads; it is given a quiet value here so the 0% frame resolves.
   ══════════════════════════════════════════════════════════════════════ */
.tcg-tablecard { --primary: rgba(255,255,255,.15); }
.tcg-tablecard.takeDamage        { animation: takeDamage .8s ease-out; }
.tcg-tablecard.fire-damage       { animation: fire-pulse 1.2s ease-out; }
.tcg-tablecard.lightning-damage  { animation: lightning-pulse 1s ease-out; }
.tcg-tablecard.void-damage       { animation: void-pulse 1.5s ease-out; }
.tcg-tablecard.aether-damage     { animation: aether-pulse 1.3s ease-out; }
.tcg-tablecard.blood-damage      { animation: blood-pulse 1.6s ease-out; }
.tcg-tablecard.chroma-damage     { animation: chroma-pulse 1.4s linear; }
.tcg-tablecard.arcana-damage     { animation: arcana-pulse 1s ease-in-out; }
.tcg-tablecard.takeDamage, .tcg-tablecard.fire-damage,
.tcg-tablecard.lightning-damage, .tcg-tablecard.void-damage,
.tcg-tablecard.aether-damage, .tcg-tablecard.blood-damage,
.tcg-tablecard.chroma-damage, .tcg-tablecard.arcana-damage {
    will-change: filter, transform; z-index: 5;
}

@keyframes takeDamage {
  0% { 
    box-shadow: 0 0 0 rgba(255, 0, 60, 0);
    border-color: var(--primary);
    background-color: transparent;
    transform: translate(0, 0) scale(1);
    filter: brightness(1);
  }
  8% { 
    box-shadow: 0 0 60px rgba(255, 255, 255, 1);
    border-color: #ffffff;
    background-color: rgba(255, 255, 255, 0.3);
    transform: translate(-6px, 3px) scale(1.08) rotate(-2deg);
    filter: brightness(1.8);
  }
  20% { 
    box-shadow: 0 0 50px rgba(255, 0, 0, 1);
    border-color: #ff0000;
    background-color: rgba(255, 0, 0, 0.4);
    transform: translate(8px, -4px) scale(1.06) rotate(3deg);
    filter: brightness(1.5) contrast(1.3);
  }
  32% { 
    box-shadow: 0 0 45px rgba(255, 255, 255, 0.9);
    border-color: #ffffff;
    background-color: rgba(255, 255, 255, 0.25);
    transform: translate(-5px, 2px) scale(1.04) rotate(-1deg);
    filter: brightness(1.6);
  }
  45% { 
    box-shadow: 0 0 40px rgba(255, 0, 60, 0.8);
    border-color: #cc0000;
    background-color: rgba(255, 0, 60, 0.3);
    transform: translate(4px, -3px) scale(1.02) rotate(1deg);
    filter: brightness(1.3) saturate(1.5);
  }
  58% { 
    box-shadow: 0 0 30px rgba(255, 255, 255, 0.6);
    border-color: #ffcccc;
    background-color: rgba(255, 255, 255, 0.15);
    transform: translate(-2px, 1px) scale(1.01) rotate(-0.5deg);
    filter: brightness(1.2);
  }
  72% { 
    box-shadow: 0 0 20px rgba(255, 0, 60, 0.4);
    border-color: #ff6666;
    background-color: rgba(255, 0, 60, 0.1);
    transform: translate(1px, -1px) scale(1.005) rotate(0.2deg);
    filter: brightness(1.1);
  }
  85% { 
    box-shadow: 0 0 10px rgba(255, 0, 60, 0.2);
    border-color: #ff9999;
    background-color: rgba(255, 0, 60, 0.05);
    transform: translate(-0.5px, 0.5px) scale(1.002) rotate(-0.1deg);
    filter: brightness(1.05);
  }
  100% { 
    box-shadow: 0 0 0 rgba(255, 0, 60, 0);
    border-color: var(--primary);
    background-color: transparent;
    transform: translate(0, 0) scale(1) rotate(0deg);
    filter: brightness(1);
  }
}

@keyframes damageShake { 0%, 100% { transform: translateX(0) rotate(-1deg); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-15px) rotate(-4deg); } 20%, 40%, 60%, 80% { transform: translateX(15px) rotate(2deg); } }

@keyframes fire-pulse {
  0% { 
    filter: drop-shadow(0 0 5px rgba(255, 69, 0, 0.5)) brightness(1) saturate(1);
    transform: scale(1);
  }
  8% { 
    filter: drop-shadow(0 0 25px rgba(255, 140, 0, 0.9)) brightness(1.4) saturate(1.3);
    transform: scale(1.02) rotate(0.5deg);
  }
  16% { 
    filter: drop-shadow(0 0 40px rgba(255, 69, 0, 1)) brightness(1.6) saturate(1.5);
    transform: scale(1.04) rotate(-0.5deg);
  }
  24% { 
    filter: drop-shadow(0 0 30px rgba(255, 140, 0, 0.8)) brightness(1.3) saturate(1.2);
    transform: scale(1.03) rotate(0.3deg);
  }
  32% { 
    filter: drop-shadow(0 0 45px rgba(255, 69, 0, 1)) brightness(1.7) saturate(1.6);
    transform: scale(1.05) rotate(-0.3deg);
  }
  40% { 
    filter: drop-shadow(0 0 35px rgba(255, 140, 0, 0.9)) brightness(1.4) saturate(1.3);
    transform: scale(1.02) rotate(0.2deg);
  }
  50% { 
    filter: drop-shadow(0 0 50px rgba(255, 69, 0, 1)) brightness(1.8) saturate(1.7);
    transform: scale(1.06) rotate(-0.2deg);
  }
  60% { 
    filter: drop-shadow(0 0 30px rgba(255, 140, 0, 0.8)) brightness(1.3) saturate(1.2);
    transform: scale(1.03) rotate(0.1deg);
  }
  70% { 
    filter: drop-shadow(0 0 25px rgba(255, 69, 0, 0.7)) brightness(1.2) saturate(1.1);
    transform: scale(1.01) rotate(-0.1deg);
  }
  80% { 
    filter: drop-shadow(0 0 20px rgba(255, 140, 0, 0.6)) brightness(1.1) saturate(1.05);
    transform: scale(1) rotate(0deg);
  }
  90% { 
    filter: drop-shadow(0 0 15px rgba(255, 69, 0, 0.4)) brightness(1.05) saturate(1.02);
    transform: scale(1) rotate(0deg);
  }
  100% { 
    filter: drop-shadow(0 0 5px rgba(255, 69, 0, 0.2)) brightness(1) saturate(1);
    transform: scale(1);
  }
}

@keyframes lightning-pulse {
  0% { 
    filter: drop-shadow(0 0 0 rgba(0, 255, 255, 0)) brightness(1);
    transform: scale(1);
  }
  3% { 
    filter: drop-shadow(0 0 50px rgba(0, 255, 255, 1)) brightness(2.2);
    transform: scale(1.08) skew(1deg);
  }
  6% { 
    filter: drop-shadow(0 0 10px rgba(0, 255, 255, 0.3)) brightness(0.9);
    transform: scale(0.98) skew(-0.5deg);
  }
  9% { 
    filter: drop-shadow(0 0 60px rgba(0, 255, 255, 1)) brightness(2.5);
    transform: scale(1.1) skew(-1deg);
  }
  12% { 
    filter: drop-shadow(0 0 5px rgba(0, 255, 255, 0.2)) brightness(0.8);
    transform: scale(0.97) skew(0.5deg);
  }
  18% { 
    filter: drop-shadow(0 0 45px rgba(0, 255, 255, 0.9)) brightness(2);
    transform: scale(1.06) skew(0.8deg);
  }
  21% { 
    filter: drop-shadow(0 0 8px rgba(0, 255, 255, 0.25)) brightness(0.85);
    transform: scale(0.99) skew(-0.3deg);
  }
  27% { 
    filter: drop-shadow(0 0 55px rgba(0, 255, 255, 1)) brightness(2.3);
    transform: scale(1.09) skew(-0.7deg);
  }
  30% { 
    filter: drop-shadow(0 0 12px rgba(0, 255, 255, 0.4)) brightness(0.9);
    transform: scale(0.98) skew(0.2deg);
  }
  36% { 
    filter: drop-shadow(0 0 40px rgba(0, 255, 255, 0.8)) brightness(1.8);
    transform: scale(1.05) skew(0.4deg);
  }
  42% { 
    filter: drop-shadow(0 0 20px rgba(0, 255, 255, 0.5)) brightness(1.2);
    transform: scale(1.02) skew(-0.2deg);
  }
  50% { 
    filter: drop-shadow(0 0 30px rgba(0, 255, 255, 0.7)) brightness(1.5);
    transform: scale(1.03) skew(0.1deg);
  }
  65% { 
    filter: drop-shadow(0 0 25px rgba(0, 255, 255, 0.6)) brightness(1.3);
    transform: scale(1.01) skew(0deg);
  }
  80% { 
    filter: drop-shadow(0 0 15px rgba(0, 255, 255, 0.4)) brightness(1.1);
    transform: scale(1) skew(0deg);
  }
  100% { 
    filter: drop-shadow(0 0 0 rgba(0, 255, 255, 0)) brightness(1);
    transform: scale(1);
  }
}

@keyframes void-pulse {
  0% { 
    filter: drop-shadow(0 0 0 rgba(75, 0, 130, 0)) blur(0px) invert(0) contrast(1);
    transform: scale(1);
  }
  20% { 
    filter: drop-shadow(0 0 30px rgba(75, 0, 130, 0.8)) blur(2px) invert(0.1) contrast(1.3);
    transform: scale(0.95) rotateX(5deg);
  }
  40% { 
    filter: drop-shadow(0 0 50px rgba(75, 0, 130, 1)) blur(3px) invert(0.2) contrast(1.5);
    transform: scale(0.9) rotateX(10deg) rotateY(3deg);
  }
  60% { 
    filter: drop-shadow(0 0 40px rgba(75, 0, 130, 0.9)) blur(2px) invert(0.15) contrast(1.4);
    transform: scale(0.92) rotateX(8deg) rotateY(-2deg);
  }
  80% { 
    filter: drop-shadow(0 0 25px rgba(75, 0, 130, 0.6)) blur(1px) invert(0.05) contrast(1.1);
    transform: scale(0.97) rotateX(3deg);
  }
  100% { 
    filter: drop-shadow(0 0 0 rgba(75, 0, 130, 0)) blur(0px) invert(0) contrast(1);
    transform: scale(1);
  }
}

@keyframes aether-pulse {
  0% { 
    filter: drop-shadow(0 0 5px rgba(64, 224, 208, 0.3)) brightness(1) saturate(1);
    transform: scale(1);
  }
  25% { 
    filter: drop-shadow(0 0 35px rgba(64, 224, 208, 0.9)) brightness(1.6) saturate(1.4);
    transform: scale(1.04);
  }
  50% { 
    filter: drop-shadow(0 0 50px rgba(64, 224, 208, 1)) brightness(1.8) saturate(1.6);
    transform: scale(1.06);
  }
  75% { 
    filter: drop-shadow(0 0 30px rgba(64, 224, 208, 0.8)) brightness(1.4) saturate(1.2);
    transform: scale(1.03);
  }
  100% { 
    filter: drop-shadow(0 0 5px rgba(64, 224, 208, 0.3)) brightness(1) saturate(1);
    transform: scale(1);
  }
}

@keyframes blood-pulse {
  0% { 
    filter: drop-shadow(0 0 5px rgba(139, 0, 0, 0.4)) brightness(1) contrast(1);
    transform: scale(1);
  }
  15% { 
    filter: drop-shadow(0 0 25px rgba(139, 0, 0, 0.8)) brightness(1.3) contrast(1.4);
    transform: scale(1.02) translateY(-1px);
  }
  30% { 
    filter: drop-shadow(0 0 40px rgba(139, 0, 0, 1)) brightness(1.5) contrast(1.6);
    transform: scale(1.04) translateY(-2px);
  }
  45% { 
    filter: drop-shadow(0 0 35px rgba(139, 0, 0, 0.9)) brightness(1.4) contrast(1.5);
    transform: scale(1.03) translateY(-1px);
  }
  60% { 
    filter: drop-shadow(0 0 30px rgba(139, 0, 0, 0.8)) brightness(1.3) contrast(1.3);
    transform: scale(1.02) translateY(0px);
  }
  75% { 
    filter: drop-shadow(0 0 20px rgba(139, 0, 0, 0.6)) brightness(1.2) contrast(1.2);
    transform: scale(1.01) translateY(0px);
  }
  100% { 
    filter: drop-shadow(0 0 5px rgba(139, 0, 0, 0.4)) brightness(1) contrast(1);
    transform: scale(1);
  }
}

@keyframes chroma-pulse {
  0% { 
    filter: drop-shadow(0 0 15px rgba(255, 0, 255, 0.9)) hue-rotate(0deg) saturate(1.5);
    transform: scale(1);
  }
  10% { 
    filter: drop-shadow(0 0 25px rgba(255, 0, 255, 1)) hue-rotate(36deg) saturate(1.6);
    transform: scale(1.02);
  }
  20% { 
    filter: drop-shadow(0 0 20px rgba(0, 255, 255, 1)) hue-rotate(72deg) saturate(1.7);
    transform: scale(1.04);
  }
  30% { 
    filter: drop-shadow(0 0 25px rgba(0, 255, 0, 1)) hue-rotate(108deg) saturate(1.6);
    transform: scale(1.03);
  }
  40% { 
    filter: drop-shadow(0 0 20px rgba(255, 255, 0, 1)) hue-rotate(144deg) saturate(1.7);
    transform: scale(1.05);
  }
  50% { 
    filter: drop-shadow(0 0 25px rgba(255, 69, 0, 1)) hue-rotate(180deg) saturate(1.8);
    transform: scale(1.06);
  }
  60% { 
    filter: drop-shadow(0 0 20px rgba(255, 0, 0, 1)) hue-rotate(216deg) saturate(1.7);
    transform: scale(1.04);
  }
  70% { 
    filter: drop-shadow(0 0 25px rgba(138, 43, 226, 1)) hue-rotate(252deg) saturate(1.6);
    transform: scale(1.03);
  }
  80% { 
    filter: drop-shadow(0 0 20px rgba(75, 0, 130, 1)) hue-rotate(288deg) saturate(1.5);
    transform: scale(1.02);
  }
  90% { 
    filter: drop-shadow(0 0 25px rgba(139, 0, 139, 1)) hue-rotate(324deg) saturate(1.6);
    transform: scale(1.01);
  }
  100% { 
    filter: drop-shadow(0 0 15px rgba(255, 0, 255, 0.9)) hue-rotate(360deg) saturate(1.5);
    transform: scale(1);
  }
}

@keyframes arcana-pulse {
  0% { 
    filter: drop-shadow(0 0 10px rgba(153, 50, 204, 0.6)) brightness(1) blur(0px);
    transform: scale(1) rotate(0deg);
  }
  25% { 
    filter: drop-shadow(0 0 30px rgba(153, 50, 204, 0.9)) brightness(1.4) blur(1px);
    transform: scale(1.03) rotate(1deg);
  }
  50% { 
    filter: drop-shadow(0 0 45px rgba(153, 50, 204, 1)) brightness(1.6) blur(2px);
    transform: scale(1.05) rotate(-1deg);
  }
  75% { 
    filter: drop-shadow(0 0 35px rgba(153, 50, 204, 0.8)) brightness(1.3) blur(1px);
    transform: scale(1.02) rotate(0.5deg);
  }
  100% { 
    filter: drop-shadow(0 0 10px rgba(153, 50, 204, 0.6)) brightness(1) blur(0px);
    transform: scale(1) rotate(0deg);
  }
}
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
    .tcg-tablecard:hover, .tcg-card:hover, .tcg-target:hover, .tcg-fan-card:hover .tcg-card { transform: none; }
}

/* ── LATE ADDITIONS ───────────────────────────────────────────────────────
   Card-type tints and the two pile faces. Kept at the end so the base rules
   above stay readable rather than growing a variant per line.
   ───────────────────────────────────────────────────────────────────────── */

/* An acolyte is a person and an outpost is a place, so they read apart at a
   glance — before you get anywhere near the name plate. */
.tcg-tablecard.acolyte { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 1px rgba(60,232,255,.24); }
.tcg-tablecard.acolyte:hover { box-shadow: 0 26px 50px rgba(0,0,0,.82), 0 0 36px rgba(60,232,255,.5); }
.tcg-tablecard.outpost { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 1px rgba(255,43,214,.3); }
.tcg-tablecard.outpost:hover { box-shadow: 0 26px 50px rgba(0,0,0,.82), 0 0 36px rgba(255,43,214,.55); }
.tcg-tablecard.spent { filter: grayscale(.6) brightness(.72); }
.tcg-tablecard.engaged { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 32px rgba(255,212,58,.55); }

/* Deck and discard are full cards standing on the table, not cropped boxes. */
.tcg-tablecard.deck { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 1px rgba(255,255,255,.16); }
.tcg-tablecard.discard { box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 1px rgba(255,212,58,.34); filter: saturate(.55) brightness(.82); }
.tcg-tablecard.discard:hover { filter: saturate(.8) brightness(1); }
body.dragging .tcg-tablecard.discard.legal { filter: none; }

.tcg-rack { position: relative; }

/* ══════════════════════════════════════════════════════════════════════════
   T6 ADDITIONS
   ══════════════════════════════════════════════════════════════════════════ */

/* ── THE DICE — an energy orb bursting in, the number at its core ───────── */
.tcg-dice-stage { display: flex; align-items: center; gap: 18px; min-height: 118px; }
.tcg-orb-roll {
    position: relative; width: 104px; height: 104px; display: grid; place-items: center;
    transform: scale(.1); opacity: 0;
    transition: transform .5s cubic-bezier(.2,1.7,.4,1), opacity .3s;
}
.tcg-orb-roll.burst { transform: scale(1); opacity: 1; }
.tcg-orb-roll i {
    position: absolute; inset: 0; background: center/contain no-repeat;
    filter: drop-shadow(0 0 22px rgba(57,255,136,.9));
    animation: orbSpin 2.6s linear infinite;
}
@keyframes orbSpin { to { transform: rotate(360deg); } }
.tcg-orb-roll b {
    position: relative; z-index: 2; font-family: var(--font-display);
    font-size: 40px; font-weight: 900; color: var(--c-bone);
    text-shadow: 0 0 14px #000, 0 0 30px rgba(57,255,136,.9);
}
/* The settle: the orb stops growing and the number stops moving at the same
   instant, so the reveal reads as the roll LANDING rather than as a fade. */
.tcg-orb-roll.settled i { animation-duration: 7s; filter: drop-shadow(0 0 14px rgba(57,255,136,.6)); }
.tcg-orb-roll.settled b { transform: scale(1.12); transition: transform .22s cubic-bezier(.2,1.8,.4,1); }
.tcg-orb-roll.won i { filter: drop-shadow(0 0 34px rgba(255,212,58,1)) hue-rotate(-58deg) saturate(1.5); }
.tcg-orb-roll.won b { color: var(--c-3); text-shadow: 0 0 16px #000, 0 0 36px rgba(255,212,58,1); }
.tcg-dice-stage.rolling .tcg-orb-roll b { opacity: .82; }

/* ── THEIR GROUND — arrows inline in the header ─────────────────────────── */
.tcg-ground-head { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; }
.tcg-arrow {
    width: 44px; height: 44px; flex: 0 0 auto; cursor: pointer; font-size: 15px;
    color: var(--c-bone); background: rgba(32,12,78,.9); border: 1px solid var(--c-line);
    border-radius: var(--r-in);
}
.tcg-arrow:hover:not(:disabled) { color: var(--c-1); box-shadow: 0 0 22px rgba(60,232,255,.5); }
.tcg-arrow:disabled { opacity: .28; cursor: not-allowed; }
.tcg-ground-name { flex: 1; min-width: 0; }
.tcg-ground-name b { font-family: var(--font-display); font-size: 17px; letter-spacing: 3px; }
.tcg-ground-name span { display: block; font-family: var(--font-mono); font-size: 11px; color: var(--c-ash); margin-top: 4px; }
.tcg-ground-name em { font-style: normal; color: var(--c-3); }
.tcg-flag.chip { width: 54px; height: 76px; flex: 0 0 auto; }
.tcg-flag.chip .tcg-flag-name { display: none; }
.tcg-unit.enemy .tcg-tablecard { cursor: default; }
.tc-edge.mystery { filter: saturate(.4) brightness(.8); }

/* ── THE EXCHANGE ──────────────────────────────────────────────────────── */
.tcg-exchange-idle { padding: 40px 12px; text-align: center; color: var(--c-ash); }
.tcg-exchange-idle h4 {
    font-family: var(--font-display); font-size: 13px; letter-spacing: 3px;
    color: var(--c-1); margin-bottom: 12px;
}
.tcg-exchange-idle p { font-size: 14px; line-height: 1.5; max-width: 44ch; margin: 0 auto 8px; }
.tcg-exchange-idle p.dim { color: var(--c-grey); font-size: 12.5px; }

/* ── THE MARKET ────────────────────────────────────────────────────────── */
.tcg-market-group { margin-bottom: 20px; }
.tcg-market-group h5 { margin: 0 0 10px; letter-spacing: 2px; }
.tcg-market-rail { display: flex; gap: 12px; flex-wrap: wrap; }
.tcg-market-card { width: calc(var(--card-w) * .62); }
.tcg-market-meta {
    display: flex; justify-content: space-between; align-items: baseline;
    margin-top: 7px; font-family: var(--font-mono); font-size: 11px;
}
.tcg-market-meta b { font-family: var(--font-display); font-size: 13px; color: var(--c-3); }
/* The odds tint themselves: gold when a deal is likely, magenta when it is a
   long shot. Reading the number is optional. */
.tcg-market-meta span {
    color: color-mix(in srgb, var(--c-3) calc(var(--pct) * 1%), var(--c-2));
}
.tcg-odds { margin: 16px 0; }
.tcg-odds-bar { height: 12px; border-radius: 6px; background: rgba(0,0,0,.6); overflow: hidden; }
.tcg-odds-bar i {
    display: block; height: 100%;
    background: linear-gradient(90deg, var(--c-2), var(--c-3));
    box-shadow: 0 0 14px rgba(255,212,58,.5);
}
.tcg-odds-read { display: flex; align-items: baseline; gap: 10px; margin-top: 9px; }
.tcg-odds-read b { font-family: var(--font-display); font-size: 22px; color: var(--c-3); }
.tcg-odds-read span { font-family: var(--font-body); font-size: 13px; color: var(--c-ash); }

/* ── LISTING A CARD ────────────────────────────────────────────────────── */
.dt-offer {
    margin-top: 18px; padding: 16px; border-radius: var(--r-in);
    background: rgba(255,212,58,.07); border: 1px solid rgba(255,212,58,.3);
}
.dt-offer > b {
    display: block; font-family: var(--font-display); font-size: 9px;
    letter-spacing: 2px; color: var(--c-3); margin-bottom: 8px;
}
.dt-offer-note { font-family: var(--font-body); font-size: 12.5px; color: var(--c-ash); line-height: 1.45; margin-bottom: 14px; }
.dt-offer-row { display: flex; align-items: center; gap: 16px; }
.dt-offer-slider { flex: 1; accent-color: var(--c-3); height: 22px; cursor: pointer; }
.dt-offer-read { text-align: right; min-width: 108px; }
.dt-offer-read .p { display: block; font-family: var(--font-display); font-size: 26px; font-weight: 900; color: var(--c-3); }
.dt-offer-read .c {
    display: block; font-family: var(--font-mono); font-size: 15px;
    color: color-mix(in srgb, var(--c-3) calc(var(--pct) * 1%), var(--c-2));
}
.dt-offer-read em { display: block; font-style: normal; font-size: 10.5px; color: var(--c-ash); margin-top: 3px; line-height: 1.35; }

.tcg-unitline.sub { font-size: 10px; color: var(--c-grey); }
.tcg-unitline.sub span { color: var(--c-grey); }

/* Field bay rails — same two-tone rule as the mat: one colour into grey.
   Their ground is magenta (a fight), the exchange cyan (your choice),
   the market gold (value), your own acolytes white (neutral, yours). */
.mat-bay.ground   { --rail-a: var(--house, rgba(255,255,255,.55)); }   /* T18: the house you face, not magenta — 10d sets --house */
.mat-bay.exchange { --rail-a: var(--c-1); min-height: 320px; }
.mat-bay.market   { --rail-a: var(--c-3); }
.mat-bay.mine     { --rail-a: #ffffff; }

/* ═══════════════════════════════════════════════════════════════════════════
   14 — ENERGY PILE, THE OFF-MAT DISCARD, AND THE PROMOTION FLASH   (T7)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The verb label belongs ON the pad it describes ─────────────────────────
   .tcg-drop had no positioning of its own, so the absolutely-positioned verb
   was resolving against the whole BAY — every pad in a bay printed its label
   in the same place. One property. */
.tcg-drop { position: relative; }

/* ── ENERGY ────────────────────────────────────────────────────────────────
   The total, laid out as the tokens you would be holding. The stack gets one
   card deeper per whole 10 points (CONFIG.ui.energyStackPer), so getting
   richer is something you SEE before you read the number. */
.mat-bay.energy.charged {
    background:
        radial-gradient(ellipse at 50% 118%, rgba(0,191,99,.26), transparent 66%),
        linear-gradient(165deg, rgba(6,40,24,.5), rgba(3,14,10,.62));
}
.mat-bay.energy:hover::after { --rail-a: #22ff92; --rail-b: rgba(0,191,99,.5); }
.mat-bay.energy:hover { box-shadow: inset 0 0 70px rgba(0,0,0,.5), 0 0 34px rgba(0,191,99,.42); }

.tcg-energy-stack { position: relative; width: var(--card-w); margin-top: 4px; }
.tcg-energy-layer {
    position: absolute; left: 0; top: 0; width: 100%; height: var(--card-h);
    border-radius: var(--r-in);
    background: linear-gradient(165deg, #084a26, #02170e);
    box-shadow: 0 0 0 1px rgba(0,191,99,.34), 0 6px 16px rgba(0,0,0,.5);
    transform: translate(calc(var(--n) * 3px), calc(var(--n) * -4px));
}
.tcg-energy-stack .tcg-tablecard.token {
    position: relative; z-index: 2; width: var(--card-w); height: var(--card-h);
    background-size: cover; background-position: center;
}
.mat-bay.energy:hover .tcg-tablecard.token { box-shadow: 0 16px 34px rgba(0,0,0,.7), 0 0 30px rgba(0,191,99,.6); }
.tc-tokenface {
    position: absolute; inset: auto 0 0 0; padding: 9px 0 11px; text-align: center;
    font-family: var(--font-display); font-size: 20px; font-weight: 900; color: #eafff3;
    text-shadow: 0 0 16px rgba(0,191,99,.95), 0 2px 5px #000;
    background: linear-gradient(180deg, transparent, rgba(2,18,10,.86));
}

/* ── OFF THE MAT ───────────────────────────────────────────────────────────
   A full-viewport layer UNDER the board. Inert until something is lifted, so
   it never intercepts an ordinary click; while dragging, anything that misses
   the mat lands on it. It answers to DROP only — clicking dead space still
   just puts the card down. */
#tcg-offmat { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
body.dragging #tcg-offmat {
    pointer-events: auto;
    background: radial-gradient(ellipse at 50% 50%, transparent 46%, rgba(255,43,94,.09) 100%);
}
.tcg-board { position: relative; z-index: 2; }

#tcg-discard-pile {
    position: fixed; left: 20px; bottom: 26px; z-index: 3; width: var(--card-w);
    opacity: .34; filter: grayscale(.7); transition: opacity .2s, filter .2s, transform .2s;
    cursor: pointer;
}
#tcg-discard-pile:hover { opacity: 1; filter: none; }
body.dragging #tcg-discard-pile { opacity: 1; filter: none; transform: scale(1.04); }
#tcg-discard-pile.legal .tcg-tablecard.discard {
    box-shadow: 0 12px 30px rgba(0,0,0,.72), 0 0 0 3px var(--c-cyan), 0 0 46px rgba(60,232,255,.7);
}
#tcg-discard-pile.illegal { opacity: .25; filter: grayscale(1) brightness(.5); }
.tcg-offmat-hint {
    margin-top: 8px; text-align: center; font-family: var(--font-display);
    font-size: 7.5px; letter-spacing: 1.6px; color: var(--c-ash);
    opacity: 0; transition: opacity .2s;
}
body.dragging .tcg-offmat-hint { opacity: 1; }

/* ── PROMOTION ─────────────────────────────────────────────────────────────
   The outpost's face IS the upgrade card for its tier, so a promotion already
   repaints it. This is the beat that says so out loud, in the new tier's own
   colour, for the chapter the works were done. */
.tcg-tablecard.outpost .tc-rank { background: var(--tier, var(--c-gold)); box-shadow: 0 0 16px var(--tier, rgba(255,212,58,.7)); }
.tcg-tablecard.outpost.promoted { animation: tierUp 1.5s ease-out 2; }
@keyframes tierUp {
    0%   { box-shadow: 0 10px 26px rgba(0,0,0,.7); }
    35%  { box-shadow: 0 10px 26px rgba(0,0,0,.7), 0 0 0 3px var(--tier), 0 0 46px var(--tier); }
    100% { box-shadow: 0 10px 26px rgba(0,0,0,.7); }
}
@media (prefers-reduced-motion: reduce) {
    .tcg-tablecard.outpost.promoted { animation: none; box-shadow: 0 0 0 3px var(--tier); }
    .tcg-spoils { animation: none; }
}

/* ── border-image squares a corner, so the last few holdouts move to a plain
      border and keep the 10px the rest of the interface now carries. ────── */
/* T16/T17: every border-image holdout is retired — the base rules carry
   flat borders outright now. */

@media (max-width: 1500px) {
    .mat-row.mid  { grid-template-columns: minmax(0,1fr) 210px 200px; }
    .mat-row.dock { grid-template-columns: minmax(0,1.5fr) minmax(0,1.5fr) 200px; }
}
@media (max-width: 1080px) {
    .mat-row, .mat-row.mid, .mat-row.dock { grid-template-columns: 1fr; }
    /* T18: sigils and energy are two narrow piles — side by side they cost
       half the scroll. The bench spans the full row above them. */
    .mat-row.mid { grid-template-columns: 1fr 1fr; }
    .mat-row.mid > .mat-bay.bench { grid-column: 1 / -1; }
    /* T18: any bay with too many cards scrolls sideways instead of
       wrapping tall — the phone rule, promoted to the whole compact band. */
    .tcg-bay-body { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 10px; }
    /* T18: the floating discard pile retires here — the inspector's
       DISCARD button and the off-mat drop layer both still work. */
    #tcg-discard-pile { display: none; }
    /* T17: CONTAINMENT. A grid item's min-width is auto, so a bay could
       size to its content and push the whole page wider than the screen —
       the bench sat at 407px on a 390px phone. Pinned here and clipped
       at the board so it can never come back. */
    .mat-bay { min-width: 0; max-width: 100%; }
    .tcg-board { overflow-x: clip; }
    /* T17: below 1080 the verb strip becomes a fixed thumb bar — END TURN
       lived inside the sideways-scrolling top bar and could sit screens
       away. The top bar goes solid here: its backdrop-filter would make
       it the containing block for the strip's position:fixed, pinning the
       bar to the top instead of the bottom. */
    #tcg-topbar { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(6,1,18,.96); }
    .screen { padding-bottom: calc(84px + env(safe-area-inset-bottom)); }
    .tcg-actions {
        position: fixed; bottom: 0; left: 0; right: 0; z-index: 70;
        flex-wrap: wrap;
        gap: 10px; padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
        background: rgba(6,1,18,.92);
        border-top: 1px solid var(--s-line);
    }
    .tcg-actions .tcg-btn { flex: 1 1 auto; padding: 13px 10px; font-size: 11px; }
    .tcg-actions .tcg-btn.ghost { flex: 0 0 auto; padding: 13px 14px; }
    #tcg-log { bottom: calc(62px + env(safe-area-inset-bottom)); }
    #tcg-toasts { top: auto; bottom: calc(70px + env(safe-area-inset-bottom)); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   15 — ELEMENTS, SHIELDS AND THE HIT THAT LANDS ON THE CARD        (T8)
   -----------------------------------------------------------------------
   Every element drives ONE custom property, --el, set inline from
   TCG.ELEMENTS (the gm engine's own colour table). That is why seventeen
   elements need one keyframe set rather than seventeen.
   ═══════════════════════════════════════════════════════════════════════════ */

.tcg-fighter { position: relative; }
.tcg-fighter-art { position: relative; overflow: visible; }

/* the strike itself — a wash of the element's colour over the card */
.fx-el::after {
    content: ''; position: absolute; inset: -4px; border-radius: var(--r-in);
    pointer-events: none; z-index: 4;
    background: radial-gradient(ellipse at 50% 45%, var(--el, #708090), transparent 68%);
    box-shadow: 0 0 40px var(--el, #708090), inset 0 0 30px var(--el, #708090);
    animation: elHit var(--burst, .72s) ease-out forwards;
}
@keyframes elHit {
    0%   { opacity: 0; transform: scale(.82); }
    22%  { opacity: .92; transform: scale(1.04); }
    100% { opacity: 0; transform: scale(1.14); }
}
.fx-shake { animation: elShake .38s cubic-bezier(.36,.07,.19,.97); }
@keyframes elShake {
    10%, 90% { transform: translateX(-2px); }
    20%, 80% { transform: translateX(4px); }
    30%, 50%, 70% { transform: translateX(-7px); }
    40%, 60% { transform: translateX(7px); }
}
/* an element that did nothing washes over and fades — no shake, no bite */
.fx-nothing::after { animation-duration: 1s; opacity: .5; box-shadow: none; }

.fx-stamp {
    position: absolute; left: 50%; top: 42%; z-index: 6; transform: translate(-50%, -50%);
    padding: 5px 11px; border-radius: var(--r-in); white-space: nowrap; pointer-events: none;
    font-family: var(--font-display); font-size: 12px; font-weight: 900; letter-spacing: 1px;
    color: #fff; background: rgba(6,2,26,.82);
    text-shadow: 0 0 12px var(--el, #708090), 0 2px 4px #000;
    box-shadow: 0 0 22px var(--el, #708090);
    animation: stampRise 1s ease-out forwards;
}
.fx-stamp.blocked { color: var(--c-cyan); }
.fx-stamp.immune  { color: var(--c-ash); box-shadow: none; }
@keyframes stampRise {
    0%   { opacity: 0; transform: translate(-50%, -30%) scale(.7); }
    18%  { opacity: 1; transform: translate(-50%, -55%) scale(1.06); }
    72%  { opacity: 1; transform: translate(-50%, -68%) scale(1); }
    100% { opacity: 0; transform: translate(-50%, -86%) scale(.96); }
}

/* the shield taking the hit instead — a hex ring, gm's own shield read */
.fx-shield {
    position: absolute; inset: -8px; z-index: 5; pointer-events: none;
    border: 3px solid var(--el, #3ce8ff);
    clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
    box-shadow: 0 0 30px var(--el, #3ce8ff), inset 0 0 26px var(--el, #3ce8ff);
    animation: shieldFlare .62s ease-out forwards;
}
@keyframes shieldFlare {
    0%   { opacity: 0; transform: scale(1.22); }
    30%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(.94); }
}

/* standing read-outs on the fighter card */
.tcg-shieldchip {
    position: absolute; top: 7px; left: 7px; z-index: 3; padding: 3px 8px;
    border-radius: 999px; font-family: var(--font-mono); font-size: 9px;
    color: var(--el, #3ce8ff); background: rgba(6,2,26,.8);
    box-shadow: 0 0 0 1px var(--el, #3ce8ff), 0 0 14px color-mix(in srgb, var(--el, #3ce8ff) 55%, transparent);
}
.tcg-elchip {
    color: var(--el, #708090); font-family: var(--font-mono); font-size: 9px;
    text-shadow: 0 0 10px var(--el, #708090);
}

/* GARRISON — leads the outpost boxes, with a face on it */
.dt-slot.garrison-slot {
    box-shadow: inset 0 0 0 2px var(--c-gold), 0 0 22px rgba(255,212,58,.28);
    cursor: pointer;
}
.dt-slot-art {
    width: 100%; aspect-ratio: 1; border-radius: var(--r-in); margin: 6px 0 5px;
    background: center/cover no-repeat rgba(11,4,38,.6);
}
.dt-slot-name { display: block; font-family: var(--font-display); font-size: 9.5px; color: var(--c-bone); }
.dt-slot-sub  { display: block; font-family: var(--font-mono); font-size: 8.5px; color: var(--c-ash); margin-top: 3px; }

/* STATION EQUIPMENT shop + queued-offer note */
.dt-shop { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.tcg-btn.dim { opacity: .45; }
.tcg-offer-queue { font-family: var(--font-mono); font-size: 10px; color: var(--c-gold); margin-top: 10px; }

/* who wants to deal — a badge on the opponent you are not looking at */
.tcg-offerbadge {
    display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px;
    margin-left: 8px; border-radius: 999px; background: var(--c-gold); color: #06010f;
    font-family: var(--font-display); font-size: 9px; font-weight: 900;
    box-shadow: 0 0 14px rgba(255,212,58,.8);
}

@media (prefers-reduced-motion: reduce) {
    .fx-el::after, .fx-shake, .fx-shield { animation: none; }
    .fx-stamp { animation: none; opacity: 1; transform: translate(-50%, -60%); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   16 — DEFENCE: THE LADDER YOUR OUTPOST ANSWERS WITH               (T9)
   ═══════════════════════════════════════════════════════════════════════════ */

.mat-bay.defending { --rail-a: var(--c-2); --rail-b: rgba(150,140,168,.28); min-height: 70vh; }

.tcg-def-head { display: flex; align-items: center; gap: 18px; margin-bottom: 20px; }
.tcg-def-title { flex: 1; min-width: 0; }
.tcg-def-title h4 {
    font-family: var(--font-display); font-size: 15px; letter-spacing: 2px;
    color: var(--c-2); margin-bottom: 5px;
}
.tcg-def-title span { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); }

/* THE LINE — one rung per defender, in the order they answer */
.tcg-ladder {
    display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-start;
    margin-bottom: 22px;
}
.tcg-rung {
    position: relative; width: 152px; padding: 12px; border-radius: var(--r-in);
    background: linear-gradient(165deg, rgba(21,8,56,.6), rgba(6,2,26,.7));
    transition: .2s;
}
.tcg-rung-tag {
    display: block; font-family: var(--font-display); font-size: 7.5px;
    letter-spacing: 1.6px; color: var(--c-ash); margin-bottom: 7px;
}
.tcg-rung-art {
    width: 100%; aspect-ratio: 1; border-radius: var(--r-in); margin-bottom: 8px;
    background: center/cover no-repeat rgba(11,4,38,.6);
}
.tcg-rung b {
    display: block; font-family: var(--font-display); font-size: 9.5px;
    color: var(--c-bone); margin-bottom: 7px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tcg-rung-state {
    display: block; margin-top: 7px; text-align: center;
    font-family: var(--font-mono); font-size: 8.5px; letter-spacing: 1px; color: var(--c-ash);
}

/* the one currently holding is the only thing lit */
.tcg-rung.holding {
    box-shadow: 0 0 0 2px var(--c-cyan), 0 0 34px rgba(60,232,255,.35);
    transform: translateY(-4px);
}
.tcg-rung.holding .tcg-rung-state { color: var(--c-cyan); }
.tcg-rung.fallen { opacity: .38; filter: grayscale(.85); }
.tcg-rung.fallen .tcg-rung-state { color: var(--c-2); }
.tcg-rung.ready .tcg-rung-art { filter: brightness(.7); }

/* the rungs read as a queue, so join them up */
.tcg-rung + .tcg-rung::before {
    content: ''; position: absolute; left: -14px; top: 50%; width: 14px; height: 2px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.22));
}

@media (max-width: 900px) {
    .tcg-rung { width: calc(50% - 7px); }
    .tcg-rung + .tcg-rung::before { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   17 — EXPOSED ACOLYTES AND THE AMBUSH                             (T10)
   ═══════════════════════════════════════════════════════════════════════════ */

/* who has left somebody standing — visible without cycling the carousel */
.tcg-exposed-marks { display: flex; gap: 8px; flex-wrap: wrap; margin-left: 14px; }
.tcg-exposed-pip {
    display: flex; align-items: center; gap: 7px; padding: 5px 11px; cursor: pointer;
    border: none; border-radius: 999px; background: rgba(255,43,94,.16);
    box-shadow: 0 0 0 1px rgba(255,43,94,.6);
    font-family: var(--font-display); font-size: 8px; letter-spacing: 1.2px; color: var(--c-2);
}
.tcg-exposed-pip b { font-size: 10px; }
.tcg-exposed-pip.here { background: rgba(255,43,94,.3); box-shadow: 0 0 0 2px var(--c-2), 0 0 18px rgba(255,43,94,.5); }
.tcg-exposed-pip:hover { filter: brightness(1.25); }

/* the band that separates a target from somebody safe on a bench */
.tcg-exposed-band {
    width: 100%; padding: 12px 16px; margin-bottom: 4px; border-radius: var(--r-in);
    background: linear-gradient(100deg, rgba(255,43,94,.2), rgba(255,43,94,.05));
    box-shadow: inset 0 0 0 1px rgba(255,43,94,.45);
}
.tcg-exposed-band b {
    display: block; font-family: var(--font-display); font-size: 10px;
    letter-spacing: 2px; color: var(--c-2); margin-bottom: 4px;
}
.tcg-exposed-band span { font-family: var(--font-mono); font-size: 10px; color: var(--c-ash); }
.tcg-group-rule {
    width: 100%; margin: 10px 0 2px; display: flex; align-items: center; gap: 12px;
    font-family: var(--font-display); font-size: 8px; letter-spacing: 2px; color: var(--c-ash);
}
.tcg-group-rule::after { content: ''; flex: 1; height: 1px; background: rgba(255,255,255,.14); }

/* a card you can actually go in on */
.tcg-tablecard.ambushable { cursor: crosshair; box-shadow: 0 10px 26px rgba(0,0,0,.7), 0 0 0 2px var(--c-2), 0 0 30px rgba(255,43,94,.45); }
.tcg-tablecard.ambushable:hover { box-shadow: 0 22px 44px rgba(0,0,0,.8), 0 0 0 3px var(--c-2), 0 0 52px rgba(255,43,94,.75); }
.tcg-unit.exposed-target { animation: exposedPulse 2.4s ease-in-out infinite; }
@keyframes exposedPulse { 50% { transform: translateY(-3px); } }

/* who goes in */
.tcg-pickrow { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.tcg-pick-art { width: 46px; height: 46px; flex: 0 0 auto; border-radius: var(--r-in); background: center/cover no-repeat rgba(11,4,38,.6); }
.tcg-pick-body { min-width: 0; }
.tcg-pick-body b { display: block; font-family: var(--font-display); font-size: 10px; color: var(--c-bone); }
.tcg-pick-body span { font-family: var(--font-mono); font-size: 9.5px; color: var(--c-ash); }
.tcg-pick { cursor: pointer; transition: .15s; }
.tcg-pick:hover { box-shadow: 0 0 0 2px var(--c-cyan); }
.tcg-pick.dim { opacity: .4; cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) { .tcg-unit.exposed-target { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════════
   18 — WARDS, THE STATION, PROJECTED INCOME                        (T11)
   ═══════════════════════════════════════════════════════════════════════════ */

/* what lands next round, beside what you hold now */
.tcg-projected {
    /* T16: income is GROWTH — the site's saga green. Orange moved to the
       attention job (the blocked nag). */
    margin-left: 9px; font-style: normal; font-family: var(--font-mono);
    font-size: 10px; color: var(--s-saga); text-shadow: 0 0 10px rgba(55,255,139,.4);
}

/* a card you can play mid-fight */
.tcg-btn.ward {
    background: linear-gradient(150deg, #00FF7F, #00bf63); color: #04120a;
    border-color: transparent;   /* T16: solid chip — no line border on a coloured fill */
}
.tcg-btn.ward:hover { filter: brightness(1.12); }

/* the station standing in as the last defender */
.tcg-rung.station .tcg-rung-art,
.tcg-fighter.station .tcg-fighter-art { background-size: cover; }
.tcg-rung.station { box-shadow: inset 0 0 0 1px rgba(255,212,58,.4); }

/* sigils hovered pull forward whole, like the hand fan */
.tcg-sigil-card:hover { z-index: 60; transform: translateX(14px) scale(1.04); }

/* ═══════════════════════════════════════════════════════════════════════════
   19 — MATCHED KIT, TIGHTER SLOTS, EXPOSURE ON THE LINE             (T12)
   ═══════════════════════════════════════════════════════════════════════════ */

/* A SLOT IS A CARD. The frame, the padding and the second name are gone. */
.dt-slot {
    position: relative; padding: 0; background: none; box-shadow: none;
}
.dt-slot .tcg-card { width: 100%; height: auto; aspect-ratio: 5 / 7; }
.dt-slot-label {
    display: block; margin-bottom: 5px; font-family: var(--font-display);
    font-size: 7.5px; letter-spacing: 1.6px; color: var(--c-ash);
}
.dt-slot:not(.filled) {
    min-height: 120px; border-radius: var(--r-in);
    background: rgba(11,4,38,.5); box-shadow: inset 0 0 26px rgba(0,0,0,.45);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.dt-slot.locked { opacity: .42; }

/* THE MATCH, in gold — on the sigil and on the piece it answered */
.dt-slot.matched .tcg-card,
.dt-slot.matched.filled {
    box-shadow: 0 0 0 2px var(--c-gold), 0 0 26px rgba(255,212,58,.55);
    border-radius: var(--r-in);
}
.dt-slot.matched .dt-slot-label { color: var(--c-gold); }

/* exposure travels with the card now, not a bay of its own */
.tc-exposed {
    position: absolute; left: 0; right: 0; top: 38%; z-index: 4; text-align: center;
    padding: 4px 0; font-family: var(--font-display); font-size: 8px; letter-spacing: 1.6px;
    color: #fff; background: rgba(255,43,94,.85);
    text-shadow: 0 1px 3px #000; pointer-events: none;
}

/* the turn cannot end while cards are loose */
.tcg-btn.blocked {
    /* T16: orange is ATTENTION — gold stays value-only. The nag pulse is
       inset now; the old outer pulse was cropped by the clip-path. */
    background: var(--s-orange); border-color: transparent; color: var(--s-void);
    animation: poolNag 2.2s ease-in-out infinite;
}
@keyframes poolNag { 50% { box-shadow: inset 0 0 0 1px rgba(255,140,66,.85), inset 0 0 22px rgba(255,140,66,.45); } }

@media (prefers-reduced-motion: reduce) {
    .tcg-btn.blocked { animation: none; }
    .tcg-rack:hover .tcg-sigil-card { top: calc(var(--n) * 58px); }
}

/* =============================================================================
   SECTION 17 — T13
   Extraction picker · station ladder · mercenaries · the score sheet
   ============================================================================= */

/* ── CREATURE NUMBERS ON A BARE FACE ──────────────────────────────────────
   Every other card on the mat reads from its art and its plate. A creature is
   the exception because its DAM is DERIVED — there is no printed card to look
   it up on, so the face has to carry it. */
.tcg-card-cstats {
    position: absolute; top: 6px; right: 6px; z-index: 3;
    display: flex; flex-direction: column; gap: 3px; align-items: flex-end;
    font-family: var(--font-mono); font-size: 9px; line-height: 1;
    text-shadow: 0 1px 4px #000;
}
.tcg-card-cstats span {
    display: flex; align-items: baseline; gap: 3px;
    padding: 2px 5px; border-radius: 3px; background: rgba(6,8,14,.72);
}
.tcg-card-cstats i { font-style: normal; font-size: 6.5px; opacity: .62; letter-spacing: .5px; }
.tcg-card-cstats .ap { color: var(--c-cyan); }
.tcg-card-cstats .dam { color: var(--c-danger); }
.tcg-card.small .tcg-card-cstats { font-size: 8px; }
/* a derived number is dimmer than a printed one — it is the engine's guess */
.tcg-card-stats .dam.derived { opacity: .72; }

/* ── THE EXTRACTION PICKER ────────────────────────────────────────────────
   One row per body in the field, each with its own price. The sum is the whole
   point of the dialog, so it is the biggest thing in it. */
.tcg-extract-list { display: flex; flex-direction: column; gap: 6px; margin: 14px 0 10px; }
.tcg-extract-row {
    display: grid; grid-template-columns: 26px 46px 1fr auto; gap: 12px; align-items: center;
    padding: 8px 12px; cursor: pointer; text-align: left;
    background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.07);
    border-radius: var(--r-in); transition: background .16s, border-color .16s;
}
.tcg-extract-row:hover { background: rgba(255,255,255,.06); }
.tcg-extract-row.on { border-color: var(--c-cyan); background: rgba(60,232,255,.09); }
.tcg-extract-box {
    width: 20px; height: 20px; display: grid; place-items: center;
    border: 1px solid rgba(255,255,255,.28); border-radius: 4px;
    font-size: 12px; color: var(--c-void);
}
.tcg-extract-row.on .tcg-extract-box { background: var(--c-cyan); border-color: var(--c-cyan); }
.tcg-extract-art i {
    display: block; width: 46px; aspect-ratio: 5/7; border-radius: 4px;
    background-size: cover; background-position: center top;
}
.tcg-extract-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tcg-extract-who b { font-family: var(--font-display); font-size: 11px; letter-spacing: 1.2px; }
.tcg-extract-who span { font-size: 10px; color: var(--c-ash); }
.tcg-extract-who em { font-family: var(--font-mono); font-size: 9px; color: var(--c-ash); opacity: .8; font-style: normal; }
.tcg-extract-cost { font-family: var(--font-mono); font-size: 15px; color: var(--c-gold); white-space: nowrap; }
.tcg-extract-cost.free { color: var(--c-cyan); font-size: 11px; letter-spacing: 1px; }

.tcg-extract-foot {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 10px 12px; border-top: 1px solid rgba(255,255,255,.09);
}
.tcg-extract-sum { font-family: var(--font-mono); font-size: 22px; color: var(--c-gold); }
.tcg-extract-sum.over { color: var(--c-danger); }
.tcg-extract-of { font-size: 10px; color: var(--c-ash); }
.tcg-extract-warn { font-size: 10px; color: var(--c-danger); flex-basis: 100%; }

/* ── THE STATION LADDER ───────────────────────────────────────────────────
   Locked rungs are SHOWN, not hidden — seeing the War Droid Bay greyed out
   with FORTRESS on it is the argument for paying 10 to promote. */
.dt-ladder { margin: 8px 0 2px; }
.dt-ladder-kind {
    display: block; font-family: var(--font-display); font-size: 8px;
    letter-spacing: 2.2px; color: var(--c-ash); opacity: .7; margin-bottom: 4px;
}
.dt-shop .tcg-btn.tiny { display: inline-flex; align-items: baseline; gap: 6px; }
.dt-shop .tcg-btn.tiny i { font-style: normal; font-family: var(--font-mono); color: var(--c-gold); }
.dt-shop .tcg-btn.tiny em {
    font-style: normal; font-family: var(--font-mono); font-size: 8px;
    color: var(--c-ash); opacity: .8;
}
.dt-shop .tcg-btn.locked {
    opacity: .45; border-style: dashed; cursor: not-allowed;
}
.dt-shop .tcg-btn.locked em { color: var(--s-accent); opacity: .85; }
.dt-shop .tcg-btn.warn { border-color: var(--s-red); color: #ffd9e2; }   /* T16: the site red — magenta left the chrome */
.dt-dark-head { color: var(--c-danger) !important; }
.dt-hint.tight { margin: 2px 0 8px; }

/* ── MERCENARIES ──────────────────────────────────────────────────────────
   The pitch, on the card panel: what you get, and what it costs forever. */
.dt-merc {
    margin: 12px 0; padding: 12px 14px; border-radius: var(--r-in);
    background: linear-gradient(150deg, rgba(255,212,58,.1), rgba(255,212,58,.02));
    border: 1px solid rgba(255,212,58,.3);
}
.dt-merc b { font-family: var(--font-display); font-size: 10px; letter-spacing: 1.8px; color: var(--c-gold); }
.dt-merc p { margin: 6px 0 0; font-size: 11px; line-height: 1.5; color: var(--c-mist); }
.dt-merc-price { display: flex; gap: 14px; flex-wrap: wrap; }
.dt-merc-price span {
    font-family: var(--font-mono); font-size: 11px; color: var(--c-gold);
    padding: 3px 8px; border-radius: 3px; background: rgba(0,0,0,.3);
}
.tcg-status.hired { color: var(--s-gold); }

/* ── THE SCORE SHEET ──────────────────────────────────────────────────────
   Every column the game scores, with the count and the weight beside the
   points, so the arithmetic can be argued with. */
.tcg-results-row { grid-template-columns: 38px 1fr 96px 1fr; align-items: start; }
.tcg-score-sheet {
    grid-column: 1 / -1; margin-top: 10px; padding-top: 8px;
    border-top: 1px solid rgba(255,255,255,.07);
    display: flex; flex-direction: column; gap: 2px;
}
.tcg-score-line {
    display: grid; grid-template-columns: 1fr 92px 56px; gap: 8px; align-items: baseline;
    font-size: 10.5px; color: var(--c-mist);
}
.tcg-score-line .cnt { font-family: var(--font-mono); font-size: 9px; color: var(--c-ash); text-align: right; }
.tcg-score-line .pt  { font-family: var(--font-mono); font-size: 11px; color: var(--c-gold); text-align: right; }
.tcg-score-line .nt  { grid-column: 1 / -1; font-size: 9px; color: var(--c-ash); opacity: .75; }
.tcg-score-line.minus .pt { color: var(--c-danger); }
.tcg-score-line.total {
    margin-top: 5px; padding-top: 5px; border-top: 1px solid rgba(255,255,255,.12);
}
.tcg-score-line.total .lbl { font-family: var(--font-display); font-size: 9px; letter-spacing: 1.8px; }
.tcg-score-line.total .pt { font-size: 15px; }

.tcg-standing {
    margin-bottom: 14px; padding: 12px; border-radius: var(--r-in);
    background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.07);
}
.tcg-standing.me { border-color: rgba(60,232,255,.45); }
.tcg-standing.out { opacity: .5; }
.tcg-standing-head {
    display: grid; grid-template-columns: 28px 1fr auto; gap: 10px; align-items: baseline;
    margin-bottom: 8px;
}
.tcg-standing-head .rank { font-family: var(--font-display); font-size: 15px; color: var(--c-ash); }
.tcg-standing-head .nm { font-family: var(--font-display); font-size: 11px; letter-spacing: 1.8px; }
.tcg-standing-head .pts { font-family: var(--font-mono); font-size: 17px; color: var(--c-gold); }

/* ── MARKET: ONE HOUSE, PLUS A POINTER TO THE OTHERS ──────────────────────── */
.tcg-market-group h5 { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.tcg-market-group h5 em {
    font-style: normal; font-family: var(--font-mono); font-size: 9px; color: var(--c-ash);
}
.tcg-market-elsewhere {
    display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
    margin-top: 12px; padding-top: 10px; border-top: 1px solid rgba(255,255,255,.07);
}
.tcg-market-elsewhere-lbl {
    font-family: var(--font-display); font-size: 7.5px; letter-spacing: 2px;
    color: var(--c-ash); opacity: .7;
}

/* the projected income can now be negative, and that has to be loud */
.tcg-projected.bad { color: var(--s-red); text-shadow: 0 0 10px rgba(255,0,64,.45); }

@media (prefers-reduced-motion: reduce) {
    .tcg-extract-row { transition: none; }
}


/* ===========================================================================
   T15 — SETUP SCREEN, TRANSFORMATION
   ---------------------------------------------------------------------------
   Same three colours as everything else (cyan interactive / magenta
   aggression / gold value), same cut corners on BUTTONS ONLY, same rule that
   bays are never clipped. Nothing here introduces a fourth colour or a new
   shape language — the setup screen is the mat's front door, not a different
   building.
   =========================================================================== */

.tcg-setup {
    max-width: 1180px; margin: 0 auto; padding: 40px 24px 64px;
    display: flex; flex-direction: column; gap: 34px; align-items: center;
}
.tcg-setup-block { width: 100%; }
.tcg-setup-head {
    font: 700 13px/1 var(--font-mono, ui-monospace, monospace);
    letter-spacing: .34em; color: var(--cyan, #3ce8ff);
    text-align: center; margin: 0 0 16px;
}
.tcg-setup-row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

.tcg-setup-card {
    position: relative; overflow: hidden;
    border: 0; border-radius: 3px; cursor: pointer;
    background: #0d1118 center/cover no-repeat;
    color: #e8eef7; text-align: left;
    transition: transform .18s ease, box-shadow .18s ease, opacity .18s ease;
}
.tcg-setup-card:hover:not(:disabled) { transform: translateY(-4px); }
.tcg-setup-card.picked {
    box-shadow: 0 0 0 2px var(--house, var(--cyan, #3ce8ff)),
                0 0 26px -4px var(--house, var(--cyan, #3ce8ff));
}

/* HOUSES — the long-drop flag art, scrimmed so the name stays legible over
   whatever the flag happens to be. */
.tcg-setup-row.houses .tcg-setup-card { width: 150px; height: 210px; }
.tcg-setup-scrim {
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(6,9,14,.15) 40%, rgba(6,9,14,.92) 100%);
}
.tcg-setup-title {
    position: relative; display: block; padding: 0 12px 14px;
    position: absolute; left: 0; right: 0; bottom: 0;
    font: 700 13px/1.25 var(--font-mono, ui-monospace, monospace);
    letter-spacing: .1em;
}
.tcg-setup-sub {
    position: absolute; left: 12px; right: 12px; bottom: 4px;
    font: 400 10px/1.3 var(--font-mono, ui-monospace, monospace);
    color: #8892a6; letter-spacing: .04em;
}

/* DECKS — text cards, no art, because a deck has no face yet. */
.tcg-setup-row.decks .tcg-setup-card {
    width: 264px; min-height: 168px; padding: 18px 18px 20px;
    display: flex; flex-direction: column; gap: 8px;
    background: linear-gradient(180deg, #131a25, #0b0f16);
}
.tcg-setup-row.decks .tcg-setup-title { position: static; padding: 0; font-size: 15px; }
.tcg-setup-count {
    font: 700 11px/1 var(--font-mono, ui-monospace, monospace);
    letter-spacing: .18em; color: var(--gold, #ffd43a);
}
.tcg-setup-blurb { font: 400 12px/1.5 inherit; color: #9fb0c6; }
.tcg-setup-lock {
    margin-top: auto; font: 400 10px/1.4 var(--font-mono, ui-monospace, monospace);
    color: #ff8c1a; letter-spacing: .05em;
}
.tcg-setup-card.locked { opacity: .5; cursor: not-allowed; }
.tcg-setup-card:disabled:hover { transform: none; }

.tcg-setup-summary {
    max-width: 620px; text-align: center; margin: 0;
    font: 400 13px/1.7 inherit; color: #9fb0c6;
}
.tcg-setup-summary b { color: #e8eef7; }

/* ---------------------------------------------------------------------------
   TRANSFORMATION — the card itself changes, because in this game the fighter
   IS a card. A flip through the vertical, an element-coloured bloom at the
   halfway point where the face is edge-on and the swap is invisible, then out.
   `--el` is set by TCG.fx.transform from the summoned card's own element, so
   every one of the 17 elements drives this with no extra rule.
   --------------------------------------------------------------------------- */
@keyframes tcg-morph {
    0%   { transform: rotateY(0)      scale(1);    filter: none; }
    38%  { transform: rotateY(84deg)  scale(1.06); filter: brightness(2.4) saturate(1.6); }
    50%  { transform: rotateY(90deg)  scale(1.08); filter: brightness(3); }
    62%  { transform: rotateY(96deg)  scale(1.06); filter: brightness(2.4) saturate(1.6); }
    100% { transform: rotateY(360deg) scale(1);    filter: none; }
}
@keyframes tcg-morph-bloom {
    0%   { opacity: 0; transform: scale(.6); }
    45%  { opacity: 1; transform: scale(1.5); }
    100% { opacity: 0; transform: scale(2.3); }
}
.tcg-transforming {
    animation: tcg-morph 1.25s cubic-bezier(.5,.05,.35,1) both;
    transform-style: preserve-3d; z-index: 40;
}
.tcg-transforming::after {
    content: ''; position: absolute; inset: -20%;
    pointer-events: none; border-radius: 50%;
    background: radial-gradient(circle, var(--el, #ff2bd6) 0%, transparent 68%);
    mix-blend-mode: screen;
    animation: tcg-morph-bloom 1.25s ease-out both;
}

@keyframes tcg-banish {
    0%   { opacity: 1; filter: none; }
    100% { opacity: 1; filter: grayscale(.5) brightness(.85); }
}
.tcg-dissolving { animation: tcg-banish .8s ease-out both; }

/* The transform button in the exchange rail reads as the big one it is. */
.tcg-btn.ward.morph {
    color: #06090e;
    background: linear-gradient(180deg, var(--magenta, #ff2bd6), #c0169f);
    box-shadow: 0 0 18px -6px var(--magenta, #ff2bd6);
}
.tcg-btn.ward.spent { opacity: .42; cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
    .tcg-transforming, .tcg-transforming::after, .tcg-dissolving { animation: none; }
}
