/* ============================================================
   ApexRoll
   Cold gunmetal ground, warm Outlands dust for type, signal red
   reserved for the live action. Every other colour on screen is
   borrowed from whichever legend is currently on the plate.
   ============================================================ */

:root {
  --void:      #0E1116;
  --plate:     #161B23;
  --card-plate: #0D1117;   /* the card face sits darker than the panels */
  --plate-hi:  #1E252F;
  --edge:      #2A323E;

  --dust:      #CBB89B;
  --dust-dim:  #8C8071;
  --steel:     #5A6879;
  --signal:    #E23B2C;

  /* per-card legend colour, overwritten inline */
  --lc:        var(--dust);

  /* how far to push into a legend picture. 1 = show the whole card. */
  --art-zoom:  1.5;

  --display: "Bahnschrift SemiCondensed", "Bahnschrift", "Franklin Gothic Medium",
             "Arial Narrow", Impact, sans-serif;
  --data:    Consolas, "Cascadia Mono", ui-monospace, monospace;
  --body:    "Segoe UI", system-ui, -apple-system, sans-serif;

  --card-round: 15px;

  --notch: polygon(0 9px, 9px 0, calc(100% - 9px) 0, 100% 9px,
                   100% calc(100% - 9px), calc(100% - 9px) 100%,
                   9px 100%, 0 calc(100% - 9px));
}

* { box-sizing: border-box; }

/* `display` on a class beats the UA rule behind the hidden attribute, so say
   it explicitly - otherwise a hidden grid still renders. */
[hidden] { display: none !important; }

/* Images and inline SVG are drag sources of their own in every browser, so a
   drag begun on a portrait would carry off the picture instead of the card.
   Nothing in here needs to receive a pointer, so make them all inert. */
img, svg { -webkit-user-drag: none; -khtml-user-drag: none; user-drag: none; }

.card img,
.card svg,
.chip img,
.chip svg { pointer-events: none; }

/* Text selection during a drag looks like a mis-grab; the name field is the
   one place selecting is the point. */
.card { user-select: none; -webkit-user-select: none; }
.card-seat { user-select: text; -webkit-user-select: text; }

html, body { height: 100%; }

body {
  margin: 0;
  min-height: 100%;
  background:
    radial-gradient(120% 80% at 50% 0%, #171E28 0%, var(--void) 62%),
    var(--void);
  color: var(--dust);
  font-family: var(--body);
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

h1, h2, h3 { margin: 0; font-weight: 600; }

/* ---------- manifest bar ---------- */

.manifest {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding: 14px 26px;
  border-bottom: 1px solid var(--edge);
  background: linear-gradient(180deg, rgba(30,37,47,.75), rgba(14,17,22,0));
}

.brand { display: flex; align-items: baseline; gap: 12px; }

.brand-mark {
  width: 13px; height: 22px;
  background: var(--signal);
  clip-path: polygon(0 0, 100% 22%, 100% 100%, 0 78%);
  align-self: center;
}

.brand-name {
  font-family: var(--display);
  font-size: 26px;
  letter-spacing: .10em;
  text-transform: uppercase;
  color: #EFE4D2;
}

.brand-sub {
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--steel);
}

.manifest-tools { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }

.stat { display: flex; align-items: baseline; gap: 8px; }

.stat-label {
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--steel);
}

.stat-val {
  font-family: var(--data);
  font-size: 15px;
  color: var(--dust);
  font-variant-numeric: tabular-nums;
}

/* ---------- toggle ---------- */

.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }

.switch-track {
  width: 40px; height: 18px;
  border: 1px solid var(--edge);
  background: #0B0E13;
  position: relative;
  transition: border-color .16s, background .16s;
}

.switch-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 12px;
  background: var(--steel);
  transition: transform .16s ease, background .16s;
}

.switch input:checked + .switch-track { border-color: var(--signal); background: #22120F; }
.switch input:checked + .switch-track .switch-knob { transform: translateX(20px); background: var(--signal); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--dust); outline-offset: 3px; }

.switch-text {
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dust-dim);
}

.switch input:checked ~ .switch-text { color: var(--dust); }

/* ---------- ghost buttons ---------- */

.ghost-btn {
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dust-dim);
  background: none;
  border: 1px solid var(--edge);
  padding: 6px 13px;
  cursor: pointer;
  transition: color .16s, border-color .16s;
}

.ghost-btn:hover { color: var(--dust); border-color: var(--steel); }
.ghost-btn:focus-visible { outline: 2px solid var(--dust); outline-offset: 2px; }

/* ---------- stage ---------- */

main {
  flex: 1;
  width: min(1080px, 100%);
  margin: 0 auto;
  padding: 40px 26px 30px;
}

.stage-wrap { min-height: 320px; display: flex; flex-direction: column; align-items: center; }

/* The stage stacks teams; each team lays its own seats out in a row. */
.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 34px;
  width: 100%;
}

.team { display: flex; flex-direction: column; align-items: center; gap: 14px; width: 100%; }

.team-head {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--data);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .30em;
  text-transform: uppercase;
  color: var(--steel);
}

.team-head::before,
.team-head::after { content: ""; width: 40px; height: 1px; background: var(--edge); }

.team-cards {
  display: grid;
  gap: 20px;
  justify-content: center;
  width: 100%;
}

.team-cards[data-count="1"] { grid-template-columns: minmax(0, 262px); }
.team-cards[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 246px)); }
.team-cards[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 228px)); }

.stage-note {
  font-family: var(--data);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--steel);
  text-align: center;
  margin: 22px 0 0;
  min-height: 16px;
}

/* ---------- the card ---------- */

.card {
  position: relative;
  padding: 10px;
  isolation: isolate;
  cursor: grab;
  perspective: 1000px;
  transition: transform .3s ease-out;
}

/* --- the reveal flip ---
   The reticle brackets live outside this, so the frame holds steady while
   the card turns inside it. */

.card-flip { position: relative; transform-style: preserve-3d; }

.card-inner { backface-visibility: hidden; }

.card-back {
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  backface-visibility: hidden;
  border-radius: var(--card-round);
  border: 1px solid var(--edge);
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 16px;
  background:
    repeating-linear-gradient(100deg, rgba(255, 255, 255, .05) 0 3px, transparent 3px 7px),
    radial-gradient(78% 58% at 50% 42%, color-mix(in srgb, var(--lc) 26%, transparent), transparent 72%),
    linear-gradient(160deg, #151A22, var(--card-plate));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .10),
    inset 0 -1px 0 rgba(0, 0, 0, .55);
}

.back-mark {
  width: 86px;
  height: 86px;
  color: color-mix(in srgb, var(--lc) 65%, var(--dust));
}

.back-word {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .30em;
  text-transform: uppercase;
  color: var(--steel);
  padding-left: .30em;
}

@keyframes cardFlip {
  0%   { transform: rotateY(0deg)   scale(1); }
  50%  { transform: rotateY(180deg) scale(1.05); }
  100% { transform: rotateY(360deg) scale(1); }
}

.card.is-flipping .card-flip { animation: cardFlip .62s cubic-bezier(.45, .05, .3, 1); }

/* While the pointer is on the card, follow it instantly instead of easing. */
.card.is-shining { transition: transform .06s linear; z-index: 5; }

.card:focus-visible { outline: 2px solid var(--dust); outline-offset: 2px; }

/* --- moving a player between seats --- */

/* The card stays solid while it is carried - fading it out reads as the card
   being lost rather than picked up. A lifted rim marks it instead. */
.card.is-dragging { cursor: grabbing; }

.card.is-dragging .card-inner {
  border-color: color-mix(in srgb, var(--lc) 75%, var(--edge));
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--lc) 45%, transparent),
    0 20px 44px -14px #000;
}

.card.is-drop .card-inner {
  border-color: var(--dust);
  box-shadow: 0 0 0 1px var(--dust), 0 0 26px -8px var(--dust);
}

.card.is-picked .card-inner {
  border-color: var(--signal);
  box-shadow: 0 0 0 1px var(--signal);
}

.drag-hint {
  margin: 8px 0 0;
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .10em;
  color: var(--steel);
  text-align: center;
  min-height: 14px;
}

.card-inner {
  position: relative;
  border-radius: var(--card-round);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--lc) 9%, transparent), transparent 52%),
    var(--card-plate);
  border: 1px solid var(--edge);
  padding: 15px 14px 13px;
  text-align: center;
  overflow: hidden;
  transition: background .25s;
  /* bevelled edge - lit along the top, shadowed at the foot, like card stock */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .10),
    inset 0 -1px 0 rgba(0, 0, 0, .55);
}

/* Content sits above the foil and below the gloss. */
.card-seat,
.portrait-wrap,
.card-idx,
.card-name,
.card-cls { position: relative; z-index: 2; }

/* --- foil --- */

.foil,
.gloss,
.flare { position: absolute; pointer-events: none; }

.foil {
  inset: 0;
  z-index: 1;
  opacity: .18;
  mix-blend-mode: screen;
  transition: opacity .3s;
  background-image:
    /* specular hotspot under the cursor */
    radial-gradient(58% 52% at var(--mx, 50%) var(--my, 50%),
      rgba(255, 255, 255, .30), transparent 62%),
    /* the holographic band, tinted to this legend */
    linear-gradient(115deg,
      transparent 18%,
      color-mix(in srgb, var(--lc) 45%, transparent) 36%,
      rgba(255, 255, 255, .26) 46%,
      color-mix(in srgb, var(--lc) 45%, transparent) 56%,
      transparent 74%),
    /* fine diffraction lines, the thing that reads as "foil" up close */
    repeating-linear-gradient(100deg,
      rgba(255, 255, 255, .055) 0 3px, transparent 3px 7px);
  background-size: 100% 100%, 250% 250%, 100% 100%;
  background-position: 0 0, var(--fx, 50%) var(--fy, 50%), 0 0;
}

.card.is-shining .foil { opacity: .85; }

.gloss {
  inset: 0;
  z-index: 3;
  mix-blend-mode: soft-light;
  background: linear-gradient(158deg, rgba(255, 255, 255, .08) 0%, transparent 34%);
}

/* The wrap exists so the shockwave can burst past the hexagon instead of
   being clipped inside it. */
.portrait-wrap {
  width: min(100%, 186px);
  aspect-ratio: 1 / 1;
  margin: 0 auto 11px;
  position: relative;
}

.portrait {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  position: relative;
  background: color-mix(in srgb, var(--lc) 9%, #0B0E13);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  overflow: hidden;
}

.shock {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 168px;
  height: 168px;
  margin: -84px 0 0 -84px;
  border: 3px solid var(--lc);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}

.portrait svg { width: 108px; height: 108px; color: var(--lc); display: block; }

/* Legend cards frame the character small against empty backdrop, so push in
   to head-and-torso. One number, --art-zoom, tunes every picture at once. */
.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(var(--art-zoom));
  transform-origin: 50% 24%;
}

.card-idx {
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .18em;
  color: var(--steel);
  display: block;
}

.card-name {
  font-family: var(--display);
  font-size: 30px;
  line-height: 1.05;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--lc);
  margin: 2px 0 4px;
  overflow-wrap: anywhere;
}

.card-cls {
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--dust-dim);
}

/* --- the guns dealt with the legend --- */

.loadout {
  list-style: none;
  margin: 10px 0 0;
  padding: 9px 0 0;
  border-top: 1px solid var(--edge);
  display: grid;
  gap: 5px;
  position: relative;
  z-index: 2;
}

.loadout:empty { display: none; }

.gun {
  --wc: var(--dust);
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: center;
  gap: 8px;
  text-align: left;
}

.gun-glyph { width: 22px; height: 22px; color: var(--wc); display: block; }

.gun-name {
  font-family: var(--display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--dust);
  line-height: 1.1;
  overflow-wrap: anywhere;
}

.gun-cls {
  font-family: var(--data);
  font-size: 9px;
  letter-spacing: .14em;
  color: var(--wc);
  border: 1px solid color-mix(in srgb, var(--wc) 40%, transparent);
  padding: 1px 5px;
}

/* The seat label is the name field - click it and type. The dashed rule is
   the only thing saying "editable", so it stays visible at rest. */
.card-seat {
  display: block;
  width: 100%;
  margin: -2px 0 9px;
  padding: 0 0 5px;
  background: none;
  border: none;
  border-bottom: 1px dashed var(--edge);
  font-family: var(--display);
  font-size: 21px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: .07em;
  text-transform: uppercase;
  text-align: center;
  color: #EFE4D2;
  cursor: text;
}

/* Placeholder keeps the size so the card never jumps once a name is typed,
   but stays quiet enough to read as "not filled in". */
.card-seat::placeholder {
  color: var(--steel);
  font-weight: 400;
  letter-spacing: .16em;
}
.card-seat:hover { border-bottom-color: var(--steel); }

.card-seat:focus {
  outline: none;
  border-bottom: 1px solid var(--lc);
  background: rgba(255, 255, 255, .05);
  color: #EFE4D2;
}

.card.is-locked .card-inner {
  border-color: color-mix(in srgb, var(--lc) 55%, var(--edge));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--lc) 22%, transparent),
              0 14px 44px -18px var(--lc);
}

/* --- the lock-in --- */

@keyframes flood {
  0%   { background: var(--lc); }
  100% { background: color-mix(in srgb, var(--lc) 9%, #0B0E13); }
}

/* the card stamps into place */
@keyframes cardPop {
  0%   { transform: scale(.90); }
  58%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}

/* a hard light sweeps the foil, the way a real card catches a lamp */
@keyframes flareSweep {
  0%   { transform: translateX(-140%) skewX(-18deg); opacity: 0; }
  14%  { opacity: 1; }
  100% { transform: translateX(260%) skewX(-18deg); opacity: 0; }
}

/* an energy ring bursts out past the hexagon */
@keyframes shockRing {
  0%   { transform: scale(.25); opacity: .95; border-width: 3px; }
  70%  { opacity: .35; }
  100% { transform: scale(2.1); opacity: 0; border-width: 1px; }
}

/* the character resolves out of a bright flash */
@keyframes materializeArt {
  0%   { transform: scale(calc(var(--art-zoom) * 1.22)); filter: brightness(2.6) saturate(.35); opacity: .15; }
  45%  { filter: brightness(1.45) saturate(.9); opacity: 1; }
  100% { transform: scale(var(--art-zoom)); filter: none; opacity: 1; }
}

@keyframes materializeEmblem {
  0%   { transform: scale(1.3); filter: brightness(2.6); opacity: .15; }
  45%  { filter: brightness(1.45); opacity: 1; }
  100% { transform: scale(1); filter: none; opacity: 1; }
}

.flare {
  top: -12%;
  bottom: -12%;
  left: 0;
  width: 42%;
  z-index: 4;
  opacity: 0;
  background: linear-gradient(90deg,
    transparent,
    rgba(255, 255, 255, .18) 35%,
    rgba(255, 255, 255, .92) 50%,
    rgba(255, 255, 255, .18) 65%,
    transparent);
}

.card.is-locked .card-inner  { animation: cardPop .5s cubic-bezier(.2, .8, .25, 1); }
.card.is-locked .flare       { animation: flareSweep .8s cubic-bezier(.25, .7, .3, 1) .05s; }
.card.is-locked .shock       { animation: shockRing .75s ease-out .04s; }
.card.is-locked .portrait    { animation: flood .45s ease-out; }
.card.is-locked .portrait img { animation: materializeArt .6s ease-out; }
.card.is-locked .portrait svg { animation: materializeEmblem .6s ease-out; }

/* empty placeholder before the first roll */

/* Before a roll the card is blank stock - no black plate punched into it. */
.card.is-empty .card-inner { border-color: var(--edge); }
.card.is-empty .portrait { background: none; }
.card.is-empty .foil { opacity: .30; }
.card.is-empty .card-name { color: var(--steel); font-size: 22px; }

/* ---------- controls ---------- */

.controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 26px;
  flex-wrap: wrap;
  margin: 30px 0 46px;
}

.seg-set { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: center; }

.seg { display: flex; align-items: center; gap: 0; border: 1px solid var(--edge); }

.seg button {
  font-family: var(--display);
  font-size: 19px;
  letter-spacing: .06em;
  width: 46px;
  padding: 9px 0;
  background: none;
  border: none;
  border-right: 1px solid var(--edge);
  color: var(--dust-dim);
  cursor: pointer;
  transition: background .16s, color .16s;
}

.seg button:hover { color: var(--dust); background: var(--plate-hi); }
.seg button:focus-visible { outline: 2px solid var(--dust); outline-offset: -2px; }
.seg button.is-on { background: var(--dust); color: var(--void); }

.seg-caption {
  font-family: var(--data);
  font-size: 10px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--steel);
  padding: 0 13px;
}

.roll {
  position: relative;
  font-family: var(--display);
  font-size: 30px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #FFF3E6;
  background: var(--signal);
  border: none;
  padding: 13px 60px;
  cursor: pointer;
  clip-path: var(--notch);
  transition: filter .16s, transform .08s;
}

.roll:hover { filter: brightness(1.14); }
.roll:active { transform: translateY(1px); }
.roll:focus-visible { outline: 2px solid var(--dust); outline-offset: 4px; }

.roll:disabled {
  background: var(--plate-hi);
  color: var(--steel);
  cursor: not-allowed;
  filter: none;
}

.roll-text { position: relative; }

/* ---------- roster ---------- */

.roster { border-top: 1px solid var(--edge); padding-top: 22px; }

.roster-head {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.tabs { display: flex; border: 1px solid var(--edge); }

.tabs button {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 7px 18px;
  background: none;
  border: none;
  border-right: 1px solid var(--edge);
  color: var(--dust-dim);
  cursor: pointer;
  transition: background .16s, color .16s;
}

.tabs button:last-child { border-right: none; }
.tabs button:hover { color: var(--dust); background: var(--plate-hi); }
.tabs button:focus-visible { outline: 2px solid var(--dust); outline-offset: -2px; }
.tabs button.is-on { background: var(--dust); color: var(--void); }

/* --- weapon chips --- */

.chips-wpn { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }

/* Scoped under .chip-gun so these beat the legend-chip .chip-art rules that
   are defined further down the file. Weapons get no hexagon plate - they are
   equipment, not characters. */
.chip-gun .chip-art {
  width: 58px;
  height: 46px;
  clip-path: none;
  background: none;
}

.chip-gun .chip-art svg { width: 50px; height: 50px; }

.chip-sub {
  font-family: var(--data);
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--steel);
}

.chip-gun { padding: 9px 6px 8px; gap: 2px; }
.chip-gun .chip-name { font-size: 13px; }

.hint { margin: 0; flex: 1; font-size: 13px; color: var(--dust-dim); }

.chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
}

.chip {
  --lc: var(--dust);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 11px 5px 9px;
  background: var(--plate);
  border: 1px solid var(--edge);
  color: var(--lc);
  cursor: pointer;
  transition: border-color .16s, background .16s, opacity .16s;
  font: inherit;
  text-align: center;
}

.chip:hover { border-color: color-mix(in srgb, var(--lc) 45%, var(--edge)); background: var(--plate-hi); }
.chip:focus-visible { outline: 2px solid var(--dust); outline-offset: 2px; }

/* The wrapper owns the hexagon and the clipping, so a zoomed picture inside
   can never spill past the chip. */
.chip-art {
  width: 52px;
  height: 58px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: color-mix(in srgb, var(--lc) 10%, #0B0E13);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

.chip-art svg { width: 32px; height: 32px; display: block; }

.chip-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(var(--art-zoom));
  transform-origin: 50% 24%;
}

.chip-name {
  font-family: var(--display);
  font-size: 14px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--dust);
  line-height: 1.1;
}

.chip-idx {
  position: absolute;
  top: 3px; left: 5px;
  font-family: var(--data);
  font-size: 9px;
  color: var(--steel);
}

.chip.is-banned { opacity: .34; }
.chip.is-banned .chip-name { color: var(--steel); text-decoration: line-through; }
.chip.is-banned::after {
  content: "";
  position: absolute;
  inset: -1px;
  background: linear-gradient(to top right,
    transparent calc(50% - 1px), var(--signal) 50%, transparent calc(50% + 1px));
  opacity: .55;
}

.chip.is-used { border-style: dotted; }
.chip.is-used .chip-idx::after { content: " used"; color: var(--steel); }

/* ---------- colophon + toast ---------- */

.colophon {
  border-top: 1px solid var(--edge);
  padding: 16px 26px 22px;
  text-align: center;
}

.colophon p { margin: 0; font-size: 12px; color: var(--dust-dim); }
.colophon code { font-family: var(--data); color: var(--steel); }

.toast {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translate(-50%, 14px);
  background: var(--plate-hi);
  border: 1px solid var(--steel);
  clip-path: var(--notch);
  padding: 11px 22px;
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dust);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s, transform .22s;
}

.toast.is-up { opacity: 1; transform: translate(-50%, 0); }

/* ---------- lock-in shake ---------- */

@keyframes shake {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-3px, 2px); }
  40% { transform: translate(3px, -2px); }
  60% { transform: translate(-2px, -1px); }
  80% { transform: translate(2px, 1px); }
}

body.is-shaking { animation: shake .26s ease-in-out; }

/* ---------- responsive ---------- */

@media (max-width: 720px) {
  .team-cards[data-count="2"],
  .team-cards[data-count="3"] { grid-template-columns: minmax(0, 280px); }
  .manifest { justify-content: center; }
  .roll { width: 100%; }
  main { padding: 26px 16px; }
}

/* ---------- reduced motion ----------
   Driven by a body class, not the media query directly, so the Effects switch
   can override the machine's setting either way. The system preference only
   decides where that switch starts. */

body.no-fx .card,
body.no-fx .card-inner,
body.no-fx .switch-knob,
body.no-fx .toast { transition: none; }

body.no-fx.is-shaking { animation: none; }

/* Keep the foil - it is a finish, not motion - but stop everything moving. */
body.no-fx .card.is-flipping .card-flip,
body.no-fx .card.is-locked .card-inner,
body.no-fx .card.is-locked .flare,
body.no-fx .card.is-locked .shock,
body.no-fx .card.is-locked .portrait,
body.no-fx .card.is-locked .portrait img,
body.no-fx .card.is-locked .portrait svg { animation: none; }

/* ---------- published at apexroll.ecran-noir.com ---------- */

.site-back {
  display: block;
  padding: 9px 26px;
  background: #08080C;
  border-bottom: 1px solid var(--edge);
  font-family: var(--data);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
  text-decoration: none;
}

.site-back:hover { color: var(--dust); }
.site-back:focus-visible { outline: 2px solid var(--dust); outline-offset: -2px; }

.disclaimer {
  margin-top: 8px;
  margin-inline: auto;
  max-width: 70ch;
  font-size: 11px;
  color: var(--steel);
}