:root{padding:env(safe-area-inset-top,0px) 0 env(safe-area-inset-bottom,0px)}body{margin:0;font:14px system-ui}img{max-width:100%}[hidden]{display:none!important}
/* Magnet Board design system: "Under lights". The rules are in DESIGN.md and docs/critique/SYSTEM.md. This file holds the tokens, the browser's
   own surfaces, the shell's base styles and the shared components. Screen styles live in src/css/s_<screen>.css, feature styles in src/css/<feature>.css.
   Colour literals live in the two token blocks below and nowhere else: node test/ds_contrast.js reads them, checks every pair and fails on a stray literal. */

/* ---------- tokens ---------- */
:root {
  /* night game. The root always carries data-theme (src/head/theme.html sets it before first paint), so this block is the dark theme. */
  --bg: #060b09; --panel: #0e1814; --panel2: #14211b; --panel3: #1c2d25;
  --line: #1e3028; --line2: #2f4a3d; --line3: #677f72;
  --ink: #eef5f0; --mute: #95aa9e; --faint: #647a6d;
  --accent: #f5c931; --accent-ink: #1a1500;
  --good: #58d196; --warn: #f2a843; --bad: #f38173; --info: #78bcec;
  --top: #f5c931; --top-ink: #1a1500; --top-line: #f5c931;
  --ln-def: #78bcec; --ln-mid: #5fd3d0; --ln-fwd: #c3a6f5; --ln-ruc: #b7c6bc;
  --turf: #1f6b3f; --turf2: #1b6039; --chalk: #dfe9e2; --ball: #f5c931; --kit-edge: #3b5647;
  --shade: rgba(0, 0, 0, .42); --glass: rgba(8, 15, 12, .92); --glow: rgba(150, 232, 190, .085); --hi: rgba(255, 255, 255, .055); --scrim: rgba(2, 6, 4, .62);
  --lift: rgba(255, 255, 255, .25); --rim: rgba(255, 255, 255, .14); --sink: rgba(0, 0, 0, .3);
  --club: #1f6b3f; --club2: #dfe9e2; --club-ink: #ffffff;
  --hold: var(--accent); --sel-mix: 10%; --focus-gap: var(--bg); --select: color-mix(in srgb, var(--accent) 34%, var(--bg));
  --hero-mute: 86%; --hero-faint: 62%; --hero-club: 58%; --hero-club2: 16%;
  --e1: inset 0 1px 0 var(--hi), 0 1px 2px rgba(0, 0, 0, .35);
  --e2: inset 0 1px 0 var(--hi), 0 14px 34px -16px rgba(0, 0, 0, .75);
  --e3: 0 0 0 1px var(--line2), 0 32px 80px -24px rgba(0, 0, 0, .85);
  --e4: 0 2px 6px rgba(0, 0, 0, .4), 0 18px 44px -14px rgba(0, 0, 0, .6);
  color-scheme: dark;

  /* roles built from the colours above: the same recipe in both themes, so a theme only swaps the colours */
  --rail: color-mix(in srgb, var(--panel) 72%, var(--bg)); --strip: color-mix(in srgb, var(--panel) 80%, var(--bg));
  --pick: var(--accent); --pick-ink: var(--accent-ink);                 /* the pick inside a control: a solid block */
  --focus: var(--hold);                                                 /* the keyboard's ring, one everywhere */
  --lit: var(--hold);                                                   /* a lit numeral: the yellow bulbs by night, plain ink by day (a red number would read as bad) */
  --sel: color-mix(in srgb, var(--hold) var(--sel-mix), transparent);   /* a selected row */
  --me: color-mix(in srgb, var(--club) 10%, transparent);               /* the coach's own row wears his club (set again on .app) */
  --link: var(--ink); --link-line: var(--line3);
  --fill: var(--mute); --track: color-mix(in srgb, var(--ink) 13%, var(--panel));   /* an amount with no judgement in it, and the unfilled part */
  --bad-wash: color-mix(in srgb, var(--bad) 10%, transparent);
  --scroll: color-mix(in srgb, var(--mute) 60%, transparent); --tap: color-mix(in srgb, var(--ink) 10%, transparent); --chev: var(--mute);
  --hover: color-mix(in srgb, var(--ink) 5%, transparent);              /* the wash under a quiet thing the pointer is on (a rail entry, a sheet's row) */

  /* type: three faces, one scale. Pick the role, never a size between two steps. */
  --f-display: 'Big Shoulders Display', 'Barlow Condensed', 'Arial Narrow', Impact, sans-serif;
  --f-cond: 'Barlow Condensed', 'Arial Narrow', 'Helvetica Neue', Arial, sans-serif;
  --f-body: 'Barlow', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --fs-micro: 11px; --fs-label: 12px; --fs-small: 13px; --fs-data: 14px; --fs-ui-s: 14px; --fs-body: 15px; --fs-ui: 16px; --fs-title: 18px; --fs-h2: 24px; --fs-h1: 42px;
  --fs-d6: 22px; --fs-d5: 30px; --fs-d4: 36px; --fs-d3: 42px; --fs-d2: 56px; --fs-d1: 76px;
  --lh-flat: 1; --lh-head: 1.05; --lh-ui: 1.2; --lh-body: 1.45;
  --tr-caps: .1em; --tr-ui: .02em; --tr-display: 0em; --measure: 68ch;
  /* space, shape, size, layers */
  --s1: 4px; --s15: 6px; --s2: 8px; --s25: 10px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s7: 32px; --s8: 44px;
  --r-s: 6px; --r-m: 10px; --r-l: 16px; --r-xl: 20px; --r-pill: 999px;
  --ctl: 36px; --ctl-s: 28px; --hit: 40px;
  --rail-w: 228px; --top-h: 78px; --tab-h: 62px; --tab-pad: 5px;
  --dock-clear: 0px;   /* the room the two corner buttons (the phone, the Magnet Mover) take above the bottom edge: 0 with no dock on the page, set on body below */
  --z-sticky: 5; --z-top: 6; --z-rail: 7; --z-dock: 30; --z-dialog: 40; --z-menu: 46; --z-toast: 50; --z-skip: 60; --z-drag: 70;
  /* motion: one exponential ease-out. fast is a press or a hover, ui a change of state, move something that travels or opens, far a long way
     (a phone sheet), data a bar or a number settling once on arrival. pop, with its slight overshoot, is only for something thrown or landed. */
  --ease-out: cubic-bezier(.16, 1, .3, 1); --ease-in: cubic-bezier(.5, 0, .84, 0);
  --t-fast: 120ms; --t-ui: 180ms; --t-move: 240ms; --t-far: 360ms; --t-data: 600ms; --t-pop: 320ms;
  --spring-pop: linear(0, 0.051, 0.17, 0.315, 0.463, 0.597, 0.711, 0.803, 0.874, 0.926, 0.963, 0.987, 1.002, 1.011, 1.014, 1.015, 1.014, 1.012, 1.01, 1.008, 1.006, 1.004, 1.003, 1.002, 1.001, 1);
  --spring: var(--ease-out); --t-spring: var(--t-move);   /* the old names, kept so nothing breaks: they now hold the same values */
}
/* day game */
/* Light is the default theme. A theme only swaps colours: everything that is not a colour is declared once, above. */
:root[data-theme="light"] {
  --bg: #e9eee6; --panel: #ffffff; --panel2: #f3f6f0; --panel3: #e6ece3;
  --line: #dde5da; --line2: #c3cfc0; --line3: #778a7c;
  --ink: #111b15; --mute: #4d6055; --faint: #74877a;
  --accent: #b3261e; --accent-ink: #ffffff;
  --good: #14683d; --warn: #844d00; --bad: #981a3a; --info: #195f91;
  --top: #e7b92c; --top-ink: #1a1500; --top-line: #7b5b00;
  --ln-def: #1f5f8f; --ln-mid: #0b6a70; --ln-fwd: #6a3d9a; --ln-ruc: #4d6055;
  --turf: #3f9c61; --turf2: #399158; --chalk: #f4faf5; --ball: #b3261e; --kit-edge: #9fb0a3;
  --shade: rgba(20, 32, 26, .2); --glass: rgba(244, 247, 241, .94); --glow: rgba(255, 255, 255, .7); --hi: rgba(255, 255, 255, .9); --scrim: rgba(20, 32, 26, .38);
  --lift: rgba(255, 255, 255, .25); --rim: rgba(255, 255, 255, .16); --sink: rgba(20, 32, 26, .16);
  --hold: var(--ink); --sel-mix: 9%; --focus-gap: var(--panel); --select: color-mix(in srgb, var(--ink) 16%, var(--panel));
  --hero-mute: 76%; --hero-faint: 58%; --hero-club: 22%; --hero-club2: 8%;
  --e1: 0 1px 2px rgba(22, 40, 30, .08), 0 2px 5px -2px rgba(22, 40, 30, .07);
  --e2: 0 1px 2px rgba(22, 40, 30, .06), 0 14px 30px -18px rgba(22, 40, 30, .28);
  --e3: 0 0 0 1px var(--line), 0 32px 80px -28px rgba(22, 40, 30, .45);
  --e4: 0 2px 6px rgba(22, 40, 30, .16), 0 18px 44px -14px rgba(22, 40, 30, .3);
  color-scheme: light;
}
/* the page heading steps down with the window: fixed steps of the scale, never a fluid size */
@media (max-width: 1100px) { :root { --fs-h1: 36px; } }
@media (max-width: 880px) { :root { --fs-h1: 30px; } }
/* a finger needs more than a pointer does: controls grow on a phone and on any touch screen */
@media (max-width: 880px), (pointer: coarse) { :root { --ctl: 40px; --ctl-s: 32px; } }

/* ---------- base ---------- */
/* The page's defaults and the browser's own surfaces: selection, the caret, scrollbars, the focus ring, links, the tap flash, placeholders. */
html, body, #app { height: 100%; }
html, body { overscroll-behavior: none; }   /* the bars are fixed and the page scrolls inside main: a pull on a bar must not rubber-band or reload the page (V-14) */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { background: var(--bg); color: var(--ink); font-family: var(--f-body); font-size: var(--fs-body); line-height: var(--lh-body); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; accent-color: var(--accent); caret-color: var(--accent); }
*, *::before, *::after { box-sizing: border-box; }
* { scrollbar-width: thin; scrollbar-color: var(--scroll) transparent; -webkit-tap-highlight-color: var(--tap); }
/* buttons, tabs and rows answer a press themselves (:active), so they do not flash as well */
button, summary, label, .btn, [role="tab"], [role="button"], tr.click { -webkit-tap-highlight-color: transparent; }
button, select, input, textarea { font: inherit; color: inherit; }
button { touch-action: manipulation; }
h1, h2, h3 { font-family: var(--f-display); font-weight: 800; margin: 0; text-wrap: balance; }
h1 { font-size: var(--fs-h1); line-height: .98; letter-spacing: var(--tr-display); text-transform: uppercase; }
h2 { font-size: var(--fs-h2); line-height: var(--lh-head); letter-spacing: var(--tr-display); text-transform: uppercase; }
h3 { font-family: var(--f-cond); font-size: var(--fs-title); font-weight: 700; line-height: 1.15; letter-spacing: .01em; }
p { margin: 0 0 .7em; text-wrap: pretty; } p:last-child { margin-bottom: 0; }
/* a link is ink with a hairline under it: the accent is for the main action and the pick, never for a link */
a { color: var(--link); text-decoration-line: underline; text-decoration-color: var(--link-line); text-decoration-thickness: 1px; text-underline-offset: .2em; transition: text-decoration-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out); }
@media (hover: hover) { a:hover { text-decoration-color: currentColor; } }
.num { font-variant-numeric: tabular-nums; }
::selection { background: var(--select); color: var(--ink); }
::placeholder { color: var(--mute); opacity: 1; }
/* icons: 24 grid, weight 2, round caps and joins, currentColor (the family's rules are at the top of src/f_icons.js). The box hangs .275em under
   the baseline so its middle is the middle of the capitals. A solid shape keeps its stroke, so it has the same corners and size as a line shape. */
.ic { display: inline-block; flex: none; width: 1.25em; height: 1.25em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vertical-align: -.275em; }
.ic .f { fill: currentColor; stroke: currentColor; }
.ic .q { opacity: .3; }   /* the quiet half of a two part drawing */
/* focus: one ring for everything, for the keyboard only. 2px in --focus, 2px clear of the control. A control that has its own shadow fills the gap
   with --focus-gap (see .btn), so the ring also reads on a club colour and on the accent. Inside a clipped strip the ring is drawn inside the control. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
/* helpers */
.ds-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.ds-prose { max-width: var(--measure); } .ds-prose p { text-wrap: pretty; }
.ds-cut { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- shell: full-height rail, glass bar over the page, the page scrolls under the bar ---------- */
.app { display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); grid-template-rows: var(--top-h) minmax(0, 1fr); height: 100%; isolation: isolate; --me: color-mix(in srgb, var(--club) 10%, transparent);
  background: radial-gradient(1100px 520px at 82% -180px, var(--glow), transparent 70%), radial-gradient(900px 460px at 24% -220px, var(--glow), transparent 70%), linear-gradient(180deg, transparent 58%, color-mix(in srgb, var(--turf) 8%, transparent)), var(--bg); }
/* The bar wears the club: a solid tint under the crest and the names, thinning to glass where the page scrolls under the status and the button. */
.top { grid-column: 2; grid-row: 1; z-index: var(--z-top); display: flex; align-items: center; gap: 14px; padding: 0 clamp(16px, calc(2.4vw / var(--ui-z, 1)), 32px); min-width: 0;
  background: linear-gradient(90deg, color-mix(in srgb, var(--club) 20%, var(--bg)) 0, color-mix(in srgb, var(--club) 20%, var(--bg)) 12%, color-mix(in srgb, var(--club) 8%, transparent) 40%, transparent 60%), var(--glass); -webkit-backdrop-filter: blur(22px) saturate(170%); backdrop-filter: blur(22px) saturate(170%); border-bottom: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
/* who: club name, coach line, then one row for the history arrows (src/navhist.js) with the phone status beside them */
.top .who { min-width: 0; flex: 1; display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; align-items: center; container-type: inline-size; }
.top .who > b { grid-column: 1 / -1; font-family: var(--f-display); font-size: var(--fs-d6); font-weight: 800; line-height: 1.02; letter-spacing: var(--tr-display); text-transform: uppercase; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top .who > span { grid-column: 1 / -1; color: color-mix(in srgb, var(--ink) 55%, var(--mute)); font-size: var(--fs-small); line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
.top .who > .nh { grid-column: 1; grid-row: 3; }
.top .sh-now { display: none; }
/* status: ladder place and record (they open the ladder), then the round and the date. Value over label, like a scoreboard. */
.top .sh-status { display: flex; align-items: center; flex: none; min-width: 0; }
.top .sh-rank { display: flex; align-items: center; margin: 0 0 0 -6px; padding: 7px 0; background: none; border: 0; border-radius: var(--r-m); color: inherit; text-align: right; cursor: pointer; transition: background-color var(--t-fast) ease, transform var(--t-fast) ease; }
.top .sh-rank > span { display: block; padding: 0 13px; }
.top .sh-rank > span + span { border-left: 1px solid var(--line2); }
.top .sh-rank b, .top .when b { display: block; font-family: var(--f-display); font-size: var(--fs-d6); font-weight: 800; line-height: 1; letter-spacing: var(--tr-display); text-transform: uppercase; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.top .sh-rank i, .top .when { font-style: normal; font-family: var(--f-cond); font-size: var(--fs-label); font-weight: 600; line-height: 1.2; letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--mute); white-space: nowrap; }
.top .sh-rank i { display: block; margin-top: 4px; }
.top .sh-rank:active { transform: scale(.97); }
@media (hover: hover) { .top .sh-rank:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); } }
.top .when { text-align: right; }
.top .when b { margin-bottom: 4px; }
.top .sh-rank + .when { padding-left: 13px; border-left: 1px solid var(--line2); }
.crest { display: grid; place-items: center; flex: none; width: 46px; height: 46px; border-radius: 13px; background: var(--c1); color: var(--ci); font-family: var(--f-cond); font-weight: 700; font-size: var(--fs-ui); letter-spacing: .04em; padding-bottom: 5px; box-shadow: inset 0 -7px 0 var(--c2), inset 0 0 0 1px var(--rim), 0 6px 16px -8px var(--shade); }
/* keyboard: the first Tab stop jumps past the bar and the menu */
.sh-skip { position: fixed; left: 12px; top: 12px; z-index: var(--z-skip); transform: translateY(-80px); }
.sh-skip:focus-visible { transform: none; }
main:focus { outline: none; }

.side { grid-column: 1; grid-row: 1 / -1; z-index: var(--z-rail); position: relative; display: flex; flex-direction: column; gap: 2px; padding: 0 10px 10px; overflow-y: auto; scroll-padding-block: 12px 64px; background: var(--rail); border-right: 1px solid var(--line); }
.side .brand { flex: none; display: flex; align-items: center; gap: 9px; height: var(--top-h); padding: 0 8px; font-family: var(--f-display); font-weight: 900; font-size: var(--fs-d6); line-height: 1; letter-spacing: 0; text-transform: uppercase; white-space: nowrap; color: var(--ink); user-select: none; }
.side .brand em { font-style: normal; color: var(--accent); }
.side .brand .ic { width: 22px; height: 22px; color: var(--accent); stroke-width: 2.2; }
.side .grp { flex: none; padding: 14px 10px 5px; font-family: var(--f-cond); font-size: var(--fs-label); font-weight: 600; letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--mute); }
.side .grp:empty { padding: 0; margin: 8px 10px; height: 1px; background: var(--line); }
.side > button { position: relative; z-index: 1; flex: none; display: flex; align-items: center; gap: 11px; width: 100%; min-height: 38px; text-align: left; background: none; border: 0; border-radius: var(--r-m); padding: 7px 10px; font-family: var(--f-cond); font-size: var(--fs-ui); font-weight: 500; letter-spacing: var(--tr-ui); color: var(--mute); cursor: pointer; white-space: nowrap; transition: color var(--t-fast) ease, transform var(--t-fast) ease; }
.side > button .ic { width: 20px; height: 20px; opacity: .85; }
.side > button .ns { display: none; }
.side > button.on { color: var(--ink); font-weight: 600; }
.side > button:focus-visible { outline-offset: -2px; }
.side > button.on .ic { color: var(--pick); opacity: 1; }   /* the screen you are on: the pick, not an action */
.side:not(.has-glide) > button.on { background: var(--panel3); }
.side > button:active:not(:disabled) { transform: scale(.975); }
.side > button:disabled { opacity: .4; cursor: not-allowed; }
.side .badge { margin-left: auto; min-width: 20px; text-align: center; background: var(--accent); color: var(--accent-ink); border-radius: var(--r-pill); font-size: var(--fs-label); font-weight: 700; line-height: 18px; padding: 0 6px; font-family: var(--f-body); font-variant-numeric: tabular-nums; }
/* Eighteen entries, three group labels, one rule, the brand and 10px of foot. On a short desktop window the rail tightens in four steps so the whole
   menu fits for as long as it can: rows of 34px to 1000 high, 32px to 900 (fits a 768px window), 30px from 756 down, 28px from 712 down (needs about
   664). Under that the rail scrolls: the edge with more behind it fades (cfRail in f_chrome.js sets .cf-up and .cf-dn) and render() keeps the entry in
   use in view (keepStrips in ui.js). */
@media (min-width: 881px) and (max-height: 1000px) { .side { gap: 1px; } .side > button { min-height: 34px; padding-block: 5px; } .side .grp { padding: 9px 10px 3px; } }
@media (min-width: 881px) and (max-height: 900px) { .side { gap: 0; } .side > button { min-height: 32px; padding-block: 4px; } .side .grp { padding: 6px 10px 2px; } }
@media (min-width: 881px) and (max-height: 756px) { .side > button { min-height: 30px; padding-block: 3px; } .side .grp { padding: 5px 10px 1px; } .side .grp:empty { padding: 0; margin-block: 5px; } }
@media (min-width: 881px) and (max-height: 712px) { .side > button { min-height: 28px; padding-block: 2px; font-size: var(--fs-body); } .side > button .ic { width: 18px; height: 18px; } .side .grp { padding: 4px 10px 0; } .side .grp:empty { padding: 0; margin-block: 4px; } }
@media (hover: hover) { .side > button:hover:not(:disabled):not(.on) { color: var(--ink); background: var(--hover); } .side > button:hover:not(:disabled):not(.on) .ic { opacity: 1; } }
/* the selection block that glides between items (drawn by FX.glide in fx.js) */
.glide { position: absolute; left: 0; top: 0; z-index: 0; pointer-events: none; border-radius: var(--r-m); background: var(--panel3); box-shadow: var(--e1); will-change: transform; }

/* Room for the last row. The phone and the Magnet Mover sit in the bottom right corner, over the page (css/f_calls.css, css/f_mover.css). While either
   is on the page --dock-clear is the room they take above the bottom edge (above the tab bar on a phone), and 0 otherwise (match day, a build without
   them). main already ends that far under its last row, and scrolls a focused control clear of them. A scroller of your own that reaches the bottom
   of the window does the same with padding-bottom: var(--dock-clear). */
body:has(> #cx-dock:not([hidden]), > #mv-dock:not([hidden])) { --dock-clear: 64px; }
main { grid-column: 2; grid-row: 1 / -1; overflow: auto; overscroll-behavior: contain; padding: calc(var(--top-h) + 22px) clamp(16px, calc(2.4vw / var(--ui-z, 1)), 32px) max(64px, calc(var(--dock-clear) + 16px)); min-width: 0; scroll-padding-top: calc(var(--top-h) + 12px); scroll-padding-bottom: calc(24px + var(--dock-clear)); }
.page { width: 100%; max-width: 1440px; margin: 0 auto; }

/* a narrow desktop has no room for the ladder place beside the round: the round stays */
@media (min-width: 881px) and (max-width: 1080px) { .top .sh-rank { display: none; } }
@media (max-width: 880px) {
  :root { --top-h: 74px; }
  .app { grid-template-columns: minmax(0, 1fr); }
  .top { grid-column: 1; gap: 10px; padding: 0 max(14px, env(safe-area-inset-right, 0px)) 0 max(14px, env(safe-area-inset-left, 0px)); }
  .top .who > b { font-size: 19px; }
  .crest { width: 40px; height: 40px; border-radius: 11px; font-size: 14.5px; }
  body:has(> #cx-dock:not([hidden]), > #mv-dock:not([hidden])) { --dock-clear: calc(64px + var(--tu-lift, 0px)); }   /* 10px over the tab bar, a 46px button, 8px of air; --tu-lift when the walkthrough's strip is under them */
  main { grid-column: 1; padding: calc(var(--top-h) + 16px) max(16px, env(safe-area-inset-right, 0px)) calc(var(--tab-h) + max(48px, var(--dock-clear) + 12px) + env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px)); scroll-padding-bottom: calc(var(--tab-h) + 16px + var(--dock-clear) + env(safe-area-inset-bottom, 0px)); }
  /* the rail becomes a tab bar along the bottom edge; it scrolls sideways and the page runs under it */
  .side { position: fixed; left: 0; right: 0; bottom: 0; top: auto; flex-direction: row; align-items: stretch; gap: 0; height: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px)); padding: var(--tab-pad) 6px calc(var(--tab-pad) + env(safe-area-inset-bottom, 0px)) max(6px, env(safe-area-inset-left, 0px)); overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-padding: 0 84px 0 12px; border-right: 0; border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); background: color-mix(in srgb, var(--bg) 92%, transparent); -webkit-backdrop-filter: blur(22px) saturate(170%); backdrop-filter: blur(22px) saturate(170%); scrollbar-width: none; }
  .side::-webkit-scrollbar { display: none; }
  .side .brand, .side .grp { display: none; }
  .side > button { flex-direction: column; justify-content: center; gap: 3px; width: auto; min-width: 66px; min-height: 0; padding: 4px 8px; font-size: var(--fs-label); font-weight: 600; letter-spacing: .03em; }
  .side > button .ic { width: 22px; height: 22px; }
  .side > button .nl { display: none; } .side > button .ns { display: block; }
  .side .badge { position: absolute; top: 2px; left: calc(50% + 6px); margin: 0; line-height: 16px; min-width: 16px; padding: 0 4px; font-size: var(--fs-micro); }
}
@media (max-width: 720px) { .top .sh-rank { display: none; } }
/* phones: the status moves in beside the arrows as one short line (the round, then the ladder place if there is room for it) */
@media (max-width: 620px) {
  .top .sh-status { display: none; }
  .top .sh-now { grid-column: 2; grid-row: 3; display: flex; flex-wrap: wrap; align-items: center; column-gap: 8px; height: 16px; margin-top: 5px; overflow: hidden; min-width: 0; font-family: var(--f-cond); font-size: var(--fs-label); font-weight: 600; line-height: 16px; letter-spacing: .08em; text-transform: uppercase; color: var(--mute); }
  .top .sh-now > * { flex: 0 1 auto; min-width: 0; height: 16px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .top .sh-now b { color: var(--ink); font-weight: 600; }
  .top .sh-now .ic { width: 13px; height: 13px; margin-right: 3px; vertical-align: -2px; }
  @container (max-width: 150px) { .top .sh-now { display: none; } }
}
@media (max-width: 880px) and (max-height: 480px) {
  :root { --tab-h: 50px; --top-h: 66px; --tab-pad: 3px; }
  .top .who > b { font-size: 17px; }
  .top .who > span { font-size: var(--fs-label); line-height: 1.2; }
  .top .who > .nh, .top .sh-now { margin-top: 3px; }
  .side > button { min-width: 58px; }
  .side > button .ns { display: none; }
}

/* ---------- controls ---------- */
/* Buttons: one shape, four kinds. Plain. .pri is the one main action of a view, a solid accent block. .ghost is a quiet action. .bad removes or ends
   something: the danger colour as text on its own wash with an edge, never a solid block, so by day (when the accent is red too) it still cannot be
   taken for the main action. States: hover (pointer only), :focus-visible, :active, :disabled or aria-disabled, aria-busy. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s2); min-height: var(--ctl); background: var(--panel3); border: 1px solid var(--line2); color: var(--ink); border-radius: var(--r-m); padding: var(--s15) 14px; cursor: pointer; font-family: var(--f-cond); font-size: var(--fs-body); font-weight: 600; letter-spacing: var(--tr-ui); line-height: 1.1; white-space: nowrap; text-decoration: none; box-shadow: inset 0 1px 0 var(--hi); transition: transform var(--t-fast) var(--ease-out), background-color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out); }
.btn:active:not(:disabled):not([aria-disabled="true"]) { transform: scale(.97); box-shadow: inset 0 1px 3px var(--sink); }
.btn:focus-visible { box-shadow: 0 0 0 2px var(--focus-gap); }
.btn.pri { background: var(--accent); border-color: transparent; color: var(--accent-ink); font-weight: 700; box-shadow: inset 0 1px 0 var(--lift), 0 6px 14px -8px var(--shade); }
.btn.pri:focus-visible { box-shadow: 0 0 0 2px var(--focus-gap); }
.btn.sm { min-height: var(--ctl-s); padding: 3px 10px; font-size: var(--fs-small); border-radius: var(--r-s); }
/* An icon beside the words of a button needs no nudge on this scale: the row centres it on the line box, and at the 15px body step its middle
   measures a quarter of a pixel above the middle of the capitals (.btn.sm 0.16px under, Sim 0.2px above; test/sh2_look.js prints them). It was
   a whole pixel out when .btn was 15.5px, which is what the icons pass saw. */
.btn.bad { background: var(--bad-wash); border-color: color-mix(in srgb, var(--bad) 45%, transparent); color: var(--bad); box-shadow: none; }
.btn.ghost { background: none; border-color: transparent; box-shadow: none; color: var(--mute); }
/* disabled: a flat empty slot. A main action that is waiting for something (pick a club first) keeps its place with a dashed edge. */
.btn:disabled:not([aria-busy="true"]), .btn[aria-disabled="true"] { background: var(--panel2); border-color: var(--line); color: var(--faint); box-shadow: none; cursor: not-allowed; filter: none; opacity: 1; }
.btn.pri:disabled:not([aria-busy="true"]), .btn.pri[aria-disabled="true"] { border: 1px dashed var(--line3); color: var(--mute); }
.btn.ghost:disabled:not([aria-busy="true"]), .btn.ghost[aria-disabled="true"] { background: none; border-color: transparent; }
/* busy: the label stays where it is, the cursor waits, and a small ring turns before the label */
.btn[aria-busy="true"] { cursor: progress; pointer-events: none; }
.btn[aria-busy="true"]:not(.cont)::before { content: ''; flex: none; width: 14px; height: 14px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: ds-spin .8s linear infinite; }
@keyframes ds-spin { to { transform: rotate(360deg); } }
@media (hover: hover) {
  .btn:hover:not(:disabled):not([aria-disabled="true"]) { border-color: var(--line3); background: color-mix(in srgb, var(--panel3) 88%, var(--ink)); }
  .btn.pri:hover:not(:disabled):not([aria-disabled="true"]) { background: color-mix(in srgb, var(--accent) 90%, var(--ink)); border-color: transparent; }
  .btn.bad:hover:not(:disabled):not([aria-disabled="true"]) { background: color-mix(in srgb, var(--bad) 14%, transparent); border-color: var(--bad); }
  .btn.ghost:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--panel3); border-color: transparent; color: var(--ink); }
}
/* a small button keeps its look on a phone and gets a taller invisible target */
@media (max-width: 880px), (pointer: coarse) { .btn.sm { position: relative; } .btn.sm::after { content: ''; position: absolute; inset: -4px -2px; } }
.cont { min-height: 46px; padding: var(--s2) var(--s4) var(--s2) var(--s5); border-radius: 12px; font-size: var(--fs-title); letter-spacing: .05em; text-transform: uppercase; }
.cont .ic { width: 20px; height: 20px; stroke-width: 2.2; }
/* working: the label stays put (the bar does not jump) and the ball tumbles. Transform only, so it keeps turning while the week is simulated. */
.cont[aria-busy="true"] { opacity: 1; cursor: progress; filter: saturate(.6) brightness(.88); box-shadow: inset 0 1px 0 var(--lift); }
.cont .sh-spin { display: grid; place-items: center; flex: none; width: 20px; height: 20px; will-change: transform; animation: sh-tumble 1s linear infinite; }
.cont .sh-spin .ic { stroke-width: 2; }
@keyframes sh-tumble { to { transform: rotate(360deg); } }
@media (max-width: 880px) { .cont { min-height: 44px; padding: var(--s15) var(--s3) var(--s15) 15px; font-size: var(--fs-ui); } }
/* phones: a long label ("Open trade period") takes two lines, so the club name keeps its room */
@media (max-width: 480px) { .cont .sh-two { line-height: 1; text-align: left; } .cont .sh-two > span { display: block; } }

/* Fields: text, number, select and textarea are one family. --panel2 fill, a --line3 edge (3 to 1 on every surface), the control height, radius --r-m.
   On a phone every field is 16px, so the browser does not zoom the page when one takes the focus: never set a smaller size on a field. */
select, textarea, input[type=text], input[type=number], input[type=search], input[type=email], input[type=tel], input[type=url], input[type=password], input[type=date], input:not([type]) { min-height: var(--ctl); background: var(--panel2); border: 1px solid var(--line3); border-radius: var(--r-m); padding: var(--s15) var(--s25); max-width: 100%; transition: border-color var(--t-fast) var(--ease-out), background-color var(--t-fast) var(--ease-out); }
select { appearance: none; -webkit-appearance: none; padding-right: 30px; cursor: pointer; background-image: linear-gradient(45deg, transparent 50%, var(--chev) 50%), linear-gradient(135deg, var(--chev) 50%, transparent 50%); background-position: calc(100% - 16px) 55%, calc(100% - 11px) 55%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
select option, select optgroup { background: var(--panel); color: var(--ink); }
textarea { min-height: 88px; line-height: var(--lh-body); resize: vertical; }
@media (hover: hover) { select:hover, textarea:hover, input[type=text]:hover, input[type=number]:hover, input[type=search]:hover, input[type=email]:hover, input[type=tel]:hover, input[type=url]:hover, input[type=password]:hover, input[type=date]:hover, input:not([type]):hover { border-color: var(--mute); } }
select:focus-visible, textarea:focus-visible, input[type=text]:focus-visible, input[type=number]:focus-visible, input[type=search]:focus-visible, input[type=email]:focus-visible, input[type=tel]:focus-visible, input[type=url]:focus-visible, input[type=password]:focus-visible, input[type=date]:focus-visible, input:not([type]):focus-visible { border-color: var(--focus); outline-offset: 1px; }
select:disabled, textarea:disabled, input:disabled { background: var(--panel3); border-color: var(--line2); color: var(--faint); cursor: not-allowed; }
select[aria-invalid="true"], textarea[aria-invalid="true"], input[aria-invalid="true"] { border-color: var(--bad); box-shadow: inset 0 0 0 1px var(--bad); }
input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill { -webkit-text-fill-color: var(--ink); box-shadow: inset 0 0 0 100px var(--panel2); caret-color: var(--accent); }
:where(input[type=checkbox], input[type=radio]) { flex: none; width: 18px; height: 18px; margin: 0; cursor: pointer; vertical-align: -3px; }
/* a slider: a 6px track that fills, in the neutral amount colour, up to a thumb in the colour of the thing in hand. FX.range keeps --ds-v at the value. */
input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 24px; margin: 0; padding: 0; background: none; border: 0; cursor: pointer; accent-color: var(--hold); --ds-v: 0%; }
input[type=range]::-webkit-slider-runnable-track { height: 6px; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--fill) var(--ds-v), var(--track) var(--ds-v)); }
input[type=range]::-moz-range-track { height: 6px; border-radius: var(--r-pill); background: var(--track); }
input[type=range]::-moz-range-progress { height: 6px; border-radius: var(--r-pill); background: var(--fill); }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; margin-top: -7px; border-radius: 50%; background: var(--hold); border: 2px solid var(--panel); box-shadow: 0 1px 3px var(--shade); }
input[type=range]::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--hold); border: 2px solid var(--panel); box-shadow: 0 1px 3px var(--shade); }
input[type=range]:focus-visible { outline: none; }
input[type=range]:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--focus); outline-offset: 2px; }
input[type=range]:focus-visible::-moz-range-thumb { outline: 2px solid var(--focus); outline-offset: 2px; }
input[type=range]:disabled { cursor: not-allowed; opacity: .5; }
@media (max-width: 880px), (pointer: coarse) {
  select, textarea, input[type=text], input[type=number], input[type=search], input[type=email], input[type=tel], input[type=url], input[type=password], input[type=date], input:not([type]) { font-size: var(--fs-ui); }
  :where(input[type=checkbox], input[type=radio]) { width: 22px; height: 22px; }
  input[type=range] { height: 40px; }
  input[type=range]::-webkit-slider-thumb { width: 24px; height: 24px; margin-top: -9px; }
  input[type=range]::-moz-range-thumb { width: 20px; height: 20px; }
}

/* segmented choice: one pick from a few. The filled block is the pick. .ds-quiet is for a page that stacks many of them (a settings list): the pick is ink. */
.seg { position: relative; display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px; background: var(--panel2); border: 1px solid var(--line2); border-radius: var(--r-m); }
.seg button { position: relative; z-index: 1; min-height: var(--ctl-s); background: none; border: 0; border-radius: calc(var(--r-m) - 3px); padding: var(--s1) 11px; cursor: pointer; font-family: var(--f-cond); font-size: var(--fs-ui-s); font-weight: 600; letter-spacing: var(--tr-ui); color: var(--mute); transition: color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out); }
.seg button:active:not(:disabled) { transform: scale(.96); }
.seg button:focus-visible { outline-offset: 1px; }
.seg button.on { background: var(--pick); color: var(--pick-ink); box-shadow: inset 0 1px 0 var(--lift); }
.seg button:disabled { color: var(--faint); cursor: not-allowed; }
@media (hover: hover) { .seg button:hover:not(.on):not(:disabled) { color: var(--ink); } }
/* a .seg with data-glide: the filled block travels between picks */
.seg.has-glide button.on { background: none; box-shadow: none; }
.seg .glide { border-radius: calc(var(--r-m) - 3px); background: var(--pick); box-shadow: inset 0 1px 0 var(--lift); }
.seg.ds-quiet { --pick: var(--ink); --pick-ink: var(--bg); --lift: transparent; }
@media (max-width: 880px), (pointer: coarse) { .seg button { min-height: var(--hit); } }

/* tabs inside a screen: a track of pills, the raised pill is where you are */
.tabs { position: relative; display: flex; gap: 2px; width: max-content; max-width: 100%; padding: var(--s1); margin-bottom: var(--s4); overflow-x: auto; overscroll-behavior-x: contain; scroll-padding-inline: 36px; background: var(--strip); border: 1px solid var(--line2); border-radius: calc(var(--r-m) + var(--s1)); scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs button { position: relative; z-index: 1; flex: none; min-height: 34px; background: none; border: 0; border-radius: var(--r-m); padding: 5px 14px; font-family: var(--f-cond); font-size: var(--fs-ui); font-weight: 600; letter-spacing: var(--tr-ui); color: var(--mute); cursor: pointer; white-space: nowrap; transition: color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out); }
.tabs button:active { transform: scale(.97); }
.tabs button:focus-visible { outline-offset: -2px; }
.tabs button.on { color: var(--ink); }
.tabs:not(.has-glide) button.on { background: var(--panel3); box-shadow: var(--e1), inset 0 0 0 1px var(--line2); }
.tabs .glide { border-radius: var(--r-m); box-shadow: var(--e1), inset 0 0 0 1px var(--line2); }
@media (hover: hover) { .tabs button:hover:not(.on) { color: var(--ink); } }
@media (max-width: 880px), (pointer: coarse) { .tabs button { min-height: 42px; } }
/* Scroll cues. FX.more keeps data-more ("s", "e" or both) on every .tabs, .tw and [data-more-watch] that holds more than it shows. A tab strip
   fades its end tabs into the track under a small arrow, a table fades its far edge (only that one: a table may pin its first column). The two cue blocks take no room, so they never change the layout,
   and each reaches 4px past the content edge so that it also covers the strip's own padding (a sliver of the next tab showed there). */
.tabs[data-more]::before, .tabs[data-more]::after { content: ''; position: sticky; z-index: 2; flex: none; align-self: stretch; width: 42px; pointer-events: none; opacity: 0; transition: opacity var(--t-ui) var(--ease-out); }
.tabs[data-more]::before { left: calc(0px - var(--s1)); margin-right: -44px; background: linear-gradient(to bottom right, transparent 41%, var(--ink) 41% 59%, transparent 59%) left 12px top calc(50% - 3px) / 6px 6px no-repeat, linear-gradient(to top right, transparent 41%, var(--ink) 41% 59%, transparent 59%) left 12px top calc(50% + 3px) / 6px 6px no-repeat, linear-gradient(270deg, transparent, var(--strip) 55%); }
.tabs[data-more]::after { right: calc(0px - var(--s1)); margin-left: -44px; background: linear-gradient(to bottom left, transparent 41%, var(--ink) 41% 59%, transparent 59%) right 12px top calc(50% - 3px) / 6px 6px no-repeat, linear-gradient(to top left, transparent 41%, var(--ink) 41% 59%, transparent 59%) right 12px top calc(50% + 3px) / 6px 6px no-repeat, linear-gradient(90deg, transparent, var(--strip) 55%); }
.tabs[data-more~="s"]::before, .tabs[data-more~="e"]::after { opacity: 1; }
.tw[data-more~="e"] { -webkit-mask-image: linear-gradient(90deg, var(--ink) calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, var(--ink) calc(100% - 28px), transparent); }

/* ---------- layout ---------- */
.row { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: center; }
.row.tight { gap: var(--s15); }
.sp { flex: 1; }
.cols { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; }
.cols.two { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
.cols.wide { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
@media (max-width: 980px) { .cols.two, .cols.wide { grid-template-columns: minmax(0, 1fr); } }
.stack { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; }
#brk:empty { display: none; }
.head { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.head > div:first-child { min-width: 0; }
.head p { margin: var(--s15) 0 0; color: var(--mute); max-width: var(--measure); }
/* The small label above a heading. One rule: it stays only where it says something the heading does not (the season, the round, the date, the club,
   whose list it is), it is the plain label in --mute, never the accent, and it sits 4px above the heading. A label that only decorates is deleted. */
.head .lbl, .sh-dlg > .lbl, .ds-over { display: block; margin-bottom: var(--s1); color: var(--mute); }

/* ---------- surfaces ---------- */
/* The panel: .panel > .ph + .pb. The head is one line of caps, 44px high, with at most one quiet link or small button at its right (.sp before it).
   The body is padded 16px at the sides and the foot and sits 4px under the head. .pb.flush takes a table to the edges. */
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--e1); min-width: 0; }
.panel > .ph { display: flex; align-items: center; gap: var(--s2); min-height: 44px; padding: var(--s25) var(--s4) var(--s2); font-family: var(--f-cond); font-size: var(--fs-ui-s); font-weight: 600; letter-spacing: var(--tr-caps); text-transform: uppercase; color: color-mix(in srgb, var(--ink) 74%, var(--mute)); }
.panel > .ph a { font-size: var(--fs-small); letter-spacing: .08em; color: var(--mute); text-decoration: none; }
@media (max-width: 880px), (pointer: coarse) { .panel > .ph a { display: inline-flex; align-items: center; min-height: var(--hit); margin-block: -12px; } }   /* a 40px target that does not make the head taller */
@media (hover: hover) { .panel > .ph a:hover { color: var(--ink); text-decoration: underline; } }
.panel > .pb { padding: var(--s1) var(--s4) var(--s4); }
.panel > .pb:first-child { padding-top: var(--s4); }
.panel > .pb.flush { padding: 0; border-top: 1px solid var(--line); overflow: hidden; border-radius: 0 0 calc(var(--r-l) - 1px) calc(var(--r-l) - 1px); }
.panel > .pb.flush:first-child { border-top: 0; border-radius: calc(var(--r-l) - 1px); }
/* hero: the one feature block at the top of a screen. It wears the colours of the club set with clubVars(). By day the wash is lighter (--hero-club),
   so ink stays readable over a dark club colour. Secondary text on the wash is tinted from the ink, never the page's grey: inside a hero --mute,
   --faint and the two hairlines are the ink at a strength, so .lbl, .sub and .mute follow the wash with no extra class. */
.hero { --mute: color-mix(in srgb, var(--ink) var(--hero-mute), transparent); --faint: color-mix(in srgb, var(--ink) var(--hero-faint), transparent); --line: color-mix(in srgb, var(--ink) 13%, transparent); --line2: color-mix(in srgb, var(--ink) 24%, transparent);
  position: relative; overflow: hidden; border-radius: var(--r-l); border: 1px solid var(--line); box-shadow: var(--e2); padding: clamp(16px, calc(2.2vw / var(--ui-z, 1)), 26px);
  background: linear-gradient(118deg, color-mix(in srgb, var(--club) var(--hero-club), var(--panel)) 0%, color-mix(in srgb, var(--club) var(--hero-club2), var(--panel)) 46%, var(--panel) 78%); }
.hero::before { content: ''; position: absolute; inset: 0 auto 0 0; width: 46%; pointer-events: none; opacity: .5; background: repeating-linear-gradient(118deg, transparent 0 22px, color-mix(in srgb, var(--club2) 16%, transparent) 22px 24px); -webkit-mask-image: linear-gradient(90deg, var(--ink), transparent); mask-image: linear-gradient(90deg, var(--ink), transparent); }
.hero > * { position: relative; }
.tile { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r-m); padding: var(--s25) var(--s3); min-width: 0; }
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: var(--s2); }
/* the empty state: one icon, one line in ink that says what will appear here, one line of what to do about it, at most one button */
.empty { display: grid; justify-items: center; gap: var(--s15); padding: 28px var(--s4); text-align: center; color: var(--mute); }
.empty .ic { width: 28px; height: 28px; color: var(--faint); }
.empty > b, .empty > h3 { font-family: var(--f-cond); font-size: var(--fs-title); font-weight: 700; line-height: 1.15; letter-spacing: .01em; color: var(--ink); }
.empty > p { max-width: 46ch; margin: 0; }
.empty > .btn { margin-top: var(--s15); }

/* ---------- text atoms ---------- */
.lbl { font-family: var(--f-cond); font-size: var(--fs-label); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--mute); font-weight: 600; line-height: 1.2; }
.mute { color: var(--mute); } .good { color: var(--good); } .bad { color: var(--bad); } .warn { color: var(--warn); } .acc { color: var(--accent); }
.big { font-family: var(--f-display); font-weight: 800; font-size: var(--fs-d4); line-height: 1; letter-spacing: var(--tr-display); font-variant-numeric: tabular-nums; }
.big.acc { color: var(--lit); }   /* a number is never the accent by day: it would read as bad */
.pre { white-space: pre-line; }
.sub { font-size: var(--fs-small); color: var(--mute); font-weight: 400; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 7px var(--s4); } .kv > span { color: var(--mute); } .kv b { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
/* a small round mark beside a line: unread is the information colour, never the accent */
.ds-dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--info); vertical-align: 1px; }
.ds-dot.good { background: var(--good); } .ds-dot.warn { background: var(--warn); } .ds-dot.bad { background: var(--bad); } .ds-dot.mute { background: var(--faint); }

/* a count beside a label (on a tab, a button, a panel head): quiet by default, solid accent (.acc) when it is something that needs you */
.ds-n { display: inline-block; min-width: 18px; margin-left: var(--s15); padding: 0 5px; border-radius: var(--r-pill); background: color-mix(in srgb, currentColor 14%, transparent); font-family: var(--f-body); font-size: var(--fs-micro); font-weight: 700; line-height: 18px; letter-spacing: 0; text-align: center; font-variant-numeric: tabular-nums; vertical-align: 1px; }
.ds-n.acc { background: var(--accent); color: var(--accent-ink); }
/* A settings row, one layout at every width: what it is (b) and one line about it (p or .sub) at the left, the control at the right.
   A control with three or more options, a select or a field takes its own line on a phone. */

/* An inline notice: one row that says why something is blocked or what just changed, above the thing it is about. The kind is the icon and
   the words, with the colour as a second cue: plain is information, .warn .bad .good the rest. Words in ink, at most one small button. */
.ds-note { --n: var(--info); display: flex; align-items: flex-start; gap: var(--s25); padding: var(--s25) var(--s3); border: 1px solid color-mix(in srgb, var(--n) 34%, var(--line2)); border-radius: var(--r-m); background: color-mix(in srgb, var(--n) 11%, var(--panel)); color: var(--ink); font-size: var(--fs-body); line-height: var(--lh-body); }
.ds-note.warn { --n: var(--warn); } .ds-note.bad { --n: var(--bad); } .ds-note.good { --n: var(--good); }
.ds-note > .ic { margin-top: 1px; color: var(--n); }
.ds-note > :not(.ic):not(.btn) { flex: 1; min-width: 0; }
.ds-note > .btn { flex: none; margin: -3px 0; }
@media (max-width: 560px) { .ds-note { flex-wrap: wrap; } .ds-note > :not(.ic):not(.btn) { flex-basis: calc(100% - 1.25em - var(--s25) - 1px); } .ds-note > .btn { margin: 0 0 0 calc(1.25em + var(--s25)); } }   /* on a phone the button sits under the words, in line with them */
.ds-set { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s1) var(--s4); padding: var(--s3) 0; border-top: 1px solid var(--line); }
.ds-set:first-child { border-top: 0; padding-top: 0; } .ds-set:last-child { padding-bottom: 0; }
.ds-set > :first-child { min-width: 0; } .ds-set b { display: block; font-weight: 600; }
.ds-set p, .ds-set .sub { margin: 2px 0 0; max-width: var(--measure); font-size: var(--fs-small); color: var(--mute); }
.ds-set > .seg { justify-self: end; flex-wrap: nowrap; }
@media (max-width: 560px) { .ds-set > .seg:has(> :nth-child(3)), .ds-set > select, .ds-set > input:not([type=checkbox]):not([type=radio]) { grid-column: 1 / -1; justify-self: stretch; } .ds-set > .seg:has(> :nth-child(3)) > button { flex: 1; } }   /* three choices or more take their own row under the words, and share it evenly */

/* ---------- data ---------- */
.tw { overflow-x: auto; }
table.t { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; font-size: var(--fs-data); }
table.t th { font-family: var(--f-cond); font-size: var(--fs-label); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--mute); font-weight: 600; text-align: right; padding: 9px var(--s25) var(--s2); border-bottom: 1px solid var(--line); white-space: nowrap; position: sticky; top: 0; background: var(--panel); }
table.t th.l, table.t td.l { text-align: left; }
table.t th[data-a] { cursor: pointer; transition: color var(--t-fast) var(--ease-out); }
@media (hover: hover) { table.t th[data-a]:hover { color: var(--ink); } }
/* the column the table is sorted by: ink, with the icon family's drawn arrow and aria-sort on the heading */
table.t th.srt { color: var(--ink); }
table.t td { padding: var(--s2) var(--s25); border-bottom: 1px solid color-mix(in srgb, var(--line) 62%, transparent); text-align: right; white-space: nowrap; }
table.t th:first-child, table.t td:first-child { padding-left: var(--s4); } table.t th:last-child, table.t td:last-child { padding-right: var(--s4); }
table.t tr:last-child td { border-bottom: 0; }
/* rows: .click takes a press (hover, pressed and keyboard focus are drawn), .me is the coach's own row (it wears his club, with the name in bold),
   .sel is a selected row (a wash of the colour of the thing in hand, ruled above and below, so it does not rest on the tint alone),
   .cut and .cut2 draw a line under a row */
table.t tr.click { cursor: pointer; }
@media (hover: hover) { table.t tr.click:hover td { background: var(--panel2); } }
table.t tr.click:active td { background: var(--panel3); }
table.t tr:focus-visible, table.t th:focus-visible { outline-offset: -2px; }
table.t tr.me td { background: var(--me); }
table.t tr.me td.name { color: var(--ink); font-weight: 700; }
table.t tr.cut td { border-bottom: 2px solid var(--ink); }
table.t tr.cut2 td { border-bottom: 2px dashed var(--line3); }
table.t tr.sel td { background: var(--sel); box-shadow: inset 0 1px 0 color-mix(in srgb, var(--hold) 45%, transparent), inset 0 -1px 0 color-mix(in srgb, var(--hold) 45%, transparent); }
table.t td.name { text-align: left; font-weight: 600; }
table.t td.name a, td a[data-a=player] { color: inherit; text-decoration: none; }
@media (hover: hover) { table.t td.name a:hover, td a[data-a=player]:hover { text-decoration: underline; text-decoration-color: var(--link-line); } }

.chip { display: inline-flex; align-items: center; justify-content: center; min-width: 38px; height: 22px; padding: 0 var(--s15) 3px; border-radius: var(--r-s); font-family: var(--f-cond); font-weight: 700; font-size: var(--fs-small); letter-spacing: .05em; line-height: 1; vertical-align: middle; border: 0; box-shadow: inset 0 -3px 0 var(--e, currentColor), inset 0 0 0 1px var(--rim); }
.chip.lg { min-width: 50px; height: 32px; font-size: var(--fs-ui); padding-bottom: 4px; border-radius: var(--r-s); box-shadow: inset 0 -4px 0 var(--e, currentColor), inset 0 0 0 1px var(--rim); }
/* a pill is a state in words: the colour class is the text and the fill is that colour at 14%. The accent one is solid, like everything else the accent does. */
.pill { display: inline-flex; align-items: center; gap: var(--s1); border-radius: var(--r-pill); padding: 0 var(--s2); font-size: var(--fs-label); font-weight: 600; line-height: 20px; letter-spacing: .01em; white-space: nowrap; background: color-mix(in srgb, currentColor 14%, transparent); }
.pill.acc { background: var(--accent); color: var(--accent-ink); }
.pill .ic { width: 12px; height: 12px; vertical-align: 0; }
/* position badges are coloured by line (--ln-def, --ln-mid, --ln-fwd, --ln-ruc), never by a meaning colour: a red badge would read as trouble.
   A badge and a rating carry their own surface (the tint is mixed into --panel), so they read the same on a plain row, your row and a selected row. */
.pos { display: inline-block; min-width: 30px; text-align: center; font-family: var(--f-cond); font-weight: 700; font-size: var(--fs-small); letter-spacing: .04em; line-height: 19px; padding: 0 5px; border-radius: var(--r-s); background: var(--panel3); color: var(--ink); }
.pos.DEF { color: var(--ln-def); background: color-mix(in srgb, var(--ln-def) 15%, var(--panel)); } .pos.MID { color: var(--ln-mid); background: color-mix(in srgb, var(--ln-mid) 15%, var(--panel)); } .pos.FWD { color: var(--ln-fwd); background: color-mix(in srgb, var(--ln-fwd) 15%, var(--panel)); } .pos.RUC { color: var(--ln-ruc); background: color-mix(in srgb, var(--ln-ruc) 15%, var(--panel)); }
/* rating badge. The ramp is ordered by lightness as well as hue: .p quiet, plain, .g green, .e (85 and over) a gold plate with dark numerals in both themes */
.ovr { display: inline-block; min-width: 32px; text-align: center; font-family: var(--f-display); font-weight: 800; font-size: var(--fs-title); line-height: 22px; border-radius: var(--r-s); padding: 0 5px; background: var(--panel3); font-variant-numeric: tabular-nums; }
/* form has moved this rating: a small corner mark, up or down (the working is in the tooltip) */
.ovr-up, .ovr-dn { position: relative; }
.ovr-up::after, .ovr-dn::after { content: ''; position: absolute; top: 2px; right: 2px; width: 6px; height: 5px; background: var(--good); clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.ovr-dn::after { background: var(--bad); clip-path: polygon(0 0, 100% 0, 50% 100%); }
.ovr.e { color: var(--top-ink); background: var(--top); } .ovr.g { color: var(--good); background: color-mix(in srgb, var(--good) 14%, var(--panel)); } .ovr.p { color: var(--mute); background: var(--panel2); }
.ovr.e.ovr-up::after, .ovr.e.ovr-dn::after { background: var(--top-ink); }
/* stars are a mark of the best, so they are gold (--top-line), never the accent. stars() draws them through the icon family (icStars in f_icons.js),
   which takes this colour for the lit ones; the unlit ones are an opaque quiet colour. */
.stars { color: var(--top-line); letter-spacing: -1px; white-space: nowrap; font-size: var(--fs-small); } .stars i { color: var(--line3); font-style: normal; }
/* drawn stars (icStars): lit, half, unlit. Sized in em, so every place that sets a font size on .stars still works. Three classes on the icon rule,
   so a screen's own ".x .ic" size never reaches a rating. The unlit star and the unlit half are the opaque --line3 (3 to 1), never a see-through
   colour: a shape's stroke overlaps its fill, and a see-through colour would paint a darker rim there. */
.stars.ic-stars { letter-spacing: 0; }
.stars.ic-stars .ic { width: .92em; height: .92em; margin: 0 -.04em; padding: 0; color: inherit; stroke-width: 2; vertical-align: -.1em; }
.stars.ic-stars i { color: inherit; }
.stars.ic-stars i .ic, .stars.ic-stars .ic .q { color: var(--line3); opacity: 1; }
/* the drawn arrow on a sorted column head (icSort) */
.ic.ic-sort { width: 1em; height: 1em; margin-left: 3px; stroke-width: 2.8; vertical-align: -.14em; }
/* a meter: plain is good, .w a warning, .b bad, .a or .n an amount with no judgement in it (never the accent). The number is always printed beside it. */
.meter { height: 6px; background: var(--track); border-radius: var(--r-pill); overflow: hidden; min-width: 40px; }
.meter > i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--good); transform-origin: 0 50%; }
.meter.w > i { background: var(--warn); } .meter.b > i { background: var(--bad); } .meter.a > i, .meter.n > i { background: var(--fill); } .meter.ok > i { background: var(--good); } .meter.top > i { background: var(--top-line); }

/* ---------- floating layers ---------- */
/* toast: one line from the game. It pops up from the bottom edge, leaves the same way, and a tap sends it off early. */
.toast { position: fixed; left: 50%; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); z-index: var(--z-toast); transform: translateX(-50%); display: flex; align-items: center; gap: 11px; width: max-content; max-width: min(calc(92vw / var(--ui-z, 1)), 560px); padding: var(--s2) 18px var(--s2) var(--s2); background: var(--ink); color: var(--bg); border: 1px solid transparent; border-radius: var(--r-l); font-weight: 600; line-height: 1.3; text-wrap: balance; box-shadow: var(--e4); cursor: pointer; }
.toast[hidden] { display: none; }
.toast .sh-tic { display: grid; place-items: center; flex: none; width: 30px; height: 30px; border-radius: calc(var(--r-l) - var(--s2)); background: var(--accent); color: var(--accent-ink); }
.toast .sh-tic .ic { width: 18px; height: 18px; stroke-width: 2; vertical-align: 0; }
.toast.is-in { animation: fx-toast var(--t-pop) var(--spring-pop) both; }
.toast.is-out { animation: fx-toast-out var(--t-ui) var(--ease-in) both; }
@keyframes fx-toast { from { opacity: 0; transform: translateX(-50%) translateY(18px) scale(.96); } }
@keyframes fx-toast-out { to { opacity: 0; transform: translateX(-50%) translateY(14px) scale(.97); } }
/* in a career (toast() adds .sh-app) on a desktop the toast is centred on the page, not on the window: the rail takes the left edge */
@media (min-width: 881px) { .toast.sh-app { left: calc(50% + var(--rail-w) / 2); max-width: min(calc(calc(92vw / var(--ui-z, 1)) - var(--rail-w)), 560px); } }
/* phones in a career: clear of the tab bar */
@media (max-width: 880px) { .toast.sh-app { bottom: calc(var(--tab-h) + 14px + env(safe-area-inset-bottom, 0px)); } }

/* tap to explain (FX.tip in fx.js): on a touch screen, the words a title tooltip would have shown, in a small bubble beside the thing tapped.
   The toast's pair, ink under the page colour, one size down. It takes no presses and is gone at the next one. */
.ds-tip { position: fixed; left: 0; top: 0; z-index: var(--z-menu); max-width: min(280px, calc(calc(100vw / var(--ui-z, 1)) - 16px)); padding: var(--s15) var(--s25); background: var(--ink); color: var(--bg); border: 1px solid transparent; border-radius: var(--r-m); font-size: var(--fs-small); font-weight: 600; line-height: 1.3; text-wrap: balance; box-shadow: var(--e4); pointer-events: none; animation: fx-fade var(--t-fast) ease both; }
.ds-tip[hidden] { display: none; }

/* dialogs (modalHtml in ui2.js): a centred card on a desktop, a bottom sheet on a phone. One structure: a title (h2#sh-dt, with a label above it only
   under the eyebrow rule), the body, then .sh-acts with the main action last. --dlg-w sets the width (460 a question, 560 by default, up to 720).
   They arrive once (.is-new) and leave along the same path, faster (.is-out, a ghost left by render()). */
.modal { position: fixed; inset: 0 0 var(--kb, 0px); z-index: var(--z-dialog); display: flex; align-items: center; justify-content: center; padding: var(--s4); background: var(--scrim); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); overscroll-behavior: contain; }
.modal > div { position: relative; width: min(var(--dlg-w, 560px), 100%); max-height: 90%; overflow: auto; overscroll-behavior: contain; padding: 22px; background: var(--panel); border: 1px solid transparent; border-radius: var(--r-xl); box-shadow: var(--e3); outline: none; }
.modal > .sh-dlg-confirm { --dlg-w: 460px; }
.modal h2 { margin-bottom: var(--s25); }
.modal.is-new { animation: fx-fade var(--t-ui) ease both; }
.modal.is-new > div { animation: fx-sheet var(--t-move) var(--ease-out) both; }
.modal.is-out { pointer-events: none; animation: fx-fade-out 170ms ease both; }
.modal.is-out > div { animation: fx-sheet-out 170ms var(--ease-in) both; }
@keyframes fx-sheet { from { opacity: 0; transform: translateY(14px) scale(.965); } }
@keyframes fx-sheet-out { to { opacity: 0; transform: translateY(10px) scale(.975); } }
@keyframes fx-fade { from { opacity: 0; } }
@keyframes fx-fade-out { to { opacity: 0; } }
.sh-grab { display: none; }
.ds-dbody { color: color-mix(in srgb, var(--ink) 70%, var(--mute)); max-width: var(--measure); }
.sh-acts { display: flex; justify-content: flex-end; gap: var(--s25); margin-top: var(--s5); }
.sh-acts .btn { min-width: 108px; min-height: 42px; padding-inline: 18px; font-size: var(--fs-ui); }
.sh-fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.sh-field { display: grid; gap: 7px; min-width: 0; align-content: start; }
.sh-field input[type=text] { width: 100%; min-height: 44px; font-size: var(--fs-ui); }
.sh-ask { display: flex; align-items: flex-start; gap: 14px; }
.sh-ask-ic { display: grid; place-items: center; flex: none; width: 42px; height: 42px; border-radius: 13px; background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.sh-ask-ic.bad { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
.sh-ask-ic .ic { width: 22px; height: 22px; }
.sh-ask > div { min-width: 0; padding-top: 2px; }
.sh-ask h2 { margin-bottom: var(--s2); }
.sh-ask p { color: color-mix(in srgb, var(--ink) 60%, var(--mute)); max-width: 52ch; }

/* contract talks: who he is, what his manager wants, what you can afford, your offer, the reply */
.modal > .sh-dlg-contract { width: min(600px, 100%); padding: 0; }
.sh-neg-head { display: flex; align-items: center; gap: 16px; min-height: 126px; padding-right: 20px; border-bottom: 1px solid var(--line); background: linear-gradient(90deg, color-mix(in srgb, var(--club) 14%, var(--panel)), var(--panel) 72%); }
/* the slanted block in club colours behind the portrait, with a trim line in the club's second colour */
.sh-neg-kit { position: relative; align-self: stretch; flex: none; display: grid; place-items: center; width: 146px; padding: 12px 30px 12px 14px; }
.sh-neg-kit::before, .sh-neg-kit::after { content: ''; position: absolute; inset: 0; }
.sh-neg-kit::before { background: color-mix(in srgb, var(--club) 84%, var(--panel)); clip-path: polygon(0 0, calc(100% - 5px) 0, calc(100% - 31px) 100%, 0 100%); }
.sh-neg-kit::after { background: var(--club2); clip-path: polygon(calc(100% - 5px) 0, 100% 0, calc(100% - 26px) 100%, calc(100% - 31px) 100%); }
.sh-neg-kit > * { position: relative; }
.sh-neg-kit .kit { filter: drop-shadow(0 8px 10px var(--shade)); }
.sh-neg-id { flex: 1; min-width: 0; padding: 16px 0; }
.sh-neg-id h2 { margin: 5px 0 9px; font-size: var(--fs-d5); line-height: .95; overflow-wrap: anywhere; }
.sh-neg-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 10px; font-size: var(--fs-small); line-height: 1.3; color: var(--mute); }
.sh-neg-ovr { flex: none; display: grid; justify-items: center; gap: 6px; }
.sh-neg-ovr .ovr { min-width: 56px; font-size: var(--fs-d4); line-height: 48px; border-radius: 13px; }
.sh-neg-body { display: grid; gap: 16px; padding: 18px 20px 2px; }
.sh-neg-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sh-neg-facts .tile { padding: 12px 14px; }
.sh-neg-facts .big { margin: 5px 0 4px; }
.sh-neg-facts .sub.bad { color: var(--bad); font-weight: 600; }
.sh-neg-facts .big small { margin-right: 5px; font-family: var(--f-cond); font-size: var(--fs-body); font-weight: 600; letter-spacing: var(--tr-ui); color: var(--mute); }
.sh-neg-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px 18px; }
.sh-neg-row .sh-field { flex: 1 1 auto; }
.sh-step { display: flex; align-items: stretch; height: 52px; background: var(--panel2); border: 1px solid var(--line3); border-radius: 13px; overflow: hidden; }
.sh-step:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.sh-step > button { display: grid; place-items: center; flex: none; width: 48px; margin: 0; padding: 0; background: none; border: 0; color: var(--mute); cursor: pointer; transition: transform var(--t-fast) ease, color var(--t-fast) ease, background-color var(--t-fast) ease; }
.sh-step > button:active { transform: scale(.88); color: var(--ink); }
.sh-step > button:focus-visible { outline-offset: -4px; border-radius: 12px; }
@media (hover: hover) { .sh-step > button:hover { color: var(--ink); background: var(--panel3); } }
.sh-step-v { flex: 1; display: flex; align-items: baseline; justify-content: center; gap: 1px; padding: 0 6px; border-inline: 1px solid var(--line); font-family: var(--f-display); font-size: var(--fs-d5); font-weight: 800; line-height: 50px; font-variant-numeric: tabular-nums; }
.sh-step-v i { font-style: normal; font-size: var(--fs-d6); color: var(--mute); }
.sh-step .sh-step-v input { width: 2.5em; min-height: 0; height: 50px; margin: 0; padding: 0; background: none; border: 0; border-radius: 0; outline: none; color: var(--ink); font: inherit; text-align: center; font-variant-numeric: tabular-nums; -moz-appearance: textfield; appearance: textfield; }
.sh-step .sh-step-v input::-webkit-outer-spin-button, .sh-step .sh-step-v input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.sh-yrs { display: flex; flex-wrap: nowrap; height: 52px; border-radius: 13px; }
.sh-yrs button { flex: 1; min-width: 38px; min-height: 0; border-radius: 9px; font-family: var(--f-display); font-size: var(--fs-d6); font-weight: 800; font-variant-numeric: tabular-nums; }
.sh-yrs.has-glide button.on { background: none; box-shadow: none; }
.sh-yrs .glide { border-radius: 9px; background: var(--pick); box-shadow: inset 0 1px 0 var(--lift); }
/* the bar is your offer, the mark is what his manager asked for */
.sh-gauge { position: relative; height: 8px; margin-top: 20px; }
.sh-gauge-b { position: absolute; inset: 0; border-radius: var(--r-pill); overflow: hidden; background: var(--track); }
.sh-gauge-f { position: absolute; inset: 0; background: var(--fill); transform-origin: 0 50%; transform: scaleX(var(--v, .8)); transition: transform var(--t-move) var(--ease-out); }
.sh-gauge-t { position: absolute; left: 80%; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--ink); }
.sh-gauge-t::after { content: 'Ask'; position: absolute; left: 50%; bottom: calc(100% + 2px); transform: translateX(-50%); font-family: var(--f-cond); font-style: normal; font-size: var(--fs-micro); font-weight: 600; line-height: 1; letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--mute); }
.sh-gauge-l { margin-top: 9px; font-size: var(--fs-small); color: var(--mute); font-variant-numeric: tabular-nums; }
.sh-neg-reply { display: flex; align-items: flex-start; gap: 10px; padding: 11px 14px; border-radius: var(--r-m); background: color-mix(in srgb, currentColor 12%, transparent); }
.sh-neg-reply .ic { flex: none; width: 20px; height: 20px; margin-top: 1px; }
.sh-neg-reply p { margin: 0; color: var(--ink); font-weight: 600; }
.sh-neg-reply.is-new { animation: fx-rise var(--t-move) var(--ease-out) both; }
.sh-neg-done { display: flex; align-items: center; gap: 16px; padding: 8px 0 4px; }
.sh-neg-tick { display: grid; place-items: center; flex: none; width: 54px; height: 54px; border-radius: 50%; background: var(--good); color: var(--panel); }
.sh-neg-tick .ic { width: 28px; height: 28px; stroke-width: 2.8; }
.sh-neg-done p { margin: 4px 0 0; font-family: var(--f-cond); font-size: var(--fs-title); font-weight: 700; line-height: 1.2; text-wrap: balance; }   /* a sentence: never the display face, never caps (R-26) */
.sh-neg-done.is-new .sh-neg-tick { animation: sh-stamp var(--t-pop) var(--spring-pop) both; }
@keyframes sh-stamp { from { opacity: 0; transform: scale(.4) rotate(-20deg); } }
.sh-dlg-contract .sh-acts { position: sticky; bottom: 0; z-index: 2; margin: 0; padding: 16px 20px 20px; background: linear-gradient(180deg, transparent, var(--panel) 14px); }
@media (max-width: 560px) {
  .modal { align-items: flex-end; padding: 0; }
  .modal > div { width: 100%; max-height: 92%; border-radius: var(--r-xl) var(--r-xl) 0 0; padding: 28px 18px calc(18px + env(safe-area-inset-bottom, 0px)); will-change: transform; }
  @keyframes fx-sheet { from { transform: translateY(100%); } }
  @keyframes fx-sheet-out { to { transform: translateY(100%); } }
  .modal.is-new > div { animation-duration: var(--t-far); }
  .modal.is-out > div { animation-duration: 220ms; }
  /* the handle: drag it down to put the sheet away (FX.sheet in fx.js) */
  .sh-grab { display: block; position: absolute; left: 0; right: 0; top: 0; z-index: 3; height: 26px; touch-action: none; cursor: grab; }
  .sh-grab::before { content: ''; position: absolute; left: 50%; top: 8px; width: 40px; height: 5px; margin-left: -20px; border-radius: 3px; background: color-mix(in srgb, var(--ink) 30%, transparent); }
  .sh-acts .btn { flex: 1; min-height: 48px; font-size: var(--fs-title); }
  .modal > .sh-dlg-contract { width: 100%; padding: 0 0 env(safe-area-inset-bottom, 0px); }
  .sh-neg-head { gap: 12px; min-height: 112px; padding-right: 16px; }
  .sh-neg-kit { width: 116px; padding: 16px 28px 10px 10px; } .sh-neg-kit .pph { --pph: 76px; }
  .sh-neg-id h2 { font-size: var(--fs-h2); }
  .sh-neg-ovr .ovr { min-width: 48px; font-size: var(--fs-d5); line-height: 42px; }
  .sh-neg-body { padding: 16px 16px 2px; }
  .sh-neg-facts .big { font-size: var(--fs-d5); }
  .sh-dlg-contract .sh-acts { padding: 16px 16px 18px; }
}
/* a phone on its side: the dialog is short, so it gives up some air and its buttons stay in reach while the rest scrolls */
@media (max-height: 480px) {
  .modal { padding: 10px; }
  .modal > div { max-height: 100%; }
  .sh-neg-head { min-height: 80px; }
  .sh-neg-kit { padding-block: 6px; }
  .sh-neg-kit .pph { --pph: 64px; }
  .sh-neg-id { padding: 8px 0; }
  .sh-neg-id h2 { margin: 3px 0 6px; font-size: var(--fs-h2); }
  .sh-neg-body { gap: 10px; padding-top: 10px; }
  .sh-neg-facts .tile { padding: 8px 12px; }
  .sh-neg-facts .big { margin: 2px 0; font-size: var(--fs-h2); }
  .sh-neg-row { gap: 8px 18px; }
  .sh-step, .sh-yrs { height: 46px; }
  .sh-step-v { font-size: var(--fs-h2); line-height: 44px; }
  .sh-step .sh-step-v input { height: 44px; }
  .sh-gauge { display: none; }
  .sh-gauge-l { margin-top: 6px; }
  .sh-dlg-contract .sh-acts { padding: 10px 20px 14px; }
}

/* ---------- motion ---------- */
/* Arriving at a screen is one moment, not a cascade, and content never waits behind it. render() puts .is-enter on #main when you arrive (.is-tab when
   a tab changes): the page settles from a third of its strength in --t-move, all at once, and only the lead block (.fx-lead: the hero or the page head)
   rises 10px into place. Then the data settles once: a bar or a number that has changed since you last saw this screen fills or counts (FX.enter marks
   the ones that have not as .fx-old). A plain re-render gets none of it. A screen may add one authored detail of its own inside its hero. */
@keyframes fx-rise { from { opacity: .35; transform: translateY(10px); } }
@keyframes ds-arrive { from { opacity: .35; } }
.is-enter .fx-in, .is-tab .fx-in { animation: ds-arrive var(--t-move) var(--ease-out) both; }
.is-enter .fx-in.fx-lead { animation: fx-rise var(--t-move) var(--ease-out) both; }
.is-enter .meter:not(.fx-old) > i, .is-enter .tally i { animation: fx-fill var(--t-data) var(--ease-out) both; }
@keyframes fx-fill { from { transform: scaleX(.3); } }

/* ---------- system settings ---------- */
/* Reduced motion is an alternative, not an absence. The first rule is the safety net for every file: no keyframe runs its course, nothing loops and
   nothing travels. Then what the shared layer does instead: an arrival (a screen, a dialog, the toast, a reply) is a short fade, and the controls keep
   their change of colour, which is what says a press or a pick was taken, with no movement. JavaScript motion checks FX.reduced() and skips. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .is-enter .fx-in, .is-enter .fx-in.fx-lead, .is-tab .fx-in { animation: ds-arrive 160ms ease both !important; animation-duration: 160ms !important; }
  .modal.is-new, .modal.is-new > div, .toast.is-in, .sh-neg-reply.is-new, .sh-neg-done.is-new .sh-neg-tick { animation: fx-fade 160ms ease both !important; animation-duration: 160ms !important; }
  .btn, .seg button, .tabs button, .side > button, select, textarea, input, a, table.t th[data-a] { transition-property: color, background-color, border-color, text-decoration-color, box-shadow !important; transition-duration: var(--t-fast) !important; }
  .btn:active, .seg button:active, .tabs button:active, .side > button:active, .top .sh-rank:active { transform: none !important; }
}
/* reduced transparency: glass becomes a solid surface everywhere it is used */
@media (prefers-reduced-transparency: reduce) {
  :root:root:root { --glass: var(--panel); }
  .top, .side, .modal { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .top { background: linear-gradient(90deg, color-mix(in srgb, var(--club) 20%, var(--bg)), var(--panel) 60%); }
  .modal { background: color-mix(in srgb, var(--bg) 86%, transparent); }
  @media (max-width: 880px) { .side { background: var(--bg); } }
}
/* more contrast: secondary text and every line step up (each is mixed from the ink, so both themes follow), glass goes solid, the focus ring thickens */
@media (prefers-contrast: more) {
  :root:root { --line: color-mix(in srgb, var(--ink) 30%, var(--bg)); --line2: color-mix(in srgb, var(--ink) 48%, var(--bg)); --line3: color-mix(in srgb, var(--ink) 66%, var(--bg)); --mute: color-mix(in srgb, var(--ink) 82%, var(--bg)); --faint: color-mix(in srgb, var(--ink) 66%, var(--bg)); --glass: var(--panel); }   /* said twice, so it also outranks the day block */
  .top, .side { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .top { background: linear-gradient(90deg, color-mix(in srgb, var(--club) 20%, var(--bg)), var(--panel) 60%); }
  .panel, .tile, .btn, .hero { border-color: var(--line2); }
  :focus-visible { outline-width: 3px; }
}
/* forced colours (Windows contrast themes): backgrounds are dropped, so a selection is drawn with the system highlight and every floating layer gets a real edge */
@media (forced-colors: active) {
  .glide { display: none; }
  .side > button.on, .tabs button.on, .seg button.on, table.t tr.me td, table.t tr.sel td { background: Highlight; color: HighlightText; forced-color-adjust: none; }
  .side > button.on .ic { color: inherit; }
  .side .badge { border: 1px solid CanvasText; }
  .crest, .chip, .ovr.e { forced-color-adjust: none; }
  .meter { border: 1px solid CanvasText; }
  .meter > i, .sh-gauge-f { background: Highlight; forced-color-adjust: none; }
  .sh-gauge-b { border: 1px solid CanvasText; } .sh-gauge-t { background: CanvasText; }
  .toast, .ds-tip, .modal > div { border-color: CanvasText; }
  .sh-neg-kit::before, .sh-neg-kit::after { display: none; }
  .btn:disabled, .side > button:disabled { color: GrayText; opacity: 1; }
  .btn.bad { border-color: CanvasText; }
  .tabs[data-more]::before, .tabs[data-more]::after { display: none; }
}

/* guernsey drawing (kit.js) */
.kit { display: block; flex: none; height: auto; }

/* theme: light (day game, the default) and dark (night game). Inside a career the control is the Appearance panel in Save & Options. */
/* The title screen keeps a small switch in its corner: two cells, sun and moon; the accent block sits on the active one. */
.th-sw, .side .th-sw { display: inline-flex; flex-direction: row; align-items: center; gap: 10px; width: auto; min-width: 40px; min-height: 40px; margin: 0; padding: 3px; background: none; border: 0; border-radius: 10px; color: var(--mute); cursor: pointer; font-family: var(--f-cond); font-size: var(--fs-label); font-weight: 600; letter-spacing: .12em; line-height: 1; text-transform: uppercase; text-align: left; white-space: nowrap; transform: none; }
.th-sw:hover, .side .th-sw:hover { background: none; color: var(--ink); }
.th-sw:hover .th-track { border-color: var(--mute); }
.th-sw:focus-visible, .side .th-sw:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.th-track { position: relative; display: grid; grid-template-columns: 1fr 1fr; flex: none; width: 68px; height: 32px; background: var(--panel2); border: 1px solid var(--line2); border-radius: 10px; overflow: hidden; }
.th-thumb { position: absolute; top: 2px; bottom: 2px; left: 2px; width: calc(50% - 2px); border-radius: 7px; background: var(--accent); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25); }
.th-sw[data-mode="dark"] .th-thumb { transform: translateX(100%); }
.th-sw:active .th-thumb { filter: brightness(.92); }
.th-ic { position: relative; display: grid; place-items: center; color: var(--mute); }
.th-ic svg { display: block; width: 16px; height: 16px; }
.th-sw[data-mode="light"] .th-sun, .th-sw[data-mode="dark"] .th-moon { color: var(--accent-ink); }
.th-say { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Save & Options: Appearance. The shared .seg does the work; the two marks sit before the words. */
.th-seg button { display: inline-flex; align-items: center; gap: 7px; }
.th-seg svg { flex: none; width: 15px; height: 15px; }
.th-opt .fr-set { position: relative; }
.th-opt .fr-set > div:first-child { flex: 1 1 240px; min-width: 0; }

/* startup screen only (the club picker carries no switch: a preference is not a step in choosing a club). Bottom left corner on a wide
   window, with its word; top right on a phone, so the bottom edge belongs to the menu. Fixed, so it is never a row of the .title grid.
   It sits on the page itself, so it needs no glass behind it. */
.th-float { position: fixed; left: calc(12px + env(safe-area-inset-left, 0px)); bottom: calc(10px + env(safe-area-inset-bottom, 0px)); z-index: 5; display: flex; align-items: center; }
.title:has(> .th-float) { padding-bottom: calc(60px + env(safe-area-inset-bottom, 0px)); }
@media (max-width: 560px) {
  .th-float { left: auto; bottom: auto; right: calc(10px + env(safe-area-inset-right, 0px)); top: calc(10px + env(safe-area-inset-top, 0px)); }
  .th-float .th-word { display: none; }
  .title:has(> .th-float) { padding-bottom: calc(40px + env(safe-area-inset-bottom, 0px)); }
}

/* motion: the block slides, and for a quarter of a second after a switch the colours fade. Nothing at all under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .th-thumb { transition: transform .32s var(--spring); }
  .th-fade, .th-fade *, .th-fade *::before, .th-fade *::after { transition: background-color .2s ease, border-color .2s ease, color .2s ease, fill .2s ease, stroke .2s ease, outline-color .2s ease !important; }
  .th-fade .th-thumb { transition: transform .32s var(--spring), background-color .2s ease !important; }
}

/* Short screens (a phone on its side): a fixed corner switch would sit on top of the New career button, so it joins the page
   flow under the content instead. */
@media (max-height: 520px) {
  .title > .th-float { position: static; justify-self: start; margin-top: 14px; right: auto; top: auto; }
  .title:has(> .th-float) { padding-bottom: 24px; }
}
@media (forced-colors: active) {
  .th-track { border-color: CanvasText; }
  .th-thumb { background: Highlight; forced-color-adjust: none; }
  .th-sw[data-mode="light"] .th-sun, .th-sw[data-mode="dark"] .th-moon { color: HighlightText; forced-color-adjust: none; }
}

/* the sun and the moon are the icon family's, a touch heavier at this size */
.th-ic svg.ic, .th-seg svg.ic { stroke-width: 2.2; }

/* board: the title screen's hero, a coach's magnet board in the game's own drawing language (see board.js) */
.title { position: relative; z-index: 0; }
.bd { -webkit-user-select: none; user-select: none; }
/* --bd-x0 is where the words end (the page's left padding plus the wordmark, which is 5.54 of its own units wide): the board is
   centred in what is left of the window and never runs off the edge */
.bd-title { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; --bd-x0: calc(clamp(16px, calc(7vw / var(--ui-z, 1)), 128px) + var(--fr-u, 100px) * 5.54); --bd-w: min(calc(70vh / var(--ui-z, 1)), calc(100vw / var(--ui-z, 1)) - var(--bd-x0) - calc(5vw / var(--ui-z, 1))); }
.bd-board { position: absolute; top: 50%; left: calc((var(--bd-x0) + calc(100vw / var(--ui-z, 1))) / 2); width: var(--bd-w); aspect-ratio: 153 / 191; translate: -50% -50%; }
/* the light on the ground: the same floodlight glow the pages carry, pooled behind the board */
.bd-board::before { content: ''; position: absolute; inset: -14% -20%; z-index: -1; pointer-events: none; background: radial-gradient(closest-side, var(--glow), transparent 74%); }
.bd-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.bd-apron { fill: color-mix(in srgb, var(--turf2) 52%, var(--bg)); stroke: var(--line2); stroke-width: .35; }
.bd-turf { fill: var(--turf); } .bd-band { fill: var(--turf2); }
.bd-lit0 { stop-color: var(--chalk); stop-opacity: .14; } .bd-lit1 { stop-color: var(--chalk); stop-opacity: 0; }
.bd-chalk > * { fill: none; stroke: var(--chalk); stroke-width: .55; opacity: .86; }
.bd-edge { fill: none; stroke: var(--chalk); stroke-width: .95; }
.bd-post { fill: var(--chalk); stroke: color-mix(in srgb, var(--turf2) 45%, var(--bg)); stroke-width: .35; }
/* the marker: a kick is a solid line, a handball a dashed one, as in the live match */
.bd-ln { fill: none; stroke: var(--accent); stroke-width: 1.15; stroke-linecap: round; }
.bd-hb .bd-ln { stroke-dasharray: 2.3 2.7; }
.bd-hd { fill: var(--accent); stroke: var(--accent); stroke-width: .5; stroke-linejoin: round; }
/* magnets: the home side wears the accent (or the saved career's club), the visitors the ink of the theme */
.bd-m { pointer-events: auto; cursor: grab; touch-action: none; }
.bd-mi { transform-box: fill-box; transform-origin: center; transition: transform var(--t-fast); filter: drop-shadow(0 .7px .65px rgba(0, 0, 0, .4)); }
.bd-ring { fill: var(--chalk); }
.bd-h .bd-fill { fill: var(--accent); } .bd-h .bd-n { fill: var(--accent-ink); }
.bd-a .bd-ring { fill: var(--bg); } .bd-a .bd-fill { fill: var(--ink); } .bd-a .bd-n { fill: var(--bg); }
.bd-club .bd-h .bd-ring { fill: var(--club2); } .bd-club .bd-h .bd-fill { fill: var(--club); } .bd-club .bd-h .bd-n { fill: var(--club-ink); }
.bd-n { font-family: var(--f-cond); font-weight: 700; font-size: 3.7px; text-anchor: middle; dominant-baseline: central; pointer-events: none; font-variant-numeric: tabular-nums; }
.bd-held { cursor: grabbing; } .bd-held .bd-mi { transform: scale(1.16); }
@media (hover: hover) { .bd-m:hover .bd-mi { transform: scale(1.08); } .bd-held:hover .bd-mi { transform: scale(1.16); } }
.bd-ball ellipse { fill: var(--ball); stroke: color-mix(in srgb, var(--ball) 52%, #000); stroke-width: .38; }
.bd-bi { transform-box: fill-box; transform-origin: center; filter: drop-shadow(0 .8px .7px rgba(0, 0, 0, .4)); }
/* arrival, once: the board comes up, the magnets are placed back line to forward line, the play is drawn on, the ball lands */
@keyframes bd-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes bd-place { from { opacity: 0; transform: translateY(-5px) scale(1.5); } to { opacity: 1; transform: none; } }
@keyframes bd-show { from { opacity: 0; } to { opacity: 1; } }
@keyframes bd-pop { from { opacity: 0; transform: scale(.2); } to { opacity: 1; transform: none; } }
.bd-in .bd-svg { animation: bd-rise 520ms var(--ease-out) backwards; animation-delay: var(--bd-e, 0ms); }
.bd-in .bd-mi { animation: bd-place 420ms var(--spring-pop) backwards; animation-delay: calc(var(--bd-e, 0ms) + 320ms + var(--i) * 24ms); }
.bd-in .bd-play { animation: bd-show 260ms ease backwards; animation-delay: calc(var(--bd-e, 0ms) + 1400ms + var(--i) * 170ms); }
.bd-in .bd-bi { animation: bd-pop 420ms var(--spring-pop) backwards; animation-delay: calc(var(--bd-e, 0ms) + 2300ms); }
/* a window that is wider than it is tall but short of room beside the words: the board sits behind them, washed back, and is not for dragging */
@media (min-width: 561px) and (max-width: 980px) and (orientation: landscape), (min-width: 561px) and (max-aspect-ratio: 5 / 4) and (orientation: landscape) {
  .bd-title { --bd-w: min(calc(62vw / var(--ui-z, 1)), calc(78vh / var(--ui-z, 1))); }
  .bd-board { left: auto; right: -calc(12vw / var(--ui-z, 1)); translate: 0 -50%; }
  .bd-title::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(90deg, var(--bg) 0, color-mix(in srgb, var(--bg) 84%, transparent) 44%, color-mix(in srgb, var(--bg) 46%, transparent) 100%); }
  .bd-m { pointer-events: none; }
}
/* a phone, and any upright window (a tablet held upright): the attacking half of the board across the top, fading out behind the wordmark */
@media (max-width: 560px), (orientation: portrait) {
  .bd-title { --bd-w: min(calc(100vw / var(--ui-z, 1)), calc(62vh / var(--ui-z, 1))); }
  .bd-board { top: 0; left: 50%; translate: -50% 0; }
  /* --bd-band is the height of board the words leave clear (f_replays.js measures it): the strip is whole down to there and gone by the foot of the caption */
  .bd-title { --bd-band: var(--rp-band, calc(24vh / var(--ui-z, 1))); }
  /* the fade is a mask on this fixed layer, not a cover painted over it: Safari on an iPhone can put the arriving board above a cover
     until something moves, which showed the whole ground behind the words. A mask cannot be painted under. */
  .bd-title { -webkit-mask-image: linear-gradient(180deg, #000 0, #000 calc(var(--bd-band) - 40px), rgba(0, 0, 0, .38) calc(var(--bd-band) - 8px), transparent calc(var(--bd-band) + 46px)); mask-image: linear-gradient(180deg, #000 0, #000 calc(var(--bd-band) - 40px), rgba(0, 0, 0, .38) calc(var(--bd-band) - 8px), transparent calc(var(--bd-band) + 46px)); }
}

/* Credit on the startup screen: "made by nilrac", bottom right, very small.
   Fixed to the corner of the screen, mirroring the theme switch on the left. A faint backing in the page colour keeps it
   readable over the 3D scene in both themes without drawing an outline round the letters. */
.title { position: relative; }
.madeby { position: fixed; right: calc(12px + env(safe-area-inset-right, 0px)); bottom: calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 4; padding: 2px 7px; border-radius: var(--r-s); background: color-mix(in srgb, var(--bg) 88%, transparent); font: 500 var(--fs-micro)/14px var(--f-cond); letter-spacing: .16em; white-space: nowrap; color: var(--mute); pointer-events: none; }

/* A screen that is both narrow and short (a small phone on its side, a tiny window): the menu runs the full width and the page scrolls,
   so a credit pinned to the corner would sit on a button. It moves to the end of the page instead, bottom right, beside the theme switch
   (s_front.css gives the title two rows there: the content, then the switch). It takes no room of its own. */
@media (max-height: 520px) and (max-width: 560px) {
  .title > .madeby { position: absolute; grid-row: 2 / 3; grid-column: 1 / 2; right: 0; bottom: -17px; }
}

/* brand: the Magnet Board crest and the paint on the grass (see f_brand.js). The full colour crest is coloured here from the tokens:
   a turf shield edged in ink, a chalk magnet with its poles in the accent, the accent ball. The one-colour crest paints itself,
   and the mark is the one-colour crest with a red ball. */
.bx-crest, .bx-beer { display: block; flex: none; overflow: visible; }
.bx-full .bx-sh { fill: var(--turf); }
.bx-full .bx-ed { stroke: var(--ink); }
.bx-full .bx-bn { fill: var(--turf2); }
.bx-full .bx-kl { stroke: var(--chalk); opacity: .5; }
.bx-full .bx-mg { fill: var(--chalk); }
.bx-full .bx-tp, .bx-full .bx-bl { fill: var(--accent); }
.bx-full .bx-bl { stroke: color-mix(in srgb, var(--accent) 52%, #000); }
.bx-full .bx-lt, .bx-full .bx-lc { fill: var(--accent-ink); }
/* the small full colour crest: its poles are the two letters, in chalk like the magnet they stand on */
.bx-full.bx-sm .bx-tp { fill: var(--chalk); }
/* the words of the beer's lock-up */
.bx-wm { font-family: var(--f-display); font-weight: 900; }
.bx-ws { font-family: var(--f-cond); font-weight: 700; }

/* the mark: the painted look, one colour (ink: white at night, black by day) with the ball in red */
.bx-mark { color: var(--ink); }
.bx-mark .bx-bl { fill: var(--bad); }
/* at night the token is a soft red made for small type; the ball is a solid shape, so the same hue is taken deeper and fuller there */
@supports (color: oklch(from red l c h)) { .bx-mark .bx-bl { fill: oklch(from var(--bad) calc(l - .1) calc(c + .07) h); } }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .bx-mark .bx-bl { fill: var(--bad); } }
:root[data-theme="light"] .bx-mark .bx-bl { fill: var(--bad); }

/* the rail: the mark beside the wordmark, one control back to the startup screen. The .brand box keeps its size (style.css, f_tabs.css). */
.side .brand .bx-home { flex: none; display: flex; align-items: center; gap: 9px; min-height: 48px; margin: 0 -6px; padding: 4px 8px 4px 6px; background: none; border: 0; border-radius: var(--r-m);
  color: inherit; text-decoration: none; font: inherit; letter-spacing: inherit; text-transform: inherit; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: transform var(--t-fast) ease; }
.side .brand .bx-home .bx-crest { width: auto; height: 40px; }
.side .brand .bx-home:hover { text-decoration: none; }
@media (hover: hover) { .side .brand .bx-home:hover { background: var(--panel3); } }
.side .brand .bx-home:active { transform: scale(.97); }
.side .brand .bx-home:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* the title screen: the mark is seated on the lock-up (s_front.js puts it in the wordmark's own block, and css/s_front.css sizes it from the
   wordmark's unit), so it is tied to the name and never lies on the board, the caption or a button at any window size */
.bx-title { pointer-events: none; }

/* paint on the title board: chalk laid thin on the grass, under the lines, the marker and the magnets */
.bx-paint { color: var(--chalk); opacity: .18; pointer-events: none; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .bx-paint { opacity: .25; } }
:root[data-theme="light"] .bx-paint { opacity: .25; }
/* while a famous play is on the board the paint steps back to under half its strength, so the eye finds the ball, the kicker and the target */
.bd-title .bx-paint { transition: opacity var(--t-far) var(--ease-out); }
.bd.rp-on .bx-paint { opacity: .08; }
:root[data-theme="light"] .bd.rp-on .bx-paint { opacity: .1; }

/* Options: a strip of mown grass that shows the paint the switch controls */
.bx-strip { display: flex; align-items: center; justify-content: center; gap: clamp(28px, 12%, 72px); height: 76px; margin-bottom: 4px; border-radius: var(--r-m); color: var(--chalk);
  background: repeating-linear-gradient(90deg, var(--turf) 0 34px, var(--turf2) 34px 68px); }
.bx-strip > svg { opacity: .5; }
.bx-strip.bx-off > svg { display: none; }
.bx-strip + .fr-set { border-top: 0; }

/* ===== The icon family (prefix ic-) =====
   The drawings are in f_icons.js. What a drawing may not carry (the weight, the solid rule, the quiet half, how an icon sits beside words, the
   drawn stars and the sort mark) is in the base section of style.css since the seventh wave, so this sheet is nearly empty on purpose. */

/* a small icon after the words of a tab (the lock on Recruitment's Trades tab is 14px in 16px text): the base rule hangs a 1.25em icon;
   a smaller one hangs less, so its middle is still the middle of the capitals. It belongs beside the size rule in css/s_recruit.css. */
.rc-page .tabs button .ic { vertical-align: -1px; }

/* replays: famous passages of play run on the title screen's magnet board (see f_replays.js). Everything here is switched on by
   classes the player adds (rp-has, rp-on), so with no plays the title board is exactly the board. */
/* --rp-x0 is where the words end and --rp-w the board's width while the plate needs room under it (the same sum as board.css) */
.fr-title { --rp-x0: calc(clamp(16px, calc(7vw / var(--ui-z, 1)), 128px) + var(--fr-u, 100px) * 5.54); --rp-w: min(calc(62vh / var(--ui-z, 1)), calc(100vw / var(--ui-z, 1)) - var(--rp-x0) - calc(5vw / var(--ui-z, 1))); --rp-cy: calc(44.5vh / var(--ui-z, 1)); }
.fr-title:has(.rp-quiet) { --rp-w: min(calc(48vh / var(--ui-z, 1)), calc(100vw / var(--ui-z, 1)) - var(--rp-x0) - calc(5vw / var(--ui-z, 1))); --rp-cy: calc(34vh / var(--ui-z, 1)); }   /* a still diagram shares the height with its numbered steps */

/* ---------- on the board ---------- */
/* the two sides wear the clubs of the play; the board's own numbers are put away, because only the data's numbers may show */
.bd.rp-on .bd-h .bd-ring { fill: var(--rp-a2); } .bd.rp-on .bd-h .bd-fill { fill: var(--rp-a1); }
.bd.rp-on .bd-a .bd-ring { fill: var(--rp-d2); } .bd.rp-on .bd-a .bd-fill { fill: var(--rp-d1); }
.bd.rp-on .bd-n { opacity: 0; }
.bd.rp-on .rp-anon .bd-mi { transform: scale(.68); opacity: .56; }   /* everyone the data does not name: small, pale, no number */
.bd.rp-on .rp-named .bd-mi { transform: scale(1.12); }
.bd.rp-on .bd-held .bd-mi { transform: scale(1.2); opacity: 1; } .bd.rp-on .rp-anon.bd-held .bd-mi { transform: scale(.82); }
.rp-num { font-family: var(--f-cond); font-weight: 700; font-size: 3.7px; text-anchor: middle; dominant-baseline: central; pointer-events: none; font-variant-numeric: tabular-nums; }
.bd-h .rp-num { fill: var(--rp-ai); } .bd-a .rp-num { fill: var(--rp-di); }
.rp-lab { pointer-events: none; } .rp-lab rect { fill: var(--bg); opacity: .84; }
.rp-lab text { fill: var(--ink); font-family: var(--f-cond); font-weight: 700; font-size: 3.1px; letter-spacing: .04em; text-anchor: middle; dominant-baseline: central; }
/* the board's own marker play and resting ball make way while a play is on, and until the magnets are home again */
.bd-title.rp-has .bd-plays, .bd-title.rp-has .bd-ball { transition: opacity 300ms ease; }
.bd.rp-on .bd-plays, .bd.rp-on .bd-ball, .bd-title.rp-back .bd-plays, .bd-title.rp-back .bd-ball { opacity: 0; transition: none; }
.rp-under, .rp-over { pointer-events: none; }
/* the live match's marks: a ring where a kick will land, a ring where a mark is taken, the path of each kick (solid) and handball (dashed),
   the man with the ball ringed in the ball's colour, the ball with its shadow on the grass, one ring from the goal mouth for a goal */
.rp-land, .rp-ring { fill: none; stroke: var(--chalk); stroke-width: .55; } .rp-ring { stroke-width: .8; }
.rp-g1 { fill: none; stroke: var(--rp-a1, var(--accent)); stroke-width: 1.3; } .rp-g2 { fill: none; stroke: var(--chalk); stroke-width: .6; }
.rp-car { fill: none; stroke: var(--ball); stroke-width: .85; }
.rp-tr { fill: none; stroke: var(--chalk); stroke-width: .8; stroke-linecap: round; stroke-linejoin: round; } .rp-hb { stroke-width: .62; stroke-dasharray: 1.4 1.4; }
.rp-trs { fill: none; stroke: #000; stroke-width: .5; stroke-linecap: round; } .rp-sh { fill: #000; }
.rp-ball ellipse { fill: var(--ball); stroke: color-mix(in srgb, var(--ball) 52%, #000); stroke-width: .38; }
/* the still diagram: the board's marker lines, a run dotted, each move numbered */
.rp-dia .bd-run .bd-ln { stroke-dasharray: .1 2.3; stroke-width: 1.3; }
.rp-no circle { fill: var(--accent); stroke: var(--turf2); stroke-width: .3; } .rp-no text { fill: var(--accent-ink); font-family: var(--f-cond); font-weight: 700; font-size: 2.9px; text-anchor: middle; dominant-baseline: central; }

/* ---------- the plate: caption, what is on, the controls, the note ---------- */
.rp-plate { display: grid; gap: 6px; min-width: 0; text-align: left; }
.rp-say { min-height: 2.6em; font: 500 var(--fs-ui)/1.3 var(--f-body); color: var(--ink); text-wrap: pretty; }
.rp-dim { color: var(--mute); }
.rp-res { display: inline-block; margin-right: 8px; padding: 1px 8px 3px; border-radius: var(--r-s); background: var(--club); color: var(--club-ink); box-shadow: inset 0 -2px 0 var(--club2), inset 0 0 0 1px rgba(255, 255, 255, .13); font: 800 var(--fs-body)/1.15 var(--f-display); letter-spacing: .05em; text-transform: uppercase; vertical-align: 1px; }
.rp-bar { display: flex; align-items: center; gap: 12px; min-width: 0; }
.rp-now { flex: 1 1 auto; min-width: 0; display: grid; gap: 3px; }
.rp-now b { font: 800 var(--fs-d6)/1.02 var(--f-display); letter-spacing: .01em; text-transform: uppercase; color: var(--ink); text-wrap: balance; }
.rp-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
.rp-mt { font: 600 var(--fs-label)/1.3 var(--f-cond); letter-spacing: .12em; text-transform: uppercase; color: var(--mute); }
.rp-chips { display: inline-flex; align-items: center; gap: 5px; } .rp-chips i, .rp-vs i { font: 600 var(--fs-label)/1 var(--f-cond); font-style: normal; letter-spacing: .1em; text-transform: uppercase; color: var(--mute); }
.rp-chips .chip { min-width: 36px; height: 19px; padding: 0 5px 2px; font-size: var(--fs-label); box-shadow: inset 0 -2px 0 var(--e, currentColor), inset 0 0 0 1px rgba(255, 255, 255, .13); }
.rp-ctl { display: flex; align-items: center; gap: 4px; flex: none; }
.rp-b { display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 1px solid var(--line2); border-radius: var(--r-m); background: transparent; color: var(--ink); cursor: pointer; transition: transform var(--t-fast); }
.rp-b .ic { width: 16px; height: 16px; } .rp-b:active { transform: scale(.94); }
@media (hover: hover) { .rp-b:hover { background: var(--panel3); } }
.rp-count { min-width: 46px; margin-left: 6px; text-align: right; font: 600 var(--fs-small)/1 var(--f-cond); letter-spacing: .08em; text-transform: uppercase; color: var(--mute); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rp-kind { padding: 1px 6px 2px; border-radius: var(--r-s); border: 1px solid var(--line2); font: 700 var(--fs-label)/1.3 var(--f-cond); letter-spacing: .1em; text-transform: uppercase; color: var(--mute); white-space: nowrap; }
.rp-kind.rp-own { border-color: transparent; background: var(--accent); color: var(--accent-ink); }   /* a moment from the save's own career, never to be taken for a real one */
/* reduced motion: the steps are a numbered list beside the still diagram, and there is nothing to pause */
.rp-quiet .rp-say { font-size: var(--fs-data); line-height: 1.5; max-height: calc(27vh / var(--ui-z, 1)); overflow-y: auto; }
.rp-quiet .rp-dim, .rp-aft { display: block; } .rp-aft { margin-top: 3px; }
.rp-steps { margin: 3px 0; padding: 0; list-style: none; } .rp-steps li { display: inline; margin-right: 9px; }
.rp-steps i { display: inline-grid; place-items: center; width: 17px; height: 17px; margin-right: 5px; border-radius: 50%; background: var(--accent); color: var(--accent-ink); font: 700 var(--fs-micro)/1 var(--f-cond); font-style: normal; vertical-align: 1px; }
.rp-quiet #rp-tog { display: none; }

/* ---------- the title card: the name of the moment, the match, the two clubs in their colours ---------- */
.rp-card { position: fixed; z-index: 2; pointer-events: none; opacity: 0; transform: translateY(8px) scale(.96); transition: opacity 240ms ease, transform var(--t-move) var(--ease-out); }
.rp-card.rp-show { opacity: 1; transform: none; transition: opacity 160ms ease, transform var(--t-pop) var(--spring-pop); }
.rp-card-in { display: grid; gap: 9px; justify-items: start; padding: 16px 18px 18px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--e2); }
.rp-title { font: 900 var(--fs-d4)/.94 var(--f-display); letter-spacing: -.005em; text-transform: uppercase; color: var(--ink); text-wrap: balance; }
.rp-vs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 7px; }
.rp-club { padding: 3px 9px 6px; border-radius: var(--r-s); background: var(--club); color: var(--club-ink); box-shadow: inset 0 -3px 0 var(--club2), inset 0 0 0 1px rgba(255, 255, 255, .13); font: 700 var(--fs-ui-s)/1.1 var(--f-cond); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }

/* ---------- a wide window: the board gives up a little height and the plate sits under it ---------- */
@media (min-width: 981px) and (min-aspect-ratio: 5001 / 4000) {
  .bd-title.rp-has { --bd-w: var(--rp-w); }
  .bd-title.rp-has .bd-board { top: var(--rp-cy); }
  .title > .rp-plate { position: fixed; z-index: 1; left: calc((var(--rp-x0) + calc(100vw / var(--ui-z, 1))) / 2); top: calc(var(--rp-cy) + var(--rp-w) * 191 / 306 - 12px); width: max(var(--rp-w), 380px); translate: -50% 0; }
  .title > .rp-plate .rp-bar { order: -1; }   /* what is on and its controls first, so a long caption never moves a button */
  .rp-card { left: calc((var(--rp-x0) + calc(100vw / var(--ui-z, 1))) / 2); top: var(--rp-cy); width: min(var(--rp-w) * .8, 420px); translate: -50% -50%; }
  @media (max-height: 660px) { .rp-say { min-height: 1.3em; } }   /* a short window: the caption keeps one line in reserve, not two */
}
/* ---------- a wide window short of room: the board is washed back behind the words and stays as it is ---------- */
@media (min-width: 561px) and (max-width: 980px) and (orientation: landscape), (min-width: 561px) and (max-aspect-ratio: 5 / 4) and (orientation: landscape) { .rp-plate, .rp-card { display: none; } }
/* ---------- a phone or an upright window: the strip of board across the top follows the ball, and the plate is one caption band on its bottom edge ---------- */
@media (max-width: 560px), (orientation: portrait) {
  .bd-title.rp-has .bd-board { transform-origin: 50% 0; transform: translateY(var(--rp-ty, 0px)) scale(var(--rp-k, 1)); }
  .title > .rp-plate { display: none; }   /* it is moved into the column as soon as it is drawn */
  /* the caption: the play's name with its match under it, and one pause button. The rotation moves by itself, so previous, next and the count stay off a phone. */
  .rp-plate { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name ctl" "meta ctl"; align-items: center; gap: 1px 10px; min-height: 48px; margin: 0 -16px 10px; padding: 4px 12px 4px 16px; background: color-mix(in srgb, var(--bg) 92%, transparent); }
  .rp-plate.rp-none { display: none; }   /* a short phone: no room above the wordmark to show a play */
  .rp-bar, .rp-now { display: contents; }
  .rp-now b { grid-area: name; align-self: end; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-wrap: nowrap; font: 700 var(--fs-body)/1.2 var(--f-cond); letter-spacing: .04em; }
  .rp-meta { grid-area: meta; align-self: start; flex-wrap: nowrap; gap: 0 7px; min-width: 0; overflow: hidden; } .rp-mt { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-label); line-height: 1.3; }
  .rp-kind { flex: none; font-size: var(--fs-micro); line-height: 1.2; }
  .rp-chips { display: none; } .rp-quiet .rp-chips { display: inline-flex; }   /* the still diagram has no title card, so its clubs show here */
  .rp-say { display: none; }
  .rp-ctl { grid-area: ctl; } .rp-ctl [data-a="rpprev"], .rp-ctl [data-a="rpnext"], .rp-count { display: none; }
  /* reduced motion: the numbered steps of the still diagram are the caption, so they keep a short scrolling block under the name */
  .rp-plate.rp-quiet { grid-template-areas: "name ctl" "meta ctl" "say say"; } .rp-quiet .rp-say { display: block; grid-area: say; max-height: 72px; }
  .rp-quiet .rp-ctl [data-a="rpprev"], .rp-quiet .rp-ctl [data-a="rpnext"] { display: grid; }   /* nothing moves by itself there, so these two are the only way to a play */
  .rp-card { left: 16px; right: 16px; top: 58px; } .rp-card-in { gap: 7px; padding: 12px 14px 14px; } .rp-title { font-size: var(--fs-d5); }
}

/* an upright window wider than a phone: the caption keeps to the column (no bleed to a phone's edge) and the title card is centred on the board */
@media (min-width: 561px) and (orientation: portrait) {
  .rp-plate { max-width: 600px; margin: 0 0 var(--s3); padding: var(--s1) 0; background: none; }   /* as wide as the column under it, so the pause button sits over the menu's right edge */
  .rp-chips { display: inline-flex; }
  .rp-card { left: 50%; right: auto; top: calc(12vh / var(--ui-z, 1)); width: min(420px, calc(80vw / var(--ui-z, 1))); translate: -50% 0; } .rp-title { font-size: var(--fs-d4); }
}

/* ---------- the player on a mount (rpMount): a small board in the page with its plate under it ---------- */
.rp-stage { display: grid; gap: 10px; min-width: 0; }
.rp-stage .rp-bd { position: relative; width: min(100%, calc(46vh / var(--ui-z, 1)), 420px); margin: 0 auto; }
.rp-stage .bd-board { position: relative; top: auto; left: auto; width: 100%; translate: none; transform: none; }
.rp-stage .bd-board::before { content: none; }
.rp-stage .bd-m { pointer-events: none; cursor: default; }
.rp-stage .rp-plate { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: none; gap: 6px; margin: 0; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
.rp-stage .rp-bar { display: flex; } .rp-stage .rp-now { display: grid; grid-area: auto; white-space: normal; overflow: visible; }
.rp-stage .rp-now b, .rp-stage .rp-meta { grid-area: auto; }
.rp-stage .rp-now b { font: 800 var(--fs-title)/1.04 var(--f-display); letter-spacing: .01em; white-space: normal; text-wrap: balance; overflow: visible; }
.rp-stage .rp-meta { flex-wrap: wrap; overflow: visible; } .rp-stage .rp-chips { display: inline-flex; }
.rp-stage .rp-say { grid-area: auto; min-height: 3.9em; font-size: var(--fs-body); line-height: 1.3; }
.rp-stage .rp-b { width: 40px; height: 40px; }
.rp-stage .rp-quiet .rp-say, .rp-stage .rp-plate.rp-quiet .rp-say { max-height: none; }

/* Interface size (f_scale.js). The factor is set on the root as CSS zoom and as --ui-z; a length in viewport units is divided by it at
   build time (build.js), so "calc(100vh / var(--ui-z, 1))" still means the whole window when the interface is drawn smaller. */
:root { --ui-z: 1; }
.sz-seg button { min-width: 52px; }
@media (max-width: 880px) { .sz-opt { display: none; } }

/* Title, new career, Save & Options, Sacked. New classes are prefixed fr-. */

/* ---------- the title frame: a scrolling grid that centres .box (both steps) ---------- */
.title { display: grid; place-items: center; padding-block: 24px; padding-inline: 16px; overflow: auto; height: 100%; background: var(--bg); }
.title .box { width: min(980px, 100%); }

.fr-seg button { min-height: var(--ctl); padding-inline: 13px; }

/* ---------- step 0: the lock-up and the menu, set against the 3D scene ---------- */
/* --fr-u is the size of the wordmark. Everything in the lock-up is cut from it, so the whole mark scales as one piece. */
.fr-title { --fr-u: clamp(54px, min(calc(9.1vw / var(--ui-z, 1)), calc(16.5vh / var(--ui-z, 1))), 164px); }   /* a wide window lets the lock-up grow, so the left half carries its share */
.fr-s0 { justify-items: start; padding-inline: clamp(16px, calc(7vw / var(--ui-z, 1)), 128px) 16px; }
.title .fr-box { width: fit-content; min-width: min(100%, 336px); max-width: 100%; }
.fr-lock { display: grid; width: max-content; max-width: 100%; overflow-x: clip; }
.fr-mark { margin: 0; font-size: var(--fr-u); font-weight: 900; line-height: .84; letter-spacing: -.012em; text-transform: uppercase; white-space: nowrap; }
.fr-mark em { font-style: normal; color: var(--accent); }
.fr-mk, .fr-mw > * { display: inline-block; }
.fr-mw { display: block; }
/* the crest is seated on the lock-up: the first row of the mark, lined up with the left edge of the M, and cut from the same unit as the letters */
.fr-mark .bx-title { display: block; margin-bottom: .15em; line-height: 0; }
.fr-mark .bx-title .bx-crest { width: auto; height: .56em; }
/* the line that says what this is: one readable caps line, then a rule out to the right edge of the wordmark */
.fr-tag { display: flex; align-items: center; gap: 14px; min-width: 0; margin-top: calc(var(--fr-u) * .1); font-family: var(--f-cond); font-weight: 600; font-size: clamp(13px, calc(var(--fr-u) * .125), 17px); letter-spacing: .2em; line-height: 1; text-transform: uppercase; white-space: nowrap; color: var(--ink); }
.fr-tag::after { content: ''; flex: 1; min-width: 10px; height: 2px; background: var(--ink); }
/* everything under the lock-up shares one column: as wide as the wordmark up to 600px (a readable measure and a sensible button), and it never sets the box's width */
.fr-hook, .fr-copy, .fr-menu, .fr-cloud, .pt-links, .pt-sure, .fr-box > .sv-title { width: 0; min-width: min(100%, max(600px, calc(var(--fr-u) * 4.4))); }   /* and wider with the wordmark on a very wide window, so the offer keeps its share of the lock-up */
/* the hook: the one line a stranger reads after the name */
.fr-hook { margin: clamp(14px, calc(2.4vh / var(--ui-z, 1)), 24px) 0 0; font-family: var(--f-display); font-weight: 800; font-size: clamp(22px, calc(var(--fr-u) * .26), 42px); line-height: 1; letter-spacing: .005em; text-transform: uppercase; text-wrap: balance; color: var(--ink); }
.fr-copy { margin: 8px 0 0; font-size: var(--fs-ui); line-height: 1.5; text-wrap: pretty; color: color-mix(in srgb, var(--ink) 90%, transparent); }
.fr-menu { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-top: clamp(16px, calc(2.6vh / var(--ui-z, 1)), 26px); }
.fr-row { display: flex; gap: 10px; }
.fr-row .btn { flex: 1 1 0; min-width: 0; min-height: 46px; padding-inline: 12px; font-size: var(--fs-ui); }
.fr-row .fr-new { flex: 1.5 1 0; min-height: 52px; font-size: var(--fs-title); }
.fr-btn .ic { color: var(--mute); }
.fr-cloud { margin: 6px 0 0; font-size: var(--fs-small); line-height: 20px; } .fr-cloud:empty { display: none; }
/* under the menu: the quiet links (the walkthrough, a career file), then one line that answers what a stranger asks before pressing */
.pt-links { display: flex; flex-wrap: wrap; align-items: center; gap: 0 4px; margin: 4px 0 0 -9px; } .pt-links:empty { display: none; }
.pt-links .btn { min-height: var(--hit); padding-inline: 9px; font-size: var(--fs-body); color: var(--mute); }
.pt-links .btn .ic { width: 16px; height: 16px; color: inherit; }
@media (hover: hover) { .pt-links .btn:hover { color: var(--ink); } }
.pt-sure { margin: 4px 0 0; font-size: var(--fs-small); line-height: 1.4; color: var(--mute); }

/* Resume: the saved career as the hero of the menu. A block in the club's colour carries the guernsey, the rest reads on the page surface. */
.fr-resume { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: stretch; width: 100%; min-height: 86px; padding: 0; overflow: hidden; text-align: left; cursor: pointer; color: var(--ink); border: 1px solid color-mix(in srgb, var(--club2) 22%, var(--line2)); border-radius: var(--r-l); background-color: var(--panel); background-image: linear-gradient(100deg, color-mix(in srgb, var(--club) 24%, var(--panel)), var(--panel) 72%); box-shadow: var(--e2); transition: transform var(--t-fast) ease, border-color var(--t-fast) ease; }
.fr-resume:active { transform: scale(.985); }
.fr-resume-kit { position: relative; display: grid; place-items: center; width: 92px; overflow: hidden; }
/* club-coloured blocks: pinstripes in the second colour, and a soft pool of it behind the guernsey so a navy strip still reads on a navy block */
.fr-resume-kit::before, .fr-feat-ban::before, .fr-offer-ban::before, .fr-save-id::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle at var(--fr-gx, 50%) var(--fr-gy, 50%), color-mix(in srgb, var(--club2) 36%, transparent) 0, transparent var(--fr-gr, 56px)), repeating-linear-gradient(118deg, transparent 0 20px, color-mix(in srgb, var(--club2) 15%, transparent) 20px 22px); }
.fr-feat-ban { --fr-gx: calc(100% - 78px); --fr-gy: 54%; --fr-gr: 128px; } .fr-offer-ban { --fr-gr: 72px; } .fr-save-id { --fr-gx: 62px; --fr-gr: 104px; }
.fr-resume-kit .kit { position: relative; filter: drop-shadow(0 6px 8px rgba(0, 0, 0, .35)); }
.fr-resume-tx { display: grid; align-content: center; gap: 3px; min-width: 0; padding: 12px 14px 13px 16px; }
.fr-resume-tx b { font-family: var(--f-display); font-weight: 900; font-size: clamp(25px, calc(var(--fr-u) * .19), 34px); line-height: .98; letter-spacing: 0; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-plain .fr-resume-tx b { font-family: var(--f-cond); font-weight: 700; font-size: var(--fs-title); text-transform: none; white-space: normal; }
.fr-resume-meta, .fr-save-meta { display: flex; flex-wrap: wrap; gap: 0 9px; font-family: var(--f-cond); font-size: var(--fs-ui-s); font-weight: 600; letter-spacing: .07em; line-height: 1.25; text-transform: uppercase; }
.fr-resume-meta { color: var(--mute); }
.fr-resume-meta span:not(:last-child)::after, .fr-save-meta span:not(:last-child)::after { content: '\00b7'; margin-left: 9px; opacity: .6; }
.fr-resume-go { display: grid; place-items: center; width: 62px; background: var(--accent); color: var(--accent-ink); }
.fr-resume-go .ic { width: 26px; height: 26px; stroke-width: 2.4; transition: transform var(--t-move) var(--ease-out); }
@media (hover: hover) {
  .fr-resume:hover { border-color: var(--mute); }
  .fr-resume:hover .fr-resume-go .ic { transform: translateX(3px); }
}

/* arrival: once per page load (scTitle decides). Waiting for the font holds the pieces back; then the words rise onto their bars,
   the bars draw, the tagline is set letter by letter and the menu comes up. Nothing that can be pressed is ever moved or resized by
   this (buttons fade, only their contents slide), so a button is where it will be from the first frame and can be pressed at once. */
@keyframes fr-hold { from, to { opacity: 0; } }
@keyframes fr-up { from { transform: translateY(106%); } }
@keyframes fr-draw { from { transform: scaleX(0); } }
@keyframes fr-show { from { opacity: 0; } }
@keyframes fr-slide { from { opacity: 0; transform: translateX(-10px); } }
.fr-wait .fr-mw > *, .fr-wait .fr-mk::after, .fr-wait .bx-title, .fr-wait .fr-tag, .fr-wait .fr-hook, .fr-wait .fr-copy, .fr-wait .fr-a, .fr-wait .fr-cloud { animation: fr-hold 1000ms linear; animation-delay: var(--fr-e, 0ms); }
.fr-arrive .fr-mw { clip-path: inset(-40% -8% 0 -8%); }
.fr-arrive .bx-title { animation: fr-show 320ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 60ms); }
.fr-arrive .fr-mw > * { animation: fr-up 640ms var(--ease-out) both; animation-delay: calc(var(--fr-e, 0ms) + 60ms); }
.fr-arrive .fr-mk2 .fr-mw > * { animation-duration: 700ms; animation-timing-function: var(--spring-pop); animation-delay: calc(var(--fr-e, 0ms) + 200ms); }
.fr-arrive .fr-mk::after { animation: fr-draw 520ms var(--ease-out) both; animation-delay: calc(var(--fr-e, 0ms) + 360ms); }
.fr-arrive .fr-mk2::after { animation-delay: calc(var(--fr-e, 0ms) + 500ms); }
.fr-arrive .fr-tag { animation: fr-show 320ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 600ms); }
.fr-arrive .fr-hook { animation: fr-show 420ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 720ms); }
.fr-arrive .fr-copy { animation: fr-show 420ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 800ms); }
.fr-arrive .fr-a { animation: fr-show 360ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 940ms + var(--a, 0) * 90ms); }
.fr-arrive .fr-a .fr-resume-tx, .fr-arrive .fr-a .btn > * { animation: fr-slide 560ms var(--ease-out) both; animation-delay: calc(var(--fr-e, 0ms) + 940ms + var(--a, 0) * 90ms); }
.fr-arrive .fr-cloud { animation: fr-show 300ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 1200ms); }
/* coming back from the club picker: one short fade */
.fr-s0.fr-step .fr-lock, .fr-s0.fr-step .fr-hook, .fr-s0.fr-step .fr-copy, .fr-s0.fr-step .fr-menu, .fr-s0.fr-step .pt-links, .fr-s0.fr-step .pt-sure { animation: fr-show 280ms ease both; animation-delay: var(--fr-e, 0ms); }

/* a very wide and tall window (the wordmark is at its largest): the pitch, the main button and the quiet lines step up one size with it */
@media (min-width: 1700px) and (min-height: 940px) {
  .fr-copy { font-size: var(--fs-title); }
  .fr-row .fr-new { min-height: 60px; font-size: var(--fs-d6); }
  .pt-links .btn { font-size: var(--fs-ui); } .pt-sure { font-size: var(--fs-data); }
}
@media (max-width: 560px) {
  .fr-title { --fr-u: clamp(56px, min(calc(30vw / var(--ui-z, 1)), calc(13vh / var(--ui-z, 1))), 132px); }   /* a short phone gives height back to the board before the words crowd it */
  .fr-tag { gap: 10px; font-size: var(--fs-small); letter-spacing: .12em; }
  .fr-hook { margin-top: 12px; font-size: clamp(22px, calc(var(--fr-u) * .26), 30px); }
  /* two words stack on a phone, so the wordmark keeps its size */
  .fr-mark { white-space: normal; } .fr-mark .fr-mk { display: block; width: max-content; } .fr-mark .fr-mk + .fr-mk { margin-top: calc(var(--fr-u) * .03); }
  /* BOARD is shorter than MAGNET: the crest sits in the notch that leaves, so it costs the board no height and lies on nothing */
  .fr-mark { position: relative; justify-self: start; width: max-content; max-width: 100%; }
  .fr-mark .bx-title { position: absolute; right: 0; bottom: .07em; margin: 0; }
  .fr-mark .bx-title .bx-crest { height: .68em; }
  .fr-s0 { align-items: end; justify-items: stretch; padding-inline: 16px; }
  .title .fr-box { width: 100%; }
  .fr-copy { margin-top: 6px; font-size: var(--fs-body); line-height: 1.45; }
  .pt-links { margin-left: -7px; } .pt-links .btn { padding-inline: 7px; font-size: var(--fs-data); } .pt-links .btn .ic, .pt-lw { display: none; }   /* the quiet links share one row: no icons, and "Load a file" for short */
  .pt-sure { font-size: var(--fs-small); }
  .fr-resume-kit { width: 78px; }
  .fr-resume-go { width: 52px; }
}
/* an upright window wider than a phone (a tablet held upright): the phone's composition at a larger size. The board runs across the top with a
   play on it, and the lock-up, the hook and the menu stand under it in one column on the page's left gutter */
@media (min-width: 561px) and (orientation: portrait) {
  .fr-title { --fr-u: clamp(54px, min(calc(12.6vw / var(--ui-z, 1)), calc(11vh / var(--ui-z, 1))), 120px); }
  .fr-s0 { align-items: end; justify-items: stretch; padding-inline: clamp(24px, calc(7vw / var(--ui-z, 1)), 64px); }
  .title .fr-box { width: 100%; }
}
@media (max-width: 560px) and (max-height: 700px) { .fr-copy { display: none; } }   /* a short phone: the pitch gives its lines to the board; the name, what it is, the hook and the reassurance stay */
@media (max-height: 520px) {
  .fr-mark .bx-title { display: none; }   /* a short window (a phone on its side): the wordmark carries the brand alone */
  .fr-s0 { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; }   /* the lock-up and menu, then the theme switch in the page flow (theme.css) */
  .fr-hook { margin-top: 10px; font-size: var(--fs-d6); } .fr-copy { font-size: var(--fs-data); line-height: 1.4; margin-top: 4px; } .pt-sure { display: none; }
  .fr-menu { margin-top: 12px; gap: 8px; }
  .fr-resume { min-height: 70px; } .fr-resume-kit { width: 70px; } .fr-resume-kit .kit { width: 40px; } .fr-resume-go { width: 46px; } .fr-resume-tx { padding: 9px 10px 10px 12px; } .fr-resume-tx b { font-size: var(--fs-d6); }
  .fr-row .btn { min-height: 42px; } .fr-row .fr-new { min-height: 46px; font-size: var(--fs-title); }
  .fr-cloud { margin-top: 6px; }
}

/* ---------- step 1: choose your club ---------- */
.fr-s1 { place-items: start center; padding-top: clamp(24px, calc(5.5vh / var(--ui-z, 1)), 60px); background: radial-gradient(1000px 520px at 88% -160px, color-mix(in srgb, var(--club) 30%, transparent), transparent 70%), radial-gradient(900px 460px at 20% -220px, var(--glow), transparent 70%), linear-gradient(180deg, transparent 60%, color-mix(in srgb, var(--turf) 9%, transparent)), var(--bg); }
.title .fr-pick { display: grid; grid-template-columns: minmax(0, 1fr) clamp(264px, calc(31vw / var(--ui-z, 1)), 400px); grid-template-rows: auto auto auto 1fr; grid-template-areas: "top side" "setup side" "clubs side" "note side"; gap: 16px 24px; align-items: start; width: min(1260px, 100%); }
.fr-top { grid-area: top; display: flex; align-items: center; gap: 12px; min-width: 0; }
.fr-back { flex: none; min-height: var(--hit); padding-inline: 8px 14px; }
.fr-h { font-size: var(--fs-h1); line-height: .94; }
.fr-setup { grid-area: setup; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 18px; }
.fr-field { display: grid; gap: 5px; min-width: 0; }
.fr-field input { width: 230px; min-height: var(--hit); font-size: var(--fs-ui); }
.fr-setup-p { flex: 1 1 250px; align-self: center; max-width: 62ch; margin: 0; font-size: var(--fs-body); line-height: 1.38; color: var(--mute); }
.fr-setup-p b { font-weight: 600; color: var(--ink); }   /* what the choice does to the first half hour leads the sentence */
.pt-hint { display: none; flex: 1 1 100%; margin: 0; font-size: var(--fs-data); line-height: 1.35; color: var(--mute); }
/* what happens to the career this browser already holds: under the start button on a wide window, above the clubs on a phone */
.pt-keep { display: flex; align-items: flex-start; gap: 8px; margin: 0; font-size: var(--fs-small); line-height: 1.35; color: var(--mute); }
.pt-keep .ic { flex: none; width: 15px; height: 15px; margin-top: 2px; }
.pt-keep-top { display: none; flex: 1 1 100%; } .pt-keep-side { margin-top: 9px; }
.pt-dockfacts { display: none; }
.pt-ask { display: grid; gap: 7px; padding: 12px; border: 1px solid color-mix(in srgb, var(--bad) 32%, var(--line)); border-radius: var(--r-m); background: var(--panel); }
.pt-ask b { font-family: var(--f-cond); font-size: var(--fs-title); font-weight: 700; line-height: 1.2; }
.pt-ask p { margin: 0; font-size: var(--fs-data); line-height: 1.4; color: var(--mute); }
.pt-ask .row { gap: 8px; flex-wrap: wrap; } .pt-ask .btn { min-height: var(--hit); }

.fr-clubs { grid-area: clubs; position: relative; display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 9px; }
.fr-club { position: relative; z-index: 1; display: grid; justify-items: center; align-content: start; gap: 5px; min-width: 0; padding: 28px 6px 10px; overflow: hidden; text-align: center; cursor: pointer; color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-l); background: var(--panel); box-shadow: var(--e1); transition: transform var(--t-fast) ease, border-color var(--t-fast) ease; }
/* the club's colours wash down from the top of its card: a pool of the second colour behind the guernsey, pinstripes, then the first colour */
.fr-club::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(circle at 50% 38%, color-mix(in srgb, var(--club2) 26%, transparent) 0, transparent 52px), repeating-linear-gradient(118deg, transparent 0 16px, color-mix(in srgb, var(--club2) 13%, transparent) 16px 18px), linear-gradient(180deg, color-mix(in srgb, var(--club) 46%, var(--panel)), color-mix(in srgb, var(--club) 14%, var(--panel))); -webkit-mask-image: linear-gradient(180deg, #000 0, #000 34%, transparent 74%); mask-image: linear-gradient(180deg, #000 0, #000 34%, transparent 74%); }
.fr-club > * { position: relative; }
/* light is the default theme and on this screen the club colours are the content: the wash is close to full strength there, the fine stripes are left
   to the big banner, and the ladder place sits on a small chip so it reads on any colour */
:root[data-theme="light"] .fr-club::before { background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--club2) 34%, transparent) 0, transparent 50px), linear-gradient(180deg, color-mix(in srgb, var(--club) 82%, var(--panel)), color-mix(in srgb, var(--club) 38%, var(--panel))); -webkit-mask-image: linear-gradient(180deg, #000 0, #000 46%, transparent 70%); mask-image: linear-gradient(180deg, #000 0, #000 46%, transparent 70%); }
:root[data-theme="light"] .fr-club-pos { top: 6px; left: 6px; padding: 2px 6px 1px; border-radius: var(--r-s); background: var(--panel); color: var(--ink); }
.fr-club:active { transform: scale(.96); }
.fr-club-pos { position: absolute; top: 7px; left: 9px; display: inline-flex; align-items: center; gap: 4px; font-family: var(--f-display); font-weight: 800; font-size: var(--fs-body); line-height: 1; letter-spacing: .02em; text-transform: uppercase; }
.fr-flag { display: inline-flex; } .fr-flag .ic { width: 14px; height: 14px; color: var(--top-line); stroke-width: 2.2; }   /* the premiers' cup: the gold of the best */
.fr-club-kit .kit { filter: drop-shadow(0 6px 7px var(--shade)); transition: transform var(--t-move) var(--ease-out); }
.fr-club b { display: grid; place-items: center; min-height: 1.15em; font-family: var(--f-cond); font-size: var(--fs-body); font-weight: 700; line-height: 1.1; letter-spacing: .01em; text-wrap: balance; }
.fr-club-st .stars { font-size: var(--fs-label); }
.fr-club.on { border-color: color-mix(in srgb, var(--club2) 40%, var(--line2)); }
.fr-club.on .kit { transform: scale(1.1) translateY(-1px); }
@media (hover: hover) {
  .fr-club:hover { border-color: var(--mute); }
  .fr-club:hover:not(.on) .kit { transform: translateY(-3px) scale(1.05); }
}
/* the pick: one ring that travels from guernsey to guernsey (FX.glide draws the block, the ring is its outline) */
.fr-clubs .glide { border-radius: var(--r-l); background: none; box-shadow: 0 0 0 2px var(--bg), 0 0 0 4.5px var(--hold); }   /* the club in hand: the ring's colour (ink by day, the ball by night), so the one solid block of the accent is the way in */
.fr-clubs:not(.has-glide) .fr-club.on { outline: 2.5px solid var(--hold); outline-offset: 2px; }
.fr-note { grid-area: note; max-width: 86ch; margin: 0; font-size: var(--fs-small); }

/* the chosen club: banner in its colours, the facts that help you choose, and the way in */
.fr-side { grid-area: side; position: sticky; top: 16px; display: flex; flex-direction: column; min-width: 0; max-height: calc(calc(100vh / var(--ui-z, 1)) - 40px); max-height: calc(calc(100dvh / var(--ui-z, 1)) - 40px); overflow: hidden; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--e2); }
.fr-feat { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.fr-feat-ban { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 8px; min-height: 184px; padding: 18px 14px 16px 18px; overflow: hidden; color: var(--club-ink); }
.fr-feat-ban > * { position: relative; }
.fr-feat-nick { margin-bottom: 6px; font-family: var(--f-cond); font-size: var(--fs-small); font-weight: 600; letter-spacing: .14em; line-height: 1.2; text-transform: uppercase; }
.fr-feat-name { font-family: var(--f-display); font-weight: 900; font-size: var(--fs-d3); line-height: .9; letter-spacing: -.005em; text-transform: uppercase; text-wrap: balance; }
.fr-feat-kit .kit { filter: drop-shadow(0 10px 14px rgba(0, 0, 0, .4)); }
.fr-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 12px 12px 8px; }
.fr-facts .fr-wide { grid-column: 1 / -1; }
.fr-facts .tile { display: grid; align-content: start; gap: 3px; }
.fr-facts .tile b { font-family: var(--f-cond); font-size: var(--fs-title); font-weight: 700; line-height: 1.15; letter-spacing: .005em; }
.fr-facts .big { font-size: var(--fs-d4); }
.fr-stars { height: 34px; display: flex; align-items: center; } .fr-stars .stars { font-size: var(--fs-d6); }
.fr-none { display: grid; place-items: center; min-height: 168px; padding: 20px 18px; }
.fr-none .empty { max-width: 36ch; padding-block: 0; }
.fr-go { flex: none; padding: 6px 12px 12px; }
.fr-go .cont { width: 100%; min-height: 50px; white-space: normal; text-wrap: balance; line-height: 1.02; }

@keyframes fr-hang { from { opacity: 0; transform: translateY(-10px) scale(.88); } }
@keyframes fr-kit { from { opacity: 0; transform: translateY(-16px) rotate(-5deg) scale(.92); } }
.fr-s1.fr-step .fr-top, .fr-s1.fr-step .fr-setup, .fr-s1.fr-step .fr-feat, .fr-s1.fr-step .fr-go, .fr-s1.fr-step .fr-note { animation: fr-show 320ms ease both; animation-delay: var(--fr-e, 0ms); }
/* the cards fade in where they stand and the guernseys are hung on them one after another */
.fr-s1.fr-step .fr-club { animation: fr-show 300ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 40ms + var(--i, 0) * 17ms); }
.fr-s1.fr-step .fr-club-kit { animation: fr-hang 460ms var(--ease-out) both; animation-delay: calc(var(--fr-e, 0ms) + 40ms + var(--i, 0) * 17ms); }
.fr-swap .fr-feat-kit { animation: fr-kit 480ms var(--spring-pop) both; animation-delay: var(--fr-c, 0ms); }
.fr-swap .fr-feat-id { animation: fr-slide 380ms var(--ease-out) both; animation-delay: var(--fr-c, 0ms); }
.fr-swap .fr-facts { animation: fr-show 300ms ease both; animation-delay: calc(var(--fr-c, 0ms) + 80ms); }

@media (max-width: 1100px), (max-height: 700px) { .fr-facts .big { font-size: var(--fs-d5); } .fr-stars { height: 30px; } .fr-stars .stars { font-size: var(--fs-title); } .fr-feat-ban { --fr-gx: calc(100% - 58px); --fr-gr: 96px; min-height: 132px; } .fr-feat-kit .kit { width: 88px; } .fr-feat-name { font-size: var(--fs-d4); } }
@media (max-width: 719px) {
  .title .fr-pick { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "top" "setup" "clubs" "note" "side"; gap: 14px; }   /* the legend sits straight under the stars it explains */
  .fr-side { position: static; max-height: none; overflow: visible; background: none; border: 0; box-shadow: none; }
  .fr-none { display: none; }   /* its one sentence sits above the grid instead (pt-hint) */
  .pt-hint { display: block; } .pt-keep-top { display: flex; }
  .fr-feat { overflow: hidden; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--e2); }
  .fr-setup { display: grid; grid-template-columns: minmax(0, 1fr); align-items: stretch; }
  .fr-field input { width: 100%; }
  .fr-setup .fr-seg { display: grid; grid-template-columns: 1fr 1fr; }
  .fr-clubs { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; }
  .fr-club { padding: 25px 4px 9px; gap: 4px; }
  .fr-club b { font-size: var(--fs-body); }
  .fr-club-kit .kit { width: 46px; }
  .fr-s1 { padding-top: calc(16px + var(--tu-drop, 0px)); }   /* --tu-drop: the walkthrough's strip across the top of a phone (f_tutorial.js), which the screen steps down for */
}
/* phones held upright: the way in is docked on the bottom edge with the picked club's facts above it, so the choice and what bears on it are in
   reach and in view wherever the list is scrolled to */
@media (max-width: 719px) and (min-height: 521px) {
  .fr-go { position: fixed; z-index: 5; left: 0; right: 0; bottom: 0; display: grid; gap: 5px; padding: 8px calc(12px + env(safe-area-inset-right, 0px)) calc(10px + env(safe-area-inset-bottom, 0px)) calc(12px + env(safe-area-inset-left, 0px)); background: var(--panel); border-top: 1px solid var(--line); box-shadow: 0 -10px 24px -16px var(--shade); }
  .fr-go .cont { min-height: 48px; padding: 5px 12px; font-size: var(--fs-ui); letter-spacing: .04em; }
  .pt-dockfacts { display: flex; gap: 0 9px; min-width: 0; overflow: hidden; white-space: nowrap; font-family: var(--f-cond); font-size: var(--fs-small); font-weight: 600; line-height: 24px; letter-spacing: .02em; color: var(--mute); }
  .pt-dockfacts span { flex: none; } .pt-dockfacts span:last-child { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--ink); }
  .pt-dockfacts span:not(:last-child)::after { content: '\00b7'; margin-left: 9px; opacity: .6; }
  .pt-keep-side { display: none; }
  .fr-go.pt-asking { max-height: calc(70vh / var(--ui-z, 1)); overflow-y: auto; } .pt-ask { padding: 4px 0 0; border: 0; }
  .title.fr-s1 { padding-bottom: calc(112px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- Save & Options ---------- */
.fr-save { display: grid; grid-template-columns: minmax(280px, 1fr) minmax(0, 1.45fr); margin-bottom: 16px; overflow: hidden; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--e2); }
.fr-save-id { position: relative; display: flex; align-items: center; gap: 16px; min-width: 0; padding: 22px 20px; overflow: hidden; background: var(--club); color: var(--club-ink); }
.fr-save-id > * { position: relative; min-width: 0; }
.fr-save-id .lbl { color: inherit; }   /* full ink on the club colour (A-06) */
.fr-save-kit { flex: none; } .fr-save-kit .kit { filter: drop-shadow(0 8px 12px rgba(0, 0, 0, .4)); }
.fr-save-club { margin: 4px 0 6px; font-family: var(--f-display); font-weight: 900; font-size: var(--fs-d3); line-height: .92; letter-spacing: -.005em; text-transform: uppercase; text-wrap: balance; overflow-wrap: anywhere; }
.fr-slots { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px; align-items: stretch; }
.fr-slot { display: grid; grid-template-rows: auto 1fr auto; gap: 9px; padding: 12px 14px 14px; }
.fr-slot-h { display: flex; align-items: center; gap: 8px; min-height: 22px; font-family: var(--f-cond); font-size: var(--fs-ui-s); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.fr-slot-h .ic { color: var(--mute); }
.fr-slot-h .pill { margin-left: auto; text-transform: none; letter-spacing: .01em; }
.fr-slot-h .pill .ic { width: 13px; height: 13px; color: inherit; stroke-width: 2.4; }
.fr-state { margin: 0; font-size: var(--fs-body); line-height: 1.4; }
.fr-slot .row { gap: 8px; }
.fr-slot .btn { min-height: var(--hit); }
.fr-slot-n { margin: 0; grid-row: 4; }
.fr-sets { display: grid; }
.fr-man { display: grid; margin: 0; }
.fr-man > div { display: grid; grid-template-columns: 118px minmax(0, 1fr); gap: 4px 16px; padding: 12px 0; border-top: 1px solid var(--line); }
.fr-man > div:first-child { border-top: 0; padding-top: 2px; } .fr-man > div:last-child { padding-bottom: 0; }
.fr-man dt { font-family: var(--f-display); font-weight: 800; font-size: var(--fs-title); line-height: 1.15; letter-spacing: .01em; text-transform: uppercase; }
.fr-man dd { margin: 0; max-width: 70ch; color: color-mix(in srgb, var(--ink) 86%, var(--mute)); }
.fr-prose p { max-width: 70ch; }
.fr-leave { border-color: color-mix(in srgb, var(--bad) 32%, var(--line)); }
.fr-leave > .ph { color: var(--bad); }
.fr-leave .btn { min-height: var(--hit); }
@media (max-width: 880px) {
  .fr-save { grid-template-columns: minmax(0, 1fr); }
  .fr-save-id { padding: 18px 16px; } .fr-save-club { font-size: var(--fs-d4); }
}
@media (max-width: 560px) {
  .fr-slots { grid-template-columns: minmax(0, 1fr); padding: 12px; }
  .fr-man > div { grid-template-columns: minmax(0, 1fr); }
  .fr-set .fr-seg button { padding-inline: 8px; }
}

/* ---------- Sacked ---------- */
/* The statement is printed in reverse: ink for the page, page colour for the type, in both themes. The old guernsey hangs grey beside it. */
.fr-sack-hero { --fr-dim: color-mix(in srgb, var(--bg) 68%, var(--ink)); --fr-red: color-mix(in srgb, var(--bad) 72%, var(--bg)); position: relative; overflow: hidden; padding: clamp(20px, calc(2.6vw / var(--ui-z, 1)), 34px) clamp(20px, calc(3.2vw / var(--ui-z, 1)), 42px); border-radius: var(--r-l); background: var(--ink); color: var(--bg); box-shadow: var(--e2); }
.fr-sack-top { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-family: var(--f-cond); font-size: var(--fs-small); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--fr-dim); }
.fr-sack-main { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: end; gap: 14px clamp(20px, calc(3.4vw / var(--ui-z, 1)), 48px); margin-top: 16px; }
.fr-sack-h { margin: 0; font-size: clamp(84px, calc(11.2vw / var(--ui-z, 1)), 140px); font-weight: 900; line-height: .82; letter-spacing: -.015em; }
.fr-sack-w1 { display: block; margin-bottom: .16em; font-size: .36em; line-height: 1; letter-spacing: .005em; }
.fr-sack-w2 { display: inline-block; color: var(--fr-red); transform-origin: 30% 60%; }
.fr-sack-say { padding-bottom: 4px; }
.fr-sack-p { margin: 0; max-width: 40ch; font-size: var(--fs-title); }
.fr-sack-q { margin: 8px 0 0; padding: 0; max-width: 30ch; font-family: var(--f-cond); font-size: clamp(20px, calc(2.2vw / var(--ui-z, 1)), 26px); font-weight: 600; line-height: 1.2; color: var(--fr-dim); }
.fr-sack-kit { align-self: center; margin-right: clamp(0px, calc(2vw / var(--ui-z, 1)), 28px); transform: rotate(7deg); filter: grayscale(1) contrast(.85); pointer-events: none; }
.fr-sack-kit .kit { width: clamp(96px, calc(12vw / var(--ui-z, 1)), 150px); filter: drop-shadow(0 16px 20px rgba(0, 0, 0, .35)); }
.fr-sack-facts { display: flex; flex-wrap: wrap; gap: 14px 40px; margin-top: 22px; padding-top: 14px; border-top: 2px solid color-mix(in srgb, var(--bg) 20%, transparent); }
.fr-sack-facts .lbl { color: var(--fr-dim); margin-bottom: 4px; }
.fr-sack-facts b { font-family: var(--f-display); font-size: var(--fs-h2); font-weight: 800; line-height: 1; text-transform: uppercase; }
.fr-next { margin-top: 22px; }
.fr-next-h { margin-bottom: 14px; }
.fr-next-h .lbl { margin-bottom: 5px; }
.fr-next-h p { margin: 6px 0 0; }
.fr-offers { display: grid; grid-template-columns: repeat(auto-fit, minmax(286px, 1fr)); gap: 12px; }
.fr-offer { display: grid; grid-template-columns: 104px minmax(0, 1fr); padding: 0; overflow: hidden; text-align: left; cursor: pointer; color: var(--ink); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-l); box-shadow: var(--e1); transition: transform var(--t-fast) ease, border-color var(--t-fast) ease; }
.fr-offer:active { transform: scale(.98); }
.fr-offer-ban { position: relative; display: grid; place-items: center; padding: 12px 8px; overflow: hidden; }
.fr-offer-ban .kit { position: relative; filter: drop-shadow(0 8px 10px rgba(0, 0, 0, .4)); transition: transform var(--t-move) var(--ease-out); }
.fr-offer-tx { display: grid; align-content: start; gap: 9px; padding: 14px 16px 15px; min-width: 0; }
.fr-offer-tx > b { font-family: var(--f-display); font-weight: 900; font-size: var(--fs-d5); line-height: .94; text-transform: uppercase; text-wrap: balance; }
.fr-offer-kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 5px 12px; align-items: baseline; font-size: var(--fs-body); }
.fr-offer-go { display: inline-flex; align-items: center; gap: 6px; justify-self: start; min-height: 38px; margin-top: 2px; padding: 6px 10px 6px 14px; border-radius: var(--r-m); background: var(--accent); color: var(--accent-ink); font-family: var(--f-cond); font-size: var(--fs-body); font-weight: 700; letter-spacing: .05em; text-transform: uppercase; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28); }
.fr-offer-go .ic { width: 16px; height: 16px; stroke-width: 2.6; }
@media (hover: hover) {
  .fr-offer:hover { border-color: var(--mute); }
  .fr-offer:hover .kit { transform: translateY(-3px) scale(1.05); }
}
.fr-retire { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.fr-retire .btn { min-height: var(--hit); white-space: normal; }

@keyframes fr-drop { from { opacity: 0; transform: translateY(-16px) scale(1.025); } }
@keyframes fr-stamp { from { opacity: 0; transform: scale(1.6) rotate(-6deg); } 55% { opacity: 1; } }
.is-enter .fr-sack.fx-in { animation: none; }   /* the landing below is this screen's entrance */
.fr-land .fr-sack-hero { animation: fr-drop 560ms var(--spring-pop) both; animation-delay: var(--fr-e, 0ms); }
.fr-land .fr-sack-top, .fr-land .fr-sack-w1 { animation: fr-show 320ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 220ms); }
.fr-land .fr-sack-w2 { animation: fr-stamp 380ms cubic-bezier(.2, .9, .3, 1) both; animation-delay: calc(var(--fr-e, 0ms) + 560ms); }
.fr-land .fr-sack-kit { animation: fr-show 600ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 760ms); }
.fr-land .fr-sack-p, .fr-land .fr-sack-q, .fr-land .fr-sack-facts { animation: fr-show 420ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 980ms); }
.fr-land .fr-sack-q { animation-delay: calc(var(--fr-e, 0ms) + 1080ms); } .fr-land .fr-sack-facts { animation-delay: calc(var(--fr-e, 0ms) + 1180ms); }
.fr-land .fr-next-h, .fr-land .fr-retire { animation: fr-show 400ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 1340ms); }
.fr-land .fr-offer { animation: fr-show 380ms ease both; animation-delay: calc(var(--fr-e, 0ms) + 1420ms + var(--i, 0) * 90ms); }
.fr-land .fr-offer-ban .kit { animation: fr-hang 480ms var(--ease-out) both; animation-delay: calc(var(--fr-e, 0ms) + 1420ms + var(--i, 0) * 90ms); }
.fr-land .fr-retire { animation-delay: calc(var(--fr-e, 0ms) + 1700ms); }

@media (max-width: 1180px) {
  .fr-sack-main { grid-template-columns: minmax(0, 1fr) auto; }
  .fr-sack-h { grid-column: 1; grid-row: 1; } .fr-sack-kit { grid-column: 2; grid-row: 1; } .fr-sack-say { grid-column: 1 / -1; grid-row: 2; }
}
@media (max-width: 719px) {
  .fr-sack-h { font-size: clamp(60px, calc(19vw / var(--ui-z, 1)), 124px); }
  .fr-sack-kit { align-self: end; margin: 0 0 4px; }
  .fr-sack-kit .kit { width: clamp(64px, calc(21vw / var(--ui-z, 1)), 130px); }
  .fr-sack-main { gap: 12px 10px; }
  .fr-sack-facts { gap: 12px 26px; } .fr-sack-facts b { font-size: var(--fs-d6); }
  .fr-offer { grid-template-columns: 92px minmax(0, 1fr); }
  .fr-offer-ban .kit { width: 56px; }
  .fr-offer-tx > b { font-size: var(--fs-h2); }
}

/* ---------- Save & Options: four groups a coach can jump between (ptOptPanels in s_front.js) ---------- */
.fr-slots:has(> .fr-slot:only-child) { grid-template-columns: minmax(0, 1fr); }
/* the jump row sits under the hero and scrolls with the page: the top bar lies over the top of the scroller, so nothing is pinned under it */
.pt-jump { display: flex; gap: 6px; margin: 0 0 16px; overflow-x: auto; scrollbar-width: none; }
.pt-jump::-webkit-scrollbar { display: none; }
.pt-jump .btn { flex: none; min-height: var(--hit); padding-inline: 14px; }
.pt-og { margin: 0 0 22px; }   /* a jump lands under the top bar by the scroller's own scroll-padding */
/* a page that stacks many switches: scOptions() gives every pick-one the shared quiet form (.seg.ds-quiet: the pick is ink, not the action colour) and every
   row the shared settings row (.ds-set), whichever system drew it */
.pt-og .btn, .pt-og .seg button { min-height: var(--hit); }   /* every control on this page is a 40px target */
.pt-og .seg button { min-width: 52px; }
.pt-og-h { margin: 0 0 var(--s25); }
/* rows from several systems under one heading: a hairline between one system's rows and the next */
.pt-merge .pt-rows + .pt-rows { margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--line); }
.pt-rows > .lg-set-o > .btn { justify-self: end; }
/* the frame's own row (keyboard shortcuts) is laid out like every other row on this page: words left, switch right */
.pt-og .cf-opt-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s1) var(--s4); }
.pt-og .cf-opt-row > .seg { justify-self: end; flex-wrap: nowrap; }
.pt-og-b { columns: 2 440px; column-gap: 16px; }
.pt-og-b > * { break-inside: avoid; margin: 0 0 16px; }
.pt-sub { margin: 16px 0 6px; font-family: var(--f-cond); font-size: var(--fs-small); font-weight: 600; letter-spacing: .12em; line-height: 1.2; text-transform: uppercase; color: var(--mute); }
.px-real .pb p { margin: 0 0 8px; max-width: 72ch; } .px-real .pb p:last-child { margin-bottom: 0; }
/* the settings row is the shared one (.ds-set: words left, control right, three choices or more on a row of their own on a phone); a button or a
   group of buttons sits at the right like a switch does */
.fr-set > .btn, .fr-set > .row { justify-self: end; }
.fr-leave .btn .ic { width: 16px; height: 16px; }
@media (max-width: 560px) { .fr-set > .btn, .pt-rows > .lg-set-o > .btn { grid-column: 1 / -1; justify-self: start; } }   /* a worded button would squeeze the words beside it: it sits under them */

/* a panel of reading that folds (the manual, the disclaimer): its head is the control, with a chevron that turns when it is open */
.pt-fold > summary { cursor: pointer; list-style: none; border-radius: calc(var(--r-l) - 1px); }
.pt-fold > summary::-webkit-details-marker { display: none; }
.pt-fold > summary .ic { width: 18px; height: 18px; color: var(--mute); transition: transform var(--t-ui) var(--ease-out); }
.pt-fold[open] > summary .ic { transform: rotate(180deg); }
.pt-fold > summary:focus-visible { outline-offset: -2px; }
.pt-fold:not([open]) > summary { padding-bottom: var(--s25); }
@media (hover: hover) { .pt-fold > summary:hover { color: var(--ink); } }

/* ---------- How it plays: the coaching manual as a page of the startup screen ---------- */
.title .pt-howbox { display: grid; gap: var(--s4); width: min(820px, 100%); }
.pt-howbox .fr-top { grid-area: auto; }   /* the picker's header, outside the picker's grid */
.pt-howgo { display: flex; } .pt-howgo .cont { min-width: min(100%, 320px); }
@media (max-width: 560px) { .pt-howgo .cont { width: 100%; } }


/* The typefaces, served from this site (SIL Open Font License 1.1: the licence texts are beside the files). Written by tools/mksite.js. */
@font-face{font-family:"Barlow";font-style:normal;font-weight:400;font-display:swap;src:url(fonts/barlow-latin-400-normal.b0a8ad37ac.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Barlow";font-style:normal;font-weight:500;font-display:swap;src:url(fonts/barlow-latin-500-normal.cd759df8ef.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Barlow";font-style:normal;font-weight:600;font-display:swap;src:url(fonts/barlow-latin-600-normal.4b52ddd483.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Barlow";font-style:normal;font-weight:700;font-display:swap;src:url(fonts/barlow-latin-700-normal.2d797dd8b3.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"MB Body A";font-style:normal;font-weight:400;src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Arimo");size-adjust:93.61%;ascent-override:106.83%;descent-override:21.37%;line-gap-override:0%}
@font-face{font-family:"MB Body A";font-style:normal;font-weight:500;src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Arimo");size-adjust:94.45%;ascent-override:105.88%;descent-override:21.18%;line-gap-override:0%}
@font-face{font-family:"MB Body A";font-style:normal;font-weight:600;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:90.04%;ascent-override:111.07%;descent-override:22.21%;line-gap-override:0%}
@font-face{font-family:"MB Body A";font-style:normal;font-weight:700;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:90.83%;ascent-override:110.09%;descent-override:22.02%;line-gap-override:0%}
@font-face{font-family:"MB Body R";font-style:normal;font-weight:400;src:local("Roboto"),local("Roboto Regular"),local("Roboto-Regular");size-adjust:95.37%;ascent-override:104.86%;descent-override:20.97%;line-gap-override:0%}
@font-face{font-family:"MB Body R";font-style:normal;font-weight:500;src:local("Roboto"),local("Roboto Regular"),local("Roboto-Regular");size-adjust:96.22%;ascent-override:103.93%;descent-override:20.79%;line-gap-override:0%}
@font-face{font-family:"MB Body R";font-style:normal;font-weight:600;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:95.38%;ascent-override:104.85%;descent-override:20.97%;line-gap-override:0%}
@font-face{font-family:"MB Body R";font-style:normal;font-weight:700;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:96.22%;ascent-override:103.93%;descent-override:20.79%;line-gap-override:0%}
@font-face{font-family:"Barlow Condensed";font-style:normal;font-weight:500;font-display:swap;src:url(fonts/barlow-condensed-latin-500-normal.460f141ec8.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Barlow Condensed";font-style:normal;font-weight:600;font-display:swap;src:url(fonts/barlow-condensed-latin-600-normal.215a93c696.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Barlow Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(fonts/barlow-condensed-latin-700-normal.3787a5a419.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"MB Cond N";font-style:normal;font-weight:500;src:local("Arial Narrow"),local("ArialNarrow"),local("Liberation Sans Narrow");size-adjust:85.65%;ascent-override:116.75%;descent-override:23.35%;line-gap-override:0%}
@font-face{font-family:"MB Cond N";font-style:normal;font-weight:600;src:local("Arial Narrow Bold"),local("ArialNarrow-Bold"),local("Liberation Sans Narrow Bold");size-adjust:84.69%;ascent-override:118.07%;descent-override:23.61%;line-gap-override:0%}
@font-face{font-family:"MB Cond N";font-style:normal;font-weight:700;src:local("Arial Narrow Bold"),local("ArialNarrow-Bold"),local("Liberation Sans Narrow Bold");size-adjust:86.53%;ascent-override:115.57%;descent-override:23.11%;line-gap-override:0%}
@font-face{font-family:"MB Cond A";font-style:normal;font-weight:500;src:local("Arial"),local("ArialMT"),local("Liberation Sans"),local("Arimo");size-adjust:70.24%;ascent-override:142.37%;descent-override:28.47%;line-gap-override:0%}
@font-face{font-family:"MB Cond A";font-style:normal;font-weight:600;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:69.45%;ascent-override:143.99%;descent-override:28.8%;line-gap-override:0%}
@font-face{font-family:"MB Cond A";font-style:normal;font-weight:700;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:70.96%;ascent-override:140.93%;descent-override:28.19%;line-gap-override:0%}
@font-face{font-family:"MB Cond R";font-style:normal;font-weight:500;src:local("Roboto"),local("Roboto Regular"),local("Roboto-Regular");size-adjust:74.1%;ascent-override:134.94%;descent-override:26.99%;line-gap-override:0%}
@font-face{font-family:"MB Cond R";font-style:normal;font-weight:600;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:74.26%;ascent-override:134.66%;descent-override:26.93%;line-gap-override:0%}
@font-face{font-family:"MB Cond R";font-style:normal;font-weight:700;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:75.87%;ascent-override:131.8%;descent-override:26.36%;line-gap-override:0%}
@font-face{font-family:"Big Shoulders Display";font-style:normal;font-weight:700 900;font-display:swap;src:url(fonts/big-shoulders-display-latin-wght-normal.075292b13a.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"MB Display N";font-style:normal;font-weight:700;src:local("Arial Narrow Bold"),local("ArialNarrow-Bold"),local("Liberation Sans Narrow Bold");size-adjust:75.97%;ascent-override:129.52%;descent-override:28.04%;line-gap-override:0%}
@font-face{font-family:"MB Display N";font-style:normal;font-weight:800;src:local("Arial Narrow Bold"),local("ArialNarrow-Bold"),local("Liberation Sans Narrow Bold");size-adjust:81.54%;ascent-override:120.68%;descent-override:26.12%;line-gap-override:0%}
@font-face{font-family:"MB Display N";font-style:normal;font-weight:900;src:local("Arial Narrow Bold"),local("ArialNarrow-Bold"),local("Liberation Sans Narrow Bold");size-adjust:87.08%;ascent-override:113%;descent-override:24.46%;line-gap-override:0%}
@font-face{font-family:"MB Display A";font-style:normal;font-weight:700;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:62.3%;ascent-override:157.95%;descent-override:34.19%;line-gap-override:0%}
@font-face{font-family:"MB Display A";font-style:normal;font-weight:800;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:66.86%;ascent-override:147.17%;descent-override:31.86%;line-gap-override:0%}
@font-face{font-family:"MB Display A";font-style:normal;font-weight:900;src:local("Arial Bold"),local("Arial-BoldMT"),local("Liberation Sans Bold"),local("Arimo Bold");size-adjust:71.4%;ascent-override:137.81%;descent-override:29.83%;line-gap-override:0%}
@font-face{font-family:"MB Display R";font-style:normal;font-weight:700;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:67.08%;ascent-override:146.7%;descent-override:31.75%;line-gap-override:0%}
@font-face{font-family:"MB Display R";font-style:normal;font-weight:800;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:71.99%;ascent-override:136.69%;descent-override:29.59%;line-gap-override:0%}
@font-face{font-family:"MB Display R";font-style:normal;font-weight:900;src:local("Roboto Bold"),local("Roboto-Bold"),local("Roboto");size-adjust:76.88%;ascent-override:127.99%;descent-override:27.71%;line-gap-override:0%}
:root,:root[data-theme]{--f-body:'Barlow', 'MB Body A', 'MB Body R', 'Helvetica Neue', Helvetica, Arial, sans-serif;--f-cond:'Barlow Condensed', 'MB Cond N', 'MB Cond A', 'MB Cond R', 'Arial Narrow', 'Helvetica Neue', Arial, sans-serif;--f-display:'Big Shoulders Display', 'MB Display N', 'MB Display A', 'MB Display R', 'Barlow Condensed', 'Arial Narrow', sans-serif}

/* Magnet Board on its own website: the few things tools/mksite.js adds to the game's page (see site_src/site.js). Tokens only. */
.sx-nojs { max-width: 34em; margin: calc(15vh / var(--ui-z, 1)) auto; padding: 0 20px; font: 17px/1.5 system-ui, sans-serif; }
.sx-web .sx-links { flex-wrap: wrap; gap: 8px; margin: 12px 0 0; }
.sx-web .sx-links .btn { min-height: 40px; text-decoration: none; }
.sx-web .sx-ver { margin: 12px 0 0; font-size: 13px; font-variant-numeric: tabular-nums; }
.sx-web .sx-new { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin: 14px 0 0; padding: 10px 12px; border: 1px solid var(--line2); border-radius: var(--r-m); background: var(--panel2); font-weight: 600; }
.sx-web .sx-new .btn { min-height: 40px; margin-left: auto; }
/* the new-version line: the game's own toast, kept clear of it, with one button */
.toast.sx-toast { padding: 7px 7px 7px 18px; gap: 14px; margin-bottom: 62px; cursor: default; }
.sx-toast button { flex: none; min-height: 40px; padding: 0 16px; border: 0; border-radius: 10px; background: var(--accent); color: var(--accent-ink); font-family: var(--f-cond); font-weight: 700; font-size: 15px; letter-spacing: .08em; text-transform: uppercase; cursor: pointer; }
.sx-toast button:focus-visible { outline: 2px solid var(--bg); outline-offset: 2px; }
.sx-toast button:disabled { opacity: .6; cursor: default; }
/* the address for a problem, in Save & Options */
.sx-web .sx-help { margin: 14px 0 0; padding: 10px 12px; border: 1px solid var(--line2); border-radius: var(--r-m); background: var(--panel2); }
.sx-web .sx-help a { font-weight: 600; text-underline-offset: 3px; overflow-wrap: anywhere; }
/* "Early access" beside the startup screen's tagline: an outlined tag in the tagline's own type, before the rule. Where the two do not
   fit on one line (a phone) the tag takes the next line and the rule runs on from it. */
.fr-tag:has(.sx-early) { flex-wrap: wrap; row-gap: 8px; }
.fr-tag .sx-early { flex: none; padding: .42em .6em .34em; border: 2px solid currentColor; font-size: .82em; letter-spacing: .16em; line-height: 1; }
/* links under the startup screen (only when CONFIG.titleLinks is on in tools/mksite.js) */
.sx-foot { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 14px; font-family: var(--f-cond); font-weight: 600; font-size: 14px; letter-spacing: .06em; }
.sx-foot a { padding: 8px 0; color: var(--mute); text-underline-offset: 3px; }
@media (hover: hover) { .sx-foot a:hover { color: var(--ink); } .sx-toast button:hover { filter: brightness(1.08); } }
/* While the game's script is still arriving: the crest and the name (tools/mksite.js puts this inside #app and the first render writes
   over it). It waits a moment before showing, so a fast line never sees it flash. */
.sx-wait { min-height: calc(100vh / var(--ui-z, 1)); min-height: calc(100dvh / var(--ui-z, 1)); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; padding: 24px; color: var(--ink); text-align: center; animation: sx-wait-in .25s .35s both; }
.sx-wait svg { width: auto; height: 72px; }
.sx-wait .mk-f { fill: currentColor; } .sx-wait .mk-s { fill: none; stroke: currentColor; } .sx-wait .mk-ball { fill: var(--bad); }
.sx-wait b { font-family: var(--f-display); font-weight: 900; font-size: 34px; line-height: 1; letter-spacing: .005em; text-transform: uppercase; }
.sx-wait b em { font-style: normal; color: var(--accent); }
.sx-wait span { font-family: var(--f-cond); font-weight: 600; font-size: 14px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute); }
@keyframes sx-wait-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .sx-wait { animation: none; } }
/* ---------- coming soon: the startup screen until an early access code is entered (site_src/site.js adds .sx-soon and .sx-gate) ---------- */
/* the game's own offer is put away; the gate's heading and sentence wear the same two classes, one level down, so they keep its type */
.sx-soon .fr-box > .fr-hook, .sx-soon .fr-box > .fr-copy, .sx-soon .fr-menu, .sx-soon .pt-links, .sx-soon .pt-sure, .sx-soon .fr-cloud, .sx-soon .fr-box > .sv-title { display: none; }
.sx-gate { display: grid; justify-items: start; min-width: 0; }
.sx-code { display: grid; gap: 8px; width: 0; min-width: min(100%, max(600px, calc(var(--fr-u) * 4.4))); margin-top: clamp(18px, calc(var(--fr-u) * .22), 30px); }
.sx-code-l { font-family: var(--f-cond); font-weight: 600; font-size: var(--fs-small); letter-spacing: .14em; text-transform: uppercase; color: var(--mute); }
.sx-code-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; }
.sx-code-in { min-width: 0; height: 56px; padding: 0 16px 2px; border: 2px solid var(--ink); border-radius: var(--r-m); background: var(--bg); color: var(--ink); font-family: var(--f-cond); font-weight: 700; font-size: 22px; letter-spacing: .14em; text-transform: uppercase; }
.sx-code-in:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sx-code-in[aria-invalid="true"] { border-color: var(--bad); }
.sx-code .sx-code-go { height: 56px; min-width: 112px; padding: 0 22px 2px; font-size: 18px; }
.sx-code-msg { min-height: 1.45em; margin: 0; font-size: var(--fs-small); line-height: 1.45; color: var(--bad); font-weight: 600; }
.sx-gate-mail { width: 0; min-width: min(100%, max(600px, calc(var(--fr-u) * 4.4))); margin: 6px 0 0; font-size: var(--fs-ui); color: var(--mute); }
.sx-gate-mail a { color: var(--ink); font-weight: 600; text-underline-offset: 3px; overflow-wrap: anywhere; }
@media (max-width: 560px) { .sx-code-in { height: 52px; font-size: 19px; } .sx-code .sx-code-go { height: 52px; min-width: 92px; padding: 0 16px 2px; } }
/* the board hollowed out to line work: no turf, the chalk in ink, every magnet a ring, the marker still in the accent */
.sx-soon .bd-apron { fill: none; stroke: var(--ink); stroke-width: .35; opacity: .28; }
.sx-soon .bd-turf, .sx-soon .bd-band, .sx-soon .bd-glow { fill: none; }
.sx-soon .bd-board::before { content: none; }
.sx-soon .bx-paint, :root[data-theme="light"] .sx-soon .bx-paint, :root[data-theme="light"] .sx-soon .bd.rp-on .bx-paint, .sx-soon .bd.rp-on .bx-paint { color: var(--ink); opacity: .09; }
.sx-soon .bd-chalk > * { stroke: var(--ink); opacity: .3; }
.sx-soon .bd-edge { stroke: var(--ink); opacity: .78; }
.sx-soon .bd-post { fill: var(--bg); stroke: var(--ink); stroke-width: .45; }
.sx-soon .bd-mi, .sx-soon .bd-bi { filter: none; }
.sx-soon .bd.bd-title .bd-h .bd-ring { fill: var(--accent); } .sx-soon .bd.bd-title .bd-a .bd-ring { fill: var(--ink); }
.sx-soon .bd.bd-title .bd-h .bd-fill, .sx-soon .bd.bd-title .bd-a .bd-fill { fill: var(--bg); }
.sx-soon .bd.bd-title .bd-h .bd-n, .sx-soon .bd.bd-title .bd-h .rp-num { fill: var(--accent); } .sx-soon .bd.bd-title .bd-a .bd-n, .sx-soon .bd.bd-title .bd-a .rp-num { fill: var(--ink); }
.sx-soon .rp-land, .sx-soon .rp-ring, .sx-soon .rp-tr, .sx-soon .rp-g2 { stroke: var(--ink); }
.sx-soon .rp-trs { stroke: none; }
.sx-soon .bd-ball ellipse, .sx-soon .rp-ball ellipse { fill: var(--bg); stroke: var(--ball); stroke-width: .75; }
