/* Relative box (design 38a + 39a, docs/RELATIVE-BOX.md) — ONE stylesheet for
   both hosts (09-18): the in-car widget on the overlay page and the pit
   wall's panel (pitwall.css overrides sizes under .pnl). Moved verbatim
   out of overlay.css; the widget's own tokens live on .relcard. */

/* ---- relative box (design 38a + 39a, docs/RELATIVE-BOX.md) -------------- */
/* Palette mirrors the DASHBOARD tokens 1:1 per skin (pscard pattern), and
   every tinted surface — player highlight, flash chips — DERIVES from the
   ground via color-mix so it tracks each skin automatically (Marcus 07-31:
   widgets must follow the skin grounds; the handoff's fixed Carbon values do
   not ship). Semantic accents (licence boxes, lap-state names, flash-tier
   inks, pace colours) are widget-own tokens; Paper's light ground swaps in
   darker inks below — data-driven class-stripe colours are the one thing
   that stays as the sim sends it. */
.relcard {
  --rel-ground: #161826; /* --bg */
  --rel-hair1: #292b31; /* --hairline */
  --rel-hair2: #3f424d; /* --frame (card border) */
  --rel-text: #e9e9ed; /* --text */
  --rel-muted: #9397ab; /* --muted */
  --rel-dim: #75798c; /* --dim */
  --rel-pos: #21d07a; /* --green: pace "you gain" */
  --rel-paceup: #ffb020; /* pace "they gain" + the pit-soon pump */
  --rel-red: #ff5252; /* lap ahead */
  --rel-blue: #56b8ff; /* lap behind, wet-compound ink */
  --rel-yellow: #ffd23d; /* flash: most recent */
  --rel-purple: #b48bff; /* flash: class fastest */
  /* Race control on a rival — the dash takeover's three domains, restated in
     this widget's own vocabulary (the box never reaches into the dash tokens;
     they are scoped to .dash and simply do not exist out here). */
  --rel-rc-ground: #23110d; /* the terminal ground black and meatball share */
  --rel-rc-black: #ff5252;
  --rel-rc-repair: #ff7a29;
  --rel-rc-furled: #d87c74;
  --rel-rc-furled-rail: #7a3d38;
  /* Licence boxes (iRacing's own ladder colours; the box IS the licence). */
  --rel-lic-r: #ff5252;
  --rel-lic-d: #ff8b3d;
  --rel-lic-c: #ffd23d;
  --rel-lic-b: #21d07a;
  --rel-lic-a: #56b8ff;
  /* Dark ink on the saturated licence chips reads on every skin. */
  --rel-lic-ink: #12141c;
  /* Player-row highlight: the ground lifted toward blue — tracks any skin. */
  --rel-hilite: color-mix(in srgb, var(--rel-ground) 87%, var(--rel-blue) 13%);
  --rel-hilite-rule: color-mix(in srgb, var(--rel-ground) 55%, var(--rel-blue) 45%);
  /* Flash-chip tints: ground + tier ink. */
  --rel-tint-recent: color-mix(in srgb, var(--rel-ground) 84%, var(--rel-yellow) 16%);
  --rel-tint-pb: color-mix(in srgb, var(--rel-ground) 84%, var(--rel-pos) 16%);
  --rel-tint-classbest: color-mix(in srgb, var(--rel-ground) 84%, var(--rel-purple) 16%);
  /* Sized for 3-digit car numbers (the number cell is a fixed grid column,
     so wide numbers can never shift the columns beside them). 10-02: the
     standings board's 24 px manufacturer badge between the class position
     and the number (Marcus) — the card grew by slot + gap (420 → 451) so
     every other column, the name included, kept its width. */
  --rel-cols: 23px 24px 34px 1fr 56px 20px 50px 46px;

  /* Screen-anchored box (Marcus 07-31 final model): the player row is
     nailed to a fixed screen position — the widget box's vertical middle
     — and the card's top and bottom edges extend independently to hug
     each direction's content (JS sets top and height; the top compensates
     for the up-extent exactly, so resizes move the edges, NEVER the
     player). Same 1px frame border and 8px corner radius as the dash. */
  position: absolute;
  left: 0;
  /* Static top + animated TRANSFORM (never animate `top`: it runs on the
     layout thread and stutters against the rows' compositor transforms —
     the two must cancel exactly to keep the player still, and any drift
     between them judders the player row on top-edge resizes; Marcus
     07-31). 183 = the 187px player anchor minus border+padding. */
  top: 183px;
  transition: transform 550ms cubic-bezier(0.2, 0.8, 0.2, 1), height 550ms cubic-bezier(0.2, 0.8, 0.2, 1);
  width: 451px;
  box-sizing: border-box;
  background: var(--rel-ground);
  border: 1px solid var(--rel-hair2);
  border-radius: 8px;
  padding: 3px 0;
  overflow: hidden;
  color: var(--rel-text);
  font-variant-numeric: tabular-nums;
}

/* Compound column only exists when the session has >1 compound (decided at
   session start — never mid-session). */
.relcard.nocmpd {
  --rel-cols: 23px 24px 34px 1fr 56px 50px 46px;
}
.relcard.nocmpd .rr-cmpd {
  display: none;
}

.relcard[data-theme='amber'] {
  --rel-ground: #0b0a07;
  --rel-hair1: #241f12;
  --rel-hair2: #2e2617;
  --rel-text: #ffb020;
  --rel-muted: #8a7245;
  --rel-dim: #6b5a38;
}

.relcard[data-theme='paper'] {
  --rel-ground: #f5f5f6;
  --rel-hair1: #e0e0e4;
  --rel-hair2: #c9c9ce;
  --rel-text: #1b1d1f;
  --rel-muted: #6f7379;
  --rel-dim: #9a9da3;
  /* Light ground: the saturated dark-skin inks wash out — darker variants
     keep the same meanings legible (paper's existing green/amber convention). */
  --rel-pos: #149655;
  --rel-paceup: #a06800;
  --rel-red: #d03030;
  --rel-blue: #1867c0;
  --rel-yellow: #8f6a00;
  --rel-purple: #6a3fc4;
  /* The dark race-control ground would black the row out on paper; a warm
     wash carries the same "this car is under a flag" reading on a light skin. */
  --rel-rc-ground: #e9cdc7;
  --rel-rc-black: #b3241c;
  --rel-rc-repair: #a35200;
  --rel-rc-furled: #8f4a43;
  --rel-rc-furled-rail: #b58079;
}

.relcard[data-theme='slate'] {
  --rel-ground: #10141c;
  --rel-hair1: #1b2230;
  --rel-hair2: #232c3d;
  --rel-text: #f0f3f8;
  --rel-muted: #8a92a3;
  --rel-dim: #6b7383;
  --rel-pos: #3ddc84;
}

.rel-rows {
  position: relative;
  overflow: hidden;
  /* JS sets the height. ONE clock for all geometry: the frame moves on
     exactly the rows' curve, or the box reads as lagging its own content
     (Marcus 07-31 — the earlier slow 1.1s ease did exactly that). */
  transition: height 550ms cubic-bezier(0.2, 0.8, 0.2, 1);
  /* Content overlapping the top/bottom edge fades through it rather than
     clipping hard — rows sliding in and out dissolve at the boundary. */
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #000 12px,
    #000 calc(100% - 12px),
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #000 12px,
    #000 calc(100% - 12px),
    transparent 100%
  );
}

/* Centring spacers: the quiet side's mirror of the busy side. Their height
   changes INSTANTLY — the FLIP transforms own every visible row movement.
   (Animating these too made the player row wobble through overtakes: two
   animation clocks measured each other mid-flight, and "Isaac moves below
   me" rendered as "I move above Isaac" — Marcus 07-31.) */

.rel-row {
  /* Every row is a slot around the anchored player: absolutely positioned,
     placed by one translateY, gliding there on its own transition. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: var(--rel-cols);
  align-items: center;
  column-gap: 7px;
  height: 30px;
  padding: 0 10px 0 9px;
  box-sizing: border-box;
  /* Class stripe: set inline per row from session data (--cls). */
  border-left: 3px solid var(--cls, var(--rel-hair2));
  transition: transform 550ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 250ms ease;
}

/* Pit lane (driving or serviced): the whole row drops back. */
.rel-row.faded {
  opacity: 0.42;
}


/* The overtaker slides OVER during a swap (+z, soft drop shadow). */
.rel-row.liftz {
  z-index: 2;
  box-shadow: 0 2px 8px #00000080;
  background: var(--rel-ground);
}

.rel-row.player {
  background: var(--rel-hilite);
  box-shadow: inset 0 1px 0 var(--rel-hilite-rule), inset 0 -1px 0 var(--rel-hilite-rule);
}

.rr-cpos {
  font-size: 13px;
  font-weight: 700;
  color: var(--cls, var(--rel-muted));
}

/* Manufacturer badge: the standings board's (overlay.css .sb-mf) — an
   unframed 24x22 slot, the mono SVG as a 21 px mask in near-text ink; a dim
   dash when the brand is unknown. */
.rr-mf {
  display: block;
  width: 24px;
  height: 22px;
  box-sizing: border-box;
}
.rr-mf::after {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: color-mix(in srgb, var(--rel-text) 80%, var(--rel-muted) 20%);
  -webkit-mask: var(--mf, none) no-repeat center / 21px 21px;
  mask: var(--mf, none) no-repeat center / 21px 21px;
}
.rr-mf[data-none]::after {
  content: '–';
  background: none;
  color: color-mix(in srgb, var(--rel-dim) 62%, var(--rel-ground) 38%);
  font-size: 11px;
  text-align: center;
  line-height: 22px;
}

/* Car number chip and the status icon share one fixed cell; a 250 ms
   opacity crossfade swaps them — nothing ever shifts. */
.rr-numcell {
  position: relative;
  height: 19px;
}

.rr-num {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rel-hair1);
  border-radius: 2px;
  font-size: 12px;
  font-weight: 600;
  color: var(--rel-muted);
  opacity: 1;
  transition: opacity 250ms ease;
}

.rel-row.player .rr-num {
  border-color: var(--rel-hilite-rule);
  color: var(--rel-text);
}

.rr-ico {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 250ms ease;
}

.rr-numcell[data-ico] .rr-num {
  opacity: 0;
}

.rr-numcell[data-ico] .rr-ico {
  opacity: 1;
}

/* The pit-soon pump breathes on the shared low-fuel pulse (same keyframes
   as the dashboard's low-fuel indicator — one vocabulary). */
.rr-numcell[data-ico='pitSoon'] .rr-ico {
  animation: lowfuel-breathe 1.6s ease-in-out infinite;
}

.rr-ico svg {
  display: block;
}

.rr-ico .i-outlap { stroke: var(--rel-muted); }
.rr-ico .i-pitsoon { stroke: var(--rel-paceup); }
.rr-ico .i-lane { stroke: var(--rel-muted); }
.rr-ico .i-box { stroke: var(--rel-text); }

.rr-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--rel-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rel-row.player .rr-name {
  font-weight: 600;
}

.rel-row[data-lap='ahead'] .rr-name {
  color: var(--rel-red);
}

.rel-row[data-lap='behind'] .rr-name {
  color: var(--rel-blue);
}

/* iRating in a filled licence-coloured box — the box IS the licence. */
.rr-ir {
  justify-self: end;
  border-radius: 2px;
  padding: 0 4px;
  font-size: 12px;
  font-weight: 700;
  line-height: 17px;
  color: var(--rel-lic-ink);
  background: var(--rel-dim);
}

.rr-ir[data-lic='R'] { background: var(--rel-lic-r); }
.rr-ir[data-lic='D'] { background: var(--rel-lic-d); }
.rr-ir[data-lic='C'] { background: var(--rel-lic-c); }
.rr-ir[data-lic='B'] { background: var(--rel-lic-b); }
.rr-ir[data-lic='A'] { background: var(--rel-lic-a); }
/* Pro: text-on-ground inversion — ink follows the skin both ways. */
.rr-ir[data-lic='P'] {
  background: var(--rel-text);
  color: var(--rel-ground);
}

.rr-cmpd {
  width: 17px;
  height: 17px;
  box-sizing: border-box;
  /* Ring shares the letter's ink (--rel-muted) so the compound reads as one
     glyph; the frame colour (--rel-hair2) rendered too faint. */
  margin-left: 2px;
  border: 1px solid var(--rel-muted);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--rel-muted);
}

/* Wet: same ring, only the ink differs (neither compound reads bolder). */
.rr-cmpd[data-c='W'] {
  color: var(--rel-blue);
}

/* The gap IS the widget (Marcus 08-09) — the biggest thing in the row. The
   column below was widened with it so the widest value ("−45.0", the 45 s
   horizon) still sits inside its own cell and can never crowd the name. */
.rr-gap {
  font-size: 18px;
  font-weight: 700;
  color: var(--rel-text);
  text-align: right;
}

/* Lap state colours the GAP as well as the name (Marcus 08-09): if the number
   is the thing you read, it should carry the red/blue too. Same-class only —
   `data-lap` is already 'same' on other classes, so this inherits that rule. */
.rel-row[data-lap='ahead'] .rr-gap {
  color: var(--rel-red);
}

.rel-row[data-lap='behind'] .rr-gap {
  color: var(--rel-blue);
}

/* Race control on a RIVAL (rival-flags design). One principle: brightness and
   motion mean "this is happening right now", not "this matters". Furled is the
   only transient one, so it is the only one that moves; black and the meatball
   can sit on a car for laps, so they hold a calm ground and carry their weight
   through colour and the mark instead.

   Every part of this is paint-only — a wash, an INSET rail and a text colour.
   Nothing enters the flow, so no cell in this row or any other moves. */
/* Same separate wash layer as the battle block. The row already spans its card
   edge to edge, so this is not about alignment here — it is so the furled
   breathe pulses the TINT and leaves the gap, name and pace at full strength.
   It must be position:absolute: the row is a grid, and an in-flow pseudo
   would become a grid item and shove every cell along. */
.rel-row[data-flag]::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: background 250ms ease, box-shadow 250ms ease;
}

/* Positioned so the cells paint above that layer. Grid placement unaffected. */
.rel-row > * {
  position: relative;
}

.rel-row[data-flag='furled']::before {
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--rel-rc-furled-rail) 55%, transparent),
    color-mix(in srgb, var(--rel-rc-furled-rail) 12%, transparent)
  );
  box-shadow: inset 3px 0 0 var(--rel-rc-furled-rail);
  animation: lowfuel-breathe 1.6s ease-in-out infinite;
}

.rel-row[data-flag='black']::before,
.rel-row[data-flag='repair']::before {
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--rel-rc-ground) 96%, transparent),
    color-mix(in srgb, var(--rel-rc-ground) 45%, transparent)
  );
}

.rel-row[data-flag='black']::before {
  box-shadow: inset 3px 0 0 var(--rel-rc-black);
}

.rel-row[data-flag='repair']::before {
  box-shadow: inset 3px 0 0 var(--rel-rc-repair);
}

/* The flag owns the name and the gap for its life, over the lap-state red/blue
   — the row is answering a different question while it is up. */
.rel-row[data-flag='furled'] .rr-name,
.rel-row[data-flag='furled'] .rr-gap {
  color: var(--rel-rc-furled);
}

.rel-row[data-flag='black'] .rr-name,
.rel-row[data-flag='black'] .rr-gap {
  color: var(--rel-rc-black);
}

.rel-row[data-flag='repair'] .rr-name,
.rel-row[data-flag='repair'] .rr-gap {
  color: var(--rel-rc-repair);
}

.rr-ico .i-black { stroke: var(--rel-rc-black); color: var(--rel-rc-black); }
.rr-ico .i-repair { stroke: var(--rel-muted); color: var(--rel-rc-repair); }
.rr-ico .i-furled { stroke: var(--rel-rc-furled); color: var(--rel-rc-furled); }

/* Pace digits and the 39a flash chip share the last cell, crossfaded the
   same way as number/icon. Pace is always bare digits; a lap time always
   arrives in a chip — the container disambiguates before colour is read. */
.rr-pacecell {
  position: relative;
  height: 19px;
}

.rr-pace {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--rel-dim);
  opacity: 1;
  transition: opacity 250ms ease;
}

.rr-pace.up { color: var(--rel-paceup); }
.rr-pace.down { color: var(--rel-pos); }

.rr-flash {
  position: absolute;
  top: 0;
  /* The chip's DIGITS align with the pace column's right edge; the tinted
     background carries its 5px padding into the row's right padding instead
     of pushing the number left (read as misaligned, Marcus 07-31). */
  right: -5px;
  bottom: 0;
  display: flex;
  align-items: center;
  border-radius: 2px;
  padding: 1px 5px;
  font-size: 12.5px;
  font-weight: 700;
  opacity: 0;
  transition: opacity 250ms ease;
}

.rr-pacecell[data-flash] .rr-pace {
  opacity: 0;
}

.rr-pacecell[data-flash] .rr-flash {
  opacity: 1;
}

.rr-flash[data-tier='recent'] {
  background: var(--rel-tint-recent);
  color: var(--rel-yellow);
}

.rr-flash[data-tier='pb'] {
  background: var(--rel-tint-pb);
  color: var(--rel-pos);
}

.rr-flash[data-tier='classBest'] {
  background: var(--rel-tint-classbest);
  color: var(--rel-purple);
}

/* Pack separator: hairlines either side of the gap it carries. 20px tall
 *  (was the design's 15) — the text sat too close to the rows either side
 *  (Marcus 07-31); the extra height is symmetric breathing room. */
.rel-sep {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  height: 23px;
  padding: 0 10px 0 12px;
  transition: transform 550ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 250ms ease;
}

/* A row (or separator) leaving the window: fades out where it stands. */
.rel-gone {
  opacity: 0 !important;
  pointer-events: none;
}

.rel-sep .rs-l,
.rel-sep .rs-r {
  flex: 1;
  height: 1px;
  background: var(--rel-hair1);
}

.rel-sep .rs-v {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--rel-dim);
}
