/* ===========================================================================
   THE LETTERING
   ---------------------------------------------------------------------------
   Two real faces, self-hosted, supplied by the owner - which finally makes the
   app look the same on every phone instead of borrowing whatever each handset
   happens to have installed.

   ANTON carries the shouting: the wordmark, round numbers, the countdown, the
   badge on a sticker. It is a single very heavy condensed weight, drawn for
   posters, and it is the closest thing to real album lettering.

   ARCHIVO BLACK does the headings and labels - still heavy, but square and
   wide where Anton is narrow, so the two never look like the same voice at
   different sizes.

   Both are `font-display: swap`: text shows immediately in a fallback and
   re-renders when the file lands, which matters on a phone on a train.
   =========================================================================== */
@font-face {
  font-family: "Anton";
  src: url("/fonts/anton.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Archivo Black";
  src: url("/fonts/archivo-black.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ===========================================================================
   LMS WINS

   A matchday programme, not an app that happens to be about football.
   The references are the printed fixture list and the pools coupon: ruled
   rows, condensed type, figures that line up, and pitch geometry drawn in
   chalk. Deliberately not a photograph of grass - a pitch behind body text
   costs contrast and gives nothing back.

   The rules that hold it together:
     - a near-white page tinted toward the pitch green, white cards. Tinted
       toward the brand's own hue, never toward warmth: the warm cream that
       used to live here is the most over-produced background in generated
       design, and it is what made the app look machine-made
     - one thing per screen is loud. On the pick screen that is the deadline,
       because it is the only fact with a clock on it
     - gold is the ONLY accent. It appears in two forms, and the difference
       matters: --gold is a FILL, for buttons and badges, and always carries
       --on-gold text. --gold-ink is the only gold legible as TEXT on paper.
       Using --gold as text on white gives about 1.7:1, which is unreadable
     - hairlines, not outlines
     - green means through, red means out. Both darkened from the dark theme's
       versions, which were chosen to glow on black and are far too pale here
     - surfaces are described by --lift, --well and --hair rather than by
       hard-coded blacks and whites, so the whole theme turns on one block
   =========================================================================== */

:root {
  /* ===========================================================================
     THE ALBUM
     ---------------------------------------------------------------------------
     The world is a football sticker album. Not a metaphor laid over the app -
     the app already IS the thing an album is for. You collect clubs, you can
     only use each one once, and the page fills up as the season goes.

     So: a cobalt album page, clubs sitting in die-cut white frames, and the
     one you are riding this week catching the light like a shiny.

     WHAT REPLACED WHAT, AND WHY

     The page ground is cobalt, not near-white. The old light page with chalk
     pitch lines was the first thing anybody would guess for a football app,
     and it made every screen read at the same volume. Colour at page scale is
     what gives the crests something to sit on; twenty club badges on a pale
     ground is a spreadsheet, on cobalt it is an album page.

     Gold is a FILL and an accent on the dark ground. It is never text on white
     - that is 1.7:1 and unreadable - which is what --gold-ink exists for.
     =========================================================================== */

  /* The album page itself. */
  --field: #12307C;
  --field-soft: #0A1F57;
  --field-deep: #071540;

  /* The stickers, and anything printed on card rather than on the page. */
  --raised: #FFFFFF;
  --raised-hi: #F7F9FF;

  /* Ink on card. */
  --text: #0A1836;
  --text-soft: #3D4A6B;
  --text-mute: #6B7796;

  /* Ink on the album page. Tinted from the ground's own hue, never grey. */
  --on-field: #FFFFFF;
  --on-field-soft: #B9C8EA;
  --on-field-mute: #8EA2D0;

  /* Gold: the album's own accent. Foil, the count that matters, section rules. */
  --gold: #FFD400;
  --gold-hi: #FFE87A;
  --gold-fill: linear-gradient(180deg, var(--gold-hi), var(--gold));
  /*
   * "Gold as text" is now RED.
   *
   * Thirty-odd rules across every tab wrote in --gold-ink: headings, the day
   * names, the live column, the stake, invite links, summaries, tags. Chasing
   * them one at a time is how the gold kept coming back after each pass. They
   * all read the same token, so the token is what changes - once, here, and
   * every one of them turns red together.
   *
   * --gold itself is untouched. That is the FILL: the foil on a picked club,
   * the band across the top, the lit tab. Yellow on navy is the album's own
   * accent and reads at 7.3:1; it is only gold-as-ink-on-white that was both
   * hard to read and off-theme.
   */
  --gold-ink: #A81E18;
  --gold-deep: #A81E18;
  --gold-dim: rgba(255, 212, 0, .34);
  --gold-faint: rgba(255, 212, 0, .14);
  --on-gold: #12151C;

  /* The foil. A real shiny shifts as you tilt it, so this is a band of hues
     rather than a single colour - and it is the only gradient in the system
     that is allowed to be decorative, because on a sticker it is the point. */
  --foil: linear-gradient(135deg,
    #FFC400 0%, #FFE87A 14%, #FFFFFF 26%, #FFEC9A 38%,
    #FFD400 50%, #FFFBE0 62%, #FFCE1A 76%, #FFC400 100%);
  --foil-edge: #FFD400;

  /* Through and out. Read on white card. */
  --green: #128A4C;
  --green-soft: rgba(18, 138, 76, .12);
  --green-ink: #0E6B3A;
  --red: #E4322B;
  --red-band: #C41E17;
  --red-soft: rgba(228, 50, 43, .10);
  --red-ink: #A81E18;
  --blue: #1F5FC0;

  /* Surfaces on card. */
  --lift: rgba(255, 255, 255, .75);
  --well: rgba(10, 24, 54, .05);
  --well-strong: rgba(10, 24, 54, .08);
  --hair: rgba(10, 24, 54, .12);
  --hair-strong: rgba(10, 24, 54, .20);

  /* Surfaces on the album page. */
  --page-well: rgba(0, 0, 0, .22);
  --page-hair: rgba(255, 255, 255, .16);

  --ink: var(--text);
  --ink-soft: var(--text-soft);
  --ink-mute: var(--text-mute);
  --yellow: var(--gold);
  --yellow-soft: var(--gold-faint);
  --surface: var(--raised);
  --pitch: var(--field-soft);
  --pitch-deep: var(--field-deep);
  --chalk: rgba(255, 255, 255, .40);
  --on-pitch: var(--on-field);
  --on-pitch-soft: var(--on-field-soft);

  /* Type.
     No webfont is loaded and none can be from here, so the display voice is
     drawn rather than set: the wordmark and the round number are authored SVG
     lettering, and the stack below is chosen to sit under them without
     pretending to be them. Numerals are tabular everywhere a count or a clock
     lines up in a column, which is what the old mono face was really for. */
  /*
   * No webfont can be fetched in this environment, so the voice has to come
   * from faces phones already have - and the two families that genuinely
   * differ on BOTH Android and iOS are condensed and rounded.
   *
   * Display is condensed: Roboto Condensed on Android, Avenir Next Condensed
   * on an iPhone. Narrow heavy capitals are the lettering a sticker album and
   * a fixture list are actually set in, and it is visibly not the system sans
   * every other app uses.
   *
   * Body stays a clean sans, because a condensed face is miserable to read at
   * paragraph length.
   *
   * To go further, a real face has to be self-hosted - see FONT.md.
   */
  /* The shout, and the speaking voice. */
  --shout: "Anton", "Archivo Narrow", "Roboto Condensed", sans-serif-condensed, sans-serif;
  --display: "Archivo Black", "Archivo Narrow", "Roboto Condensed", sans-serif;
  --body: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --figures: var(--body);

  --radius: 14px;
  --radius-sm: 10px;
  --radius-sticker: 5px;
  --line: 1px;

  /* Depth. A sticker sits ON the page, so it casts a real offset shadow with
     a soft blur - never a zero-offset halo, which is decoration pretending to
     be light. */
  --pop: 0 10px 26px rgba(4, 12, 38, .28), 0 2px 4px rgba(4, 12, 38, .20);
  --pop-sm: 0 4px 12px rgba(4, 12, 38, .22), 0 1px 2px rgba(4, 12, 38, .16);
  --glow: 0 0 0 1px var(--gold-dim);
}

* { box-sizing: border-box; }

html {
  /* The single type dial. Raise for larger text throughout. */
  font-size: 18px;
  scrollbar-gutter: stable;
  background: var(--field);

  /* Declared on both html and body so the browser paints the scrollbars, form
     controls and any overscroll area to match. Getting this wrong is what once
     made the website and the installed app look like two different products. */
  color-scheme: light;
}

body {
  color-scheme: light;
  margin: 0;
  /* The same top-lit gradient as the icon's field, so the app feels like the
     inside of the badge rather than a different surface. */
  background:
    radial-gradient(120% 60% at 50% 0%, #FFFFFF 0%, transparent 60%),
    var(--field);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 450;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--gold-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; font-weight: 600; }
a:hover { color: var(--gold-ink); }

/* --- chrome -------------------------------------------------------------- */

.topbar {
  max-width: 760px;
  margin: 0 auto;
  background: linear-gradient(180deg, var(--raised) 0%, var(--field-soft) 100%);
  color: var(--text);
  padding: calc(16px + env(safe-area-inset-top)) 20px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  border-bottom: var(--line) solid var(--gold-dim);
}
/* One line: "Last Man Standing" in ink, "Wins" picked out in green so the bit
   that matches the address stands out. Wraps to two lines on a narrow phone
   rather than shrinking, which keeps it readable. */
.brand {
  color: var(--text);
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.15rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1.05;
  display: block;
}
/* "Wins" picked out in solid gold ink - the word that matches the address.
   This used to be gradient-filled text (background-clip: text). Gradient text
   is decoration that carries no meaning, it renders unevenly at small sizes,
   and it disappears entirely if the background fails to paint. A single solid
   colour and a heavier weight say the same thing and always survive. */
.brand span {
  color: var(--gold-ink);
  font-weight: 700;
}
.brand:hover { color: var(--text); }
.topbar nav { display: flex; align-items: center; gap: 16px; }
.topbar nav a { font-size: 0.75rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }

main {
  max-width: 760px;
  margin: 0 auto;
  padding: 18px 14px 0;
  display: grid;
  gap: 18px;
}

.masthead {
  /* One item now that the serial has gone - centred rather than pushed left. */
  display: flex; justify-content: center; align-items: baseline;
  max-width: 760px; margin: 0 auto;
  padding: 10px 20px;
  background: transparent;
  border-bottom: var(--line) solid var(--gold-faint);
  color: var(--gold-deep);
  font-family: var(--display);
  font-size: 0.5625rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
}

/* Panels, lifted off the field by shadow and a lit top edge. The hairline is
   gold at low opacity - present, never loud. */
.card {
  background: linear-gradient(180deg, var(--raised) 0%, var(--field-soft) 100%);
  border: var(--line) solid var(--gold-dim);
  border-radius: var(--radius);
  box-shadow: var(--pop);
  padding: 22px;
}
.card.narrow { max-width: 420px; margin: 28px auto; }
.card.tight { padding: 16px 18px; }
.card.tight.ok { background: var(--green-soft); border-color: rgba(30, 138, 76, .35); }
.card.knocked { background: var(--red-soft); border-color: rgba(198, 58, 44, .35); }
.card.winner {
  background: linear-gradient(180deg, rgba(227, 178, 60, .16), rgba(227, 178, 60, .04));
  border-color: var(--gold-ink);
}

h1 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.75rem;
  letter-spacing: -.01em;
  line-height: 1.1;
  margin: 0 0 4px;
  color: var(--text);
}
/* Section headings borrow the badge's tracked-out caps. */
h2 {
  font-family: var(--display);
  font-size: 0.75rem; font-weight: 600; margin: 0 0 14px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--gold-ink);
}

.cardhead {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}

.muted, .hint { color: var(--ink-soft); font-size: 0.8125rem; margin: 3px 0; font-weight: 600; }
.hint { font-size: 0.6875rem; letter-spacing: .04em; }
.error { color: var(--red-ink); font-size: 0.8125rem; font-weight: 800; }
.warn { color: var(--ink); font-size: 0.8125rem; }

/* --- the masthead and the countdown -------------------------------------- */

/* The pick card carries the masthead, so it holds no padding of its own -
   the band has to reach the card's edges. */
.pickcard { padding: 0; overflow: hidden; }
.pickcard > *:not(.mast) { margin-left: 22px; margin-right: 22px; }
.pickcard > *:last-child { margin-bottom: 22px; }

/* Penalty-box geometry drawn in chalk.
   The box FRAMES the words rather than running behind them. The first version
   centred the box but left the text ranged left, so the chalk cut straight
   through "Round 1" and through the countdown - it read as a rendering fault
   rather than as a design. Now the text is centred and the box is inset to
   the edges, so no line ever crosses a letter.
   The D that used to break out of the box is gone: at this size there was no
   clear space left to put it in, and one accessory too many is worse than
   none. Purely decorative, so it is drawn in pseudo-elements and never
   reaches assistive tech. */
.mast {
  position: relative;
  overflow: hidden;
  background: var(--pitch);
  padding: 20px 22px 22px;
  text-align: center;
}
.mast::before {
  content: "";
  position: absolute;
  left: 18px; right: 18px; top: 12px; bottom: 12px;
  border: 2px solid var(--chalk); border-top: 0;
  pointer-events: none;
}
/* The centre spot, on the goal line the box opens onto. Small, and in the
   one place on this panel where there is never any text. */
.mast::after {
  content: "";
  position: absolute; left: 50%; top: 12px;
  width: 7px; height: 7px; margin-left: -3.5px; margin-top: -3.5px;
  border-radius: 50%; background: var(--chalk);
  pointer-events: none;
}
.mast > * { position: relative; z-index: 1; }

.mast h1 {
  color: var(--on-pitch);
  font-size: 2.1rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .005em;
  margin: 0 0 16px;
  text-wrap: balance;
}
.masteyebrow {
  font-family: var(--display);
  font-size: 0.6875rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--on-pitch-soft);
  margin: 0 0 4px;
}

.deadline { text-align: center; padding-top: 2px; }
.deadline .label {
  display: block; font-family: var(--display); font-size: 0.625rem;
  letter-spacing: .2em; text-transform: uppercase; font-weight: 600;
  color: var(--on-pitch-soft);
  margin-bottom: 3px;
}
/* Mono figures so the countdown does not jitter as the digits tick over -
   proportional numerals change width and make the whole line shuffle. */
.deadline strong {
  font-family: var(--figures); font-size: 1.75rem; font-weight: 700;
  font-variant-numeric: tabular-nums; display: block; line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--on-pitch);
}
.mast.shut { background: var(--pitch-deep); }
.deadline.urgent .label { color: #FFC9C2; }
.deadline.urgent strong { color: #FFC9C2; }

.current-pick {
  background: var(--green-soft);
  border: var(--line) solid rgba(30, 138, 76, .3);
  border-radius: var(--radius-sm);
  padding: 13px 16px;
  font-size: 0.875rem;
  margin: 0 0 6px;
}
.current-pick strong { font-family: var(--display); font-weight: 500; font-size: 1.05rem; color: var(--green-ink); }

/* --- fixture picker ------------------------------------------------------ */

.picker { display: block; margin-top: 16px; }
.pickerhint { color: var(--ink-soft); font-size: 0.8125rem; margin: 0 0 14px; }

.day { margin-bottom: 22px; }

/* A day is a heading over a printed list, not a pill. The rule under it is
   the coupon's rule - it says "the column starts here" and costs nothing. */
.dayname {
  display: block;
  font-family: var(--display);
  font-size: 0.75rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: 2px solid var(--text);
  padding: 0 2px 6px;
  margin: 0 0 2px;
}

/* Ruled rows, not cards. A fixture list is a list, and printing it as one is
   most of what makes this read as football rather than as software. Cards
   here were the lazy answer: twenty rounded boxes, all the same weight. */
.fixrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 62px minmax(0, 1fr);
  align-items: stretch;
  background: var(--raised);
  border-bottom: var(--line) solid var(--hair);
  margin-bottom: 0;
}
.fixrow:last-child { border-bottom: 0; }

.side {
  display: flex; align-items: center; gap: 11px;
  background: transparent; border: 0; color: var(--ink);
  font-family: var(--body); font-size: 0.9375rem; font-weight: 700;
  padding: 13px 14px; min-height: 64px;
  cursor: pointer; text-align: left;
  transition: background .12s ease;
}
.side.away { flex-direction: row-reverse; text-align: right; }
.side:hover:not(:disabled) { background: var(--raised-hi); }
.side:focus-visible { outline: 3px solid var(--blue); outline-offset: -3px; }

.sidename { display: flex; flex-direction: column; min-width: 0; }
.side .full {
  font-family: var(--display); font-weight: 500; font-size: 0.9375rem; line-height: 1.15;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.side .why { font-size: 0.625rem; color: var(--ink-soft); font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }

/* Your pick goes green with a tick. */
.side.selected { background: var(--green-soft); box-shadow: inset 0 0 0 1px rgba(30, 138, 76, .45); }
.side.selected .full { color: var(--green-ink); font-weight: 600; }
.side.selected:hover { background: var(--green-soft); }
/* The tick on the team you have backed.
   Pinned to the corner rather than pushed by auto margins - those worked when
   the crest and name sat side by side, and stopped meaning anything once the
   button became a column. */
.side.selected::after {
  content: '✓';
  position: absolute; top: 7px; right: 8px;
  font-family: var(--display); font-size: 0.75rem; font-weight: 800;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-deep));
  color: var(--on-gold);
  border: 0;
}
.side.away.selected::after { right: 8px; }

.side.unavailable, .side:disabled { cursor: not-allowed; color: var(--text-mute); background: var(--well); }
.side.unavailable .full { text-decoration: line-through; text-decoration-thickness: 2px; }
.side.unavailable .crest { opacity: .3; }

.ko {
  display: flex; align-items: center; justify-content: center;
  background: var(--yellow-soft);
  border-left: var(--line) solid var(--ink); border-right: var(--line) solid var(--ink);
  font-family: var(--display); font-size: 0.75rem; font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.fixrow.haspick .ko { background: var(--gold-faint); color: var(--gold-ink); }

/* --- badges -------------------------------------------------------------- */

.crest {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex: none;
  background: transparent; vertical-align: middle;
}
.crest img { width: 100%; height: 100%; object-fit: contain; display: block; }
.crest .ph {
  display: none; font-family: var(--display);
  font-size: 0.5625rem; font-weight: 600; color: var(--ink-soft);
}
.crest.failed img { display: none; }
.crest.failed .ph { display: inline; }

/* Crests sit in an outlined disc, like a badge sticker. */
/* The crest on its own - no disc behind it and no ring around it.
   Those were left over from the light sticker-book theme, where a crest needed
   something to sit on. On the dark field it just looked like a white circle. */
.crest.md {
  width: 42px; height: 42px;
  background: transparent;
  border: 0;
  padding: 0;
}
.crest.md .ph { font-size: 0.625rem; }

.crest.sealed {
  border: 2px dashed var(--ink-mute); border-radius: 50%;
  width: 28px; height: 28px;
}
.crest.sealed .lockicon { font-size: 0.5625rem; filter: grayscale(1); opacity: .6; }

/* --- chips and pills ----------------------------------------------------- */

.usedlist { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }
.chip {
  background: var(--well); border: var(--line) solid var(--hair-strong);
  color: var(--text-soft);
  border-radius: 999px;
  padding: 4px 12px; font-family: var(--display);
  font-size: 0.625rem; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
}
.chip.warn { background: var(--red-soft); border-color: rgba(198, 58, 44, .4); color: var(--red-ink); }
/* A count beside a heading. Was gold on near-black, from the dark theme. */
.pill {
  background: var(--gold); color: var(--on-gold); border-radius: 999px;
  padding: 3px 12px; font-family: var(--figures);
  font-size: 0.625rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* --- tables -------------------------------------------------------------- */

table { border-collapse: collapse; width: 100%; font-size: 0.8125rem; }
/* Table headings.
   These used to be gold text on a near-black fill - correct on the old dark
   theme, and left behind when the app went light. It read as a black bar
   across the table, except in the sticky Player column which paints its own
   white background over the top. Now a heading is what a heading is on a
   printed table: quiet type over a firm rule. */
th {
  font-family: var(--display);
  font-size: 0.625rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-soft);
  background: var(--raised);
  font-weight: 600;
  text-align: left; padding: 9px 10px;
  border-bottom: 2px solid var(--text);
}
td { padding: 10px; border-bottom: var(--line) solid var(--hair); }

.scroll { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }

.standings .player {
  position: sticky; left: 0; background: var(--surface);
  min-width: 158px; white-space: nowrap;
  font-family: var(--display); font-weight: 500; font-size: 0.875rem;
}
/* The round being played. Picked out in gold ink rather than a fill, so it
   reads as emphasis instead of as a second black bar. */
.standings th.now {
  color: var(--gold-ink);
  background: var(--gold-faint);
}
.standings tr.out .player { color: var(--ink-mute); }
.standings tr.out { background: var(--well); }
.standings tr.out .player { background: var(--well); }

.cell {
  text-align: center; min-width: 58px; padding: 9px 6px;
  font-family: var(--display); font-size: 0.6875rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: .04em;
}
.cell .cellname { display: block; margin-top: 3px; }
.cell .crest { margin: 0 auto; }

.cell.win, .cell.void_win { color: var(--green-ink); }
.cell.loss, .cell.draw, .cell.no_pick { color: var(--red-ink); }
.cell.loss .cellname, .cell.draw .cellname { text-decoration: line-through; text-decoration-thickness: 2px; }
.cell.no_pick { font-style: italic; }
.cell.pending { color: var(--ink); }
.cell.hidden { color: var(--ink-mute); }
.cell.nopick-yet { color: var(--text-mute); letter-spacing: .24em; }

.badge {
  font-family: var(--display);
  font-size: 0.5625rem; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px; margin-left: 8px; white-space: nowrap;
  border: var(--line) solid transparent;
}
.badge.alive { background: var(--green-soft); border-color: rgba(30, 138, 76, .4); color: var(--green-ink); }
.badge.out { background: var(--red-soft); border-color: rgba(198, 58, 44, .4); color: var(--red-ink); }
.badge.winner {
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-deep));
  color: var(--on-gold); font-weight: 600;
}

.legend { display: flex; gap: 16px; flex-wrap: wrap; margin: 18px 0 0; }
.key {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.6875rem; color: var(--ink-soft); font-weight: 800;
}
.key::before {
  content: ''; width: 13px; height: 13px; border-radius: 50%;
  border: var(--line) solid var(--gold-dim); background: var(--raised);
}
.key.win::before { background: var(--green); }
.key.loss::before { background: var(--red); }
.key.hidden::before { background: var(--text-mute); }

.stake {
  font-size: 0.8125rem; margin: 16px 0 0; padding-top: 14px;
  border-top: var(--line) solid var(--gold-faint);
  font-variant-numeric: tabular-nums; font-weight: 600; color: var(--gold-ink);
}
.stakenote {
  display: block; font-size: 0.6875rem; color: var(--ink-soft);
  font-weight: 600; margin-top: 3px;
}
.paidcount {
  display: inline-block; margin-left: 6px;
  background: var(--gold-faint); border: var(--line) solid var(--gold-dim);
  color: var(--gold-ink);
  border-radius: 999px;
  padding: 3px 11px; font-family: var(--display);
  font-size: 0.625rem; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
}
.paidcount.all { background: var(--green-soft); border-color: rgba(30, 138, 76, .45); color: var(--green-ink); }
.payrow { margin: 14px 0 8px; }

/* --- fixtures list (after the deadline) ---------------------------------- */

.fixtures td { border: none; padding: 8px; font-family: var(--display); font-size: 0.875rem; font-weight: 500; }
.fixtures .r { text-align: right; }
/* The score, or the kick-off time before a game starts.
   This was a near-black pill with gold text - the dark theme again. On paper
   it read as a row of black lozenges down the middle of the fixture list, and
   worse, the "in play" colour below would have been dark green ON near-black,
   which is unreadable. Figures only, in mono so the columns line up. */
.fixtures .score {
  text-align: center;
  color: var(--text);
  font-family: var(--figures);
  font-weight: 500;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fixtures .crest { margin: 0 9px; }

/* --- forms --------------------------------------------------------------- */

form { display: grid; gap: 14px; }
form.inline { display: inline-grid; grid-auto-flow: column; gap: 10px; align-items: center; margin: 0 10px 10px 0; }
label {
  display: grid; gap: 6px; font-family: var(--display);
  font-size: 0.6875rem; font-weight: 500; letter-spacing: .04em; text-transform: uppercase;
}

input, select {
  background: var(--well);
  border: var(--line) solid var(--hair);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 500;
  padding: 13px 15px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
input::placeholder { color: var(--text-mute); font-weight: 400; }
/* Focus is gold, so the eye lands on the field you are in. */
input:focus, select:focus {
  outline: none;
  border-color: var(--gold-ink);
  box-shadow: 0 0 0 3px var(--gold-faint);
}

/* Secondary by default: an outlined pill. The gold is saved for `.primary`,
   so on any screen there is exactly one obvious thing to press. */
button {
  background: var(--raised);
  color: var(--text);
  border: var(--line) solid var(--hair-strong);
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: .04em;
  padding: 12px 24px;
  cursor: pointer;
  min-height: 46px;
  transition: transform .08s ease, background .14s ease, border-color .14s ease;
}
button:hover { background: var(--well-strong); border-color: var(--gold-dim); }
button:active { transform: translateY(1px); }
button.primary {
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-deep));
  color: var(--on-gold);
  border-color: transparent;
  font-weight: 600;
}
button.primary:hover { filter: brightness(1.07); }
button.danger { background: rgba(198, 58, 44, .16); color: var(--red-ink); border-color: rgba(198, 58, 44, .4); }
button.danger:hover { background: rgba(198, 58, 44, .24); }
button.link {
  background: none; border: 0; padding: 0; min-height: 0; box-shadow: none;
  color: var(--ink); font-family: var(--body);
  font-size: 0.8125rem; font-weight: 800; text-decoration: underline;
}
button.link:hover { background: none; }
button.link:active { transform: none; }
.actions form { display: flex; gap: 8px; }

.btnlink {
  display: inline-block; background: var(--green); color: var(--ink);
  border: var(--line) solid var(--ink); border-radius: 999px;
  box-shadow: var(--pop-sm);
  padding: 12px 24px;
  font-family: var(--display); font-weight: 500; font-size: 0.8125rem;
  text-decoration: none;
}
.btnlink:active { transform: translate(3px, 3px); box-shadow: none; }

.flash {
  margin: 0 0 16px;
  border: 2px solid currentColor;
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-size: 0.9375rem;
  font-weight: 800;
  line-height: 1.35;
  box-shadow: 0 8px 20px rgba(4, 12, 38, .24);
}
.flash.ok { background: #08783F; border-color: #BDE8CE; color: #FFFFFF; }
.flash.error { background: #A81E18; border-color: #FFD0CC; color: #FFFFFF; }
.flash.warn { background: var(--field-deep); border-color: var(--gold); color: #FFFFFF; }
.flash.warn a { color: #FFFFFF; text-decoration-thickness: 2px; text-underline-offset: 3px; }

.whatsapp-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  margin: 0 0 18px;
  padding: 18px;
  background: #E8F7EE;
  border-radius: var(--radius);
}
.whatsapp-card h2 { margin: 0; color: #063D35; font-size: 1.35rem; text-transform: none; }
.whatsapp-card p { max-width: 58ch; margin: 6px 0 0; color: #174F46; line-height: 1.45; }
.whatsapp-actions {
  display: grid;
  justify-items: stretch;
  gap: 8px;
  min-width: 230px;
  text-align: center;
}
.whatsapp-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 50px;
  padding: 11px 18px;
  background: #075E54;
  color: #FFFFFF;
  border-radius: 999px;
  box-shadow: 0 8px 18px rgba(7, 94, 84, .24);
  font-weight: 850;
  line-height: 1.15;
  text-decoration: none;
}
.whatsapp-button img { flex: 0 0 auto; }
.whatsapp-button:hover { background: #064C44; }
.whatsapp-button:active { transform: translateY(1px); box-shadow: 0 4px 10px rgba(7, 94, 84, .2); }
.whatsapp-copy {
  min-height: 44px;
  padding: 9px 14px;
  background: transparent;
  border-color: #075E54;
  box-shadow: none;
  color: #063D35;
}
.whatsapp-copy:hover { background: rgba(7, 94, 84, .08); }
.whatsapp-actions .copied { margin: 0; color: #063D35; font-weight: 750; }
.broadcast-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin: 16px 0;
  overflow: hidden;
  background: var(--hair);
  border-radius: var(--radius-sm);
}
.broadcast-summary div { min-width: 0; padding: 12px; background: var(--raised); }
.broadcast-summary dt { color: var(--text-mute); font-size: .78rem; font-weight: 750; }
.broadcast-summary dd { margin: 3px 0 0; overflow-wrap: anywhere; font-weight: 850; }
.broadcast-link { display: grid; justify-items: start; gap: 8px; margin: 16px 0; }
.broadcast-link .btnlink { min-height: 44px; }
.broadcast-link span { overflow-wrap: anywhere; color: var(--text-mute); }
.broadcast-preview { margin: 16px 0; }
.broadcast-preview > summary { cursor: pointer; font-weight: 800; text-decoration: underline; text-underline-offset: 3px; }
.broadcast-preview > div { max-width: 65ch; margin-top: 12px; padding: 16px; background: var(--well); border-radius: var(--radius-sm); }
.broadcast-preview p { margin: 0 0 12px; overflow-wrap: anywhere; }
.broadcast-preview a { overflow-wrap: anywhere; }
.broadcast-preview p:last-child { margin-bottom: 0; }
.admin-whatsapp-email form { display: grid; justify-items: start; gap: 12px; margin-top: 16px; }
@media (max-width: 560px) {
  .whatsapp-card { grid-template-columns: minmax(0, 1fr); gap: 14px; padding: 16px; }
  .whatsapp-actions { min-width: 0; width: 100%; }
  .whatsapp-button { width: 100%; }
  .broadcast-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .broadcast-summary div:last-child { grid-column: 1 / -1; }
  .admin-whatsapp-email form button { width: 100%; }
}

/* --- pay to play --------------------------------------------------------- */

.unpaid {
  background: var(--gold-faint);
  border: var(--line) dashed var(--gold-dim);
  border-radius: var(--radius);
  padding: 22px 20px;
  margin-top: 16px;
  text-align: center;
}
.unpaid h2 { margin-bottom: 8px; }
.unpaid p { margin: 6px 0; font-size: 0.9375rem; }

/* The real fixtures, showing faintly behind the ask.

   Not decoration: it is the answer to "what am I paying for?". The picker is
   the genuine one, so what somebody sees dimmed is exactly what they get. */
.paygate { position: relative; margin-top: 16px; }

.paygate-behind {
  opacity: .22;
  filter: saturate(.35);
  pointer-events: none;
  user-select: none;
  /* Enough to read the shape of a fixture list, not so much that it competes
     with the thing we are asking them to do. */
  max-height: 340px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 40%, transparent 97%);
          mask-image: linear-gradient(#000 40%, transparent 97%);
}

/* The notice sits on top of it rather than after it. */
.paygate .unpaid {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(100%, 420px);
  margin: 0;
  background: rgba(255, 255, 255, .93);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  border-style: solid;
  box-shadow: 0 18px 44px rgba(60, 50, 20, .18);
}

.paygate-caption { font-size: 0.8125rem !important; opacity: .75; margin-top: 12px !important; }

/* On a narrow screen there is no room to overlap without one covering the
   other, so stack them: the ask first, the fixtures below it. */
@media (max-width: 480px) {
  .paygate-behind { max-height: 260px; margin-top: 14px; }
  .paygate .unpaid { position: static; transform: none; width: auto; }
  .paygate { display: flex; flex-direction: column-reverse; }
}

/* --- add to home screen -------------------------------------------------- */

.install { border-style: dashed; }
.install-go { margin-top: 14px; }

.install-steps ol {
  margin: 14px 0 0;
  padding-left: 1.25rem;
  display: grid;
  gap: 10px;
  font-size: 0.9375rem;
}
.install-steps li { padding-left: 4px; }

/* Both sets of instructions are in the page; only the right one is shown.
   Keeping the markup identical for everybody means the page is the same for
   every player and nothing has to be decided on the server. */
/* Every set of instructions stays on the page. The script opens one; nothing
   is ever hidden, because a wrong guess must cost a tap and not the answer. */
.install-steps { display: grid; gap: 8px; }

.how {
  background: var(--well);
  border: var(--line) solid var(--gold-dim);
  border-radius: var(--radius-sm);
  padding: 0;
}
.how > summary {
  cursor: pointer;
  padding: 13px 15px;
  font-family: var(--display); font-weight: 600; font-size: .875rem;
  color: var(--gold-ink);
  list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.how > summary::-webkit-details-marker { display: none; }
.how > summary::after {
  content: '+';
  font-family: var(--display); font-weight: 700; font-size: 1.1rem;
  color: var(--gold-deep); line-height: 1;
}
.how[open] > summary::after { content: '\2212'; }
.how[open] > summary { border-bottom: var(--line) solid var(--gold-dim); }

.how > p, .how > ol { margin: 12px 15px; }
.how > ol { padding-left: 1.15rem; display: grid; gap: 9px; font-size: .9375rem; }

.linkish {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 8px 0 0;
  margin: 0;
  color: var(--text-soft);
  text-decoration: underline;
  font-size: 0.9375rem;
  min-height: 44px;
}
.linkish:active { transform: none; }
.small { font-size: 0.8125rem; margin-top: 0; }

/* --- league chat --------------------------------------------------------- */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.chatform { margin: 16px 0 20px; }
.chatform textarea {
  width: 100%;
  background: var(--well);
  border: var(--line) solid var(--hair);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 450;
  padding: 13px 15px;
  resize: vertical;
}
.chatform textarea::placeholder { color: var(--text-mute); font-weight: 400; }
.chatform textarea:focus {
  outline: none;
  border-color: var(--gold-ink);
  box-shadow: 0 0 0 3px var(--gold-faint);
}
.chatform button { justify-self: start; }

.msglist { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }

.msg {
  position: relative;
  background: var(--raised);
  border: var(--line) solid var(--hair);
  border-radius: var(--radius-sm);
  padding: 13px 15px;
}
/* Your own messages carry a gold left edge, so a thread is easy to scan
   without tinting half the screen. */
.msg.mine {
  background: var(--gold-faint);
  border-color: var(--gold-dim);
  box-shadow: inset 3px 0 0 var(--gold-deep);
}

.msghead { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.msgwho {
  font-family: var(--display); font-weight: 500; font-size: 0.9375rem; color: var(--text);
}
.msgwhen { font-size: 0.6875rem; color: var(--ink-soft); font-weight: 700; }

.msgbody {
  margin: 0; font-size: 0.9375rem; line-height: 1.45;
  /* Player text, so it must wrap rather than stretch the page. */
  overflow-wrap: anywhere; white-space: pre-wrap;
}

.msgdel { position: absolute; top: 10px; right: 12px; margin: 0; }
.msgdel button { font-size: 0.6875rem; color: var(--red-ink); }

.msgempty {
  color: var(--ink-soft); font-size: 0.875rem; padding: 18px 0; text-align: center;
}

/* --- invite sharing ------------------------------------------------------ */

.invitelink { margin: 14px 0 12px; }
/* 1rem, not 0.8125rem, and the reason is iOS rather than taste.
   Safari on iPhone zooms the whole page in when you focus a text field whose
   computed size is under 16px, and it does not zoom back out afterwards. At
   18px root, 0.8125rem computed to 14.6px - so tapping the invite link on the
   admin page zoomed the page and left it there. No other screen has a field
   that small, which is why the admin page was the only one that did it.
   Never take any input below 16px. See the test that enforces this. */
.invitelink input {
  width: 100%;
  font-size: 1rem;
  color: var(--gold-ink);
  font-family: var(--display);
  letter-spacing: .02em;
}
.inviteactions { display: flex; flex-wrap: wrap; gap: 10px; }
.admin-invites > .muted { margin-bottom: 14px; }
.admin-league-invite { border-top: var(--line) solid var(--hair); }
.admin-league-invite:last-child { border-bottom: var(--line) solid var(--hair); }
.admin-league-invite > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 54px; padding: 10px 0; cursor: pointer;
}
.admin-league-invite > summary h3 { margin: 0; overflow-wrap: anywhere; }
.admin-league-invite > .hint { display: block; margin: 0 0 10px; }
.admin-league-invite > .muted { margin: 12px 0 16px; }
.copied {
  font-family: var(--display); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; margin: 14px 0 0;
  background: var(--green-soft); border: var(--line) solid rgba(30, 138, 76, .45);
  color: var(--green-ink);
  border-radius: 999px; padding: 5px 14px; display: inline-block;
}
.invited {
  background: var(--gold-faint); border: var(--line) solid var(--gold-dim);
  color: var(--gold-ink);
  border-radius: var(--radius-sm);
  padding: 13px 15px; font-size: 0.8125rem; font-weight: 500; margin: 0 0 18px;
}

/* --- odds and ends ------------------------------------------------------- */

.rules { padding-left: 22px; display: grid; gap: 12px; font-size: 0.9375rem; }
.rules::marker { color: var(--gold-deep); font-weight: 600; }
.rules strong { font-family: var(--display); font-weight: 500; color: var(--text); }
.invite {
  background: var(--gold-faint); border: var(--line) solid var(--gold-dim);
  color: var(--gold-ink);
  border-radius: 999px; padding: 5px 16px; font-family: var(--display);
  font-size: 0.875rem; font-weight: 500; letter-spacing: .18em;
}
.waiting { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 8px; }
.waiting .attention-link { text-decoration: none; }
.waiting .attention-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.auto { font-size: 0.5625rem; font-weight: 800; color: var(--red-ink); vertical-align: super; }
.lock { display: block; }

footer {
  max-width: 760px; margin: 0 auto;
  color: var(--text-mute); font-size: 0.6875rem; text-align: center; font-weight: 400;
  padding: 24px 20px calc(100px + env(safe-area-inset-bottom));
}

/* On Selection, leave enough scroll room for the official-results notice to
   clear both fixed bars. At the end of the page the notice sits above the
   confirmation control, so "Your selection" is the last action before the
   navigation instead of covering the footer copy. */
body:has(.pick-confirm) footer {
  padding-bottom: calc(172px + env(safe-area-inset-bottom));
}

/* --- bottom tabs --------------------------------------------------------- */

/* The bar has to stay welded to the bottom of the screen while the page
   scrolls underneath it. Three things here are load-bearing, and all three
   were learnt from it coming unstuck on somebody's Android:

   1. NO backdrop-filter. A blurred fixed element gets promoted to its own
      compositor layer, and on Chrome for Android that layer stops being
      redrawn in step with the scroll - so the bar visibly drifts up the
      screen mid-scroll and snaps back at the end. The background is opaque
      instead, which costs nothing: there is a solid page behind it anyway.

   2. NO transform. `left: 50%` plus `translateX(-50%)` was doing the
      centring, and a transform is the other thing that promotes the layer.
      Centring is done with `inset` and `margin: auto` instead, which is
      plain layout and cannot desynchronise.

   3. The background is opaque. A translucent bar over scrolling content is
      also what makes any drift obvious rather than invisible.

   The colour was also still the old cream from before the palette changed,
   so it no longer matched the page it sits on. */
.tabbar {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  position: fixed;
  inset: auto 0 0 0;
  width: 100%; max-width: 760px; margin-inline: auto;
  z-index: 20;
  background: var(--field);
  border-top: var(--line) solid var(--gold-dim);
  padding-bottom: env(safe-area-inset-bottom);
}

.tab {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 9px 2px 8px; min-height: 62px;
  color: var(--ink-soft); text-decoration: none;
  font-family: var(--display);
  font-size: 0.5625rem; font-weight: 500; letter-spacing: .04em;
  position: relative;
}
.tab svg { width: 22px; height: 22px; position: relative; display: block; }
.tab span { white-space: nowrap; position: relative; }

/* Unread count.

   Selector note: it has to out-rank `.tab span` above, which sets
   position:relative on every span in the bar. When it did not, the badge
   dropped out of its corner and into the flow underneath the icon. */
.tab .tabicon { position: relative; display: block; }

.tab .badge {
  position: absolute; top: -6px; right: -9px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-deep));
  border: 2px solid var(--field);   /* cuts it away from the icon underneath */
  color: var(--on-gold);
  font-family: var(--display);
  font-size: 0.5625rem; font-weight: 700; letter-spacing: 0;
  line-height: 13px; text-align: center;
  box-sizing: border-box;
}

/* One quiet pulse on arrival. Enough to catch the eye on the walk back from
   the bar, not enough to be the thing you notice about the app. */
@keyframes badge-in {
  from { transform: scale(.4); opacity: 0; }
  60%  { transform: scale(1.12); }
  to   { transform: scale(1); opacity: 1; }
}
.tab .badge { animation: badge-in .26s cubic-bezier(.2,.9,.3,1.2) both; }

@media (prefers-reduced-motion: reduce) {
  .tab .badge { animation: none; }
}
.tab:hover { color: var(--text); }

/* The live tab is marked by a gold rule above it - the same hairline language
   as the badge, rather than a coloured blob. Absolutely positioned so lighting
   it cannot shift the layout. */
.tab::before {
  content: '';
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 34px; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0; transition: opacity .14s ease;
}
.tab.active { color: var(--gold-ink); }
.tab.active::before { opacity: 1; }

button, .btnlink, .side, .tab, .topbar nav a {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  button:active { transform: none; }
}

@media (max-width: 560px) {
  h1 { font-size: 1.6rem; }
  .card { padding: 16px 14px; }
  main { padding: 14px 11px 0; }
  .masthead { padding: 8px 14px; font-size: 0.5rem; }
  .topbar { padding-left: 14px; padding-right: 14px; }
  /* The fixture row's own phone rules live with the rest of that component,
     further down. They used to be duplicated here for the old side-by-side
     layout, and the leftovers said white-space: normal - which is the setting
     that lets a team name wrap mid-word. */
  .crest.md { width: 36px; height: 36px; }
  .cardhead { flex-direction: column; gap: 12px; }
  .deadline { text-align: left; width: 100%; }
}

@media (max-width: 340px) {
  .tab { font-size: 0.5rem; }
  .tab svg { width: 20px; height: 20px; }
  .tab::before { width: 34px; }
}

.install-trouble { margin-top: 16px; }
.install-trouble summary {
  cursor: pointer;
  font-weight: 700;
  padding: 10px 0;
  min-height: 44px;
  display: flex;
  align-items: center;
}
.install-trouble ol { margin: 10px 0; padding-left: 1.25rem; display: grid; gap: 8px; }
.install-trouble p, .install-trouble li { font-size: 0.9375rem; }

/* A single-purpose install strip. The two copies make the scroll seamless;
   neither is clipped or ellipsized, and there is no close control competing
   with the message. */
.promo {
  display: flex;
  overflow: hidden;
  max-width: 100%;
  padding-top: env(safe-area-inset-top);
  background: var(--red-band);
  border-bottom: 2px solid var(--field-deep);
}
.promo-track {
  display: flex;
  flex: 1;
  min-width: 0;
  color: #fff;
  text-decoration: none;
  animation: promo-scroll 24s linear infinite;
  will-change: transform;
}
.promo-line {
  flex: 0 0 auto;
  padding: 8px 32px 8px 0;
  color: #fff;
  font-family: var(--display);
  font-size: 0.75rem;
  white-space: nowrap;
}
@keyframes promo-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .promo-track { animation: none; }
  .promo-line + .promo-line { display: none; }
  .promo-line { white-space: normal; padding-left: 12px; }
}

/* --- several leagues at once --------------------------------------------- */

/* The switcher only appears when somebody is in more than one league, so it
   can afford to sit above everything without earning its place every time. */
.switcher {
  display: flex; gap: 8px; overflow-x: auto;
  margin: 0 0 14px; padding-bottom: 2px;
  scrollbar-width: none;
}
.switcher::-webkit-scrollbar { display: none; }

/* Named apart from .chip, which the "still to pick" list already uses for a
   different thing entirely. Two meanings on one class name is how a change to
   one screen quietly breaks another. */
.lchip {
  flex: 0 0 auto;
  padding: 7px 14px;
  border-radius: 999px;
  border: var(--line) solid var(--gold-dim);
  background: var(--raised);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 0.8125rem; font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.lchip.on {
  background: linear-gradient(180deg, var(--gold-hi), var(--gold-deep));
  border-color: transparent;
  color: var(--on-gold);
  font-weight: 600;
}

.leaguelist { list-style: none; margin: 10px 0 22px; padding: 0; display: grid; gap: 10px; }

.leaguerow {
  padding: 14px 16px;
  background: var(--raised);
  border: var(--line) solid var(--gold-dim);
  border-radius: var(--radius-sm);
}
.leaguerow.current { border-color: var(--gold-ink); }

/* One league inside the single "leagues running" card.

   Separated by a rule rather than by another card, so the page reads as one
   thing that happens to contain several leagues - which is what it is. */
.leagueblock + .leagueblock {
  border-top: var(--line) solid var(--hair);
  margin-top: 22px;
  padding-top: 20px;
}
.leagueblock h3 {
  font-family: var(--display); font-weight: 700;
  letter-spacing: .01em; margin: 0 0 4px;
}

/* Inviting somebody into a league you are already in.

   Inside that league's own row, under a hairline. It began as a separate box
   below the list, and with two leagues that read as two loose share buttons
   with nothing saying which belonged to which. */
.leaguetop {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.sharerow {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin: 12px 0 0; padding-top: 12px;
  border-top: var(--line) solid var(--hair);
}
/* Quieter than the buttons that act on your own league - inviting is an
   afterthought on this screen, not the reason you opened it. */
.sharerow button { padding: 8px 12px; font-size: 0.6875rem; }
.sharenote {
  margin: 10px 0 0; padding-top: 10px;
  border-top: var(--line) solid var(--hair);
}
.leaguerow p { margin: 4px 0 0; font-size: 0.8125rem; }
.leaguerow form { margin: 0; }

.tag {
  font-family: var(--display); font-size: 0.6875rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gold-ink);
  white-space: nowrap;
}

/* --- another way to pay --------------------------------------------------- */

.otherpay { margin-top: 14px; text-align: left; }
.otherpay summary {
  cursor: pointer; font-size: 0.875rem; color: var(--gold-ink);
  font-family: var(--display); font-weight: 500;
}
.paybank {
  margin: 10px 0 0; padding: 12px 14px;
  background: var(--well);
  border-radius: var(--radius-sm);
  font-size: 0.875rem; line-height: 1.6;
}

/* The chat's league row. Shown even with one league, because the page is now
   about choosing a conversation. */
.chattabs { margin-bottom: 12px; }

.lchipdot {
  display: inline-block;
  min-width: 16px; height: 16px; padding: 0 4px;
  margin-left: 7px;
  border-radius: 999px;
  background: var(--gold);
  color: var(--on-gold);
  font-size: 0.625rem; font-weight: 700;
  line-height: 16px; text-align: center;
  vertical-align: 1px;
}
.lchip.on .lchipdot { background: var(--on-gold); color: var(--gold-hi); }


/* ==========================================================================
   The game, rather than the spreadsheet.

   Same palette as before. What changes is emphasis: one thing on each screen
   is loud, the fixture list behaves like something you choose from, and
   choosing reacts.

   ALIGNMENT IS LOAD-BEARING HERE. A fixture row can hold a one-word team, a
   long one that wraps onto two lines, and a note saying why a team cannot be
   picked. Left to itself each of those changes the row's height and pushes the
   name and the kick-off time out of line with the row above - which is exactly
   what showed up on the Bournemouth fixture. Every rule below that sets a
   height, reserves a band, or takes something out of flow is there to stop
   that, and should not be relaxed without checking a long name again.
   ========================================================================== */

/* --- one focal point per screen ------------------------------------------ */

/* Solid ink, not a gradient fill. Size and weight do the shouting; a gradient
   across a headline is decoration that carries no meaning and thins the
   strokes at the top of every letter. */
.cardhead h1 {
  font-family: var(--display);
  font-size: clamp(2.4rem, 11vw, 3.4rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -.02em;
  line-height: .94;
  margin: 0;
  color: var(--text);
  text-wrap: balance;
}
.cardhead > div:first-child > .muted {
  font-family: var(--display); font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em;
  font-size: .6875rem; color: var(--gold-deep); margin-top: 6px;
}

/* The deadline as a scoreboard. Tabular figures so it cannot jitter as the
   seconds tick over. */
.deadline {
  display: flex; flex-direction: column; justify-content: center;
  min-width: 168px; padding: 12px 18px; border-width: 2px;
}
.deadline strong {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 1.9rem; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.deadline.urgent { animation: dl-pulse 1.6s ease-in-out infinite; }
@keyframes dl-pulse {
  50% { border-color: var(--red); box-shadow: 0 0 0 4px rgba(198, 58, 44, .14); }
}

/* --- the pitch under it all ---------------------------------------------- */

/* The pitch, drawn in shadow rather than light now the page is paper. */
body {
  background-image:
    repeating-linear-gradient(90deg,
      rgba(23, 23, 28, .018) 0 44px, transparent 44px 88px),
    radial-gradient(120% 70% at 50% 0%, rgba(227, 178, 60, .16), transparent 62%);
  background-attachment: fixed;
}

.card {
  border-width: 2px;
  border-color: rgba(227, 178, 60, .2);
  box-shadow: var(--pop);
}

/* --- choosing a team ------------------------------------------------------ */

.dayname {
  font-family: var(--display); font-weight: 700;
  text-transform: uppercase; letter-spacing: .16em;
  font-size: .6875rem; color: var(--gold-deep);
  display: flex; align-items: center; gap: 12px;
}
.dayname::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--gold-dim), transparent);
}

.fixrow {
  grid-template-columns: minmax(0, 1fr) 56px minmax(0, 1fr);
  border-width: 2px;
  margin-bottom: 10px;
  background:
    linear-gradient(180deg, var(--lift), transparent),
    var(--raised);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.fixrow:hover { border-color: var(--gold-ink); box-shadow: 0 0 0 3px var(--gold-faint); }

/* THE ROW HEIGHT IS FIXED, and the crest sits ABOVE the name.

   Side by side, the name gets about 60px on a 390px phone once the crest and
   padding are taken out - not enough for "ARSENAL", let alone "BOURNEMOUTH".
   Stacked, the name gets the whole column, roughly 140px, and every Premier
   League name fits on one line at this size.

   That is the whole reason for the column layout. Going back to a row puts
   "Arsena / l" back on everybody's phone. */
.side {
  position: relative;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 8px;
  min-height: 104px;
  padding: 12px 8px 22px;             /* the bottom band is for the reason */
  font-size: .875rem;
}
.side.away { flex-direction: column; text-align: center; }

/* Crests never resize, whatever the name does. */
.side img, .side .crest, .side svg {
  width: 36px !important; height: 36px !important;
  flex: 0 0 36px;
}

.sidename { display: flex; flex-direction: column; align-items: center; min-width: 0; width: 100%; }

/* One line, always.

   NEVER add overflow-wrap: anywhere here. It lets a word split between any two
   letters, which is what produced "Arsena" above "l". If a name is ever too
   wide the ellipsis is the fallback - ugly, but readable, and it cannot
   silently change the row height. */
.side .full {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(.6875rem, 3.1vw, .875rem);
  text-transform: uppercase; letter-spacing: 0;
  line-height: 1.1;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Out of flow entirely. Present or absent, it cannot move the name. */
.side .why {
  position: absolute;
  left: 6px; right: 6px; bottom: 6px;
  font-size: .5625rem; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--red-ink);
  text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.side.away .why { text-align: center; }

/* The kick-off time sits on the same centre line as both crests. */
.ko {
  display: flex; align-items: center; justify-content: center;
  padding-bottom: 22px;               /* matches the reason band beside it */
  background: var(--well);
  font-family: var(--display); font-weight: 700; font-size: .75rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

/* --- locking one in ------------------------------------------------------- */

.side:active:not(:disabled) { transform: scale(.97); }

.side.selected {
  background: linear-gradient(180deg, rgba(227, 178, 60, .34), rgba(227, 178, 60, .14));
  box-shadow: inset 0 0 0 2px var(--gold);
  animation: locked-in .5s ease-out;
}
.side.selected .full { color: var(--gold-ink); }
@keyframes locked-in {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.03); box-shadow: inset 0 0 0 3px var(--gold), 0 0 26px rgba(227, 178, 60, .55); }
  100% { transform: scale(1); }
}

/* A team already spent is struck through, not merely dimmed. */
.side.unavailable { opacity: .4; }
.side.unavailable .full { text-decoration: line-through; text-decoration-thickness: 2px; }

.pickerhint {
  font-family: var(--display); font-weight: 700;
  text-transform: uppercase; letter-spacing: .1em; font-size: .75rem;
  color: var(--gold-deep);
}

/* The fixtures deal in on arrival. */
.day .fixrow { animation: deal-in .3s cubic-bezier(.2, .8, .3, 1) both; }
.day .fixrow:nth-child(3) { animation-delay: .04s; }
.day .fixrow:nth-child(4) { animation-delay: .08s; }
.day .fixrow:nth-child(5) { animation-delay: .12s; }
@keyframes deal-in { from { opacity: 0; transform: translateY(10px); } }

@media (prefers-reduced-motion: reduce) {
  .day .fixrow, .deadline.urgent, .side.selected, .pickerhint { animation: none; }
}

/* Narrow phones. Only the spacing tightens - the layout and the one-line rule
   are the same, because they are what make the names fit at all. */
@media (max-width: 380px) {
  .fixrow { grid-template-columns: minmax(0, 1fr) 44px minmax(0, 1fr); }
  .side { padding: 10px 6px 20px; gap: 6px; min-height: 96px; }
  .side img, .side .crest, .side svg {
    width: 30px !important; height: 30px !important; flex: 0 0 30px;
  }
  .ko { font-size: .6875rem; padding-bottom: 20px; }
}

/* --- who picked who, this gameweek --------------------------------------- */

.thisweek h2 { margin-bottom: 6px; }

.teamgroups { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 10px; }

.teamgroup {
  background: var(--raised-hi);
  border: var(--line) solid var(--hair);
  border-left: 3px solid var(--hair-strong);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
}
/* The result colours the group, so a glance says who is through. */
.teamgroup.win  { border-left-color: var(--green); background: var(--green-soft); }
.teamgroup.loss { border-left-color: var(--red);   background: var(--red-soft); }
.teamgroup.draw { border-left-color: var(--red);   background: var(--red-soft); }

.teamgrouphead { display: flex; align-items: center; gap: 10px; }
.teamgrouphead strong {
  font-family: var(--display); font-weight: 700; font-size: 0.9375rem;
}
.teamgrouphead .count {
  margin-left: auto;
  min-width: 24px; height: 24px; padding: 0 7px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--gold-fill); color: var(--on-gold);
  font-family: var(--display); font-weight: 700; font-size: 0.75rem;
}

.teamgroup .who {
  margin: 9px 0 0; font-size: 0.875rem; line-height: 1.6;
  display: flex; flex-wrap: wrap; gap: 4px 10px;
}
.teamgroup .who .me { font-weight: 700; color: var(--gold-ink); }
.teamgroup .who span:not(:last-child)::after { content: ' ·'; color: var(--text-mute); }

/* A card that folds itself away.

   For things the admin needs a few times a season rather than every week. The
   summary carries the same <h2> the card would otherwise have, so the page
   reads identically whether a section is open or shut - only the triangle and
   a bit of height change. */
.fold > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary h2, .fold > summary h3 { margin: 0; }
.fold > summary::after {
  content: ""; margin-left: auto; flex: none;
  width: 8px; height: 8px;
  border-right: 2px solid var(--ink-soft);
  border-bottom: 2px solid var(--ink-soft);
  rotate: 45deg;
  transition: rotate .15s ease;
}
.fold[open] > summary::after { rotate: -135deg; }
.fold > summary:hover::after { border-color: var(--ink); }
.league-money-heading { margin-bottom: 10px; }
.league-money-heading h2 { margin-bottom: 4px; }
.league-money-heading p { margin: 0; color: var(--text-mute); }
.league-money-admin > .fold { padding-block: 4px; border-top: 1px solid var(--hair); }
.league-money-admin > .fold > summary { min-height: 58px; }
.league-money-admin > .fold > summary h3 { color: var(--text); font-size: 1.08rem; }
.league-payment-settings { margin-block: 14px 18px; }
.league-money-footnote { margin: 16px 0 0; }

.everyone { margin-top: 14px; }
.everyone > summary {
  cursor: pointer; font-family: var(--display); font-weight: 600;
  font-size: 0.8125rem; color: var(--gold-ink);
}
.whopicked { width: 100%; border-collapse: collapse; margin-top: 10px; }
.whopicked td {
  padding: 9px 6px; border-bottom: var(--line) solid var(--hair);
  font-size: 0.875rem; vertical-align: middle;
}
.whopicked td:last-child { display: flex; align-items: center; gap: 8px; }
.whopicked .player { font-weight: 600; }

/* The mail setup check. Green means that part is fine, red means it is not -
   the whole point is telling the two failures apart at a glance. */
.mailfail table.admin { margin-top: 10px; }
.mailfail td.ok { color: var(--green-ink); font-weight: 600; }
.mailfail td.error { color: var(--red-ink); font-weight: 600; }
.mailfail .code { display: block; margin-top: 8px; word-break: break-all; }

/* A quiet divider inside a card that holds two unrelated actions. */
.rule { border: 0; border-top: var(--line) solid var(--hair); margin: 18px 0; }

/* The key the app actually loaded. Shown always, not only on failure - it is
   the fastest way to tell "I changed the variable" from "the app got it". */
.keyline {
  background: var(--well); border: var(--line) solid var(--hair);
  border-radius: var(--radius-sm); padding: 11px 13px;
  font-size: 0.875rem; margin: 0 0 12px;
}
.keyline strong { font-family: ui-monospace, Menlo, monospace; }

/* The ready-to-send reset message. Shown as it will look when pasted. */
.pastebox {
  white-space: pre-wrap;
  background: var(--well); border: var(--line) solid var(--hair);
  border-radius: var(--radius-sm); padding: 12px 14px;
  font-size: 0.875rem; line-height: 1.5; margin: 10px 0 0;
}

/* --- the season ahead ----------------------------------------------------- */

/* Planning screen: a long printed fixture list. Ruled rows again, and the one
   piece of information that has to survive a fast scroll is whether a club is
   already spent - so that is a strikethrough on the name itself rather than a
   note somewhere else on the page. */
.seasonlink {
  margin: 18px 0 0; padding-top: 14px;
  border-top: var(--line) solid var(--hair);
}
.seasonlink .hint { display: block; color: var(--text-mute); margin-top: 2px; }

.fxweek { margin: 20px 0 0; }
.fxweek.gone { opacity: .5; }

.fxhead {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; margin: 0 0 2px; padding: 0 2px 6px;
  border-bottom: 2px solid var(--text);
}
.fxround {
  font-family: var(--display); font-weight: 700; font-size: 0.9375rem;
  letter-spacing: .06em; text-transform: uppercase;
}
.fxwhen {
  font-family: var(--figures); font-size: 0.6875rem; color: var(--text-soft);
  font-variant-numeric: tabular-nums;
}

.fxline {
  display: grid; grid-template-columns: minmax(0, 1fr) 46px minmax(0, 1fr);
  align-items: center; gap: 4px;
  padding: 9px 2px;
  border-bottom: var(--line) solid var(--hair);
}
.fxline:last-child { border-bottom: 0; }

.fxteam { display: flex; align-items: center; gap: 8px; min-width: 0; }
.fxline .fxteam:last-of-type { flex-direction: row-reverse; text-align: right; }
.fxname {
  font-family: var(--display); font-weight: 600; font-size: 0.875rem;
  text-transform: uppercase; line-height: 1.1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Already used. The strikethrough is the whole point of this screen. */
.fxteam.spent { opacity: .45; }
.fxteam.spent .fxname { text-decoration: line-through; }

.fxv {
  font-family: var(--figures); font-size: 0.6875rem; font-weight: 700;
  color: var(--text-soft); text-align: center;
  font-variant-numeric: tabular-nums;
}

/* --- live scores ---------------------------------------------------------- */

/* A match in progress. The number is the thing that moves, so it gets the
   weight; nothing pulses or animates, because a page that twitches every
   thirty seconds is unreadable when you are trying to follow four games. */
/* A match in progress: heavier and green, on paper rather than on a fill, so
   it is legible. Nothing pulses - a table that twitches every thirty seconds
   is unreadable when you are following four games at once. */
.fixtures .score.playing {
  font-weight: 700;
  color: var(--green-ink);
  background: var(--green-soft);
  border-radius: 999px;
}

.livedot {
  font-family: var(--display);
  font-size: 0.625rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--on-gold);
  background: var(--gold);
  border-radius: 999px;
  padding: 3px 9px;
  align-self: center;
}

/* The row with your own club in it. A tint, not a border - a coloured stripe
   down the side of a row is the thing that makes a table look generated. */
.fixtures tr.minerow td { background: var(--gold-faint); }

/* What it means for you, in words, because a score alone does not answer
   "am I still in?" for somebody who does not follow the league closely. */
.mystatus {
  margin: 0 0 12px;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-soft);
}
.mystatus.winning { color: var(--green-ink); }
.mystatus.losing, .mystatus.drawing { color: var(--red-ink); }

/* The split, when the admin takes a share. Shown wherever the pot is shown -
   a fee somebody only hears about when the money changes hands is the kind of
   thing that sours a league. */
.stakesplit {
  display: block;
  margin-top: 3px;
  font-size: 0.75rem;
  color: var(--text-soft);
}
.stakesplit strong { color: var(--text); }

/* A checkbox with an explanation under it. The label carries the reasoning
   because this one has a consequence people should understand before ticking. */
.check { display: flex; gap: 10px; align-items: flex-start; }
.check input { width: auto; margin-top: 3px; flex: none; }
.check .hint { display: block; margin-top: 2px; }

/* ===========================================================================
   THE ALBUM PAGE
   ---------------------------------------------------------------------------
   Everything above this line was written for a light page. These rules turn
   the surfaces themselves over to the album: a cobalt ground, cards that read
   as pages laid on it, and clubs sitting in die-cut frames.

   Kept as one block at the end rather than threaded through the file, so the
   world can be read - and reversed - in one place.
   =========================================================================== */

html { background: var(--field); }

body {
  color-scheme: light;
  background: var(--field);
  /* The album's own furniture: the faint ruled grid a page is printed on, and
     a pool of light at the top so the page has somewhere to sit. Two flat
     layers, no noise texture. */
  background-image:
    linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px),
    radial-gradient(120% 62% at 50% -6%, rgba(122, 160, 240, .28), transparent 62%);
  background-size: 46px 46px, 46px 46px, 100% 100%;
  background-attachment: fixed;
  color: var(--on-field);
}

/* Text sitting directly on the album page, rather than on a card. */
.muted, .hint, footer { color: var(--on-field-soft); }
.hint { color: var(--on-field-mute); }

/* A card is a page laid on the album: white stock, a hard edge, and a real
   shadow with offset and blur. Never a glow. */
.card {
  background: var(--raised);
  border: 2px solid var(--field-deep);
  border-radius: var(--radius);
  box-shadow: var(--pop);
  color: var(--text);
}
.card .muted { color: var(--text-soft); }
.card .hint { color: var(--text-mute); }
.card h1, .card h2, .card h3 { color: var(--text); }

/* The masthead is the album's cover strip. */
.topbar {
  background: var(--field-deep);
  border-bottom: 2px solid rgba(0, 0, 0, .35);
}
.brand { color: var(--on-field); }

/* Section labels on the page are gold; on a card they are ink. */
.sect, .masteyebrow { color: var(--gold); }
.card .sect, .card .masteyebrow { color: var(--gold-ink); }

/* --- the sticker -----------------------------------------------------------
   A club in the fixture list is a sticker: die-cut white, a hard keyline, and
   a shadow that says it is stuck ON the page rather than printed into it. */
.side {
  /* Crest above name, not beside it. Restated because this override is now the
     last .side rule in the file, and dropping it squeezes ARSENAL into the
     60px left over next to a badge on a phone. */
  flex-direction: column;
  background: var(--raised);
  border: 2px solid var(--field-deep);
  border-radius: var(--radius-sticker);
  box-shadow: 0 2px 0 rgba(7, 21, 64, .55);
  transition: transform .16s cubic-bezier(.2, .8, .3, 1), box-shadow .16s;
}
.side:hover { transform: translateY(-1px); box-shadow: 0 4px 0 rgba(7, 21, 64, .55); }
.side:active { transform: translateY(1px); box-shadow: 0 1px 0 rgba(7, 21, 64, .55); }

/* The one you are riding this week. A real shiny shifts as you tilt it, so
   the foil travels slowly across the sticker rather than sitting still. */
.side.selected, .side[aria-pressed="true"] {
  background: var(--foil);
  background-size: 260% 260%;
  border-color: var(--foil-edge);
  box-shadow: 0 2px 0 rgba(7, 21, 64, .55), 0 0 18px rgba(242, 196, 56, .45);
  animation: foil 7s ease-in-out infinite;
}
@keyframes foil {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* A club already spent. Gone matte, and stamped rather than merely faded, so
   it reads as used up rather than as broken. */
.side.unavailable {
  background: #9AA3B8;
  border-color: #58607A;
  box-shadow: none;
  transform: none;
}
.side.unavailable .crest img { filter: grayscale(1); opacity: .40; }
.side.unavailable .teamname { color: #3A4258; }

@media (prefers-reduced-motion: reduce) {
  .side.selected, .side[aria-pressed="true"] { animation: none; }
  .side, .side:hover, .side:active { transition: none; transform: none; }
}

/* The bar along the bottom is the album's spine. */
.tabbar {
  background: var(--field-deep);
  border-top: 2px solid rgba(0, 0, 0, .4);
}
.tab { color: var(--on-field-mute); }
.tab.active { color: var(--gold); }

/* --- browser surfaces ------------------------------------------------------
   The parts nobody draws still belong to the design. Left at their defaults
   they are the cheapest tell that a page was assembled rather than built. */
::selection { background: var(--gold); color: var(--on-gold); }
:root { accent-color: var(--gold); caret-color: var(--field); }
* { scrollbar-color: rgba(255, 255, 255, .28) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .26);
  border-radius: 6px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

/* Counts and clocks line up in columns wherever they are compared. */
.tbl, .admin, .countdown, .stake, .standings, td, th { font-variant-numeric: tabular-nums; }

/* The drawn wordmark. Letterforms are fixed here rather than left to whatever
   face the phone has, so the app's one piece of lettering looks the same on
   every device. */
.wordmark { display: block; width: 148px; height: auto; overflow: visible; }
/* Size and tracking live on the elements as SVG presentation attributes, not
   here. Inside a viewBox those are user units that scale with the drawing, so
   writing them in CSS px would look like sizes that ignore the root dial when
   they are nothing of the kind. */
.wm-small { fill: var(--gold); font-family: var(--display); font-weight: 700; }
.wm-big { fill: var(--on-field); font-family: var(--display); font-weight: 900; }
.brand { display: inline-block; padding: 2px 0; }
.brand:hover .wm-big { fill: var(--gold-hi); }

/* --- the album's cover panel ------------------------------------------------
   Where the chalk penalty box used to be. An album page has a printed header
   panel, not a pitch marking, so the geometry goes and the panel becomes the
   thing it always was: the round number and the clock, loudest on the page. */
.mast {
  background: var(--field-deep);
  border-bottom: 3px solid var(--gold);
  padding: 22px 20px 24px;
}
/* The chalk box and centre spot belonged to the old world. Replaced with the
   perforation a sticker page is torn from - a row of punched holes across the
   top, which is album furniture rather than pitch furniture. */
.mast::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0; height: 8px;
  border: 0;
  background-image: radial-gradient(circle at 6px 4px,
    rgba(0, 0, 0, .55) 0 3px, transparent 3px);
  background-size: 16px 8px;
  opacity: .5;
}
.mast::after { content: none; }

.mast h1 {
  color: var(--on-field);
  font-size: clamp(2.2rem, 11vw, 3.1rem);
  letter-spacing: -.02em;
  margin: 2px 0 14px;
}
.masteyebrow { color: var(--gold); }

/* The clock. One thing on this screen has a deadline attached, so it is the
   only thing allowed to be this size. */
.deadline .countdown {
  color: var(--on-field);
  font-variant-numeric: tabular-nums;
}
.deadline .label { color: var(--on-field-soft); }

/* Picks are shut. The panel goes flat and the gold rule goes out, so a closed
   week looks closed at a glance rather than reading the same as an open one. */
.mast.shut {
  background: var(--field-soft);
  border-bottom-color: rgba(255, 255, 255, .18);
}
.mast.shut h1, .mast.shut .countdown { color: var(--on-field-soft); }

/* --- your album ------------------------------------------------------------
   The clubs you have spent, in the order you spent them, with the weeks ahead
   still empty. Scrolls sideways rather than wrapping, because a season reads
   as one continuous strip and a wrapped grid loses the sense of a run. */
.album-strip {
  display: flex; gap: 8px;
  list-style: none; margin: 14px 0 0; padding: 0 0 6px;
  overflow-x: auto; scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.album-strip .slot {
  flex: none; width: 62px;
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 9px 4px 7px;
  border-radius: var(--radius-sticker);
  border: 2px dashed var(--hair-strong);
  background: var(--well);
  scroll-snap-align: start;
  position: relative;
}
/* A club stuck down. Solid keyline and a real shadow: it is ON the page now,
   where an empty slot is only printed onto it. */
.album-strip .slot.filled {
  border-style: solid;
  border-color: var(--field-deep);
  background: var(--raised);
  box-shadow: 0 2px 0 rgba(7, 21, 64, .35);
}
.album-strip .wk {
  font-family: var(--display);
  font-size: 0.625rem; font-weight: 800; letter-spacing: .08em;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}
.album-strip .slot.filled .wk { color: var(--text); }
.album-strip .slot .crest img { width: 26px; height: 26px; }

/* The week it went wrong. The crest stays - it is part of your run - but it
   is stamped, the way a spent sticker is. */
.album-strip .slot.knockedout { border-color: var(--red-ink); }
.album-strip .slot.knockedout .crest img { filter: grayscale(1); opacity: .45; }
.album-strip .slotout {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-12deg);
  font-family: var(--display);
  font-size: 0.625rem; font-weight: 900; letter-spacing: .1em;
  color: var(--red-ink);
  border: 2px solid var(--red-ink);
  border-radius: 3px; padding: 1px 4px;
  background: rgba(255, 255, 255, .82);
  pointer-events: none;
}
/* A pick whose club is no longer in the dataset. Says so, rather than leaving
   a blank sticker that reads as a broken image. */
.album-strip .slotgone {
  width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 50%; background: var(--well-strong);
  color: var(--text-mute); font-weight: 800; font-size: 0.8125rem;
}

/* --- stop the page moving under people -------------------------------------
   Three separate things all read as "the app zoomed", and only one of them is
   somebody deliberately pinching:

   1. DOUBLE-TAP. Tapping a team twice quickly used to zoom the page instead of
      registering two taps. `manipulation` tells the browser there is no
      double-tap gesture here, which also removes the 300ms delay before every
      tap is acknowledged.
   2. FOCUS. iOS zooms in when a field smaller than 16px is focused, and never
      zooms back out. Guarded by its own test; nothing here is under 16px.
   3. OVERFLOW. Anything wider than the screen makes the whole page shrink to
      fit, which looks exactly like being zoomed out.

   Deliberate pinch-zoom is left alone. Turning it off with `user-scalable=no`
   would fix nothing above and would lock out anybody who needs to magnify
   text - it is the one accessibility rule phones still honour by default. */
html { touch-action: manipulation; }

/* Nothing may be wider than the screen. The usual culprits are a long club
   name, a wide table, or a pasted link. */
img, svg, video, canvas { max-width: 100%; height: auto; }
pre, code, .code, .pastebox { overflow-wrap: anywhere; }
table { max-width: 100%; }
/* max-width is the load-bearing half of this rule. Without it the div grows
   to its content instead of scrolling, and every page with a table - the
   selection screen and the admin screen - gets pushed wider than the phone.
   An earlier copy of this rule further up the file has it; this one dropped
   it and, being later, won. */
.scroll { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }

/* The spine sits on the bottom edge of the window and stays there. `fixed`
   alone leaves a gap on phones whose gesture bar overlays the page, which
   reads as the bar floating just above the bottom rather than being part of
   the screen. */
.tabbar {
  padding-bottom: max(env(safe-area-inset-bottom), 0px);
  background-clip: padding-box;
}

/* --- the field -------------------------------------------------------------
   The table of who is left. It reads top to bottom on a phone, so the rule
   between rows does the work and there are no verticals: a grid of boxes at
   this width is a spreadsheet, and this is a list of people. */
.standings th, .admin th, th {
  background: transparent;
  color: var(--text-mute);
  font-family: var(--display);
  font-size: 0.625rem; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase;
  border-bottom: 2px solid var(--hair-strong);
}
.standings td, .admin td { border-bottom: 1px solid var(--hair); }
.standings .player { font-weight: 650; color: var(--text); }

/* Out. The row goes quiet and the name is struck, rather than merely paler -
   at a glance you should be able to count who is left without reading. */
.standings tr.out { background: var(--well); }
.standings tr.out .player {
  color: var(--text-mute);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--red-ink);
}
/* The column being played this week. */
.standings th.now { color: var(--gold-ink); border-bottom-color: var(--gold); }

/* --- chips, pills, tags ---------------------------------------------------- */
.chip {
  background: var(--well);
  border: 1px solid var(--hair-strong);
  border-radius: 999px;
  color: var(--text);
}
.chip.warn {
  background: var(--red-soft);
  border-color: rgba(168, 30, 24, .40);
  color: var(--red-ink);
}
.pill {
  background: var(--field);
  color: var(--on-field);
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.tag { color: var(--gold-ink); }
.badge.alive { background: var(--green-soft); color: var(--green-ink); }
.badge.out { background: var(--red-soft); color: var(--red-ink); }

/* --- buttons ---------------------------------------------------------------
   A sticker-album button is printed card with a hard edge, so the press is a
   real downward movement against a block shadow rather than a fade. */
button, .btnlink {
  border-radius: var(--radius-sticker);
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: .04em;
  border: 2px solid var(--field-deep);
  background: var(--raised);
  color: var(--text);
  box-shadow: 0 3px 0 rgba(7, 21, 64, .30);
  transition: transform .12s, box-shadow .12s;
}
button:hover, .btnlink:hover { background: var(--raised-hi); }
button:active, .btnlink:active {
  transform: translateY(3px);
  box-shadow: 0 0 0 rgba(7, 21, 64, .30);
}
button.primary {
  background: var(--red);
  color: #fff;
  border-color: #7E1712;
  box-shadow: 0 3px 0 #7E1712;
}
button.primary:hover { background: #F03A32; filter: none; }
button.danger {
  background: var(--raised);
  color: var(--red-ink);
  border-color: var(--red-ink);
  box-shadow: 0 3px 0 rgba(168, 30, 24, .45);
}
button.ghost, .btnlink.ghost {
  background: transparent;
  border-color: var(--hair-strong);
  box-shadow: none;
  color: var(--text);
}
button:disabled {
  background: var(--well);
  color: var(--text-mute);
  border-color: var(--hair);
  box-shadow: none;
  transform: none;
}

/* --- fixtures list --------------------------------------------------------- */
.fixtures td { font-family: var(--body); font-weight: 600; }
.fixtures .score {
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  color: var(--text);
}

/* --- league rows, chat, forms ---------------------------------------------- */
.leaguerow { background: var(--raised-hi); border-color: var(--hair-strong); }
.leaguerow.current { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }

input, select, textarea {
  border-radius: var(--radius-sticker);
  border: 2px solid var(--hair-strong);
  background: var(--raised);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--field);
  outline: 3px solid var(--gold);
  outline-offset: 1px;
}

/* Anything sitting straight on the album page rather than on a card needs its
   own light text; a card resets it back to ink. */
main > .muted, main > p, footer { color: var(--on-field-soft); }

/* --- nothing may push the page wider than the phone ------------------------
   With scaling off, an overflow no longer shrinks the page to fit - it just
   sits there off the edge where nobody can reach it. So the elements that
   carry text somebody typed get a hard ceiling.

   These all had `white-space: nowrap` and no way to give ground. A league
   called "The Big Premier League Sweepstake 2026/27" is not a strange thing
   for somebody to type, and on a 360px phone it was wider than the screen on
   its own. */
.lchip, .tag, .badge, .chip, .standings .player {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Flex and grid children refuse to shrink below their content by default,
   which is what lets one long word drag a whole row off the screen. */
.leaguetop, .leaguerow, .sharerow, .fixture, .payrow, .waiting {
  min-width: 0;
}
.leaguetop > *, .fixture > * { min-width: 0; }

/* A long club or player name breaks rather than overflowing. */
.teamname, .sidename, .player, .leaguerow strong { overflow-wrap: anywhere; }

/* ===========================================================================
   BACK TO THE OLD KIT'S GEOMETRY
   ---------------------------------------------------------------------------
   The album's colours and materials stay. Its measurements go back to what
   the app used before, because the old kit fitted phones correctly and this
   did not, and the owner is the one who can actually see it.

   What changed and why it is suspect:

   - 2px borders on full-width elements. Harmless in theory with border-box
     sizing, but they were on cards, buttons, inputs and stickers all at once,
     and the old kit used a 1px hairline throughout.
   - `overflow-x: clip` on html and body. Meant to stop overflow; on iOS it
     also interferes with how the visual viewport is worked out, and the old
     kit never needed it.
   - A 3px focus outline with a 2px offset, which paints five pixels beyond an
     element that already reaches the edge of the screen.

   None of these is proven guilty from here - there is no phone in this
   environment to watch. What is known is that the old geometry worked, so it
   is the one being restored rather than a fourth guess.
   =========================================================================== */

/* One hairline, everywhere, as before. */
.card,
.side,
button, .btnlink,
input, select, textarea {
  border-width: var(--line);
}

/* The stickers keep their stuck-on shadow - that is material, not geometry -
   but the block shadow under buttons goes back to a soft one, so nothing sits
   in a 3px well that has to be accounted for. */
button, .btnlink { box-shadow: var(--pop-sm); }
button:active, .btnlink:active { transform: translateY(1px); box-shadow: none; }
button.primary { box-shadow: var(--pop-sm); }
button.danger { box-shadow: var(--pop-sm); }

/* A focus ring that stays inside the element it belongs to. */
:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

/* ===========================================================================
   LOUDER
   ---------------------------------------------------------------------------
   Three things the owner could see and I could not: the strip along the top
   was too quiet to register, the name of the game had no presence, and the
   accent was a muted antique gold that belonged to the old world rather than
   to a game.

   The gold is now a flat, bright yellow. Antique gold is a colour for a
   trophy cabinet; this is a colour for a sticker packet, and it reads at
   8.4:1 on the album blue instead of hiding on it.
   =========================================================================== */

/* The strip under the masthead. It carried a thin gold line nobody noticed.
   Now it is a printed band - solid yellow, dark type - the way a title bar is
   printed across the top of an album page. */
.masthead {
  background: var(--gold);
  color: var(--on-gold);
  border-bottom: 3px solid var(--field-deep);
  padding: 7px 20px;
  text-align: center;
}
.masthead span {
  font-family: var(--display);
  font-size: 0.6875rem;
  font-weight: 900;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--on-gold);
}

/* The name of the game. It was set small and quiet in the corner; it is the
   cover of the album, so it gets the room. */
.topbar {
  background: var(--field-deep);
  padding: 12px 16px 13px;
  border-bottom: 0;
}
.wordmark { width: 208px; }
.wm-small { fill: var(--gold); }
.wm-big { fill: #fff; }

/* The heavy outline is what turns lettering into a badge rather than a label.
   Drawn with paint-order so the stroke sits behind the letterform and does
   not eat into it. */
.wm-big {
  paint-order: stroke fill;
  stroke: var(--red);
  stroke-width: 4px;
  stroke-linejoin: round;
}
.brand:hover .wm-big { fill: var(--gold); stroke: var(--red); }

/* Everything that was antique gold is now the bright one. */
.sect, .masteyebrow, .tab.active { color: var(--gold); }
.mast { border-bottom-color: var(--gold); }

/* ===========================================================================
   THE AWAY BOX WAS BEING CUT OFF
   ---------------------------------------------------------------------------
   `grid-template-columns: 1fr 46px 1fr` looks like it splits the row in half.
   It does not: a bare `1fr` is `minmax(auto, 1fr)`, and `auto` refuses to go
   below the width of its contents. A sticker is a crest, a club name, padding
   and a border, and when two of those plus the kick-off time came to more
   than the phone, the row grew instead of shrinking - so the away side ran
   off the right-hand edge.

   `minmax(0, 1fr)` is the same intent actually expressed: two equal columns
   that are allowed to be narrower than what is in them.
   =========================================================================== */
.fixrow {
  /* 56px, matching the rule this supersedes - the kick-off time needs it. */
  grid-template-columns: minmax(0, 1fr) 56px minmax(0, 1fr);
}
.fixrow > * { min-width: 0; }
/* flex-direction restated: this is now the last .side rule, and without it the
   crest and the club name go back to sitting side by side. Second time this
   has bitten - any new .side rule has to carry it. */
.side { flex-direction: column; max-width: 100%; }
.teamname, .sidename { max-width: 100%; }

/* --- the leftovers from the old kit ---------------------------------------
   The league bars on the selection screen were still wearing the antique
   gold gradient, which is the single most obviously-old thing on the page. */
.lchip {
  background: var(--raised);
  border: var(--line) solid var(--hair-strong);
  color: var(--text);
  font-weight: 700;
}
.lchip.on, .lchip[aria-current="true"], .lchip.current {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}
.lchip .lchipdot { background: var(--red); color: #fff; }
.lchip.on .lchipdot, .lchip.current .lchipdot { background: #fff; color: var(--red); }

/* --- the band along the top -------------------------------------------------
   Yellow on its own was still not registering. Red reads as a printed banner
   rather than as a highlight, and white on it is unmissable. */
.masthead {
  /* A deeper red than the buttons use. The button red is 4.38:1 against white,
     which is under the readable floor - fine for a large label on a control,
     not fine for a band of small tracked capitals. */
  background: var(--red-band);
  border-bottom: 3px solid var(--field-deep);
}
.masthead span { color: #fff; }

/* ===========================================================================
   NOTHING ESCAPES THE COLUMN
   ---------------------------------------------------------------------------
   Five attempts at finding the one element that was too wide, five misses.
   So this stops hunting and contains the problem instead: the page column
   clips its own overflow, and every grid and flex child inside it is told it
   may be narrower than its contents.

   Why this is a real fix and not a plaster: on a phone the content column IS
   the screen. Nothing on this page is ever meant to be read by scrolling
   sideways - the one thing that legitimately scrolls, a wide table, has its
   own scroller and keeps it. So anything reaching past the column is a bug by
   definition, and clipping at the column is the same statement in CSS.

   It goes on `main`, not on html or body: putting it there interferes with
   how iOS works out the visual viewport, which is a lesson from earlier in
   this same rebuild.
   =========================================================================== */
main {
  overflow-x: clip;
  max-width: 100%;
}

/* Grid and flex children keep their content's width unless told otherwise.
   This is the single commonest cause of a row that will not shrink, and it
   has to be said explicitly at every level, not just the top. */
.card,
.card > *,
.fixrow,
.fixrow > *,
.side,
.side > *,
.sidename,
.sidename > *,
.day,
.day > * {
  min-width: 0;
}

/* A button does not shrink below its content on its own, whatever the parent
   says - and every club on the selection screen is a button. */
button.side { flex-direction: column; max-width: 100%; overflow: hidden; }
button.side .teamname { max-width: 100%; overflow-wrap: anywhere; hyphens: auto; }

/* ===========================================================================
   THE BAND WAS WIDER THAN THE PHONE
   ---------------------------------------------------------------------------
   From a photograph of the actual screen, which is what finally settled it.
   The red strip reads LAST MAN STANDING · PREMIER LEAGUE 26/27 in tracked
   capitals: about 420px on a 412px phone. One line, one element, and the
   whole page was damaged by it - because an element wider than the screen
   makes the DOCUMENT wider than the screen, and `main` then centres itself
   inside that wider document. That is why the card, the fixture row and the
   banner were all shifted left and clipped at the same edge: they were not
   each too wide, they were all being pushed by one thing that was.

   The fix is to let it give ground: it wraps, its tracking eases, and it
   sizes against the viewport instead of a fixed value.
   =========================================================================== */
.masthead {
  padding: 7px 14px;
  text-align: center;
}
.masthead span {
  /* Sized against the screen, so it cannot be wider than the screen. */
  font-size: clamp(0.5rem, 2.9vw, 0.6875rem);
  letter-spacing: .08em;
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
}

/* --- cards that carry a state ----------------------------------------------
   `--green-soft` is a 12% tint. On the old light page it sat over white and
   read as a pale green panel; on the album page there is nothing opaque
   underneath, so the cobalt came straight through and "You're paid up"
   disappeared into the background. Every state card now paints an opaque
   colour of its own. */
.card.ok, .card.tight.ok {
  background: #EAF7EF;
  border-color: var(--green);
  color: var(--text);
}
.card.ok h2 { color: var(--green-ink); }

.card.warn, .card.bad {
  background: #FDECEA;
  border-color: var(--red-ink);
}
.card.warn h2, .card.bad h2 { color: var(--red-ink); }

.card.knocked { background: #FDECEA; border-color: var(--red-ink); }
.card.winner { background: #FFF8DC; border-color: var(--gold); }

/* --- the rules -------------------------------------------------------------
   The rules were set in the display face to mark them out, which made a page
   of body text harder to read for no gain. Colour does the same job better:
   the rule itself is ordinary text, and the part that actually binds you is
   red. */
.rules {
  font-family: var(--body);
  font-weight: 450;
  color: var(--text);
  line-height: 1.55;
}
.rules strong, .rules b {
  color: var(--red-ink);
  font-weight: 800;
}
/* The numbers down the side, in the album's own accent. */
.rules > li::marker {
  color: var(--red-ink);
  font-family: var(--display);
  font-weight: 800;
}

/* --- where the shouting happens --------------------------------------------
   Anton is a single heavy weight with no bold, so anything set in it must
   never ask for one - a synthesised bold on an already-black face turns to
   mud. It also runs tall and tight, which is why the line-height comes down
   wherever it is used. */
.wm-big, .wm-small,
.mast h1,
.deadline .countdown,
.rd, .album h2 .pill,
.masthead span {
  font-family: var(--shout);
  font-weight: 400;
  letter-spacing: .01em;
}
.mast h1 { line-height: .92; letter-spacing: 0; }
.deadline .countdown { line-height: 1; letter-spacing: .01em; }

/* Headings and labels: square and wide, against Anton's narrow. */
h1, h2, h3,
.sect, .masteyebrow, .tag, .badge, .tab, .wk, .dayname,
button, .btnlink, th, .lchip, .pill {
  font-family: var(--display);
  font-weight: 400;
}

/* Archivo Black has no lighter weight either. Asking for 700 or 800 gets a
   synthesised one that smears; the face is already as heavy as it goes. */
h1, h2, h3, button, .btnlink, th, .tag, .badge, .sect, .lchip, .pill {
  font-weight: 400 !important;
}

/* ===========================================================================
   THE FONT, EVERYWHERE
   ---------------------------------------------------------------------------
   The previous attempt listed selectors and applied the face to those. That is
   how you end up with "you changed some of it" - every element nobody thought
   of keeps the phone's own font, and the app reads as two designs.

   So it is applied at the root and inherited by everything. Only running prose
   is pulled back to a readable face, and only where prose actually lives.
   =========================================================================== */
:root, body, input, select, textarea, button, table, th, td, li, ul, ol, label,
summary, details, legend, fieldset, option, a, span, div, section, header,
footer, nav, main, form, h1, h2, h3, h4, h5, h6, p, strong, em, small, time {
  font-family: var(--display);
}

/*
 * Archivo Black is a display face. A paragraph set in it is exhausting, so
 * anything that is genuinely a sentence steps down to the body stack - and
 * that is a deliberate, named list rather than a leftover.
 */
/*
 * NOT bare `p`, and NOT `.muted`. Those two matched nearly every line on
 * every screen and dragged the whole app straight back to the phone's own
 * font - which is exactly why the change kept looking half-applied. Only
 * genuine long-form reading is listed here.
 */
.rules, .rules li, .pastebox, .chatmsg, .msgbody, blockquote,
textarea, input, .why, .risk {
  font-family: var(--body);
  font-weight: 450;
}

/* Numbers stay in the shout: counts, clocks, scores, the countdown. */
.countdown, .pill, .cell, .score, .wk, .alive b, .stakebig {
  font-family: var(--shout);
  font-weight: 400;
}

/* ===========================================================================
   THE MASTHEAD
   ---------------------------------------------------------------------------
   A full-width navy bar with the wordmark stranded in the left corner, doing
   nothing with the other three quarters of it. The mark is the thing, so it
   goes in the middle and the bar shrinks to fit it.
   =========================================================================== */
.topbar {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 16px 11px;
  background: var(--field-deep);
  border-bottom: 3px solid var(--gold);
}
.brand { margin: 0; }
.wordmark { width: min(62vw, 260px); }

/* ===========================================================================
   THE ROUND PANEL
   ---------------------------------------------------------------------------
   It was a flat navy box that did not belong to anything. It is now the top of
   the album page itself: the same deep navy, edge to edge with the card, with
   the perforated strip above it and a gold rule under it, so it reads as the
   header of the page rather than as a box dropped onto one.
   =========================================================================== */
.pickcard { padding: 0; overflow: hidden; }
.pickcard > *:not(.mast) { padding-left: 18px; padding-right: 18px; }
.pickcard > *:last-child { padding-bottom: 18px; }

.mast {
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(122, 160, 240, .26), transparent 70%),
    var(--field-deep);
  padding: 24px 18px 22px;
  text-align: center;
  border-bottom: 4px solid var(--gold);
  border-radius: 0;
}

/* The league name above the round. It was gold on navy, which is legible but
   quiet; white is what you actually want to read first. */
.masteyebrow {
  color: #fff;
  opacity: .82;
  font-size: 0.6875rem;
  letter-spacing: .14em;
  margin: 0 0 6px;
}

/* Everything in the panel sits on the centre line, including the clock, which
   was left-aligned inside a centred box. */
.mast .deadline {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-width: 0;
  margin: 0 auto;
  gap: 2px;
}
.mast .deadline .label {
  color: var(--gold);
  font-family: var(--display);
  font-size: 0.625rem;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.mast .deadline .countdown {
  color: #fff;
  font-size: clamp(1.6rem, 8.5vw, 2.4rem);
  line-height: 1;
}

/* ===========================================================================
   THE LAST OF THE GOLD, AND THE THINGS THAT WOULD NOT FIT
   =========================================================================== */

/* The league name above ROUND 1. White, and stated with enough force that no
   earlier rule can quietly put gold back. */
.mast .masteyebrow,
.pickcard .masteyebrow,
p.masteyebrow {
  color: #FFFFFF;
  opacity: .9;
}

/* The league chips. "FREE ENTRY - Championship" ran off the screen; the strip
   scrolls sideways and each chip keeps its own width rather than the row
   trying to fit them all. */
.switcher {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 2px 2px 6px;
  margin-inline: -2px;
  max-width: 100%;
  scrollbar-width: none;
}
.switcher::-webkit-scrollbar { display: none; }
.lchip {
  flex: 0 0 auto;
  scroll-snap-align: start;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  max-width: 68vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 0.6875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 8px 14px;
  cursor: pointer;
}

/* ===========================================================================
   ONE VOICE, IN CAPITALS
   ---------------------------------------------------------------------------
   Named individually because each was reported by name: the pick line, the
   season link, the paid-up card, the album. They are labels, not prose, so
   they take the display face and the same tracked capitals as everything else.
   =========================================================================== */
.current-pick,
.seasonlink,
.seasonlink a,
.card.ok h2, .card.ok p,
.album h2, .album p,
.usedlist,
.stake, .stakesplit,
.alive, .sect {
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: .05em;
}

.current-pick {
  font-size: 0.8125rem;
  color: var(--text);
}
.current-pick strong { color: var(--red-ink); font-size: 0.9375rem; }

.seasonlink { font-size: 0.75rem; }
.seasonlink a { color: var(--red-ink); text-decoration-thickness: 2px; }
/* This line was deliberately opted OUT of the new voice - lower case, body
   face - on the grounds that it was a sentence. It sits directly under a
   heading in tracked capitals, so it read as a leftover rather than as a
   choice. It joins the rest. */
.seasonlink .hint {
  display: block;
  font-family: var(--display);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: 0.625rem;
  color: var(--text-mute);
  margin-top: 5px;
}

.card.ok p, .album p { font-size: 0.75rem; letter-spacing: .04em; }

/* The badge either side of the wordmark. It fills a bar that was three
   quarters empty, and puts the icon somebody taps on their home screen at the
   top of the app it opens - the cheapest way to make the two feel like one
   object. Hidden from screen readers: the link is already labelled. */
.brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 3vw, 20px);
}
.brandcrest {
  flex: none;
  width: clamp(34px, 11vw, 48px);
  height: auto;
  border-radius: 9px;
  border: 2px solid var(--gold);
  box-shadow: 0 2px 0 rgba(0, 0, 0, .45);
}
.wordmark { width: min(46vw, 220px); }

/* On a narrow phone the pair of badges plus the mark is too much. The second
   one goes rather than everything shrinking to fit. */
@media (max-width: 340px) {
  .brandcrest:last-of-type { display: none; }
}

/* ===========================================================================
   ONE VOICE ON EVERY TAB
   ---------------------------------------------------------------------------
   Capitals applied the same way the face was: at the root, inherited by
   everything, with only genuine long-form reading exempt. Applying it label by
   label is what left the field, the chat, the leagues and the admin screens
   half-converted after every previous pass.
   =========================================================================== */
body, h1, h2, h3, h4, h5, h6,
p, span, div, li, td, th, label, a, strong, em, small, time, summary,
button, .btnlink, .tag, .badge, .chip, .pill, .sect, .hint, .muted,
.dayname, .teamname, .sidename, .player, .wk, .ko, .stake, .paidcount,
.invited, .invite, .leaguerow, .lchip, .tab, .cell, .score, .alive {
  text-transform: uppercase;
  letter-spacing: .04em;
}

/*
 * Exempt: things somebody reads a sentence of, and things where the exact
 * characters matter. An invite code in capitals is fine; an invite LINK in
 * capitals is a broken URL, and a chat message in capitals is shouting.
 */
.rules, .rules li, .pastebox, .chatmsg, .msgbody, blockquote,
textarea, input, .copyable, .code, .invitelink input,
.why, .risk, .email, .seasonlink .hint + *,
.card.narrow p, .authpage p, .auth-page p {
  text-transform: none;
  letter-spacing: normal;
}

/* Names are people's names. They keep their capitals as written, because
   ZACK CHARILAOU on a table of thirty is harder to scan than Zack Charilaou. */
.standings .player, .waiting .chip, .teamgroup .who {
  text-transform: none;
  letter-spacing: .01em;
}

/* ===========================================================================
   THE IPHONE WAS SETTING THE TYPE BIGGER THAN THE ANDROID
   ---------------------------------------------------------------------------
   Reported as "fine on my phone, cut off on my friend's iPhone", which is the
   shape of a browser difference rather than of a layout mistake - the same
   CSS cannot produce two widths unless something outside the CSS is changing
   the numbers.

   It was. Safari on iOS runs TEXT AUTOSIZING: it inflates the font size of
   text inside block containers, on its own, to what it guesses is comfortable
   on a phone. Chrome on Android has the same feature but switches it off the
   moment a page declares `width=device-width`, which this one does. Safari
   does not - it needs to be told, and nothing here ever told it. So every
   label on the iPhone was being drawn larger than the size it was designed
   at, and the things sized to hold those labels were not.

   Confirmed rather than assumed. Rendering the live pages in a real 390px
   viewport at the designed size shows nothing overflowing; re-rendering them
   with the root size raised - which is what Safari was doing - reproduces
   every single thing in the photographs, including which tab loses its label
   first:

     designed (18px)   /field, /leagues, /   nothing overflows the screen
     inflated (24px)   the tab bar runs to 505px on a 390px screen, and
                       "Account" is the part that falls off the right edge

   That is the photograph, exactly.

   `100%`, not `none`. `none` would also block the reader's own text-size
   setting, which is somebody's eyesight and not ours to overrule. `100%`
   means "render text at the size the page asked for" and leaves deliberate
   zoom alone.
   =========================================================================== */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ---------------------------------------------------------------------------
   AND THEN THE THREE THINGS THAT WERE FRAGILE ENOUGH TO BREAK WHEN IT DID
   ---------------------------------------------------------------------------
   Fixing the cause is not enough on its own. A phone with large text turned
   on in its accessibility settings, or a longer league name, would walk into
   the same three failures - so each of them is made unbreakable rather than
   merely made to fit today.
   --------------------------------------------------------------------------- */

/* 1. THE TAB BAR.
   `grid-auto-columns: 1fr` is the same trap the fixture row fell into: a bare
   `1fr` is `minmax(auto, 1fr)`, and `auto` will not go below the width of its
   contents. Seven tabs that each refuse to shrink add up to more than a
   phone, and the last one walks off the edge. `minmax(0, 1fr)` is seven equal
   columns that are genuinely allowed to be narrow, and the label ellipsises
   inside its own column instead of pushing the bar wider. */
.tabbar { grid-auto-columns: minmax(0, 1fr); }
.tab { min-width: 0; }
/* The label only - `.tabicon` holds the drawing and the unread count, and
   neither wants a text overflow rule. */
.tab > span:not(.tabicon) {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 2. THE LEAGUE SWITCHER.
   "FREE ENTRY - Championship" is 250px of chip on a 390px screen, sitting in
   a sideways scroller behind a chip that is already 150px wide. It scrolled,
   technically. What it looked like was a word cut in half at the edge of the
   screen, which is indistinguishable from a bug.

   Chips now wrap onto a second line instead. A league is named by whoever
   made it, so there is no width that is safe to assume; wrapping is the only
   arrangement where a long name cannot be hidden. */
.switcher { flex-wrap: wrap; overflow-x: visible; }
.lchip { max-width: 100%; }

/* 3. "VIEWING" WAS TRUNCATED TO "VIE..." ON EVERY PHONE, NOT JUST THE IPHONE.
   Measured at the designed size: the tag's box is 47px and its text is 65px.
   It has been clipped since the day the rule below it was written.

   `.leaguetop > * { min-width: 0 }` was added to stop long names overflowing,
   and it worked - but it applies to every child, so the two-word label and
   the button were told to shrink as readily as the league name. In a row of
   a name and a button, the name is the part that should give way: it is the
   long one, it is the one somebody typed, and it is the one that still makes
   sense with an ellipsis on the end. "Vie..." does not. */
.leaguetop > :first-child { flex: 1 1 auto; min-width: 0; }
.leaguetop > .tag,
.leaguetop > a,
.leaguetop > form,
.leaguetop > button {
  flex: 0 0 auto;
  min-width: max-content;
  overflow: visible;
}

/* --- and the tab labels never fitted their columns anyway --------------------
   Found while checking the fix rather than the fault, which is the useful
   half of measuring instead of guessing. Once the columns were allowed to be
   narrow, the labels started ellipsising - at the DESIGNED size, not just the
   inflated one. "Selection" is 68px of lettering in a 52px column.

   So it had always been too wide. It never looked ellipsised before only
   because nothing was clipping it: the labels simply overflowed their columns
   and ran into each other. That is visible in the photograph of the phone -
   SELECTION and THE FIELD are touching, with no gap between them.

   Shrinking the type further would make it unreadable, and shortening the
   words would rename parts of the app to solve a typesetting problem. The
   third option is the one that costs nothing: set them in the condensed face
   the app already loads. Anton is roughly a third narrower than Archivo Black
   at the same size, which is the whole point of a condensed face and exactly
   the room needed.

   Measured after the change, in a real 390px viewport, signed in as an admin
   so all seven tabs are present: nothing off screen and no label clipped, at
   the designed size and at both inflated sizes. */
.tab {
  font-family: var(--shout);
  /* Sized against the screen as well, so seven tabs cannot outgrow it. */
  font-size: clamp(0.5rem, 2.5vw, 0.625rem);
  letter-spacing: .02em;
}
.tab > span:not(.tabicon) { font-family: var(--shout); }

/* ===========================================================================
   SELECTION + FIELD: PHONE-FIRST OPERATING PASS
   ---------------------------------------------------------------------------
   These are the two screens people use under time pressure. The fixture list
   keeps the matchday-coupon character, but a club name is allowed to be a
   club name rather than an ellipsis. The field keeps its complete history,
   while the player column is bounded so it cannot shove the current round
   beyond the phone.
   =========================================================================== */

.pickerhint {
  color: var(--text-soft);
  font-family: var(--body);
  font-size: 0.9375rem;
  font-weight: 650;
  letter-spacing: 0;
  text-transform: none;
}

.fixrow {
  border-bottom-color: var(--hair-strong);
  min-height: 112px;
}

.side {
  position: relative;
  flex-direction: column;
  justify-content: flex-start;
  min-height: 112px;
  padding: 12px 8px 28px;
  gap: 8px;
  border-radius: 0;
}

.side .full {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow-wrap: normal;
  hyphens: none;
  font-size: clamp(0.6875rem, 3vw, 0.8125rem);
  line-height: 1.18;
  text-align: center;
}

.side .why,
.pick-status {
  position: absolute;
  inset-inline: 5px;
  bottom: 7px;
  min-height: 16px;
  font-family: var(--body);
  font-size: 0.625rem;
  font-weight: 750;
  line-height: 1.15;
  letter-spacing: .02em;
  text-align: center;
  text-transform: none;
}

.pick-status {
  color: var(--green-ink);
}

.side.selected,
.side[aria-pressed="true"] {
  background: #FFF7CC;
  box-shadow: inset 0 0 0 3px var(--gold), inset 0 -26px 0 rgba(255, 212, 0, .18);
}

.side.selected::after {
  top: 7px;
  right: 7px;
  width: 22px;
  height: 22px;
  background: var(--green);
  color: #fff;
  box-shadow: 0 2px 5px rgba(7, 21, 64, .24);
}

.ko {
  align-self: stretch;
  font-family: var(--shout);
  font-size: 0.8125rem;
  letter-spacing: .02em;
}

.field-scroll-hint {
  margin: 2px 0 10px;
  color: var(--text-soft);
  font-family: var(--body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

.field-scroll {
  position: relative;
  border-block: 1px solid var(--hair-strong);
  scrollbar-color: var(--gold) var(--well);
  scrollbar-width: thin;
  overscroll-behavior-inline: contain;
}

.field-scroll:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.field-scroll .standings {
  width: max-content;
  min-width: 100%;
  table-layout: fixed;
}

.field-scroll .standings .player {
  z-index: 2;
  width: clamp(164px, 52vw, 220px);
  min-width: clamp(164px, 52vw, 220px);
  max-width: clamp(164px, 52vw, 220px);
  white-space: normal;
  line-height: 1.25;
  box-shadow: 8px 0 10px -10px rgba(7, 21, 64, .65);
}

.field-scroll .standings th.player {
  z-index: 3;
}

.field-scroll .standings .cell {
  width: 72px;
  min-width: 72px;
}

@media (max-width: 380px) {
  .fixrow { grid-template-columns: minmax(0, 1fr) 48px minmax(0, 1fr); }
  .side { padding-inline: 5px; }
  .side .crest.md { width: 38px; height: 38px; }
  .field-scroll .standings .player {
    width: 168px;
    min-width: 168px;
    max-width: 168px;
  }
}

@media (pointer: coarse) {
  .side { min-height: 116px; }
}

/* MATCHDAY SCOREBOARD — visible Selection + Field redesign. */
.pickcard {
  border: 0;
  border-radius: 12px 12px 6px 6px;
  box-shadow: 0 16px 38px rgba(4, 12, 38, .34), 0 3px 8px rgba(4, 12, 38, .2);
}
.pickcard .mast {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(132px, .72fr);
  grid-template-areas: "league deadline" "round deadline";
  align-items: stretch;
  gap: 0;
  min-height: 154px;
  padding: 0;
  text-align: left;
  background: var(--field-deep);
  border-bottom: 5px solid var(--gold);
}
.pickcard .mast .masteyebrow {
  grid-area: league;
  align-self: end;
  margin: 0;
  padding: 22px 18px 2px;
  color: var(--on-field-soft);
  font-size: .6875rem;
  line-height: 1.2;
  letter-spacing: .1em;
  text-align: left;
}
.pickcard .mast h1 {
  grid-area: round;
  align-self: start;
  margin: 0;
  padding: 0 18px 20px;
  color: #fff;
  font-size: clamp(3.25rem, 16vw, 5.25rem);
  line-height: .88;
  text-align: left;
}
.pickcard .mast .deadline {
  grid-area: deadline;
  align-self: stretch;
  position: relative;
  margin: 0;
  padding: 18px 10px;
  background: var(--gold);
  color: var(--on-gold);
}
.pickcard .mast .deadline::before,
.pickcard .mast .deadline::after {
  content: '';
  position: absolute;
  left: -9px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--field-deep);
}
.pickcard .mast .deadline::before { top: 22px; }
.pickcard .mast .deadline::after { bottom: 22px; }
.pickcard .mast .deadline .label { color: var(--on-gold); font-size: .625rem; line-height: 1.2; letter-spacing: .12em; text-align: center; }
.pickcard .mast .deadline .countdown { color: var(--on-gold); font-size: clamp(1.65rem, 8vw, 2.6rem); line-height: .9; text-align: center; }
.pickcard .mast.shut .deadline { background: #D8DEEA; color: var(--text); }
.pickcard .mast.shut .deadline .label,
.pickcard .mast.shut .deadline .countdown { color: var(--text); }
.pickcard .current-pick,
.pickcard > .warn { margin: 18px 18px 4px; padding: 13px 14px; border-radius: 4px; }
.pickcard .current-pick {
  display: flex;
  align-items: center;
  gap: 12px;
}
.pickcard .current-pick > span { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.pickcard .current-pick small { color: var(--green-ink); font-size: .6875rem; font-weight: 750; }
.pickcard .current-pick strong { line-height: 1.1; }
.pickcard .current-pick strong + span { color: var(--text-soft); font-size: .75rem; line-height: 1.3; }
.pickcard .picker { margin-top: 0; padding-top: 16px; }
.entry-switcher { display: flex; gap: 8px; overflow-x: auto; padding: 12px 18px; background: #EEF1F7; }
.entry-switcher a { flex: none; min-height: 42px; display: inline-flex; align-items: center; padding: 8px 14px; border: 1px solid #AAB4C7; border-radius: 999px; background: #fff; color: var(--field-deep); font-weight: 750; text-decoration: none; }
.entry-switcher a.active { background: var(--field-deep); color: #fff; border-color: var(--field-deep); }
.add-entry { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 18px; background: #FFF4AC; }
.add-entry p { display: flex; min-width: 0; flex-direction: column; margin: 0; }
.add-entry p span { color: var(--text-soft); font-size: .75rem; }
.add-entry button { flex: none; min-height: 42px; }
@media (max-width: 390px) { .add-entry { align-items: stretch; flex-direction: column; } .add-entry button { width: 100%; } }
.pickcard .pick-form { padding-bottom: 94px; }
.pickcard .pickerhint { margin: 0 0 12px; padding: 0 2px; color: var(--text); font-size: 1rem; }
.pickcard .day {
  margin: 0 0 12px;
  border: 2px solid var(--field-deep);
  border-radius: 5px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 5px 14px rgba(7, 21, 64, .12);
}
.pickcard .dayname { margin: 0; padding: 9px 12px 8px; background: var(--field-deep); color: #fff; border: 0; font-size: .6875rem; letter-spacing: .12em; }
.pickcard .dayname::after { display: none; }
.pickcard .fixrow { min-height: 108px; background: #fff; border-bottom: 1px solid #CBD2E1; }
.pickcard .fixrow:last-child { border-bottom: 0; }
.pickcard .side { min-height: 108px; background: #fff; }
.pickcard .side input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  opacity: 0;
  pointer-events: none;
}
.pickcard .side:has(input:focus-visible) { outline: 3px solid var(--gold); outline-offset: -3px; }
.pickcard .side:has(input:disabled) { cursor: not-allowed; }
.pickcard .side .full {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.3em;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
  color: var(--text);
  font-family: var(--body);
  font-size: clamp(.75rem, 3.25vw, .875rem);
  font-weight: 750;
  line-height: 1.15;
  letter-spacing: 0;
  text-transform: none;
  text-wrap: balance;
}
.pickcard .revealed-picks .side { min-height: 126px; }
.pickcard .pick-count {
  margin-top: 5px;
  color: var(--text-soft);
  font-size: .625rem;
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
}
.pickcard .side:hover:not(:disabled) { background: #F5F7FB; }
.pickcard .side.selected,
.pickcard .side[aria-pressed="true"] { background: #FFF4AC; box-shadow: inset 0 0 0 3px var(--gold), inset 0 -26px 0 rgba(255, 212, 0, .24); }
.pickcard .ko { position: relative; background: #EEF1F7; color: var(--field-deep); border-inline: 1px solid #CBD2E1; font-size: .875rem; }
.pickcard .fixrow.haspick .ko { background: var(--red-band); color: #fff; }
.pickcard .seasonlink { margin: 12px 18px 4px; padding: 16px 2px 4px; border-top: 2px solid var(--hair-strong); }
.used-drawer { margin: 16px 18px 4px; border-top: 1px solid var(--hair-strong); }
.used-drawer summary { padding: 14px 0 8px; color: var(--text); font-weight: 750; cursor: pointer; }
.used-drawer p { display: flex; flex-wrap: wrap; gap: 7px; margin: 4px 0 8px; }
.used-drawer p span { display: inline-flex; align-items: center; gap: 5px; padding: 5px 9px; background: #EEF1F7; border-radius: 3px; color: var(--text-soft); font-size: .6875rem; }
.pick-confirm {
  position: fixed;
  z-index: 12;
  right: 12px;
  bottom: calc(68px + env(safe-area-inset-bottom));
  left: 12px;
  width: min(calc(100% - 24px), 720px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  margin: 0 auto;
  padding: 12px 14px;
  background: var(--field-deep);
  color: #fff;
  border-top: 4px solid var(--gold);
  box-shadow: 0 -8px 20px rgba(7, 21, 64, .22);
}
.pick-confirm span { display: flex; min-width: 0; flex-direction: column; }
.pick-confirm small { color: var(--on-field-soft); font-size: .625rem; font-weight: 700; }
.pick-confirm strong { overflow: hidden; text-overflow: ellipsis; color: #fff; font-size: .875rem; white-space: nowrap; }
.pick-confirm button { min-height: 44px; margin: 0; padding-inline: 14px; }
.pick-confirm button:disabled { background: #D8DEEA; color: #58647A; border-color: #AAB4C7; }
.pick-form.deadline-closed .side { cursor: not-allowed; }
.pick-form.deadline-closed .side:not(.selected) { opacity: .62; }
.pick-form[aria-busy="true"] .pick-confirm { cursor: progress; }

.field-card {
  padding: 0 0 18px;
  overflow: hidden;
  border: 0;
  border-radius: 10px 10px 5px 5px;
  box-shadow: 0 16px 38px rgba(4, 12, 38, .3), 0 3px 8px rgba(4, 12, 38, .2);
}
.field-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: stretch;
  gap: 0;
  margin: 0;
  padding: 0;
  background: var(--field-deep);
  border-bottom: 5px solid var(--gold);
}
.field-title { padding: 19px 18px 17px; }
.field-title h1 { margin: 0; color: #fff; font-size: clamp(2.8rem, 13vw, 4.5rem); line-height: .88; }
.field-title p { margin: 7px 0 0; color: var(--on-field-soft); font-size: .6875rem; letter-spacing: .08em; }
.field-score {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 118px;
  margin: 0;
  padding: 14px 12px;
  background: var(--gold);
  color: var(--on-gold);
  font-size: .6875rem;
  line-height: 1.05;
  text-align: center;
}
.field-score strong {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: baseline;
  gap: 7px;
  font-family: var(--shout);
  font-size: clamp(2.1rem, 9.5vw, 3.2rem);
  font-weight: 400;
  line-height: .9;
  letter-spacing: 0;
}
.field-score strong b { font: inherit; letter-spacing: 0; }
.field-score strong b:first-child { text-align: right; }
.field-score strong b:last-child { text-align: left; }
.field-score strong i { font: inherit; font-size: .68em; opacity: .58; }
.field-score span { display: block; margin-top: 7px; color: #5B4A00; font-size: .6875rem; line-height: 1.1; }
.field-stake { grid-column: 1 / -1; padding: 0 18px 14px; color: #fff; }
.field-stake:empty { display: none; }
.field-stake .stake { margin: 0; color: var(--on-field-soft); }
.field-card .field-scroll-hint { margin: 0; padding: 12px 16px 10px; background: #EEF1F7; color: var(--text-soft); border-bottom: 1px solid var(--hair-strong); }
.field-card .field-scroll { border: 0; }
.field-card .standings th { padding-block: 11px; background: #F7F8FB; border-bottom: 2px solid var(--field-deep); }
.field-card .standings th.now { background: var(--gold); color: var(--on-gold); border-bottom-color: var(--red-band); }
.field-card .standings td { height: 64px; background: #fff; }
.field-card .standings tbody tr:nth-child(even) td { background: #F7F8FB; }
.field-card .standings tbody tr.out td { background: #ECEFF4; }
.field-card .standings .player { padding-left: 16px; border-right: 2px solid var(--field-deep); }
.field-card .legend,
.field-card > .muted { margin-inline: 16px; }
.field-view-tabs {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  padding: 12px 16px 0;
  background: #EEF1F7;
  border-bottom: 1px solid var(--hair-strong);
}
.field-view-tabs button {
  min-height: 44px;
  margin: 0;
  border: 0;
  border-bottom: 4px solid transparent;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--text-soft);
}
.field-view-tabs button[aria-selected="true"] { border-bottom-color: var(--red-band); color: var(--field-deep); }
.field-view { background: #fff; }
.field-round-head { display: flex; align-items: end; justify-content: space-between; gap: 18px; padding: 18px 16px 12px; }
.field-round-head h2 { margin: 0; color: var(--field-deep); font-size: 1.65rem; }
.field-round-head p { max-width: 19rem; margin: 0; color: var(--text-soft); font-size: .75rem; line-height: 1.35; text-align: right; }
.field-player-group { margin: 0; }
.field-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 16px;
  background: var(--field-deep);
  color: #fff;
}
.field-group-head h3 { margin: 0; color: inherit; font-family: var(--body); font-size: .75rem; font-weight: 800; }
.field-group-head span {
  display: grid;
  min-width: 25px;
  min-height: 25px;
  place-items: center;
  padding-inline: 6px;
  border: 1px solid rgba(255, 255, 255, .38);
  border-radius: 999px;
  font-size: .6875rem;
  font-weight: 850;
}
.field-waiting-group { border-top: 8px solid #D9DFEA; }
.field-waiting-group .field-group-head { background: #6B5500; }
.field-out-group { border-top: 8px solid #D9DFEA; }
.field-out-group .field-group-head { background: #46516A; }
.field-players { margin: 0; padding: 0; list-style: none; }
.field-player {
  display: grid;
  grid-template-columns: minmax(120px, .8fr) minmax(150px, 1.2fr);
  align-items: center;
  gap: 12px;
  min-height: 72px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--hair-strong);
}
.field-player.is-me { background: #FFF1A8; }
.field-player.out { background: #EEF1F4; color: #4E5B78; }
.field-player-name { display: flex; min-width: 0; flex-direction: column; align-items: flex-start; gap: 2px; }
.field-player-name > small { color: var(--red-ink); font-size: .625rem; font-weight: 800; }
.field-player-name > strong { max-width: 100%; overflow-wrap: anywhere; font-size: .875rem; line-height: 1.2; }
.field-player-name .badge { margin: 3px 0 0; }
.field-player-state { display: flex; flex-direction: column; align-items: flex-start; color: var(--text-soft); font-size: .75rem; font-weight: 750; line-height: 1.3; }
.field-player-state small { color: var(--text-mute); font-size: .625rem; font-weight: 600; }
.picked-state::before { content: ''; width: 8px; height: 8px; margin-bottom: 5px; border-radius: 50%; background: var(--green); }
.out-state { color: var(--red-ink); }
.field-player-pick { display: flex; align-items: center; gap: 9px; min-width: 0; }
.field-player-pick > span { display: flex; min-width: 0; flex-direction: column; }
.field-player-pick strong { overflow-wrap: anywhere; font-size: .8125rem; line-height: 1.2; }
.field-player-pick small { color: var(--text-soft); font-size: .625rem; }
.field-player-pick.win small, .field-player-pick.void_win small { color: var(--green-ink); }
.field-player-pick.loss small, .field-player-pick.draw small { color: var(--red-ink); }
.field-survival {
  display: grid;
  gap: 16px;
  padding: 18px 16px 16px;
  background: #F7F8FB;
  border-bottom: 1px solid var(--hair-strong);
}
.field-survival h2 { margin: 0; color: var(--field-deep); font-size: 1.35rem; }
.field-survival > div > p { margin: 3px 0 0; color: var(--text-soft); font-size: .75rem; }
.field-survival ol {
  position: relative;
  display: flex;
  gap: 0;
  margin: 0;
  padding: 0 2px 2px;
  overflow-x: auto;
  list-style: none;
  scrollbar-color: var(--field) #DDE3EE;
}
.field-survival li {
  position: relative;
  z-index: 1;
  display: grid;
  flex: 1 0 66px;
  justify-items: center;
  color: var(--text-soft);
  text-align: center;
}
.field-survival li::before {
  position: absolute;
  z-index: -1;
  top: 7px;
  right: 50%;
  width: 100%;
  height: 2px;
  background: #AEB8CC;
  content: '';
}
.field-survival li:first-child::before { display: none; }
.field-survival li > span {
  width: 16px;
  height: 16px;
  margin-bottom: 6px;
  border: 3px solid #F7F8FB;
  border-radius: 50%;
  background: var(--field);
  box-shadow: 0 0 0 1px var(--field);
}
.field-survival li.is-current > span { background: var(--gold); box-shadow: 0 0 0 2px var(--red-band); }
.field-survival li strong { color: var(--field-deep); font-size: .6875rem; }
.field-survival li small { margin-top: 1px; font-size: .625rem; white-space: nowrap; }
.field-view > .thisweek.card {
  margin: 18px 16px 0;
  padding: 18px 0 0;
  border: 0;
  border-top: 2px solid var(--field-deep);
  border-radius: 0;
  box-shadow: none;
}
.field-view > .thisweek.card h2 { font-size: 1.35rem; }

@media (max-width: 350px) {
  .pickcard .mast { grid-template-columns: minmax(0, 1fr) 118px; }
  .pickcard .mast h1 { font-size: 3rem; padding-inline: 14px; }
  .pickcard .mast .masteyebrow { padding-inline: 14px; }
  .field-score { min-width: 104px; }
  .pickcard .picker { padding-top: 12px; }
  .pickcard .day { margin-bottom: 10px; }
  .pickcard .side { padding-inline: 4px; }
}

@media (max-width: 420px) {
  .pick-confirm { grid-template-columns: minmax(0, 1fr) minmax(132px, auto); padding-inline: 12px; }
  .pick-confirm button { padding-inline: 10px; font-size: .75rem; }
  .field-player { grid-template-columns: minmax(104px, .72fr) minmax(132px, 1.28fr); padding-inline: 14px; }
}

/* Natural casing everywhere the app communicates. The wordmark is a drawn
   brand asset and stays untouched; every page, tab, control, table and status
   now takes its capitalization from the actual copy instead of CSS shouting. */
main, main *,
.topbar nav, .topbar nav *,
.tabbar, .tabbar *,
.promo, .promo *,
.masthead, .masthead *,
footer, footer * {
  text-transform: none !important;
  letter-spacing: normal;
}

/* Stop a normal tap on labels and status copy opening Android's text-search
   affordance. Text entry remains selectable so editing and password-manager
   behaviour are unchanged. */
body {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  isolation: isolate;
}
input, textarea, [contenteditable="true"] {
  -webkit-touch-callout: default;
  -webkit-user-select: text;
  user-select: text;
}

/* One quiet watermark behind the working surface. It stays fixed while the
   album scrolls, never receives taps, and cards remain fully opaque above it. */
body::before {
  content: '';
  position: fixed;
  left: 50%;
  top: 52%;
  width: min(86vw, 560px);
  aspect-ratio: 1;
  background: url('/logo-watermark.svg') center / contain no-repeat;
  opacity: .16;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 0;
}
body > * {
  position: relative;
  z-index: 1;
}

/* ===========================================================================
   LEAGUES: THE PLAYER'S LEAGUE WALLET
   ---------------------------------------------------------------------------
   One current competition leads. Other memberships remain compact and open
   competitions live on their own join board, so "where am I playing?" and
   "what can I enter?" never compete in the same row.
   =========================================================================== */

.leagues-page {
  overflow: hidden;
  background: #FFFFFF;
  color: var(--text);
  border-radius: 10px 10px 5px 5px;
  box-shadow: 0 16px 38px rgba(4, 12, 38, .3), 0 3px 8px rgba(4, 12, 38, .2);
}

.leagues-hero {
  padding: 24px 18px 22px;
  background: var(--field-deep);
  color: #FFFFFF;
  border-bottom: 5px solid var(--gold);
}
.leagues-hero h1 {
  max-width: 9ch;
  margin: 0;
  color: #FFFFFF;
  font-family: var(--shout);
  font-size: clamp(3.5rem, 17vw, 5.5rem);
  font-weight: 400 !important;
  line-height: .84;
  text-wrap: balance;
}
.leagues-hero p {
  max-width: 34rem;
  margin: 13px 0 0;
  color: var(--on-field-soft);
  font-family: var(--body);
  font-size: .875rem;
  line-height: 1.45;
}

.league-create {
  margin-top: 18px;
  padding: 0 18px 20px;
  background: #F7F8FB;
  border-top: 1px solid #DDE2EC;
}
.league-create > summary,
.league-owner-controls > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 62px;
  cursor: pointer;
}
.league-create > summary h2,
.league-owner-controls > summary h2 { margin: 0; color: var(--field-deep); font-size: 1.3rem; }
.league-create > p { margin: 0 0 16px; color: var(--text-soft); font-size: .8125rem; line-height: 1.45; }
.league-create > form,
.league-owner-controls > form,
.owner-payment-details { display: grid; gap: 13px; }
.league-create label,
.league-owner-controls label { min-width: 0; }
.league-create input,
.league-create select,
.league-owner-controls input,
.league-owner-controls textarea { width: 100%; text-transform: none; }
.league-create button { width: 100%; min-height: 46px; }

.league-section { padding: 24px 18px 6px; }
.open-leagues.join-first { padding-top: 22px; background: #FFF9D8; }
.open-leagues.join-first .league-section-head { border-bottom-color: var(--gold-dark); }
.league-section + .league-section,
.league-empty + .league-section { border-top: 8px solid #EEF1F7; }
.league-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--field-deep);
}
.league-section-head h2 { margin: 0; color: var(--field-deep); font-size: 1.55rem; }
.league-section-head > span {
  flex: none;
  color: var(--text-soft);
  font-size: .6875rem;
  font-weight: 700;
}
.league-section-copy {
  max-width: 36rem;
  margin: 12px 0 0;
  color: var(--text-soft);
  font-family: var(--body);
  font-size: .8125rem;
  line-height: 1.45;
}

.leagues-page .leaguelist {
  display: grid;
  gap: 12px;
  margin: 14px 0 18px;
}
.leagues-page .leaguerow {
  position: relative;
  min-width: 0;
  padding: 0;
  overflow: hidden;
  background: #F7F8FB;
  border: 1px solid #CBD2E1;
  border-radius: 5px;
  box-shadow: 0 5px 14px rgba(7, 21, 64, .1);
}
.leagues-page .leaguerow.current {
  background: #FFFFFF;
  border: 2px solid var(--field-deep);
  box-shadow: 0 10px 24px rgba(7, 21, 64, .16);
}
.league-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 31px;
  padding: 6px 12px;
  background: #E7EBF3;
  color: var(--text-soft);
  font-size: .625rem;
  font-weight: 750;
}
.current .league-strip { background: var(--field-deep); color: var(--on-field-soft); }
.league-state { color: var(--field-deep); }
.current .league-state { color: #FFFFFF; }
.league-open .league-strip { background: var(--gold); color: #5B4A00; }
.league-open .league-state { color: var(--on-gold); }

.leagues-page .leaguetop {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 14px;
  padding: 16px 14px 10px;
}
.league-copy { min-width: 0; }
.league-copy strong {
  display: block;
  overflow: visible;
  color: var(--field-deep);
  font-size: clamp(1rem, 4.8vw, 1.3rem);
  line-height: 1.12;
  overflow-wrap: anywhere;
}
.league-copy p { margin: 6px 0 0; color: var(--text-soft); font-family: var(--body); font-size: .75rem; }
.league-entry {
  max-width: 110px;
  padding: 5px 8px;
  background: #E7EBF3;
  color: var(--field-deep);
  border-radius: 3px;
  font-size: .625rem;
  font-weight: 750;
  line-height: 1.2;
  text-align: right;
}
.league-open .league-entry { background: #FFF1A8; color: #5B4A00; }

.league-actions { padding: 0 14px 15px; }
.league-actions form { margin: 0; }
.league-actions .btnlink,
.league-actions button { width: 100%; min-height: 44px; margin: 0; text-align: center; }
.league-actions .btnlink { display: flex; align-items: center; justify-content: center; }
.league-direct {
  display: block;
  min-height: 36px;
  padding: 10px 4px 0;
  color: var(--field-deep);
  font-size: .6875rem;
  font-weight: 750;
  text-align: center;
  text-underline-offset: 3px;
}

.league-invite {
  margin: 0 14px 14px;
  border-top: 1px solid #CBD2E1;
}
.league-invite summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 0 4px;
  color: var(--field-deep);
  font-size: .75rem;
  font-weight: 750;
  cursor: pointer;
}
.league-invite > p {
  margin: 2px 0 8px;
  color: var(--text-soft);
  font-family: var(--body);
  font-size: .75rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.leagues-page .sharerow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
  margin: 0;
  padding: 0 0 3px;
  border: 0;
}
.leagues-page .sharerow button { min-height: 42px; padding: 8px; font-size: .6875rem; }
.league-closed-note {
  margin: 0 14px 14px;
  padding-top: 11px;
  color: var(--text-soft);
  border-top: 1px solid #CBD2E1;
  font-family: var(--body);
  font-size: .75rem;
  line-height: 1.4;
}

.open-leagues { padding-bottom: 10px; background: #F7F8FB; }
.open-leagues .leaguerow { background: #FFFFFF; border-color: #C6A900; }
.league-empty { padding: 24px 18px; background: #FFFFFF; }
.league-empty h2 { margin: 0; color: var(--field-deep); font-size: 1.35rem; }
.league-empty p { margin: 9px 0 0; color: var(--text-soft); font-family: var(--body); font-size: .8125rem; line-height: 1.45; }
.league-empty .btnlink { margin-top: 14px; }
.league-empty-quiet { background: #EEF1F7; border-top: 1px solid #CBD2E1; }
.past-leagues {
  padding: 0 18px 8px;
  background: #EEF1F7;
  border-top: 1px solid #CBD2E1;
}
.past-leagues > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 68px;
  cursor: pointer;
}
.past-leagues > summary > span:first-child { display: grid; gap: 3px; }
.past-leagues > summary strong { color: var(--field-deep); font-size: 1.3rem; }
.past-leagues > summary small { color: var(--text-soft); font-family: var(--body); font-size: .75rem; }
.past-leagues .leaguelist { margin-top: 2px; }
.past-leagues .leaguerow { box-shadow: none; }
.chat-closed {
  margin: 0;
  padding: 18px 20px max(18px, env(safe-area-inset-bottom));
  background: var(--well);
  color: var(--text-soft);
  border-top: var(--line) solid var(--hair-strong);
  font-size: .8125rem;
  text-align: center;
}

@media (min-width: 700px) {
  .leagues-page .leaguelist { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .leagues-page .leaguerow.current { grid-column: 1 / -1; }
  .leagues-page .leaguerow.current .leaguetop { padding: 20px 18px 12px; }
  .leagues-page .leaguerow.current .league-actions,
  .leagues-page .leaguerow.current .league-invite,
  .leagues-page .leaguerow.current .league-closed-note { margin-inline: 18px; padding-inline: 0; }
}

@media (max-width: 360px) {
  .leagues-hero { padding-inline: 15px; }
  .league-section, .league-empty, .past-leagues { padding-inline: 14px; }
  .leagues-page .leaguetop { grid-template-columns: minmax(0, 1fr); }
  .league-entry { max-width: none; justify-self: start; text-align: left; }
}

/* One league reads like the season ticket a player carries through the run:
   identity, holder status, punched destinations, then the small print. */
.league-detail-page {
  width: 100%;
  max-width: 760px;
  margin-inline: auto;
  overflow: hidden;
  background: #FFFFFF;
  color: var(--text);
  border-radius: 10px 10px 5px 5px;
  box-shadow: 0 16px 38px rgba(4, 12, 38, .3), 0 3px 8px rgba(4, 12, 38, .2);
}
.league-back {
  display: block;
  min-height: 44px;
  padding: 14px 18px 10px;
  background: #E7EBF3;
  color: var(--field-deep);
  font-size: .75rem;
  font-weight: 750;
  text-underline-offset: 3px;
}
.league-ticket { background: var(--field-deep); color: #FFFFFF; border-bottom: 5px solid var(--gold); }
.league-ticket-strip {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 8px 18px;
  background: var(--red-band);
  color: #FFFFFF;
  font-size: .6875rem;
  font-weight: 800;
}
.league-ticket-main { padding: 22px 18px 20px; }
.league-ticket-main h1 {
  max-width: 13ch;
  margin: 0;
  overflow-wrap: anywhere;
  color: #FFFFFF;
  font-size: clamp(2.8rem, 13vw, 5.2rem);
  line-height: .88;
  text-wrap: balance;
}
.league-ticket-main p { margin: 10px 0 0; color: var(--on-field-soft); font-size: .75rem; }
.league-ticket-numbers {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  border-top: 1px dashed rgba(255, 255, 255, .35);
}
.league-ticket-numbers > div { min-width: 0; padding: 13px 12px 15px; text-align: center; }
.league-ticket-numbers > div + div { border-left: 1px solid rgba(255, 255, 255, .22); }
.league-ticket-numbers dt { color: var(--on-field-soft); font-size: .625rem; font-weight: 700; }
.league-ticket-numbers dd {
  margin: 4px 0 0;
  overflow-wrap: anywhere;
  color: #FFFFFF;
  font-family: var(--display);
  font-size: clamp(1.25rem, 6vw, 2rem);
  font-weight: 900;
  line-height: 1;
}
.league-ticket-numbers dd span { color: var(--on-field-soft); font-size: .7em; }
.league-holder {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(160px, auto);
  align-items: center;
  gap: 18px;
  padding: 22px 18px;
  background: #FFF1A8;
  border-bottom: 1px solid #D7BF3A;
}
.league-holder h2 { margin: 0; color: #5B4A00; font-family: var(--body); font-size: .75rem; }
.league-holder strong { display: block; margin-top: 4px; color: var(--field-deep); font-size: 1.15rem; line-height: 1.2; }
.league-holder p { max-width: 34rem; margin: 5px 0 0; color: #615523; font-size: .75rem; line-height: 1.4; }
.league-holder .btnlink { margin: 0; text-align: center; }
.league-winner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(170px, auto);
  align-items: center;
  gap: 18px;
  padding: 24px 18px;
  background: #FFF1A8;
  border-bottom: 1px solid #D7BF3A;
}
.league-winner h2 {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--field-deep);
  font-size: clamp(1.35rem, 5vw, 2rem);
  letter-spacing: -.02em;
  line-height: 1.05;
  text-transform: none;
}
.league-winner p { max-width: 38rem; margin: 8px 0 0; color: #514618; line-height: 1.45; }
.league-winner .btnlink { margin: 0; text-align: center; }
.winner-handover { margin: 14px 0; padding: 14px; background: #FFF1A8; border-radius: 12px; }
.winner-handover h4, .winner-handover p { margin: 0 0 8px; overflow-wrap: anywhere; }
.winner-handover-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.winner-handover-actions form, .winner-handover-actions button { width: 100%; margin: 0; }
.owner-overview {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin: 14px 0 18px;
}
.owner-overview > div {
  min-width: 0;
  padding: 12px;
  background: var(--paper-soft);
  border: 1px solid var(--hair);
  border-radius: var(--radius-sticker);
}
.owner-overview strong,
.owner-overview span { display: block; text-transform: none; }
.owner-overview strong { color: var(--field-deep); font-size: 1.35rem; }
.owner-overview span { margin-top: 2px; color: var(--text-soft); font-size: .72rem; }
.owner-payment-mode { margin: 0 0 18px; color: var(--text-soft); }
.league-route-list { display: grid; background: #FFFFFF; }
.league-route-list a {
  position: relative;
  display: grid;
  grid-template-columns: minmax(110px, .62fr) minmax(0, 1.38fr);
  align-items: center;
  gap: 16px;
  min-height: 68px;
  padding: 12px 48px 12px 18px;
  color: var(--text);
  border-bottom: 1px solid #CBD2E1;
  text-decoration: none;
}
.league-route-list a::after {
  position: absolute;
  right: 19px;
  width: 10px;
  height: 10px;
  border-top: 2px solid var(--red-band);
  border-right: 2px solid var(--red-band);
  content: '';
  transform: rotate(45deg);
}
.league-route-list a:hover,
.league-route-list a:focus-visible { background: #F3F5F9; }
.league-route-list span { color: var(--field-deep); font-family: var(--display); font-size: 1.15rem; font-weight: 900; }
.league-route-list small { color: var(--text-soft); font-size: .75rem; line-height: 1.35; }
.league-access { padding: 22px 18px 20px; background: #EEF1F7; }
.league-access > h2 { margin: 0 0 10px; color: var(--field-deep); font-size: 1.35rem; }
.league-detail-page .league-invite { margin: 16px 0 0; }
.league-detail-page .sharerow { margin-inline: 0; }
.league-admin-link { display: inline-block; margin-top: 16px; color: var(--field-deep); font-size: .75rem; font-weight: 750; }

.league-owner-controls {
  padding: 0 18px 22px;
  background: #F7F8FB;
  border-top: 8px solid #E7EBF3;
}
.league-owner-controls > form { padding: 17px 0; border-top: 1px solid #CBD2E1; }
.league-owner-controls > form button { justify-self: start; min-height: 44px; }
.owner-payment-details h3,
.owner-payment-list h3 { margin: 0; color: var(--field-deep); font-size: 1.05rem; }
.owner-platform-fee {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 8px 14px;
  padding: 17px 0;
  border-top: 1px solid #CBD2E1;
}
.owner-platform-fee > div { min-width: 0; }
.owner-platform-fee h3 { margin: 0; color: var(--field-deep); font-size: 1.1rem; }
.owner-platform-fee > div p,
.owner-platform-fee > p { margin: 4px 0 0; color: var(--text-soft); font-size: .8125rem; line-height: 1.45; }
.owner-platform-fee > strong { color: var(--field-deep); font-family: var(--display); font-size: 1.55rem; }
.owner-platform-fee > .badge { justify-self: start; }
.owner-platform-fee > p,
.owner-platform-fee > .btnlink,
.owner-platform-fee > .otherpay { grid-column: 1 / -1; }
.owner-platform-fee > .btnlink { width: 100%; margin: 5px 0 0; text-align: center; }
.owner-platform-fee.needs-fee { background: #FFF4B8; margin-inline: -18px; padding-inline: 18px; }
.owner-payment-details > p { margin: -5px 0 0; }
.owner-payment-list { padding: 17px 0; border-top: 1px solid #CBD2E1; }
.owner-payment-list > form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  min-height: 55px;
  margin: 0;
  border-bottom: 1px solid #DCE1EA;
}
.owner-payment-list > form > span:first-of-type { min-width: 0; overflow-wrap: anywhere; }
.owner-payment-list button { min-height: 44px; margin: 0; }
.league-owner-controls .danger-disclosure { margin-top: 4px; border-top: 1px solid #CBD2E1; }
.league-owner-controls .danger-disclosure > summary { min-height: 48px; color: var(--red); cursor: pointer; font-weight: 750; }
.league-owner-controls .danger-disclosure form { display: grid; gap: 10px; padding: 12px 0; }
.league-owner-controls summary:focus-visible,
.league-create summary:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

.admin-platform-fee {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px 14px;
  margin: 14px 0;
  padding: 14px;
  background: #EEF1F7;
  border: 1px solid #CBD2E1;
  border-radius: 5px;
}
.admin-platform-fee > div { min-width: 0; }
.admin-platform-fee > div strong,
.admin-platform-fee > div span { display: block; overflow-wrap: anywhere; }
.admin-platform-fee > div span { margin-top: 3px; color: var(--text-soft); font-size: .75rem; }
.admin-platform-fee form { grid-column: 1 / -1; margin: 0; }
.admin-platform-fee button { width: 100%; margin: 0; min-height: 44px; }

@media (max-width: 520px) {
  .winner-handover-actions { grid-template-columns: minmax(0, 1fr); }
  .owner-overview { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .league-holder, .league-winner { grid-template-columns: minmax(0, 1fr); }
  .league-holder .btnlink, .league-winner .btnlink { width: 100%; }
  .owner-payment-list > form { grid-template-columns: minmax(0, 1fr) auto; padding: 10px 0; }
  .owner-payment-list button { grid-column: 1 / -1; width: 100%; }
  .league-owner-controls > form button { width: 100%; }
  .owner-platform-fee { grid-template-columns: minmax(0, 1fr); }
  .owner-platform-fee > strong { grid-row: 2; }
  .admin-platform-fee { grid-template-columns: minmax(0, 1fr); }
}

/* Backup controls stay compact until an administrator deliberately enters recovery. */
.admin-backups .backup-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  margin-top: 16px;
}
.admin-backups .backup-actions form,
.admin-backups .backup-actions button,
.admin-backups .backup-actions .btnlink { width: 100%; margin: 0; }
.admin-backups .backup-actions .btnlink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  text-align: center;
}
.admin-backups select { width: 100%; }
.admin-backups .admin-recovery input { text-transform: none; }
@media (max-width: 560px) {
  .admin-backups .backup-actions { grid-template-columns: minmax(0, 1fr); }
}

.match-centre-hero {
  margin: 14px 0 12px;
  padding: 15px;
  color: #fff;
  background: var(--field-deep);
  border-radius: var(--radius-sticker);
}
.match-phase { display: block; margin-bottom: 10px; color: #fff; font-size: .75rem; font-weight: 850; }
.match-centre-teams { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 10px; }
.match-centre-teams > span,
.match-centre-teams > span:last-child {
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  text-align: center;
}
.match-centre-teams .crest { flex: 0 0 auto; margin: 0; }
.match-centre-teams strong { min-width: 0; overflow-wrap: anywhere; color: #fff; font-size: .8125rem; line-height: 1.15; text-transform: none; }
.match-centre-teams b {
  display: inline-block;
  padding: 2px 4px;
  color: #fff;
  border-radius: 4px;
  font-size: clamp(1.7rem, 8vw, 2.4rem);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.fixtures .score.goal-flash,
.match-centre-teams b.goal-flash {
  position: relative;
  z-index: 1;
  animation: goal-flash .7s cubic-bezier(.16, 1, .3, 1);
}
@keyframes goal-flash {
  0% { color: #fff; background-color: var(--red); box-shadow: 0 2px 6px rgb(120 19 32 / 20%); transform: scale(.94); }
  42% { color: #fff; background-color: var(--red); box-shadow: 0 7px 18px rgb(120 19 32 / 34%); transform: scale(1.1); }
  100% { box-shadow: none; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .fixtures .score.goal-flash,
  .match-centre-teams b.goal-flash { animation: goal-flash-reduced .7s ease-out; }
  @keyframes goal-flash-reduced {
    0%, 55% { color: #fff; background-color: var(--red); }
  }
}
.match-centre-all { margin-top: 12px; }
.match-centre-all > summary { min-height: 44px; padding-block: 10px; font-weight: 800; }
.match-centre-all .fixtures { table-layout: fixed; }
.match-centre-all .fixtures .score { width: 66px; padding-inline: 6px; }
.match-centre-all .fixture-team {
  min-width: 0;
  padding: 9px 8px;
  overflow: hidden;
}
.match-centre-all .crest { flex: 0 0 auto; margin: 0; }
.match-centre-all .fixture-club,
.match-centre-all .fixture-club.home,
.match-centre-all .fixture-club.away {
  max-width: 100%;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding-inline: 0;
  overflow: hidden;
  text-align: center;
}
.match-centre-all .fixture-club-name { width: 100%; }
.fixture-club {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 7px;
  text-align: left;
}
.fixture-club.home { flex-direction: row-reverse; padding-inline-end: 4px; text-align: right; }
.fixture-club.away { padding-inline-start: 4px; }
.fixture-club-name {
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--text);
  font-family: var(--body);
  font-size: .8125rem;
  font-weight: 700;
  line-height: 1.15;
  text-transform: none;
}
.fixture-club.missing { color: var(--text-soft); font-size: .75rem; }
.league-stats { margin-top: 24px; }
.league-stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; padding: 1px; background: var(--hair); }
.league-stat-grid > div { min-width: 0; padding: 16px; background: var(--raised); }
.league-stat-grid dt { color: var(--text-soft); font-size: .75rem; }
.league-stat-grid dd { margin: 5px 0 0; overflow-wrap: anywhere; color: var(--field-deep); font-size: 1.35rem; font-weight: 900; }
.league-stat-grid dd small { display: block; margin-top: 2px; color: var(--text-soft); font-size: .6875rem; font-weight: 700; }
.notify-leagues { margin: 18px 0; padding-top: 16px; border-top: 1px solid var(--hair); }
.notify-league { border-bottom: 1px solid var(--hair); }
.notify-league > summary { display: flex; min-height: 48px; align-items: center; justify-content: space-between; gap: 10px; }
.notify-league > summary span { color: var(--text-soft); font-size: .75rem; }
.notify-league .check { padding-inline: 4px; }
.notify-league .notify-custom { margin-block: 6px 10px; padding: 10px; background: var(--well); }
.admin-activity ol { max-height: 420px; margin: 12px 0 0; padding: 0; overflow: auto; list-style: none; }
.admin-activity li { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 11px 0; border-bottom: 1px solid var(--hair); }
.admin-activity li span { min-width: 0; }
.admin-activity li strong, .admin-activity li small { display: block; overflow-wrap: anywhere; }
.admin-activity li small, .admin-activity time { color: var(--text-soft); font-size: .6875rem; }
.admin-activity time { flex: 0 0 auto; }
@media (max-width: 420px) {
  .match-centre-teams { gap: 7px; }
  .match-centre-teams img { width: 25px; height: 25px; }
  .match-centre-all .fixture-team { padding-inline: 7px; }
  .match-centre-all .fixture-club { gap: 4px; }
  .match-centre-all .fixture-club-name { font-size: .75rem; }
  .match-centre-all .crest { width: 24px; height: 24px; }
  .league-stat-grid { grid-template-columns: minmax(0, 1fr); }
  .admin-activity li { flex-direction: column; gap: 4px; }
}

@media (max-width: 360px) {
  .league-ticket-main, .league-holder, .league-winner, .league-access { padding-inline: 14px; }
  .league-ticket-strip { padding-inline: 14px; }
  .league-ticket-numbers > div { padding-inline: 7px; }
  .league-route-list a { grid-template-columns: minmax(0, 1fr); gap: 3px; padding-left: 14px; }
}

/* Admin is an operating surface: weekly actions lead, setup and recovery fold
   into named zones, and the page can be scanned before it is read. */
.admin-page { display: grid; gap: 18px; }
.admin-page > * { margin-block: 0; }
.admin-hero {
  display: grid;
  padding: 22px;
  background: var(--field-deep);
  color: #fff;
  border: 0;
  border-bottom: 5px solid var(--gold);
}
.admin-hero h1 { margin: 0; color: #fff; font-size: clamp(2.6rem, 11vw, 4.4rem); line-height: .9; }
.admin-hero-copy > p { margin: 9px 0 0; color: var(--on-field-soft); }
.admin-status {
  display: flex;
  align-items: baseline;
  gap: 9px;
  width: fit-content;
  padding: 9px 11px;
  background: rgba(255, 255, 255, .1);
  border-radius: 4px;
}
.admin-status strong { color: #fff; }
.admin-status span { font-size: .75rem; }
.admin-status a { color: inherit; font-weight: 800; text-underline-offset: 3px; }
.league-money-admin tr[id^="payment-entry-"] { scroll-margin-top: 24px; transition: background-color .2s ease, outline-color .2s ease; }
.league-money-admin tr[id^="payment-entry-"]:target { background: #FFF3A6; outline: 3px solid #E0B400; outline-offset: -3px; }
.admin-data { font-size: .75rem; line-height: 1.4; }
.admin-jump {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
  padding: 6px;
  background: var(--field-deep);
  border-radius: 7px;
}
.admin-jump a {
  min-width: 0;
  padding: 10px 6px;
  color: var(--on-field-soft);
  font-family: var(--body);
  font-size: .75rem;
  font-weight: 750;
  line-height: 1.15;
  text-align: center;
  text-decoration: none;
}
.admin-jump a:hover,
.admin-jump a:focus-visible { background: var(--gold); color: var(--on-gold); }
.admin-zone { display: grid; gap: 12px; scroll-margin-top: 18px; }
.admin-zone > h2 {
  margin: 12px 2px 0;
  color: #fff;
  font-size: 1.45rem;
  line-height: 1;
}
.admin-zone > .card { margin: 0; }
.admin-clear {
  margin: 0;
  padding: 14px 16px;
  background: rgba(255, 255, 255, .1);
  color: var(--on-field-soft);
  border-radius: 6px;
}
.admin-tool-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.admin-tool-actions form,
.admin-tool-actions button { width: 100%; margin: 0; }
.admin-danger-zone {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.admin-danger-zone > summary {
  min-height: 44px;
  color: var(--danger);
  font-weight: 800;
  cursor: pointer;
}
.admin-danger-zone > summary:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}
.admin-danger-zone[open] > summary { margin-bottom: 8px; }
.admin-danger-zone form + form,
.admin-danger-zone p + form { margin-top: 10px; }
.admin-recovery { margin-top: 14px; }
@media (max-width: 560px) {
  .admin-hero { grid-template-columns: minmax(0, 1fr); padding: 19px 16px; }
  .admin-status { align-items: flex-start; flex-direction: column; gap: 2px; width: 100%; }
  .admin-tool-actions { grid-template-columns: minmax(0, 1fr); }
  .admin-jump { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Account keeps daily controls obvious and lets occasional setup recede.
   This lives after the final card theme layer so the identity header wins. */
.account-page { display: grid; gap: 14px; }
.account-page > * { margin-block: 0; }

/* System health is a compact operating checklist, not another dashboard. */
.system-status ul,
.match-timeline ol,
.onboarding ol { list-style: none; margin: 0; padding: 0; }
.system-line {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  padding: 12px 0;
  border-bottom: 1px solid var(--hair);
}
.system-line:last-child { border-bottom: 0; }
.system-dot { width: 10px; height: 10px; margin-top: 4px; border-radius: 50%; background: var(--gold); }
.system-line.ok .system-dot { background: var(--green); }
.system-line strong, .system-line small { display: block; }
.system-line small { margin-top: 3px; color: var(--text-soft); overflow-wrap: anywhere; }

.match-timeline ol { position: relative; margin-top: 8px; }
.timeline-standing { margin: 8px 0 2px; color: var(--green-ink); font-weight: 850; }
.match-event {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0 11px 22px;
  border-bottom: 1px solid var(--hair);
  position: relative;
}
.match-event::before { content: ''; position: absolute; left: 2px; top: 16px; width: 8px; height: 8px; border-radius: 50%; background: var(--gold); }
.match-event.goal::before { background: var(--green); }
.match-event.correction::before { background: var(--red); }
.match-event:last-child { border-bottom: 0; }
.match-event time { flex: none; color: var(--text-soft); font-variant-numeric: tabular-nums; }

.onboarding { border-bottom: 5px solid var(--gold); }
.onboarding .cardhead { align-items: start; }
.onboarding .cardhead p { margin: 5px 0 0; }
.onboard-skip { min-height: 44px; }
.onboard-step {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  min-height: 54px;
  padding: 8px 0;
  border-top: 1px solid var(--hair);
}
.onboard-link {
  display: grid;
  min-width: 0;
  min-height: 44px;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  color: var(--text);
  text-decoration: none;
}
.onboard-link:hover .onboard-action,
.onboard-link:focus-visible .onboard-action { text-decoration: underline; text-underline-offset: 3px; }
.onboard-copy { min-width: 0; }
.onboard-mark { display: grid; place-items: center; width: 24px; height: 24px; border: 2px solid var(--line); border-radius: 50%; color: var(--on-field); }
.onboard-step.done .onboard-mark { border-color: var(--green); background: var(--green); }
.onboard-step.done .onboard-mark::after { content: ''; width: 8px; height: 4px; border-left: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(-45deg) translateY(-1px); }
.onboard-step strong, .onboard-step small { display: block; }
.onboard-step strong { white-space: nowrap; }
.onboard-step.done .onboard-copy strong {
  color: var(--text-soft);
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--green);
}
.onboard-step small { margin-top: 2px; color: var(--text-soft); text-transform: none; letter-spacing: normal; }
.onboard-action { color: var(--field-deep); font-weight: 850; }

@media (max-width: 420px) {
  .onboard-step { grid-template-columns: 28px minmax(0, 1fr); }
  .onboard-link { display: block; }
  .onboard-action { display: none; }
  .match-event { gap: 8px; }
}

.card.account-hero {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 18px;
  padding: 22px;
  background: var(--field-deep);
  color: #fff;
  border: 0;
  border-bottom: 5px solid var(--gold);
}
.card.account-hero h1 { margin: 0; color: #fff; font-size: clamp(2.6rem, 11vw, 4.4rem); line-height: .9; }
.account-hero p { margin: 10px 0 0; color: #fff; font-weight: 750; }
.account-hero .account-email { margin-top: 3px; color: var(--on-field-soft); font-size: .8125rem; font-weight: 500; overflow-wrap: anywhere; }
.account-hero form { flex: 0 0 auto; margin: 0; }
.account-hero button { margin: 0; background: #fff; color: var(--field-deep); border-color: #fff; box-shadow: none; }
.account-cardhead { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.account-cardhead h2 { margin: 0; }
.account-danger > summary { color: var(--danger); }
.account-danger > summary:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}
@media (max-width: 480px) {
  .card.account-hero { align-items: stretch; flex-direction: column; padding: 19px 16px; }
  .account-hero button { width: 100%; }
  .account-cardhead { align-items: flex-start; }
}

/* Chat reads like one conversation, not a stack of unrelated cards. */
.chat-page { display: grid; gap: 12px; }
.chat-page .chattabs { margin: 0; }
.card.chat-shell {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  height: clamp(480px, calc(100dvh - 210px), 680px);
  padding: 0;
  overflow: hidden;
}
.chat-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 22px 17px;
  background: var(--field-deep);
  color: #fff;
  border-bottom: 4px solid var(--gold);
}
.chat-head h1 { margin: 0; color: #fff; font-size: clamp(2rem, 9vw, 3.5rem); line-height: .95; overflow-wrap: anywhere; }
.chat-head p { margin: 7px 0 0; color: var(--on-field-soft); font-size: .75rem; }
.chat-count { flex: 0 0 auto; color: var(--on-field-soft); font-size: .75rem; font-weight: 750; }
.chat-room {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  min-height: 0;
}
.chat-room .chatform {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 12px 14px max(12px, env(safe-area-inset-bottom));
  background: var(--well);
  border-top: var(--line) solid var(--hair-strong);
  border-radius: 0;
}
.chat-room .chatform textarea { min-height: 58px; max-height: 120px; margin: 0; background: var(--raised); resize: none; }
.chat-send { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.chat-send span { color: var(--text-mute); font-size: .6875rem; }
.chat-send button { flex: 0 0 auto; margin: 0; }
.chat-room .msglist {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  padding: 18px 20px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  scroll-behavior: smooth;
  scrollbar-color: var(--hair-strong) var(--well);
}
.chat-room .msg {
  align-self: flex-start;
  width: min(88%, 560px);
  padding: 12px 14px 10px;
  background: var(--raised-hi);
  border-color: var(--hair-strong);
  border-radius: 4px 14px 14px 14px;
}
.chat-room .msg.mine {
  align-self: flex-end;
  background: var(--gold-faint);
  border-color: var(--gold-dim);
  border-radius: 14px 4px 14px 14px;
  box-shadow: none;
}
.chat-room .msghead { min-width: 0; padding-right: 42px; }
.chat-room .msgwho { min-width: 0; overflow-wrap: anywhere; text-transform: none; }
.chat-room .msgwhen { flex: 0 0 auto; }
.chat-room .msgbody { font-size: 1rem; line-height: 1.5; }
.chat-room .msgdel { top: 7px; right: 10px; }
.chat-room .msgdel button { min-height: 44px; padding: 4px 2px; text-decoration: underline; text-underline-offset: 3px; }
.chat-room .msgempty {
  display: grid;
  gap: 4px;
  padding: 28px 18px;
  background: var(--well);
  border-radius: var(--radius-sticker);
  text-align: center;
}
.chat-room .msgempty strong { color: var(--text); }
.chat-room .msgempty span { color: var(--text-soft); font-size: .8125rem; }
@media (max-width: 480px) {
  .chat-head { align-items: flex-start; flex-direction: column; gap: 8px; padding: 18px 16px 15px; }
  .card.chat-shell { height: clamp(470px, calc(100dvh - 190px), 720px); }
  .chat-room .msglist { padding: 14px 12px; }
  .chat-room .chatform { padding: 10px 12px max(10px, env(safe-area-inset-bottom)); }
  .chat-send { align-items: stretch; flex-direction: column; }
  .chat-send button { width: 100%; }
  .chat-room .msg { width: 94%; }
}

/* Authentication is one calm, trustworthy journey from arrival to recovery. */
.auth-page {
  width: min(100%, 480px);
  margin: 28px auto;
}
.card.auth-shell {
  padding: 0;
  overflow: hidden;
}
.auth-head {
  padding: 24px 24px 20px;
  background: var(--field-deep);
  color: #fff;
  border-bottom: 5px solid var(--gold);
}
.auth-head h1 {
  max-width: 11ch;
  margin: 0;
  color: #fff;
  font-size: clamp(2.5rem, 11vw, 4rem);
  line-height: .9;
  letter-spacing: -.025em;
  text-wrap: balance;
}
.auth-head p {
  max-width: 36rem;
  margin: 11px 0 0;
  color: var(--on-field-soft);
  font-size: .8125rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.auth-body { padding: 22px 24px 24px; }
.auth-form { display: grid; gap: 16px; }
.auth-form label { margin: 0; }
.auth-form input { width: 100%; margin-top: 7px; }
.auth-form .hint { margin: 5px 0 -1px; color: var(--text-soft); line-height: 1.35; text-transform: none; }
.auth-form button { width: 100%; margin: 2px 0 0; }
.auth-invite,
.auth-alert {
  margin: 0 0 18px;
  padding: 12px 14px;
  border-radius: var(--radius-sticker);
  font-size: .8125rem;
  line-height: 1.4;
}
.auth-invite { background: var(--gold-faint); color: var(--on-gold); border: 1px solid var(--gold-dim); }
.auth-alert { background: var(--red-soft); color: var(--red-ink); border: 1px solid var(--red); font-weight: 750; }
.auth-links {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 20px;
  padding-top: 17px;
  border-top: 1px solid var(--hair);
}
.auth-links p { margin: 0; color: var(--text-soft); font-size: .75rem; }
.auth-links a { font-weight: 800; text-underline-offset: 3px; }
.auth-state > :first-child { margin-top: 0; }
.auth-state > :last-child { margin-bottom: 0; }
.auth-state .install-trouble { margin-top: 22px; }

@media (max-width: 520px) {
  .auth-page { margin-block: 16px; }
  .auth-head { padding: 21px 17px 18px; }
  .auth-body { padding: 19px 17px 21px; }
  .auth-links { align-items: flex-start; flex-direction: column; gap: 9px; }
}

/* A late sign-up is welcomed into a useful waiting room, not shown an error. */
.card.waiting-room { padding: 0; overflow: hidden; }
.waiting-room-head {
  padding: 22px 24px 20px;
  background: var(--field-deep);
  color: #fff;
  border-bottom: 5px solid var(--gold);
}
.waiting-room-head .sect { margin: 0 0 8px; color: #fff; }
.waiting-room-head h1 {
  max-width: 15ch;
  margin: 0;
  color: #fff;
  font-size: clamp(2.15rem, 9vw, 3.65rem);
  line-height: .94;
  text-wrap: balance;
}
.waiting-room-head p:last-child {
  max-width: 58ch;
  margin: 14px 0 0;
  color: var(--on-field-soft);
  line-height: 1.5;
}
.waiting-room-head strong { color: #fff; }
.waiting-room-body { padding: 20px 24px 24px; }
.waiting-room-body > :first-child { margin-top: 0; }
.waiting-room-actions {
  display: grid;
  margin: 18px 0;
  border-block: 1px solid var(--hair-strong);
}
.waiting-room-actions a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 68px;
  padding: 12px 2px;
  color: var(--text);
  text-decoration: none;
}
.waiting-room-actions a + a { border-top: 1px solid var(--hair); }
.waiting-room-actions span { min-width: 0; }
.waiting-room-actions strong,
.waiting-room-actions small { display: block; text-transform: none; letter-spacing: normal; }
.waiting-room-actions strong { overflow-wrap: anywhere; }
.waiting-room-actions small { margin-top: 3px; color: var(--text-soft); line-height: 1.35; }
.waiting-room-actions b { flex: 0 0 auto; color: var(--field-deep); font-size: .75rem; }
.waiting-room-actions a:hover strong { text-decoration: underline; text-underline-offset: 3px; }
.waiting-room-note {
  padding: 13px 14px;
  background: var(--gold-faint);
  color: var(--on-gold);
  border: 1px solid var(--gold-dim);
  border-radius: var(--radius-sticker);
  line-height: 1.45;
}
.waiting-room-note a { font-weight: 850; }
@media (max-width: 480px) {
  .waiting-room-head { padding: 20px 17px 18px; }
  .waiting-room-body { padding: 18px 17px 21px; }
  .waiting-room-actions a { min-height: 72px; }
}
