/*
 * The landing's design system and layout (ENG-48), ported from variant D of the ENG-9 prototype
 * (prototype/teaser-landing, frontend/landing-prototype/index.html).
 *
 * The Content-Security-Policy allows no inline styles, so every style lives in this file. A bar or a value that
 * changes per page goes into an SVG attribute, never a style attribute.
 *
 * Contrast: every text colour here meets WCAG AA on its background. Small text on the green hero stays clear of the
 * radial glow, which is why the glow shrinks on narrow screens and the language toggle sits on a dark pill.
 */

/* ===== Fonts: self-hosted, each folder with its SIL Open Font License (OFL.txt) ===== */

@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/bricolage-grotesque/bricolage-grotesque-latin-ext.b21945eb5067.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/bricolage-grotesque/bricolage-grotesque-latin.c47ac31e5437.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: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans/instrument-sans-latin-ext.e2385a017626.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/instrument-sans/instrument-sans-latin.e35fad09c70b.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: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/jetbrains-mono/jetbrains-mono-latin-ext.e6155c5cfacf.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/jetbrains-mono/jetbrains-mono-latin.570751c5f8b4.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;
}

/* ===== Design tokens v0 (ENG-9) ===== */

:root {
  --color-green-50: #E9F6EF;
  --color-green-100: #E3F1EA;
  --color-green-200: #D6F8E8;   /* 5.0:1 on green-700: small text on the hero */
  --color-green-300: #9FE8C8;   /* 4.0:1 on green-700: large text and graphics on the hero only */
  --color-green-500: #0FA972;
  --color-green-600: #0A8A5F;   /* brand; 4.4:1 on white, so fills, graphics and large text only */
  --color-green-700: #087650;   /* 5.7:1 on white: buttons with body-size labels, links, small brand text */
  --color-green-800: #0A6B4C;
  --color-green-900: #065F42;
  --color-ink-900: #101826;
  --color-ink-800: #17202E;
  --color-ink-700: #2A3648;
  --color-slate-600: #55647A;   /* the only muted text colour that passes AA on paper (5.6:1) */
  --color-slate-500: #7A8698;   /* 3.4:1 on paper: icons and borders, never text */
  --color-slate-400: #8A94A6;
  --color-slate-300: #A5AEBC;
  --color-paper: #F7F6F2;
  --color-paper-2: #F1EFE8;
  --color-line: #E7E4DB;
  --color-line-strong: #DCD9CF;
  --color-coral-600: #C2412C;
  --color-coral-500: #E04A32;
  --color-coral-300: #FF8A7A;
  --color-coral-50: #FBEEE9;
  --color-amber-400: #FFB454;

  --bg: var(--color-paper);
  --surface: #FFFFFF;
  --surface-2: var(--color-paper-2);
  --text: var(--color-ink-900);
  --text-muted: var(--color-slate-600);
  --border: var(--color-line);
  --border-strong: var(--color-line-strong);
  /* The edge of a form field, which is all that shows where the field is: 3.7:1 on a white surface (WCAG 1.4.11). */
  --border-field: var(--color-slate-500);
  --brand: var(--color-green-600);
  --brand-strong: var(--color-green-700);
  --brand-tint: var(--color-green-50);
  --accent: var(--color-coral-600);
  /* Keyboard focus: a solid outline, at least 3:1 against what it sits on. The hero switches it to white. */
  --focus-ring: var(--color-green-700);
  /* Keyboard focus on a link: a fill inside the link, under ink text (10.1:1) and an ink bar (ENG-85). */
  --focus-highlight: var(--color-amber-400);
  /* The Wordmark's text and its .MD. The top bar over the hero sets them light, and focus sets the .MD to ink. */
  --wordmark-text: var(--text);
  --wordmark-accent: var(--brand);

  /* Type scale */
  --font-display: 'Bricolage Grotesque', 'Instrument Sans', system-ui, sans-serif;
  --font-body: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --text-hero: clamp(40px, 5.4vw, 74px);
  --text-h2: clamp(30px, 3.6vw, 46px);
  --text-lead: clamp(17px, 1.8vw, 20px);
  --text-body: 15px;
  --text-small: 13px;
  --text-label: 11.5px;

  /* Radii, shadows and the container */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 38, .04);
  --shadow-md: 0 12px 36px rgba(16, 24, 38, .06);
  --shadow-lg: 0 18px 50px rgba(16, 24, 38, .07);
  --shadow-brand: 0 10px 26px rgba(10, 138, 95, .28);
  --container: 1180px;

  --topbar-height: 78px;
}

/* ===== Base ===== */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
body { font-family: var(--font-body); font-size: var(--text-body); line-height: 1.55; color: var(--text); background: var(--bg); -webkit-font-smoothing: antialiased; }
svg { display: block; }
a { color: var(--brand-strong); text-underline-offset: 3px; }
/* A form control takes the page's font and colour. Left alone, it keeps the browser's own. */
button, input, select, textarea { font: inherit; color: inherit; }
/* A browser never lets a fieldset get narrower than its longest word, which pushes a phone's page sideways. */
fieldset { min-width: 0; border: 0; }
:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
/* A link shows its focus inside its own box, as GOV.UK's links do, since a ring around a link in a line of text would
   cover the letters beside it and the line above (ENG-85). Its outline is see-through: a forced-colours mode paints it
   in a colour of its own, as the one sign of the focus left once the mode drops the fill and the bar. The Wordmark
   shows it too, so that focus on a link looks the same everywhere, and its .MD turns ink with it (see "Wordmark"). A
   link drawn as a box of its own, with room around it, keeps the ring: a button, the hero's chip (whose amber icon
   would vanish on the fill) and a language in the top bar's toggle, whose own rules over the hero outweigh this one
   and would leave white text on the amber. */
a:not(.btn, .hero-chip, .language-toggle-link):focus-visible {
  outline: 3px solid transparent;
  outline-offset: 0;
  background-color: var(--focus-highlight);
  color: var(--text);
  text-decoration: none;
  box-shadow: inset 0 -3px var(--text);
}
ol, ul { list-style: none; }
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 20px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ===== Type ===== */

.h1 { font-family: var(--font-display); font-weight: 800; font-size: var(--text-hero); line-height: .98; letter-spacing: -.035em; }
.h1 em { font-style: normal; color: var(--brand); }
.h2 { font-family: var(--font-display); font-weight: 800; font-size: var(--text-h2); line-height: 1.03; letter-spacing: -.03em; }
.h3 { font-family: var(--font-display); font-weight: 700; font-size: 21px; line-height: 1.15; letter-spacing: -.02em; }
.lead { font-size: var(--text-lead); line-height: 1.5; color: var(--text-muted); }
.small { font-size: var(--text-small); }
.muted { color: var(--text-muted); }
.mono { font-family: var(--font-mono); }
.eyebrow { font-family: var(--font-mono); font-size: var(--text-label); font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--brand-strong); }

/* ===== Wordmark ===== */

/* Its two colours are custom properties, which the top bar over the hero sets, so that the focus highlight's ink
   outweighs them without a longer selector (ENG-85). */
.wordmark { font-family: var(--font-display); font-weight: 800; font-size: 22px; letter-spacing: -.03em; color: var(--wordmark-text); text-decoration: none; }
.wordmark span { color: var(--wordmark-accent); }
/* With the keyboard's focus, the .MD takes the highlight's ink: the brand green is 2.5:1 on the amber. */
.wordmark:focus-visible { --wordmark-accent: var(--text); }
/* Below large-text size, the brand green is too light for text, so the small Wordmark takes the stronger one. */
.wordmark-small { font-size: 17px; }
.wordmark-small span { color: var(--brand-strong); }

/* ===== Top bar and language toggle ===== */

.topbar-inner { display: flex; justify-content: space-between; align-items: center; gap: 16px; min-height: var(--topbar-height); }
.language-toggle { display: inline-flex; gap: 2px; padding: 3px; border: 1px solid var(--border-strong); border-radius: var(--radius-pill); background: var(--surface); }
.language-toggle a { border-radius: var(--radius-pill); padding: 4px 10px; font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--text-muted); text-decoration: none; }
.language-toggle a:hover { color: var(--text); }
.language-toggle a[aria-current="true"] { background: var(--text); color: #fff; }

/* On a page with the hero, the top bar lies over the hero's green, in light colours. */
body:has(.hero) .topbar { position: absolute; inset: 0 0 auto; z-index: 1; --focus-ring: #fff; --wordmark-text: #fff; --wordmark-accent: var(--color-green-300); }
body:has(.hero) .language-toggle { background: rgba(6, 40, 28, .45); border-color: rgba(255, 255, 255, .3); }
body:has(.hero) .language-toggle a { color: #fff; }
body:has(.hero) .language-toggle a:hover { background: rgba(255, 255, 255, .14); }
body:has(.hero) .language-toggle a[aria-current="true"] { background: #fff; color: var(--color-green-800); }

/* ===== Hero ===== */

.hero {
  --focus-ring: #fff;
  overflow-x: clip;
  padding-top: var(--topbar-height);
  color: #fff;
  background: radial-gradient(900px 520px at 85% -10%, rgba(15, 169, 114, .9), transparent 60%), var(--color-green-700);
}
.hero-grid { display: grid; grid-template-columns: 1fr 1fr; grid-template-areas: "head card" "lead card" "form card"; column-gap: 56px; row-gap: 20px; align-content: center; padding-top: 36px; padding-bottom: 64px; min-height: min(760px, calc(100vh - 150px)); }
.hero-head { grid-area: head; display: grid; gap: 20px; align-self: end; }
.hero-head .eyebrow { color: var(--color-green-200); }
.hero .h1 em { color: var(--color-green-300); }
.hero-lead { grid-area: lead; display: grid; gap: 16px; justify-items: start; }
.hero-lead .lead { color: rgba(255, 255, 255, .92); }
.hero-form { grid-area: form; align-self: start; }
.hero-card { grid-area: card; display: grid; justify-items: center; align-content: center; gap: 22px; }

/* ===== Player card ===== */

.pcard { width: min(370px, 100%); aspect-ratio: 3 / 4; display: grid; grid-template-rows: auto auto 1fr auto auto; gap: 14px; padding: 24px; border-radius: 26px; background: var(--color-paper); color: var(--text); box-shadow: 0 30px 70px rgba(6, 40, 28, .4); transform: rotate(-2.5deg); }
.pcard-top { display: flex; justify-content: space-between; align-items: center; }
.pcard-type { font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.pcard-number { font-family: var(--font-mono); font-weight: 700; font-size: clamp(46px, 6vw, 64px); line-height: 1; letter-spacing: -.05em; }
.pcard-status { margin-top: 6px; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--brand-strong); }
.pcard-ecg { align-self: center; width: 100%; height: 44px; color: var(--brand); }
.pcard-rows { display: grid; gap: 8px; }
.pcard-row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; padding-top: 8px; border-top: 1px dashed var(--border-strong); font-size: 14px; }
.pcard-row dt { flex: none; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.pcard-row dd { font-weight: 700; text-align: right; }
.pcard-row .pcard-placeholder { font-weight: 500; color: var(--text-muted); }
.pcard-foot { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 11.5px; color: var(--text-muted); }
@media (prefers-reduced-motion: no-preference) {
  .pcard { transition: transform .3s; }
  .pcard:hover { transform: rotate(0); }
}

/* ===== Icons, cards and buttons ===== */

.icon { flex: none; width: 22px; height: 22px; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
/* Every button but a small one (.btn-sm) is at least 48 px tall, on a link and on a button element alike. A label too
   long for one line wraps, as a Polish one does on a phone, so the button has padding above and below it. It has no
   edge, as in variant D: the outlined buttons draw theirs as a ring inside the box, and an edge would push that ring
   inwards. A forced-colours mode gets an edge of its own, at the end of this section. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 10px 20px; border: 0; border-radius: var(--radius-md); background: var(--brand-strong); color: #fff; font-weight: 700; font-size: 15px; line-height: 1.3; text-align: center; text-decoration: none; cursor: pointer; box-shadow: var(--shadow-brand); }
.btn:hover { background: var(--color-green-800); }
.btn-block { width: 100%; }
/* A small button is at least 40 px tall (ENG-84): variant D's is 38 px, and 40 px is well over the 24 px target of
   WCAG 2.2 AA, 2.5.8. */
.btn-sm { min-height: 40px; padding: 8px 14px; font-size: 14px; box-shadow: none; }
/* A second choice, quieter than a main button: variant D's ghost button, and the outlined one of the Cohort list's
   rows and the Player card page. */
.btn-ghost { border: 1px solid var(--border-strong); background: transparent; color: var(--text); box-shadow: none; }
.btn-ghost:hover { background: var(--surface-2); }
.btn-outline { background: var(--surface); color: var(--brand-strong); box-shadow: inset 0 0 0 1.5px var(--brand-strong); }
.btn-outline:hover { background: var(--brand-tint); }
@media (prefers-reduced-motion: no-preference) {
  .btn { transition: background .15s, transform .15s; }
  .btn:active { transform: translateY(1px); }
}
/* A forced-colours mode paints over a button's fill and drops its shadow, so an edge is then all that shows it. */
@media (forced-colors: active) {
  .btn { border: 1px solid ButtonBorder; }
}

/* ===== Forms (ENG-69): fields with their labels, hints and errors, and the boxes to tick ===== */

/* Shared by every form on the landing's pages, on paper. The sign-up form restyles them for the green hero below. */

/* A form's rows, one under another. */
.form { display: grid; gap: 12px; }
/* A label above its field, with the field's hint and error under it. */
.field { display: grid; gap: 6px; }
.field-label { font-size: var(--text-small); font-weight: 600; }
/* The text is 16 px, where variant D has 15: iOS Safari zooms the page in on a field with smaller text. The edge is
   all that shows where the field is, so it takes --border-field. */
.input { -webkit-appearance: none; appearance: none; width: 100%; min-height: 48px; padding: 0 14px; border: 1.5px solid var(--border-field); border-radius: var(--radius-md); background: var(--surface); color: var(--text); font-size: 16px; font-weight: 400; }
.input[aria-invalid="true"] { border-color: var(--accent); }
/* Chrome, Edge and Safari put a button that clears the text into a search field. It keeps its job and takes the
   landing's cross for the browser's own. */
.input::-webkit-search-cancel-button { -webkit-appearance: none; width: 24px; height: 24px; margin-left: 8px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 3l8 8M11 3l-8 8' fill='none' stroke='%2355647A' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / 14px no-repeat; cursor: pointer; }
.field-hint { font-size: var(--text-small); color: var(--text-muted); }
.field-error { font-size: var(--text-small); font-weight: 600; color: var(--accent); }
/* A required field's mark (ENG-94), after its label or beside the consent box's text: smaller and lighter than the
   label, and no lighter than the hint, so it passes AA (5.6:1 on paper). */
.field-required { font-size: 12px; font-weight: 400; color: var(--text-muted); }

/* A form's error summary (ENG-94), at the top of a form that came back with errors. Its border is real, so the box
   stays in a forced-colours mode, which drops fills and shadows. On paper: the error colour on a white fill (5.1:1).
   The entries stand 8 px apart: a link's line is 19 px tall, and WCAG 2.5.8 wants 24 px between the centres of
   targets that small. */
.form-error-summary { display: grid; gap: 8px; padding: 14px 16px; border: 2px solid var(--accent); border-radius: var(--radius-md); background: var(--surface); color: var(--accent); }
.form-error-summary-title { font-size: 16px; font-weight: 700; line-height: 1.3; }
.form-error-summary-list { display: grid; gap: 8px; font-size: 15px; font-weight: 600; line-height: 1.4; }
/* :not(:focus-visible), so that the rule never meets the landing's focus on a link (ink on amber). */
.form-error-summary a:not(:focus-visible) { color: inherit; text-decoration: underline; }
/* The summary, "Check your inbox" and every target of a summary's link land 2.5rem below the window's top: a label
   stands 26.6 px above its field, and the focus ring 5 px outside its element. In rem, not px, so that the room grows
   with a reader's larger text, as the label does. Only on the forms' own pages, so that the Cohort list's search
   field keeps its place. */
.form-error-summary,
.form-error-summary a,
.hero-form .signup-inbox,
.hero-form .form .input,
.hero-form .form .checkbox,
.hero-form .form .choices,
.school-pick-page .form .input,
.school-pick-page .form .choices,
.confirmation-page-form .confirmation-page-news-fieldset { scroll-margin-top: 2.5rem; }

/* A list of choices under its legend, and one choice: a radio button or a check box with its text beside it. The
   text's first line sits level with the box. A choice may hold a name that a visitor typed, so its text breaks
   inside a word that is too long for the line. */
.choices legend { padding-bottom: 8px; }
.choice { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; align-items: start; }
.choice + .choice { margin-top: 10px; }
.choice label { overflow-wrap: anywhere; cursor: pointer; }
.choice > label { line-height: 24px; }

/* A check box and a radio button, drawn here. The browser's own, tinted green as in variant D, would show on the
   green hero as a tick without a box. Each is 24 px wide and tall, the size WCAG 2.2 asks of a pointer target
   (2.5.8), where variant D has 18 px. */
.checkbox, .radio { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; border: 1.5px solid var(--border-field); background: var(--surface) center / 14px no-repeat; cursor: pointer; }
.checkbox { border-radius: 7px; }
.radio { border-radius: 50%; }
.checkbox:checked { border-color: var(--brand-strong); background-color: var(--brand-strong); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M2.5 7.5l3 3 6-6.5' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
/* A thick ring around a dot of the fill. */
.radio:checked { border: 7px solid var(--brand-strong); }
.checkbox[aria-invalid="true"],
.radio[aria-invalid="true"] { border-color: var(--accent); }
/* In a forced-colours mode the browser paints over these colours, so it draws the two itself. */
@media (forced-colors: active) {
  .checkbox, .radio { -webkit-appearance: auto; appearance: auto; }
}

/* ===== Prize chip and ticker, in the hero ===== */

/* The chip sits on the language toggle's dark pill: on a light tint, its small white text would fall below AA. */
.hero-chip { display: inline-flex; gap: 8px; align-items: center; padding: 7px 14px; border: 1px solid rgba(255, 255, 255, .3); border-radius: var(--radius-pill); background: rgba(6, 40, 28, .45); color: #fff; font-weight: 600; font-size: 14px; text-decoration: none; }
.hero-chip:hover { background: rgba(6, 40, 28, .6); }
.hero-chip .icon { width: 18px; height: 18px; color: var(--color-amber-400); }
.hero-ticker { border-top: 1px solid rgba(255, 255, 255, .22); padding: 16px 0; font-family: var(--font-mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: rgba(255, 255, 255, .92); }

/* ===== Content sections ===== */

.section { padding-bottom: 96px; }
.section-head { display: grid; gap: 12px; max-width: 680px; margin-bottom: 28px; }

.tiles { padding-top: 88px; padding-bottom: 96px; }
.tile-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.tile { display: grid; gap: 10px; align-content: start; padding: 26px; }
.tile-icon, .prize-icon { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; }
.tile-icon { padding: 9px; background: var(--brand-tint); color: var(--brand-strong); font-family: var(--font-mono); font-weight: 700; font-size: 13px; }
.tile-icon .ecg { width: 100%; height: 100%; }

/* The prize section: a dark card, its accents in amber. */
.prizes { display: grid; gap: 24px; padding: 36px; border-color: var(--color-ink-700); background: var(--color-ink-900); color: #fff; }
.prizes .section-head { margin-bottom: 0; }
.prizes .lead, .prizes .muted { color: var(--color-slate-300); }
.prize-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.prize { display: grid; gap: 10px; align-content: start; padding: 20px; border: 1.5px dashed rgba(255, 180, 84, .55); border-radius: var(--radius-lg); color: var(--color-slate-300); }
.prize b { color: #fff; }
.prize-icon { background: rgba(255, 180, 84, .14); color: var(--color-amber-400); }

/* The Rank path: a line of dots. The step for the unnamed Ranks has a dotted ring, the steps after launch a grey dashed one. */
.rank-path { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); }
.rank-path::before { content: ''; position: absolute; left: 8px; right: 0; top: 15px; height: 2px; background: var(--border-strong); }
.rank-path-step { position: relative; display: grid; gap: 2px; align-content: start; padding: 42px 14px 0 0; }
.rank-path-step::before { content: ''; position: absolute; left: 0; top: 7px; width: 18px; height: 18px; border: 3px solid var(--brand); border-radius: 50%; background: var(--bg); }
.rank-path-step:first-child::before { background: var(--brand); }
.rank-path-step-ranks-in-between::before { border-style: dotted; }
.rank-path-step-after-launch::before { border-color: var(--color-slate-500); border-style: dashed; }
.rank-path-step b { font-family: var(--font-display); font-size: 19px; letter-spacing: -.02em; }
.rank-path-step small { font-size: var(--text-small); color: var(--text-muted); }
.rank-path-step-tag { justify-self: start; margin-top: 4px; padding: 1px 8px; border: 1px solid var(--border-strong); border-radius: var(--radius-pill); font-family: var(--font-mono); font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); }

.team-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.person { display: grid; gap: 12px; align-content: start; padding: 22px; }
/* The ring sits outside the photo, so a white-background photo still reads as a circle on the white card (ENG-43). */
.person-photo { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; background: var(--brand-tint); box-shadow: 0 0 0 2px var(--brand); }
.person-name { font-weight: 700; }
.person-role { font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--brand-strong); }
.team-trust { margin-top: 18px; }

.closing { display: grid; gap: 20px; justify-items: center; padding-bottom: 96px; text-align: center; }

/* ===== Sign-up form, in the hero ===== */

/* The honeypot (ENG-58): no person sees it, so only a bot fills it in. No rule may show it again: a person who
   then fills it in is dropped as a bot, without a word. */
.signup-form-trap { display: none; }

/* The form's column gives way on a phone, whatever the form holds: an address or a typed name too long for the line
   must not widen the hero. */
.hero-form { min-width: 0; }
/* A link here takes the hero's white, never the page's link colour, which is the hero's own green. */
.hero-form a { color: #fff; }
/* On the green, the main button is dark, as in variant D: the brand green would not show. */
.hero-form .btn { background: var(--color-ink-900); box-shadow: 0 10px 26px rgba(6, 40, 28, .35); }
.hero-form .btn:hover { background: var(--color-ink-700); }
.hero-form .btn-ghost { border-color: rgba(255, 255, 255, .4); background: transparent; color: #fff; box-shadow: none; }
.hero-form .btn-ghost:hover { background: rgba(255, 255, 255, .1); }

/* A white field and a white box need no edge on the green: the fill shows where they are (5.6:1). The hint and the
   error take colours that pass AA there: variant D's muted white (82%) and its error pink (#FFD9D2) fall just
   short. The hint takes the white of variant D's consent text (88%, 4.8:1). */
.hero-form .input, .hero-form .checkbox, .hero-form .radio { border-color: transparent; }
.hero-form .input[aria-invalid="true"], .hero-form .checkbox[aria-invalid="true"] { border-color: var(--color-coral-500); }
/* The same tick as on paper, in ink on the white box. */
.hero-form .checkbox:checked { background-color: var(--surface); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M2.5 7.5l3 3 6-6.5' fill='none' stroke='%23101826' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.hero-form .radio:checked { border-color: var(--surface); background-color: var(--color-ink-900); }
.hero-form .field-hint { color: rgba(255, 255, 255, .88); }
.hero-form .field-error { color: var(--color-coral-50); }
/* The error summary takes the error's colour for its border and its text (5.0:1), with no fill of its own: the
   paper's coral border would fall short of 3:1 on the green. The required mark takes the hint's white (4.8:1). */
.hero-form .form-error-summary { border-color: var(--color-coral-50); background: transparent; color: var(--color-coral-50); }
.hero-form .field-required { color: rgba(255, 255, 255, .88); }

/* The consent box's text, smaller than a choice's, with the link to the privacy notice after it. */
.signup-form-consent-text { padding-top: 2px; font-size: var(--text-small); line-height: 1.5; color: rgba(255, 255, 255, .88); }
.signup-form-consent .field-error { grid-column: 2; }
/* The link's own box is 24 px tall, though the line it sits in is not: a link beside a label is a target too. */
.signup-form-consent-text a { padding: 4px 0; }

/* "Check your inbox", in place of the form: variant D's panel. Its fill is darker than the hero, where variant D's
   is lighter: on the lighter one, only pure white text passes AA. An address too long for the line breaks inside
   itself. */
.signup-inbox { display: grid; gap: 14px; justify-items: start; padding: 20px; border: 1px solid rgba(255, 255, 255, .28); border-radius: var(--radius-lg); background: rgba(6, 40, 28, .25); overflow-wrap: anywhere; }
.signup-inbox-title { display: flex; gap: 8px; align-items: center; font-family: var(--font-mono); font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--color-green-200); }
.signup-inbox-title .icon { width: 16px; height: 16px; }
.signup-inbox-note { font-size: var(--text-small); color: rgba(255, 255, 255, .88); }

/* ===== Private-link pages, one column: confirmation, school pick (ENG-61), unsubscribe (ENG-56), Product news (ENG-82, ENG-92) ===== */

/* A page may show a name that a visitor typed: one too long for the line breaks inside itself. */
.confirmation-page,
.school-pick-page,
.unsubscribe-page,
.stop-product-news-page,
.extend-product-news-page { display: grid; gap: 16px; justify-items: start; padding-top: 56px; padding-bottom: 72px; overflow-wrap: anywhere; }
.confirmation-page > *,
.school-pick-page > *,
.unsubscribe-page > *,
.stop-product-news-page > *,
.extend-product-news-page > * { max-width: 640px; }
/* The school-pick forms and the confirmation form: as wide as a phone lets them be, and no wider than a field reads
   well. */
.school-pick-page .form,
.confirmation-page-form { width: 100%; max-width: 480px; }

/* The Product news question above the confirmation button (ENG-82), in a card: the question, the line under it, the
   error, two answers alike and the fine print. No design of variant D has it; the maintainer chose this layout on
   2026-10-16. */
/* The card is a box around the fieldset: an edge on the fieldset itself would run through the middle of its legend. */
.confirmation-page-news { padding: 16px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-sm); }
.confirmation-page-news-fieldset { display: grid; gap: 12px; }
/* A legend stands outside its fieldset's grid, so the gap does not reach it: it keeps its own space below. */
.confirmation-page-news-question { padding: 0 0 6px; font-size: 16px; font-weight: 600; line-height: 1.4; }
.confirmation-page-news-line { font-size: 15px; line-height: 1.5; }
/* The line that says to choose an answer, in place of a required mark (ENG-94). */
.confirmation-page-news-instruction { font-size: 15px; font-weight: 600; line-height: 1.5; }
.confirmation-page-news-answers { display: grid; gap: 8px; }
/* The whole row is the radio's label, so the full width is the pointer target. Its edge takes --border-field, as a
   text field's does: it alone shows where the row is, so it needs 3:1 (WCAG 1.4.11). Slate-500 is 3.7:1 on white and
   3.2:1 on the hover's paper-2. Once chosen, the row turns green-700 on green-50, 5.1:1. */
.confirmation-page-news-answer { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: center; min-height: 52px; padding: 12px 14px; border: 1.5px solid var(--border-field); border-radius: var(--radius-md); background: var(--surface); font-weight: 500; line-height: 1.3; cursor: pointer; }
.confirmation-page-news-answer:hover { background: var(--surface-2); }
.confirmation-page-news-answer:has(.radio:checked) { border-color: var(--brand-strong); background: var(--brand-tint); }
.confirmation-page-news-answer:has(.radio[aria-invalid="true"]) { border-color: var(--accent); }
.confirmation-page-news-fine-print { font-size: var(--text-small); line-height: 1.5; color: var(--text-muted); }

/* ===== Cohort bar (landing/blocks/cohort_bar.html): one block for the Player card and the Cohort list ===== */

/* The server draws it as inline SVG, so its fill width is an attribute, never a style. */

.cohort-bar { display: block; width: 100%; height: 8px; border-radius: var(--radius-pill); overflow: hidden; }
.cohort-bar-track { fill: var(--color-green-100); }
.cohort-bar-fill { fill: var(--brand); }
.cohort-bar-full .cohort-bar-fill { fill: var(--color-green-500); }

/* ===== Cohort list (ENG-54): the race between Medical schools, below the tiles ===== */

/* A class that sets display would show an element the template or cohort-list.js hides. */
.cohort-list [hidden] { display: none; }
.cohort-list-card { display: grid; gap: 12px; padding: 20px; }
.cohort-list-title { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; }
.cohort-list-live { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.cohort-list-live::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--color-coral-500); }
/* The dot blinks three times, then rests: a visitor has no way to stop a blink that goes on. */
@media (prefers-reduced-motion: no-preference) {
  .cohort-list-live::before { animation: cohort-list-blink 1.6s 3; }
}
@keyframes cohort-list-blink { 50% { opacity: .25; } }
.cohort-list-rows { display: grid; gap: 4px; }
.cohort-list-row { display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 12px; border: 1.5px solid transparent; border-radius: var(--radius-md); }
.cohort-list-row:hover { background: var(--surface-2); }
/* The school picked in the form. */
.cohort-list-row-picked, .cohort-list-row-picked:hover { border-color: var(--brand); background: var(--brand-tint); }
.cohort-list-number { font-family: var(--font-mono); font-weight: 700; color: var(--text-muted); }
.cohort-list-body { display: grid; gap: 6px; min-width: 0; }
.cohort-list-school { display: flex; gap: 8px; align-items: baseline; min-width: 0; }
/* The names stay on one line and cut off with an ellipsis. The acronym never shrinks: any shrinking would cut it, so
   the full name and the country give way. A school without an acronym shows its full name in bold, which then gives
   way, and the country stays. */
.cohort-list-school b, .cohort-list-name { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.cohort-list-school b, .cohort-list-school-without-acronym .cohort-list-name { flex-shrink: 0; }
.cohort-list-school-without-acronym b { flex-shrink: 1; }
.cohort-list-name { font-size: 12px; color: var(--text-muted); }
.cohort-list-meta { display: flex; justify-content: space-between; gap: 12px; font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
.cohort-list-gap { font-family: var(--font-mono); line-height: 1; text-align: center; color: var(--text-muted); }
.cohort-list-empty { padding: 4px; color: var(--text-muted); }

/* "Show all": a details element. Its summary is a small button that names what it does next, quieter than a row's
   Join. */
.cohort-list-show-all { display: grid; gap: 12px; }
.cohort-list-toggle { justify-self: start; background: transparent; color: var(--brand-strong); list-style: none; box-shadow: inset 0 0 0 1.5px var(--border-strong); }
.cohort-list-toggle::-webkit-details-marker { display: none; }
.cohort-list-toggle:hover { background: var(--brand-tint); }
.cohort-list-show-all[open] .cohort-list-show-all-label, .cohort-list-show-all:not([open]) .cohort-list-show-top-label { display: none; }
/* With the whole list open, the pinned row would show its school twice. */
.cohort-list-card:has(.cohort-list-show-all[open]) .cohort-list-pinned { display: none; }
/* The search is a .field with an .input. The status keeps its line while it says nothing, so the rows under it stay
   put when it speaks. */
.cohort-list-search-status { min-height: 1.55em; font-size: var(--text-small); color: var(--text-muted); }

/* ===== Player card page (ENG-52): the card on a green stage, with the controls to share it ===== */

.player-card-page { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "intro stage" "share stage"; column-gap: 56px; row-gap: 28px; align-content: start; padding-top: 48px; padding-bottom: 72px; }
.player-card-page-intro { grid-area: intro; display: grid; gap: 16px; align-self: end; }
.player-card-page-share { grid-area: share; display: grid; gap: 10px; justify-items: start; align-content: start; }
.player-card-page [hidden] { display: none; }
.player-card-page-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; }
.player-card-page-actions:not(:has(> :not([hidden]))) { display: none; }
.player-card-page-link-label { font-family: var(--font-mono); font-size: var(--text-label); font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--text-muted); }
.player-card-page-link { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; padding: 10px 10px 10px 16px; border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface); }
.player-card-page-link a { font-family: var(--font-mono); font-weight: 700; font-size: 16px; overflow-wrap: anywhere; }
.player-card-page-copy { border-radius: var(--radius-sm); background: var(--brand-tint); color: var(--brand-strong); }
.player-card-page-copy:hover { background: var(--color-green-100); }
.player-card-page-stage { grid-area: stage; display: grid; place-items: center; padding: 48px 32px; border-radius: var(--radius-lg); background: radial-gradient(520px 320px at 85% -10%, rgba(15, 169, 114, .9), transparent 60%), var(--color-green-700); }
/* A claimed card: its number in the brand colour, as the image draws it. */
.player-card-page-card .pcard-number { color: var(--brand-strong); }
.player-card-page-cohort { display: grid; grid-template-columns: minmax(48px, 150px) auto; gap: 10px; align-items: center; }

/* ===== Error pages (ENG-64): the status, a heading, one line and the way back, on paper ===== */

.error-page { display: grid; justify-items: start; align-content: center; gap: 20px; min-height: min(560px, 70vh); padding-top: 48px; padding-bottom: 96px; }
.error-page .h2 { max-width: 18ch; }
.error-page .lead { max-width: 60ch; }
.error-page .btn { margin-top: 8px; }

/* ===== Footer ===== */

.footer { border-top: 1px solid var(--border); padding: 28px 0; }
.footer-inner { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; align-items: center; }
.footer-about { display: grid; gap: 4px; max-width: 620px; font-size: var(--text-small); color: var(--text-muted); }
.footer-about .wordmark { justify-self: start; margin-bottom: 4px; }
/* The invitation to partners (ENG-83). Its link is a box of its own, so a pointer has a target at least 24 px tall:
   inline, a link is only as tall as its line of small text. */
.footer-partnership a { display: inline-flex; align-items: center; min-height: 24px; }
.footer-links { display: flex; gap: 8px 20px; flex-wrap: wrap; font-size: var(--text-small); color: var(--text-muted); }

/* ===== Privacy notice ===== */

/* A page of text on paper, about 75 characters to a line. The reset above strips lists of their markers and
   everything of its margins, so the notice puts them back. A table too wide for the screen scrolls in its own box. */
.privacy-notice-page { max-width: 760px; padding-top: 24px; padding-bottom: 72px; }
.privacy-notice-version-id { font-family: var(--font-mono); font-size: var(--text-label); font-weight: 500; letter-spacing: .08em; color: var(--text-muted); }
.privacy-notice { display: grid; gap: 14px; margin-top: 10px; font-size: 16px; }
.privacy-notice h1 { font-family: var(--font-display); font-weight: 800; font-size: clamp(30px, 4.2vw, 46px); line-height: 1.05; letter-spacing: -.03em; }
.privacy-notice h2 { margin-top: 22px; font-family: var(--font-display); font-weight: 700; font-size: 22px; line-height: 1.2; letter-spacing: -.02em; }
.privacy-notice-version-line { color: var(--text-muted); }
.privacy-notice ul, .privacy-notice ol { display: grid; gap: 6px; padding-left: 24px; }
.privacy-notice ul { list-style: disc; }
.privacy-notice ol { list-style: decimal; gap: 10px; }
.privacy-notice li > ul { margin-top: 6px; }
.privacy-notice li::marker { color: var(--text-muted); }
.privacy-notice-table { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.privacy-notice table { width: 100%; border-collapse: collapse; font-size: var(--text-small); }
.privacy-notice-table-wide table { min-width: 640px; }
.privacy-notice th, .privacy-notice td { padding: 10px 12px; border-top: 1px solid var(--border); text-align: left; vertical-align: top; }
.privacy-notice thead th { border-top: 0; background: var(--surface-2); }
.privacy-notice tbody th { font-weight: 600; }

/* ===== Narrow screens ===== */

@media (max-width: 920px) {
  /* A smaller glow, kept in the top bar's corner behind the language toggle, so no small text sits on it. */
  .hero { background: radial-gradient(300px 160px at 100% 0, rgba(15, 169, 114, .9), transparent 60%), var(--color-green-700); }
  .hero-grid { grid-template-columns: 1fr; grid-template-areas: "head" "card" "lead" "form"; min-height: 0; row-gap: 18px; padding-top: 12px; }
  .hero-card { gap: 14px; }

  /* The compact card, above the form. */
  .pcard { width: 100%; aspect-ratio: auto; grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); grid-template-rows: none; column-gap: 20px; row-gap: 12px; padding: 16px 18px; transform: rotate(-1deg); }
  .pcard-top, .pcard-foot { grid-column: 1 / -1; }
  .pcard-number { font-size: 42px; }
  .pcard-ecg, .pcard-full-only { display: none; }
  .pcard-row:first-child { border-top: 0; padding-top: 0; }

  /* The card page keeps the full card: there, the card is the page. */
  .player-card-page { grid-template-columns: minmax(0, 1fr); grid-template-areas: "intro" "stage" "share"; padding-top: 28px; }
  .player-card-page-stage { padding: 32px 20px; }
  .player-card-page-card { aspect-ratio: 3 / 4; grid-template-columns: none; grid-template-rows: auto auto 1fr auto auto; padding: 22px; transform: rotate(-2.5deg); }
  .player-card-page-card .pcard-number { font-size: clamp(46px, 13vw, 64px); }
  .player-card-page-card .pcard-ecg { display: block; }
  .player-card-page-card .pcard-row:first-child { border-top: 1px dashed var(--border-strong); padding-top: 8px; }

  .tiles { padding-top: 56px; }
  .tile-grid { grid-template-columns: 1fr; }
  .prizes { padding: 24px; }
  .prize-grid { grid-template-columns: 1fr; }
  .rank-path { grid-template-columns: repeat(3, 1fr); row-gap: 28px; }
  .rank-path::before { display: none; }
  .team-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 560px) {
  .rank-path { grid-template-columns: 1fr 1fr; }
  .team-grid { grid-template-columns: 1fr; }
  .cohort-list-card { padding: 12px; }
  .cohort-list-row { grid-template-columns: 24px minmax(0, 1fr) auto; gap: 10px; padding: 10px 8px; }
}
