/* ---- Entrant sports card --------------------------------------------
   The card is authored at 750x1050 and only ever SCALED. The stage sets
   --card-scale; nothing inside reflows. Muted ink is color-mix into its own
   ground, never opacity -- opacity greys out over cardboard and drifts per
   surface.

   Every <p> on the card is qualified with the .fyf-sportscard-stage ancestor
   (two classes, (0,2,0)) rather than left as a bare class ((0,1,0)).
   fyf_foundation.css's `.fyf p{margin:0 0 1em}` is a class+element selector
   ((0,1,1)), which outranks a bare class regardless of source order or
   !important-free intent -- a 1em bottom margin computed AT THAT ELEMENT'S
   OWN FONT SIZE, so it was landing as 136px under the spice word (font-size:
   136px) and 24px under the lock stamp (font-size: 24px), not the 0/32px the
   rules below actually declare. Same trap ContestsController documents for
   `.fyf h1`-`h4` against Tailwind headings, and the same fix marketing.css
   already uses for .fyf-hero__headline and .fyf-section__headline: two
   classes beats one class-plus-element on specificity, so this wins without
   sprinkling !important anywhere. Applied consistently to every <p>-rendered
   class in this file, including the wide-canvas aside's. */

.fyf-sportscard-stage[data-parallel="pink"] {
  --stock: var(--fyf-stock-tint);
  --stock-ink: var(--fyf-charcoal);
  --frame: var(--fyf-pink);
  --frame-ink: var(--fyf-charcoal);
  --name: var(--fyf-pink);
  --name-deep: var(--fyf-pink-deep);
  --name-shadow: var(--fyf-charcoal);
  --accent: var(--fyf-yellow);
  --well: var(--fyf-charcoal);
  --rule: var(--fyf-charcoal);
}

.fyf-sportscard-stage {
  --stock-mute: color-mix(in oklab, var(--stock-ink) 66%, var(--stock));
  --frame-mute: color-mix(in oklab, var(--frame-ink) 72%, var(--frame));
  --hair: color-mix(in oklab, var(--stock-ink) 30%, var(--stock));
  --hair-solid: color-mix(in oklab, var(--stock-ink) 52%, var(--stock));

  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  box-sizing: border-box;
  overflow: hidden;
  background: #241826;
  font-variant-numeric: tabular-nums;
  /* The side-by-side pair's gap, scaled with the cards it separates -- see
     EntrantCardComponent#stage_style. Zero when only one card renders. */
  gap: calc(var(--stage-gap, 0px) * var(--card-scale, 1));
}

.fyf-sportscard-stage[data-canvas="wide"] { background: #1a1220; }
/* The :card canvas is ALWAYS embedded directly in a page (the moment screen,
   the public entry page) -- the screenshot pipeline only ever requests
   :wide (see BuildEntrantCardJob / card.html.erb). The dark "desk" colour
   makes sense standing alone under a card on its own; on a page with its own
   cream background it read as a stray dark frame, worst of all in the
   rounded-corner slivers .fyf-sportscard's own border-radius exposes. */
.fyf-sportscard-stage[data-canvas="card"] { background: transparent; }

/* Unpadded measurement box for card_scale_controller.js -- see the two page
   templates that wrap the card in this. `justify-content: center` only
   matters if this frame is ever wider than the (already-shrunk-to-fit)
   card, which does not happen at either page's current container width but
   costs nothing to guard against a future wider one. */
.fyf-card-frame { display: flex; justify-content: center; }

.fyf-sportscard-stage__backdrop { display: none; }
.fyf-sportscard-stage[data-canvas="wide"] .fyf-sportscard-stage__backdrop {
  display: block;
  position: absolute; inset: 0;
  background: var(--fyf-turf-deep) url("/assets/fyf/turf-plate-wide-38d35ff5.png") center / cover;
  filter: var(--turf-crisp);
}
.fyf-sportscard-stage[data-canvas="wide"] .fyf-sportscard-stage__backdrop::after {
  content: ""; position: absolute; inset: 0; background: var(--scrim-turf);
}

/* ---- Square / story: the social canvases ----------------------------
   Same turf-and-scrim treatment as wide, plus the centred card and the
   social chrome (eyebrow up top, CTA row down bottom). All chrome geometry
   (--chrome-*) is written inline by EntrantCardComponent#stage_style from
   the same CANVASES row that sizes the stage, so the CSS reads numbers
   rather than restating them per canvas. */
.fyf-sportscard-stage[data-canvas="square"],
.fyf-sportscard-stage[data-canvas="story"] { justify-content: center; }

.fyf-sportscard-stage[data-canvas="square"] .fyf-sportscard-stage__backdrop,
.fyf-sportscard-stage[data-canvas="story"] .fyf-sportscard-stage__backdrop {
  display: block;
  position: absolute; inset: 0;
  background: var(--fyf-turf-deep) url("/assets/fyf/turf-plate-wide-38d35ff5.png") center / cover;
  filter: var(--turf-crisp);
}
/* The story stage is 1080x1920 -- the tall plate keeps the grass from
   stretching. background-image alone so the shorthand above still carries
   the fallback colour and sizing. */
.fyf-sportscard-stage[data-canvas="story"] .fyf-sportscard-stage__backdrop {
  background-image: url("/assets/fyf/turf-plate-tall-b37eaad0.png");
}
.fyf-sportscard-stage[data-canvas="square"] .fyf-sportscard-stage__backdrop::after,
.fyf-sportscard-stage[data-canvas="story"] .fyf-sportscard-stage__backdrop::after {
  content: ""; position: absolute; inset: 0; background: var(--scrim-turf);
}

.fyf-sportscard-stage .fyf-sportscard-chrome__eyebrow {
  position: absolute; top: var(--chrome-top); left: 0; right: 0; z-index: 2;
  margin: 0; text-align: center; white-space: nowrap;
  font-family: var(--font-subhead); font-weight: 700;
  font-size: var(--chrome-eyebrow); letter-spacing: .2em; text-transform: uppercase;
  color: var(--fyf-cream);
}
.fyf-sportscard-stage .fyf-sportscard-chrome__cta {
  position: absolute; bottom: var(--chrome-bottom); left: 0; right: 0; z-index: 2;
  margin: 0; display: flex; align-items: center; justify-content: center; gap: 24px;
  font-family: var(--font-subhead); font-weight: 700;
  font-size: var(--chrome-line); letter-spacing: .1em; text-transform: uppercase;
  color: var(--fyf-cream);
}
/* The oval device -- the brand keyline, ringing the one loud phrase. */
.fyf-sportscard-stage .fyf-sportscard-chrome__oval {
  border: 3px solid currentColor; border-radius: 50%;
  padding: .18em .7em; white-space: nowrap;
}
.fyf-sportscard-stage .fyf-sportscard-chrome__domain {
  font-size: .62em; letter-spacing: .16em; color: var(--fyf-cream-deep); white-space: nowrap;
}

/* The scale transform. transform-origin top left plus an explicitly sized box
   so the scaled card occupies its real footprint in the flex row. */
.fyf-sportscard {
  position: relative;
  flex: none;
  transform: scale(var(--card-scale));
  transform-origin: top left;
  margin-bottom: calc(1050px * (var(--card-scale) - 1));
  margin-right: calc(750px * (var(--card-scale) - 1));
  box-sizing: border-box;
  padding: 18px;
  border-radius: 26px;
  /* Flat stock -- the cardboard cross-grain read as a grid over the whole
     card and came out as noise in the exported PNG. The worn-edge inset
     stays: it shades the rim, not the field. */
  background-color: var(--stock);
  box-shadow: var(--edge-card-wear);   /* inset only — never a blurred drop shadow */
  color: var(--stock-ink);
}

.fyf-sportscard__frame {
  position: relative;
  display: flex; flex-direction: column;
  height: 100%;
  border: 3px solid var(--rule);
}


/* Header band */
.fyf-sportscard__header {
  background: var(--frame); color: var(--frame-ink);
  border-bottom: 3px solid var(--rule);
  padding: 16px 24px 18px;
}
.fyf-sportscard__meta {
  display: flex; align-items: baseline; justify-content: space-between;
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase; white-space: nowrap;
  color: var(--frame-mute);
}
.fyf-sportscard__franker { color: var(--frame-ink); }
/* The left cell gives before the row overflows the card: an over-long
   CONTEST name ellipsizes at the frame's edge rather than shoving the
   franker number through it. The franker never shrinks -- it is the card's
   serial. Only metadata may lose its tail here: the entrant's name used to
   share this cell and was the thing that got cut, which is why it no longer
   lives in the header (see .fyf-sportscard__label--byline). */
.fyf-sportscard__meta > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.fyf-sportscard__meta > .fyf-sportscard__franker { flex: none; }
/* The header carries the byline only when the board promoted nobody, so
   there is no call row to hold it -- and the body then has neither the
   surname nor the ladder, which is the one time a second header line is
   affordable. Full width, wraps freely. */
.fyf-sportscard-stage .fyf-sportscard__byline--header {
  margin: 6px 0 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--frame-ink);
}
.fyf-sportscard-stage .fyf-sportscard__archetype {
  margin: 10px 0 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 60px;
  line-height: 1; letter-spacing: .005em; text-transform: uppercase;
  color: var(--frame-ink);
}

/* Body */
.fyf-sportscard__body { flex: 1; display: flex; flex-direction: column; padding: 32px 24px 24px; }
.fyf-sportscard-stage .fyf-sportscard__label {
  margin: 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--stock-mute);
}
/* The entrant's byline: the far end of the "On the record" row, the same
   space-between pair the ladder head draws ("Me … Consensus"). Here
   because the header could not hold it -- its meta row has 464px beside
   the franker serial and "contest · name" needs 501px at that type, and a
   second header line costs 31px the plate does not have once the archetype
   renders (18px of slack under the lock stamp). This row has the whole
   660px and nothing on its right. The name never ellipsizes: a long one
   steps its type down (EntrantCardComponent::BYLINE_STEPS, inline
   font-size) and past the last step it wraps. */
.fyf-sportscard__label--byline { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; }
.fyf-sportscard__label--byline > span:first-child { flex: none; }
.fyf-sportscard__label--byline .fyf-sportscard__byline {
  min-width: 0; text-align: right; overflow-wrap: anywhere;
  color: var(--stock-ink);
}

/* The one spice word. Size is set inline in whole steps by the component —
   never wraps, never reflows. */
.fyf-sportscard-stage .fyf-sportscard__spice {
  margin: 12px 0 0;
  font-family: var(--font-spice); text-transform: uppercase;
  line-height: .84; letter-spacing: -.03em; white-space: nowrap;
  color: var(--name);
  text-shadow: .05em .05em 0 var(--name-shadow);
  -webkit-text-stroke: .012em currentColor;
}
/* The stacked full name: first name rides as a small tracked subhead line
   over the surname's spice word -- NOT a shrunken spice copy: at ~40px the
   inherited hard shadow and stroke turned the small line to mud. Shadow and
   stroke are explicitly zeroed; the deep name ink keeps it on-palette.
   Artboard numbers: 30px / .14em, 6px above the surname. */
.fyf-sportscard__spice-first {
  display: block;
  font-family: var(--font-subhead); font-weight: 700;
  font-size: 30px; line-height: 1; letter-spacing: .14em;
  margin-bottom: 6px;
  color: var(--name-deep);
  text-shadow: none;
  -webkit-text-stroke: 0;
}
.fyf-sportscard__spice-last { display: block; }

/* Conviction ladder */
.fyf-sportscard__ladder { margin-top: 32px; }
.fyf-sportscard__ladder-head {
  display: flex; align-items: baseline; justify-content: space-between;
  font-family: var(--font-subhead); font-weight: 700; font-size: 18px;
  letter-spacing: .14em; text-transform: uppercase;
}
.fyf-sportscard__ladder-mine { color: var(--name-deep); }
.fyf-sportscard__ladder-theirs { color: var(--stock-mute); }

/* The positional pair rides in the head row itself -- the plate has 3px of
   vertical slack with an archetype, so a second line is not affordable. Same
   size as the head words, tracked a touch tighter so "Me · TE11 … TE29 ·
   Consensus" still fits the 660px row at the widest labels ("WR104"). */
.fyf-sportscard__ladder-pos { letter-spacing: .06em; opacity: .85; }

.fyf-sportscard__track { position: relative; height: 168px; margin-top: 16px; }
.fyf-sportscard__rail { position: absolute; left: 0; right: 0; bottom: 80px; height: 5px; background: var(--hair); }
.fyf-sportscard__conviction { position: absolute; bottom: 80px; height: 5px; background: var(--name); }

/* .marker is a zero-size anchor point at its true `left: N%` -- NOT a box
   its children shrink-wrap and get centered together, which is what used to
   make the two markers' labels collide. The dot below always centers on
   this exact point (bottom: 0; left: 50%; translateX(-50%) of the DOT's own
   24px, not the marker's), so the dots stay correctly placed no matter what
   the rank label does. The rank label defaults to the same centering, but
   see the --crowded-left/--crowded-right modifiers below: those change only
   the label's anchor, never the dot's. */
.fyf-sportscard__marker { position: absolute; bottom: 64px; width: 0; }
.fyf-sportscard__marker-rank {
  position: absolute; bottom: 34px; left: 50%; transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--font-subhead); font-weight: 700; font-size: 60px;
  letter-spacing: -.015em; line-height: 1;
}
.fyf-sportscard__marker--mine .fyf-sportscard__marker-rank { color: var(--name-deep); }
.fyf-sportscard__marker--consensus .fyf-sportscard__marker-rank { color: var(--stock-mute); }
.fyf-sportscard__marker-dot {
  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  width: 24px; height: 24px; border-radius: 999px; border: 3px solid var(--rule);
}
.fyf-sportscard__marker--mine .fyf-sportscard__marker-dot { background: var(--name); }
.fyf-sportscard__marker--consensus .fyf-sportscard__marker-dot { background: var(--stock); }

/* Two positional ranks centered on their own dots collide whenever the dots
   are close together -- both labels grow toward the same midpoint, and at
   60px type that overlap starts well before the dots themselves touch (see
   Contests::EntrantCardComponent::MARKER_CROWD_THRESHOLD_PCT for the exact
   number and the geometry it's based on). When the component decides the
   pair is crowded, the LOWER-percentage marker's label anchors its RIGHT
   edge to its own dot (grows left, away from the other label) and the
   higher one anchors its LEFT edge (grows right) -- so the two labels
   diverge outward instead of stacking on the same center. The dot rule
   above is untouched by either modifier: only the label's horizontal anchor
   ever moves. */
/* 6px, not 0 -- at the limit (two ranks that coincide exactly, exercised in
   the browser-verification case, not by real data) edge-anchoring at 0
   still guarantees no character overlap, but butts the two labels together
   with no visible gap at all ("RB33RB40"). This small fixed clearance keeps
   a readable gap between the pair even then, without depending on either
   label's actual width. */
.fyf-sportscard__marker--crowded-left .fyf-sportscard__marker-rank {
  left: auto; right: 6px; transform: none;
}
.fyf-sportscard__marker--crowded-right .fyf-sportscard__marker-rank {
  left: 6px; transform: none;
}

.fyf-sportscard__gap {
  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%) rotate(-2deg);
  background: var(--fyf-orange); color: var(--fyf-charcoal);
  border: 3px solid var(--fyf-charcoal); border-radius: var(--radius-pill);
  padding: 6px 24px 8px; white-space: nowrap;
  font-family: var(--font-subhead); font-weight: 700; font-size: 24px; letter-spacing: .1em;
  box-shadow: var(--shadow-hard-sm);
}

/* Detail block — all variants occupy the same slot so the lock stamp stays put.
   margin-bottom is the lock stamp's minimum clearance -- see __lock. */
.fyf-sportscard__detail { margin-top: 32px; padding-top: 16px; margin-bottom: 24px; border-top: 2px solid var(--rule); }
.fyf-sportscard-stage .fyf-sportscard__prose {
  margin: 8px 0 0;
  font-family: var(--font-header); font-size: 31px; line-height: 1.18;
}
.fyf-sportscard__figures { display: flex; gap: 3px; margin: 12px 0 0; background: var(--rule); border: 3px solid var(--rule); }
.fyf-sportscard__figures > div { flex: 1; background: var(--stock); padding: 12px 4px 14px; text-align: center; }
.fyf-sportscard__figures dt {
  font-family: var(--font-subhead); font-weight: 700; font-size: 16px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--stock-mute);
}
.fyf-sportscard__figures dd {
  margin: 0; font-family: var(--font-subhead); font-weight: 700; font-size: 44px; letter-spacing: -.015em;
}

.fyf-sportscard-stage .fyf-sportscard__lock {
  /* The 24px clearance the README wants above the stamp lives OUTSIDE the
     border -- a previous padding-top override put it INSIDE, which slumped
     the text to the bottom of its own box. margin-top: auto pins the stamp
     to the slot's floor; the detail block above carries the minimum gap
     (see .fyf-sportscard__detail's margin-bottom). */
  margin: auto 0 0; align-self: flex-start;
  border: 3px solid var(--name-deep); color: var(--name-deep);
  padding: 8px 20px 10px;
  transform: rotate(-2.5deg);
  font-family: var(--font-subhead); font-weight: 700; font-size: 24px;
  letter-spacing: .14em; text-transform: uppercase;
}

/* Footer bar */
.fyf-sportscard__footer {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  border-top: 3px solid var(--rule); padding: 16px 20px;
}
.fyf-sportscard__logo { height: 52px; width: auto; }
.fyf-sportscard__footer-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.fyf-sportscard__url {
  font-family: var(--font-subhead); font-weight: 700; font-size: 18px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--stock-mute);
}
.fyf-sportscard__cta {
  white-space: nowrap;
  background: var(--fyf-orange); color: var(--fyf-charcoal);
  border: 3px solid var(--fyf-charcoal); border-radius: var(--radius-pill);
  padding: 6px 24px 8px;
  font-family: var(--font-subhead); font-weight: 700; font-size: 26px;
  line-height: 1; letter-spacing: .12em; text-transform: uppercase;
  box-shadow: var(--shadow-hard-sm);
}

/* ---- Identity face (Face C) ------------------------------------------
   Archetype-led. Header trades the take face's meta band for the entrant's
   name beside their circled number; the well prints the archetype as the
   one spice word; the trio restates the board's departures; the torn slab
   carries the same detail block the take face's lower third does. */
.fyf-sportscard__idhead {
  display: flex; align-items: center; gap: 18px;
  background: var(--frame); color: var(--frame-ink);
  border-bottom: 3px solid var(--rule);
  padding: 16px 18px;
}
.fyf-sportscard__idnumber {
  flex: none; width: 76px; height: 76px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); border: 3px solid var(--rule);
  font-family: var(--font-subhead); font-weight: 700; font-size: 30px;
  color: var(--fyf-charcoal);
}
.fyf-sportscard-stage .fyf-sportscard__idname {
  margin: 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 46px;
  line-height: 1; text-transform: uppercase; color: var(--frame-ink);
}
.fyf-sportscard-stage .fyf-sportscard__idmeta {
  margin: 8px 0 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--frame-mute);
}

.fyf-sportscard__well {
  position: relative;
  background: var(--well); color: var(--fyf-cream);
  border-bottom: 3px solid var(--rule);
  padding: 40px 24px; text-align: center;
}
/* The halftone screen at the well's own opacity -- an overlay rather than a
   background on the well itself, so the dots dim without dimming the type. */
.fyf-sportscard__well::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--texture-halftone); background-size: 6px 6px;
  opacity: .25;
}
.fyf-sportscard-stage .fyf-sportscard__well-label {
  margin: 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--fyf-cream-deep);
}
/* The spice word again -- size set inline in whole steps by the component
   (see EntrantCardComponent::ARCHETYPE_SPICE_STEPS); a two-word archetype
   may wrap once, set solid. */
.fyf-sportscard-stage .fyf-sportscard__well-archetype {
  margin: 12px 0 0;
  font-family: var(--font-spice); text-transform: uppercase;
  line-height: .84; letter-spacing: -.03em;
  color: var(--name);
  text-shadow: .05em .05em 0 var(--name-shadow);
  -webkit-text-stroke: .012em currentColor;
}
.fyf-sportscard-stage .fyf-sportscard__well-claim {
  margin: 24px 0 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 24px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--fyf-cream);
}

.fyf-sportscard__trio {
  display: flex; gap: 3px; margin: 0;
  background: var(--rule); border-bottom: 3px solid var(--rule);
}
.fyf-sportscard__trio > div { flex: 1; background: var(--stock); padding: 18px 4px 20px; text-align: center; }
.fyf-sportscard__trio dt {
  font-family: var(--font-subhead); font-weight: 700; font-size: 18px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--stock-mute);
}
.fyf-sportscard__trio dd {
  margin: 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 60px; letter-spacing: -.015em;
}
.fyf-sportscard__trio-lead dt, .fyf-sportscard__trio-lead dd { color: var(--name-deep); }

.fyf-sportscard__slab {
  flex: 1; display: flex; flex-direction: column;
  margin: 24px 20px; padding: 24px 24px 20px;
  background: var(--fyf-cream-tint);
  clip-path: var(--clip-torn-top);
  transform: rotate(-.8deg);
}
.fyf-sportscard-stage .fyf-sportscard__slab-label {
  margin: 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 18px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--name-deep);
}
.fyf-sportscard-stage .fyf-sportscard__slab-prose {
  margin: 8px 0 0;
  font-family: var(--font-header); font-size: 32px; line-height: 1.18;
  color: var(--fyf-charcoal);
}
.fyf-sportscard-stage .fyf-sportscard__slab-call {
  margin: 10px 0 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 54px;
  line-height: 1; text-transform: uppercase; color: var(--fyf-charcoal);
}
.fyf-sportscard-stage .fyf-sportscard__slab-gap {
  margin: 8px 0 0;
  font-family: var(--font-subhead); font-weight: 700; font-size: 22px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--fyf-charcoal-80);
}
/* Inside the slab the lock keeps its pin-to-bottom job; the slab's own
   cream-tint ground already separates it, so no extra top clearance. */
.fyf-sportscard__slab .fyf-sportscard__lock { margin-top: auto; }

/* ---- The back ---------------------------------------------------------
   One back serves every face: the Face C header, the convictions table,
   the judging slab with its blank scorecard, and the motto footer. */
.fyf-sportscard__convictions { padding: 24px 22px 8px; }
.fyf-sportscard__convictions-caption {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding-bottom: 16px;
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase; white-space: nowrap;
}
.fyf-sportscard__convictions-title { color: var(--name-deep); }
.fyf-sportscard__convictions-count { color: var(--stock-mute); }

.fyf-sportscard__gaps { width: 100%; border-collapse: collapse; }
.fyf-sportscard__gaps th {
  font-family: var(--font-subhead); font-weight: 700; font-size: 17px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--stock-mute);
  text-align: right; padding: 0 0 10px; border-bottom: 2px solid var(--rule);
}
.fyf-sportscard__gaps th:first-child { text-align: left; }
.fyf-sportscard__gaps th.fyf-sportscard__gaps-gaphead { text-align: left; padding-left: 20px; }
.fyf-sportscard__gaps td {
  font-family: var(--font-subhead); font-weight: 700; font-size: 28px;
  padding: 12px 0; border-bottom: 1px solid var(--hair); white-space: nowrap;
}
.fyf-sportscard__gaps tbody tr:last-child td { border-bottom: none; }
.fyf-sportscard__gaps-player { text-align: left; }
.fyf-sportscard__gaps-me { text-align: right; }
.fyf-sportscard__gaps-consensus { text-align: right; color: var(--stock-mute); }
/* Two classes ((0,2,0)) outrank the `.fyf-sportscard__gaps td` default
   ((0,1,1)) for the padding, without !important -- same specificity trick
   documented at the top of this file. Flex inside the cell lays the track
   beside its number. */
.fyf-sportscard__gaps .fyf-sportscard__gaps-gap {
  display: flex; align-items: center; gap: 12px; padding-left: 20px;
}

/* The DIVERGING track. The gap column used to draw one left-anchored bar
   per row, same colour, sized on the absolute delta -- so "I have him 18
   spots higher" and "I have him 18 spots lower" were the same picture, and
   the only thing separating them was a U+2212 the eye skips. This table is
   the whole argument of the card's back; direction cannot be the part you
   have to read for.

   So: a fixed track with a centre rule, a bar that grows RIGHT for a
   promotion and LEFT for a fade, a triangle pointing the way the call
   moves, and separate ink per direction. Three redundant channels, none of
   which needs a legend. The track keeps the 140px the single bar had, so
   the column's footprint on the 750px plate is unchanged. */
.fyf-sportscard__gaps-track {
  position: relative; flex: none;
  width: 140px; height: 18px;
  border: 2px solid var(--rule);
  background: transparent;
}
/* The centre rule the bars diverge from -- 2px, on the track's own border
   colour, drawn inside the box so it lines up across all four rows.
   ::after, not ::before: a pseudo-element paints in tree order against its
   absolutely-positioned siblings, and as ::before the bar covered the half
   of the rule it grew over -- leaving the axis to be inferred from where
   the fill happened to stop. Last child, so it sits on top of every bar. */
.fyf-sportscard__gaps-track::after {
  content: ""; position: absolute; top: -2px; bottom: -2px; left: 50%;
  width: 2px; margin-left: -1px; background: var(--rule);
}
.fyf-sportscard__gaps-bar { position: absolute; top: 0; bottom: 0; }
.fyf-sportscard__gaps-gap--up .fyf-sportscard__gaps-bar {
  left: 50%; background: var(--name);
}
.fyf-sportscard__gaps-gap--down .fyf-sportscard__gaps-bar {
  right: 50%; background: var(--stock-ink);
}

/* The arrow: a CSS triangle, not a glyph. The back renders through the
   headless screenshot pipeline as well as in the browser, and a font that
   does not ship a U+25B2 substitutes a box there and nowhere else. */
.fyf-sportscard__gaps-num {
  display: inline-flex; align-items: center; gap: 8px;
}
.fyf-sportscard__gaps-arrow {
  width: 0; height: 0; flex: none;
  border-left: 9px solid transparent; border-right: 9px solid transparent;
}
.fyf-sportscard__gaps-gap--up .fyf-sportscard__gaps-arrow {
  border-bottom: 12px solid var(--name);
}
.fyf-sportscard__gaps-gap--down .fyf-sportscard__gaps-arrow {
  border-top: 12px solid var(--stock-ink);
}
.fyf-sportscard__gaps-gap--up .fyf-sportscard__gaps-num { color: var(--name-deep); }

/* The widest gap still leads -- but the fill colour is direction's now, so
   the lead is marked by weight instead: a heavier track outline, which
   reads on either direction and on a monochrome print. */
.fyf-sportscard__gaps-lead .fyf-sportscard__gaps-track { border-width: 3px; }

.fyf-sportscard__slab--judging { margin: 24px 22px 0; flex: none; }
/* The back's CTA block -- pinned above the footer, OUTSIDE the slab. */
.fyf-sportscard-stage .fyf-sportscard__backcta {
  margin: auto 22px 0; padding-top: 20px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
}
.fyf-sportscard__scorecard { display: flex; gap: 12px; margin: 20px 0 0; }
.fyf-sportscard__scorecard > div {
  flex: 1; text-align: center;
  border: 2px dashed var(--fyf-charcoal-30);
  padding: 10px 6px 12px;
}
.fyf-sportscard__scorecard dt {
  font-family: var(--font-subhead); font-weight: 700; font-size: 16px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--fyf-charcoal-80);
}
/* Ship the blanks -- the em dashes fill in only after the season grades. */
.fyf-sportscard__scorecard dd {
  margin: 0; font-family: var(--font-subhead); font-weight: 700; font-size: 40px;
  color: var(--fyf-charcoal-30);
}
.fyf-sportscard-stage .fyf-sportscard__slab-cta {
  margin: auto 0 0; padding-top: 20px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
}
/* The 24px variant of the CTA pill, for the slab. */
.fyf-sportscard__cta--slab { font-size: 24px; }
.fyf-sportscard__slab-url {
  font-family: var(--font-subhead); font-weight: 700; font-size: 18px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--fyf-charcoal-80);
}
.fyf-sportscard__motto {
  font-family: var(--font-subhead); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--stock-mute);
}

/* Wide-canvas side column */
.fyf-sportscard-aside {
  position: absolute; right: 96px; top: 0; bottom: 0; width: 720px;
  display: flex; flex-direction: column; justify-content: center; gap: 28px;
  color: var(--fyf-cream);
}
.fyf-sportscard-stage .fyf-sportscard-aside__eyebrow {
  margin: 0; font-family: var(--font-subhead); font-weight: 700; font-size: 28px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--fyf-yellow);
}
.fyf-sportscard-stage .fyf-sportscard-aside__quote {
  margin: 0; font-family: var(--font-header); font-size: 92px; line-height: 1.04;
  letter-spacing: -.01em; text-wrap: pretty;
}
.fyf-sportscard-stage .fyf-sportscard-aside__meta {
  margin: 0; font-family: var(--font-subhead); font-weight: 700; font-size: 26px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--fyf-cream-deep);
}
/* Stacked, not a row. Side by side, the CTA pill and the URL need 963px of
   min-content inside a 720px aside -- flex items do not shrink below their
   min-content, and the URL is one unbreakable token at 24px with .16em of
   tracking -- so the URL ran 147px past the STAGE's right edge and the
   screenshot cut it to "FRANK.FRONTYARDFANTA". Measured in headless Chrome
   at the wide canvas's real 1920x1080, both faces: the entrant card needed
   963px, the unclaimed card 947px. Same column shape the left plate's
   __slab-cta already uses. */
.fyf-sportscard-stage .fyf-sportscard-aside__cta {
  display: flex; flex-direction: column; align-items: flex-start; gap: 16px; margin: 0;
}
.fyf-sportscard-aside__url {
  font-family: var(--font-subhead); font-weight: 700; font-size: 24px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--fyf-cream-deep);
  /* A longer host than today's still cannot reach the frame: it wraps
     instead of overflowing, since nothing outside this file governs how
     long card_host is. */
  max-width: 100%; overflow-wrap: anywhere;
}

/* ---- The unclaimed card (Contests::ClaimPreviewCardComponent) ---------
   The portrait slot is defined on the entrant card and unfilled there (no
   photos in the product yet); the unclaimed card fills it with a plainly-
   placeholder frame: dashed rule, a flat silhouette, a label. Sized so the
   rest of the body's stack (the name, the claim block, the lock stamp)
   lands the footer on the same floor as the entrant card's: the body has
   ~805px of content height; 380 here + ~150 of name + ~175 of claim block
   + the stamp leaves ~50px of slack at the largest name step. */
.fyf-sportscard__portrait--placeholder {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  height: 380px;
  border: 3px dashed var(--hair-solid);
  border-radius: 12px;
  background: color-mix(in oklab, var(--stock-ink) 5%, var(--stock));
}
/* Head over shoulders, two flat shapes in the hairline ink. */
.fyf-sportscard__portrait-silhouette {
  position: relative; width: 190px; height: 190px; overflow: hidden;
}
.fyf-sportscard__portrait-silhouette::before {
  content: ""; position: absolute; top: 4px; left: 50%; transform: translateX(-50%);
  width: 84px; height: 84px; border-radius: 50%; background: var(--hair-solid);
}
.fyf-sportscard__portrait-silhouette::after {
  content: ""; position: absolute; top: 104px; left: 50%; transform: translateX(-50%);
  width: 170px; height: 150px; border-radius: 85px 85px 0 0; background: var(--hair-solid);
}
.fyf-sportscard__portrait-label {
  font-family: var(--font-subhead); font-weight: 700; font-size: 26px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--stock-mute);
}
/* The claim block sits in the detail slot; the label is the entrant card's
   own label style, so nothing new to set. The prose inherits __prose. */
