/* 2027 Kickoff registration microsite.
   Tokens lifted from the CoVet design system (covet-style-guide-package/DESIGN_SYSTEM.md).
   ponytail: hand-written CSS, no Tailwind build step — this is six pages. */

:root {
  --blue: #00A3E8;
  --dark: #002D4F;
  --navy: #00609B;
  --gray-dark: #393939;
  --gray: #595959;
  --gray-light: #A7A7A7;
  --border: #CACCCC;
  --off-white: #E4E6E6;
  --bg: #F2F4F8;
  --card: #FAFAFA;
  --gold-light: #E8A667;
  --danger: #B3261E;
  --danger-bg: #FCEEED;
  --warn-bg: #FDF3E8;
  --ok: #1B7F4B;
  --ok-bg: #EAF6EF;
  --radius: 12px;   /* matches the R2 mock's panel corners; cards follow it */
  --shadow: 0 1px 3px rgba(0, 45, 79, .08), 0 6px 18px rgba(0, 45, 79, .06);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Plus Jakarta Sans", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--gray-dark);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--navy); }
a:hover { color: var(--blue); }

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

.demobar {
  background: var(--gold-light); color: #4A2E0B; text-align: center;
  font-size: .8125rem; padding: .5rem 1rem;
}
.demobar strong { font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.demobar a { color: #4A2E0B; font-weight: 700; margin-left: .5rem; }

/* Three columns rather than space-between, so the logo is centred on the PAGE and not merely
   in the space the nav leaves over. The empty first column is what balances the nav, which
   means the logo stays put whether or not somebody is signed in — otherwise it would shift
   sideways the moment an email address appeared on the right. minmax(0,…) lets the side
   columns shrink instead of forcing the header wider than the screen. */
.topbar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 1rem; padding: .75rem 1.5rem;
  background: #fff; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 20;
}
.topbar-brand { grid-column: 2; justify-self: center; display: flex; align-items: center; }
.topbar-nav {
  grid-column: 3; justify-self: end; min-width: 0;
  display: flex; align-items: center; gap: 1rem; font-size: .875rem;
}
.topbar-who { color: var(--gray-light); }

/* A centred logo has to share its row with the nav, and on a phone a full work email does not
   fit beside it — it printed straight across the logo, and "Sign out" wrapped onto two lines.
   The address drops out below 640px; "Sign out" is the only thing there you can act on, so
   that is what stays. */
@media (max-width: 640px) {
  .topbar { padding: .75rem 1rem; gap: .5rem; }
  .topbar-who { display: none; }
  .topbar-nav { white-space: nowrap; }
}

.wrap { max-width: 760px; margin: 0 auto; padding: 2rem 1.5rem 5rem; }
.wrap-wide { max-width: 1400px; margin: 0 auto; padding: 2rem 1.5rem 5rem; }
/* Edge to edge — the home page's hero is full-bleed and each section holds its own
   container, so <main> imposes nothing. `wrap-hero` went with it. */
.full { width: 100%; }

/* ------------------------------------------------------- full-bleed hero */

/* The home page hero: photo across the full width, with the title, location and dates as
   real text on top. The photo has no text baked in, so the wording is editable here.

   It keeps its own proportions rather than being squeezed into a fixed strip — cropping it
   shorter cut the tops of people's heads off. Capped so it can't eat a whole wide monitor. */
/* Everything in the hero is sized off one unit, `--u` = 1% of the viewport width, so the
   whole block — height, card, type, padding — scales together as the window widens. Every
   number below is the R2 mock's pixel value / 14.4 (the mock is 1440 wide).

   Deliberately NOT `aspect-ratio` + `max-height`: once max-height bites, aspect-ratio
   shrinks the WIDTH to match and the hero stops short of the right edge. The 78vh ceiling
   only crops the photo — the card and its type keep scaling with the width either way, so
   the sign-in button can't be pushed off a short screen. */
.hero-full {
  --u: 1vw;
  position: relative; background: var(--dark);
  width: 100%; height: min(calc(38.82 * var(--u)), 78vh); overflow: hidden;
}
.hero-full picture, .hero-full img {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
/* The photo is 2:1 and this slot is ~2.58:1, so about a fifth of the height has to go. `top`
   cut the front row's legs off; `bottom` kept everyone but left a band of empty sand under
   them. 66% sits between the two — everyone in frame, a little sand beneath them, and the
   card hanging over the sky above.

   A percentage, not the pixel offsets this was eyeballed at: the hero's height scales with the
   viewport width, so the slack to move within is only ~147px at 1365 wide and under 100px
   below about 900 wide — a fixed offset overshoots into a dark band at the top. A percentage
   holds the same framing at every width. At 1365 wide, 34 points ~= 50px.

   All of this is a fudge for a 2:1 photo in a 2.58:1 slot. A re-cut 2.576:1 file needs none
   of it — see the safe-area note in welcome.html. */
.hero-full img { object-fit: cover; object-position: center 66%; display: block; }

/* The translucent slab hanging off the top edge — 828x169 at 1440, square on top, 32px
   round below. 85% white measured off the mock against the untouched photo. */
.hero-card {
  position: relative; z-index: 1;
  width: calc(57.5 * var(--u)); margin: 0 auto;
  background: rgba(255, 255, 255, .85);
  border-radius: 0 0 calc(2.22 * var(--u)) calc(2.22 * var(--u));
  padding: calc(2.19 * var(--u)) calc(2 * var(--u)) calc(2.33 * var(--u));
  text-align: center;
}
/* Sizes solved against the mock, not guessed: 56px cap height / 0.757 (Plus Jakarta Sans'
   measured cap ratio) = 74px, and the tracking was whatever made the line 753px wide.
   Same method for the subline: 14px cap, 464px wide.

   The tracking is now -.02em rather than the mock's -.042em: at -.042em the E and T of COVET
   very nearly touch. That costs width — the line was filling 817 of the card's 836px, so
   loosening it alone wrapped the title onto two lines. The font-size drops 5.14 -> 4.9vw to
   pay for it, which is the smaller of the two compromises: the slab's width is measured off
   the mock, the cap height is derived. Both are in vw, so the fit holds at every viewport
   above the 700px breakpoint rather than only at 1440. */
.hero-card h1 {
  color: var(--blue); margin: 0;
  font-size: calc(4.9 * var(--u));
  font-weight: 800; line-height: 1; letter-spacing: -.02em;
  text-transform: uppercase;
}
.hero-sub {
  color: var(--blue); margin: calc(.79 * var(--u)) 0 0;
  font-size: calc(1.285 * var(--u));
  font-weight: 400; line-height: 1; letter-spacing: .243em;
  text-transform: uppercase;
}
.hero-sub strong { font-weight: 800; }

/* Below ~700px the vw maths gives a postage stamp, so the card goes full width and the
   photo gets a taller crop. */
@media (max-width: 700px) {
  .hero-full { height: 62vw; min-height: 300px; }
  .hero-card {
    width: 100%; border-radius: 0; padding: 1.25rem 1rem 1.375rem;
  }
  .hero-card h1 { font-size: clamp(1.625rem, 7.6vw, 2.5rem); }
  .hero-sub { font-size: clamp(.6875rem, 2.9vw, 1rem); letter-spacing: .12em;
              margin-top: .5rem; }
}

/* ------------------------------------------- white band under the hero */

/* A secondary section rather than a floating card: full-width, flush under the photo, with
   its own inner container.

   Solid white, not the old white-to-CoVet-card gradient. The gradient ended on exactly the
   colour the boxes inside it are filled with, so a card-tinted panel dissolved into the
   background at the bottom of the band — which is what forced a border onto it. White here
   means the tint alone is enough to define a box. */
.band {
  background: #fff;
  border-bottom: 1px solid var(--border);
}
/* 800 wide content, 48px in from the top, then a flat 32px between every block — measured
   off the R2 mock. */
.band-inner {
  max-width: 832px; margin: 0 auto; padding: 3rem 1.5rem 3.5rem; text-align: center;
}
/* The band's type scale, as Philippe marked it up on review: a display headline, a
   second-level line under it, then supporting sublines. The subline tier is `.lede`, which
   already existed at the right size — reused rather than duplicated.

   heading-lg, in CoVet Blue — the reference mock uses the brand blue here, not navy. The
   bottom margin is small because `.band-sub` now sits directly underneath; the old 2rem gap
   belonged to a headline that stood alone. */
.band-head {
  font-size: 40px; font-weight: 800; line-height: 1.05; letter-spacing: -.02em;
  color: var(--blue); margin: 0 0 .75rem;
}
@media (max-width: 1023px) { .band-head { font-size: 28px; } }

/* Second level, directly under the headline. Navy rather than blue: two blues stacked read
   as one headline that wrapped, which is the opposite of a hierarchy. */
.band-sub {
  font-size: 24px; font-weight: 700; line-height: 1.25; letter-spacing: -.01em;
  color: var(--dark); margin: 0 0 1.5rem;
}
@media (max-width: 1023px) { .band-sub { font-size: 19px; } }

/* The subline tier. Scoped to `.band-inner` on purpose: `.lede` is 17px against 16px body
   text, which is a 1px difference nobody can see — but it is used on ten other pages, so the
   size bump belongs here rather than on the shared class.

   Also on a readable measure instead of the full 832px: a centred paragraph running the whole
   band width is hard to track back to the start of the next line. */
.band-inner .lede {
  font-size: 20px; line-height: 1.45; color: var(--gray);
  max-width: 60ch; margin-inline: auto;
}
@media (max-width: 640px) { .band-inner .lede { font-size: 17px; } }

/* The deadline: brand blue, white semi-bold text. It is the only thing in the band with a
   date attached, so it gets the loudest treatment. inline-block so the box hugs the sentence
   rather than spanning the band.

   ACCESSIBILITY, decided rather than overlooked: white on --blue measures 2.84:1. At 20px/600
   this counts as large text, so the WCAG AA bar is 3.0:1 — it misses by 0.16. Philippe was
   shown the measurement and a --navy alternative at 6.67:1 on 4 Aug 2026 and chose to keep the
   brand blue. Leave it. Swapping --blue for --navy is the one-word fix if an audit ever
   requires it; it needs a brand decision, not a tidy-up. */
.band-callout {
  display: inline-block;
  background: var(--blue);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 1rem 1.5rem; margin: 0 auto 1.5rem;
}
.band-callout h3 {
  font-size: 20px; font-weight: 600; line-height: 1.35;
  color: #fff; margin: 0;
}
@media (max-width: 640px) {
  .band-callout { padding: .875rem 1.125rem; }
  .band-callout h3 { font-size: 17px; }
}

/* The sign-in block, boxed so the one thing you actually have to do doesn't sit loose at the
   bottom of a wall of copy. Card tint and the standard shadow, no stroke — the shadow is what
   separates it from the white band now, which is why the band above is no longer a gradient
   ending on this same colour.

   A heavier shadow than the shared `--shadow` token: with the stroke gone and only 2% of tint
   between the box and the white band, the shadow is doing all the work of separating them, so
   it is deepened to ~12–14% rather than the token's 6–8%. */
.band-signin {
  background: var(--card); border: 0;
  border-radius: var(--radius);
  box-shadow: 0 1px 3px rgba(0, 45, 79, .12), 0 8px 24px rgba(0, 45, 79, .14);
  padding: 2rem 1.75rem 1.75rem;
}

/* The anchor target for "confirm your attendance below". scroll-margin clears the sticky
   topbar, same reason `.card` carries one. */
#start { scroll-margin-top: 5rem; }
.band-signin .signin-note { margin-bottom: 1.5rem; }
.band-signin .band-note { margin-bottom: 0; }
@media (max-width: 640px) { .band-signin { padding: 1.5rem 1.125rem 1.25rem; } }

/* Centred text orphans its last word far too easily — every headline and paragraph in the
   band gets its lines evened out rather than fixing them one at a time. */
.band-inner p, .band-inner h2, .band-inner h3 { text-wrap: balance; }

/* ---------------------------------------------------- vertical rhythm in the band

   Doubled from the R2 mock's spacing, on Philippe's review: the band read as one dense
   block. Five of the seven gaps are doubled; the headline-to-subhead gap and the
   pastel-de-nata-to-contact gap are deliberately left alone, because tightness is what
   binds those two pairs together as single thoughts.

   A gap between siblings is the LARGER of the two facing margins, not their sum, so each one
   is set from a single side only — otherwise the numbers here wouldn't match what you measure
   on screen. All of these are `.band-inner > x` so they beat the shared `.lede` / `.card`
   rules regardless of where those sit in the file, and so the identically-classed heading
   INSIDE the sign-in box is not dragged along with them. */
.band-inner > .band-sub     { margin-bottom: 3rem; }   /* was 1.5rem — subhead to intro */
.band-inner > .band-intro   { margin-bottom: 2rem; }   /* was 1rem   — intro to instructions */
.band-inner > .band-para    { margin: 2rem 0; }        /* was 1em    — instructions to deadline */
.band-inner > .band-callout { margin-bottom: 3rem; }   /* was 1.5rem — deadline to sign-off */
.band-inner > .band-contact { margin-bottom: 1.5rem; } /* contact to the Rippling notice */

/* The Rippling notice sits between the contact line and the sign-in box, and inherits the
   4rem the contact line used to own. Left-aligned on a readable measure rather than centred
   with the rest of the band: it is four sentences, and the file already notes that a centred
   paragraph running the full band width is hard to track back to the next line. */
.band-inner > .band-notice {
  max-width: 60ch; margin: 0 auto 4rem; text-align: left;
}

/* "For any questions, reach out to Dyanca, Carla, or Megan." — brand blue, because it is the
   one line on the page telling you there are humans behind this. */
.band-contact {
  font-size: 16px; font-weight: 600; line-height: 1.4;
  color: var(--blue); margin: 0 0 2rem;
}

/* Vertical only — the shorthand would reset the `margin-inline: auto` that centres
   `.deadline-soft`, and this selector is the more specific of the two. */
.band-inner .deadline { margin-top: 0; margin-bottom: 2rem; }
.band-note { margin-top: 1rem; }
@media (max-width: 640px) { .band-inner { padding: 2.25rem 1.25rem 2.75rem; } }

/* Two lines, deliberately different weights: the instruction reads first, the practical
   detail second. Measured at 16px in the reference. */
.signin-lead {
  font-size: 16px; font-weight: 600; line-height: 1.375;
  color: var(--gray-dark); margin: 0;
}
.signin-note {
  font-size: 16px; font-weight: 400; line-height: 1.375;
  color: var(--gray); margin: 0 0 2rem;
}
@media (max-width: 640px) {
  .signin-lead, .signin-note { font-size: 15px; }
}

.subtle {
  font-size: 14px; font-weight: 400; line-height: 1.4; letter-spacing: -.01em;
  color: var(--gray); margin: 0 0 1rem;
}

/* "You're 20 of 41 questions in." */
.statusline { font-size: 1rem; font-weight: 600; color: var(--dark); margin: 0 0 .625rem; }
.statusline.ok { color: var(--ok); }
.statusline.bad { color: var(--danger); }
.band-inner .progress-track { width: 100%; margin: 0 auto .75rem; }

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

/* A slimmer crop of the same image for the top of the form. Only ~48% of the photo's height
   fits in this 170px band, so where it lands matters more than in the hero: 72% shows image
   rows 38%-85%, which is the raised arms down to the front row with the sand below them just
   out of frame. Lower than that and the front row loses its legs. */
.hero-strip {
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
  margin-bottom: 1.75rem; height: 170px; background: var(--dark);
}
.hero-strip img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: center 72%;
}
@media (max-width: 640px) { .hero-strip { height: 120px; } }

.footer {
  border-top: 1px solid var(--border); background: #fff;
  padding: 1.5rem; text-align: center; font-size: .8125rem; color: var(--gray-light);
}
.footer p { margin: .25rem 0; }

/* -------------------------------------------------------------- typography */

/* One rule carries the R2 look across the site: the 32px heading is CoVet Blue, everything
   smaller stays navy. Blue on white is only 2.8:1, so keeping it to display sizes is what
   stops the weak contrast reaching body-scale text. */
h1 { font-size: 2rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.1;
     color: var(--blue); margin: 0 0 .75rem; }
h2 { font-size: 1.3125rem; font-weight: 700; letter-spacing: -.01em;
     color: var(--dark); margin: 0 0 .25rem; }
h3 { font-size: 1rem; font-weight: 700; color: var(--dark); margin: 0 0 .5rem; }
.lede { font-size: 1.0625rem; color: var(--gray); margin: 0 0 1rem; }
.muted { color: var(--gray); font-size: .875rem; }
.tag { font-size: .75rem; font-weight: 800; letter-spacing: .08em;
       text-transform: uppercase; color: var(--navy); }

/* ------------------------------------------------------------------ deadline */

/* Same blue panel as the home page, so the deadline looks like one thing wherever it turns
   up — form, review, home. 12px radius and the soft outer shadow come from the R2 mock. */
.deadline {
  background: var(--blue); color: #fff; border-radius: 12px;
  padding: 1.25rem 1.5rem; margin: 1.5rem 0; text-align: center;
  box-shadow: 0 2px 6px rgba(0, 45, 79, .10), 0 10px 26px rgba(0, 45, 79, .12);
}
.deadline .tag { color: #fff; }
.deadline strong { display: block; font-size: 1.75rem; font-weight: 800;
                   letter-spacing: -.02em; margin-top: .25rem; }
@media (max-width: 640px) { .deadline strong { font-size: 1.375rem; } }

/* Home page variant — just the mock's 520x87 box; the blue, radius and shadow now come
   from `.deadline` itself. */
.deadline-soft {
  max-width: 520px; margin-left: auto; margin-right: auto; padding: .88rem 1.5rem;
}
.deadline-soft .tag { font-size: 12px; }
.deadline-soft strong { font-size: 28px; line-height: 1.1; margin-top: .25rem; }
@media (max-width: 640px) { .deadline-soft strong { font-size: 22px; } }

/* No accent stripe down the left edge — Philippe's call, and he's right: it's decoration
   standing in for hierarchy. The tint carries the meaning instead, with a hairline in the
   same hue so the block still has an edge against the page. */
/* ----------------------------------------------------------- booking sheet */

/* The People Team's working surface: one reservation's worth of detail, dense enough to sit
   beside an airline's booking form without scrolling. Two columns on a wide screen, one on a
   narrow one; free-text rows span the full width because they're read, not copied. */
.bookingsheet .help { margin: -.25rem 0 1.25rem; }
.booking-group {
  font-size: .75rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--navy); margin: 1.5rem 0 .5rem; padding-bottom: .375rem;
  border-bottom: 1px solid var(--border);
}
.booking-group:first-of-type { margin-top: 0; }

.booking-rows {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 2rem; margin: 0;
}
.booking-row { padding: .5rem 0; min-width: 0; }
.booking-row.wide { grid-column: 1 / -1; }
.booking-row dt { font-size: .8125rem; color: var(--gray); margin: 0 0 .125rem; }
.booking-row dd { margin: 0; font-size: .9375rem; font-weight: 600; min-width: 0; }
@media (max-width: 720px) { .booking-rows { grid-template-columns: 1fr; } }

/* A button, not a span: copying is an action, and this way it's reachable from the keyboard
   and announced as clickable rather than looking like inert text. */
.copyval {
  font: inherit; text-align: left; color: var(--dark);
  background: none; border: 0; border-radius: 6px; padding: .125rem .375rem;
  margin-left: -.375rem; cursor: pointer; max-width: 100%;
  overflow-wrap: anywhere; white-space: pre-line;
}
.copyval:hover { background: var(--bg); }
.copyval:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.copyval.copied { background: var(--ok-bg); color: var(--ok); }
.copyval.copied::after { content: " copied"; font-size: .75rem; font-weight: 700; }
/* Copy failed and we selected the text instead — say so rather than let it look copied. */
.copyval.copyfailed { background: var(--warn-bg); color: #7A4A12; }
.copyval.copyfailed::after { content: " press Ctrl+C"; font-size: .75rem; font-weight: 700; }

.booking-row .missing { color: var(--danger); font-weight: 600; font-size: .875rem; }
.booking-row .none { color: var(--gray-light); font-weight: 500; }

.bookingsheet .banner { margin-bottom: 0; }

.banner {
  border-radius: var(--radius); padding: 1rem 1.25rem; margin: 1.5rem 0;
  background: #fff; box-shadow: var(--shadow); border: 1px solid transparent;
}
.banner-warn  { background: var(--warn-bg);   border-color: #EBCBA6; box-shadow: none; }
.banner-error { background: var(--danger-bg); border-color: #EFC9C6; box-shadow: none; }
.banner-ok    { background: var(--ok-bg);     border-color: #BFE0CD; box-shadow: none; }
.banner p:first-child { margin-top: 0; }
.banner p:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------- cards */

.card {
  background: #fff; border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 1.75rem; margin-bottom: 1.25rem;
}
/* Jump targets sit under a sticky topbar and section nav, so they need headroom:
   `#review-<section>` on the review page, `#field-<key>` from its list of problems. */
.card, .card > h2 { scroll-margin-top: 5rem; }
.field { scroll-margin-top: 7rem; }
.section-hint { color: var(--gray); font-size: .875rem; margin: 0 0 1.5rem; }

/* -------------------------------------------------------------- section nav */

.sectionnav {
  position: sticky; top: 3.75rem; z-index: 10;
  background: var(--bg); padding: .75rem 0; margin-bottom: 1rem;
  display: flex; gap: .375rem; flex-wrap: wrap;
}
.sectionnav a {
  font-size: .8125rem; font-weight: 600; text-decoration: none;
  padding: .375rem .75rem; border-radius: 999px;
  background: #fff; border: 1px solid var(--border); color: var(--gray);
}
.sectionnav a:hover { border-color: var(--blue); color: var(--navy); }
.sectionnav a.done { border-color: var(--ok); color: var(--ok); }
.sectionnav a.done::before { content: "✓ "; }
.sectionnav a.bad { border-color: var(--danger); color: var(--danger);
                    background: var(--danger-bg); }
.sectionnav a .count {
  display: inline-block; min-width: 1.125rem; margin-left: .25rem;
  background: var(--danger); color: #fff; border-radius: 999px;
  font-size: .6875rem; font-weight: 800; text-align: center;
}

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

.field { margin-bottom: 1.5rem; }
.field:last-child { margin-bottom: 0; }
.field > label, .field .field-label {
  display: block; font-weight: 600; font-size: .9375rem;
  color: var(--gray-dark); margin-bottom: .375rem;
}
.field .req { color: var(--danger); margin-left: .125rem; }
.field .help { font-size: .8125rem; color: var(--gray); margin: -.125rem 0 .5rem; }

/* `search` belongs in this list. Without it the admin's search box fell through to the
   browser's native control — 21px tall with a 2px inset border, beside 43px selects. */
input[type="text"], input[type="email"], input[type="tel"], input[type="date"],
input[type="search"], textarea, select {
  width: 100%; padding: .625rem .75rem; font: inherit; font-size: .9375rem;
  color: var(--gray-dark); background: #fff;
  border: 1px solid var(--border); border-radius: 8px;
}
/* The native dropdown arrow sits at whatever inset the browser picks — in Chrome it's tight
   against the right edge, so the chevron looked pinned while the text had .75rem of air on the
   left. Swapping in our own chevron is the only way to control that gap: it sits .75rem from
   the right edge, and the padding reserves .75rem + 12px chevron + .75rem so the space either
   side of it matches the text inset exactly. The SVG is inline as a data URI rather than a
   file so it can't 404 and costs no extra request. */
select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23595959' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .75rem center;
  padding-right: 2.25rem;
}

input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(0, 163, 232, .15);
}
input:disabled, textarea:disabled, select:disabled {
  background: var(--bg); color: var(--gray); cursor: not-allowed;
}
textarea { min-height: 5.5rem; resize: vertical; }
input::placeholder { color: var(--gray-light); }

/* Native date input keeps its own control — we just size it consistently. */
input[type="date"] { max-width: 16rem; }

.choices { display: flex; gap: 1.25rem; flex-wrap: wrap; }
.choice, .check {
  display: flex; align-items: flex-start; gap: .5rem;
  font-size: .9375rem; font-weight: 500; cursor: pointer;
}
.choice input, .check input {
  width: 1.125rem; height: 1.125rem; margin: .125rem 0 0; accent-color: var(--blue);
  flex: none; cursor: pointer;
}
.check { align-items: flex-start; }
/* `.field > label` (0,1,1) outranks `.check` (0,1,0), so a checkbox label inside a .field fell
   back to display:block: it lost `.check`'s gap, and as an inline element the 18px box sat on
   the text baseline, riding high above the x-height. This restores the flex row the class was
   written for. No checkbox questions exist in fields.py today, so it currently affects only the
   admin deadline toggle.

   `center` rather than `.check`'s flex-start, and margin-top cleared, because Philippe asked for
   the box to sit lower — on one line of label that reads level. If a longer label ever wraps in
   these narrow panels the box will centre across both lines; switch back to flex-start with a
   ~2px margin-top if that turns up. 4px gap, also his call. */
.field > label.check {
  display: flex; align-items: center; gap: .25rem;
  font-weight: 500; margin-bottom: .375rem;
}
.field > label.check input { margin-top: 0; }

.field.has-error input, .field.has-error textarea, .field.has-error select {
  border-color: var(--danger); background: var(--danger-bg);
}
.field-error { font-size: .8125rem; color: var(--danger); font-weight: 600;
               margin-top: .375rem; }

.note {
  background: var(--bg); border: 1px solid var(--off-white);
  border-radius: 8px; padding: .75rem 1rem; font-size: .875rem; color: var(--gray);
  margin-bottom: 1.5rem;
}

/* ------------------------------------------------------- file input (roster CSV)

   The only upload left in the app is the People Team's roster CSV — the `.upload` /
   `.upload-state` rules that used to dress the passport drop zone went with it.

   A file input is two things the browser draws for you: a system button, reachable via
   ::file-selector-button, and the "No file chosen" label, which is the input's OWN text and
   inherits from it. So the button takes the blue CTA treatment and the input itself takes the
   fine-print treatment. It sits inside a .toolbar, so the 2.5rem row height already applies —
   the button fills that height instead of adding padding of its own and pushing the row taller
   than the Upload button beside it. */
input[type="file"] {
  font: inherit; font-size: .8125rem; color: var(--gray-light);
  padding: 0; border: 0; background: none;
}
/* Secondary, not primary: picking a file is a step on the way, and "Upload roster" beside it
   is the button that actually does something. The blue belongs on the action. */
input[type="file"]::file-selector-button {
  height: 2.5rem; margin-right: .75rem; padding: 0 1.25rem;
  font: inherit; font-size: .9375rem; font-weight: 600;
  border: 1px solid var(--border); border-radius: 8px;
  background: #fff; color: var(--navy); cursor: pointer;
}
input[type="file"]::file-selector-button:hover { background: var(--bg); }
input[type="file"]:focus-visible::file-selector-button {
  outline: 2px solid var(--blue); outline-offset: 2px;
}

/* ----------------------------------------------------------------- buttons */

/* The CoVet style guide's CTA button — `button_cta_01`. 50px tall, 8px radius, 16px/600,
   16px/48px padding. The guide is explicit that the pill-shaped component is a reserve and
   should not be used on new pages, so `.btn-cta` is what new work should reach for. */
.btn-cta {
  display: inline-flex; align-items: center; justify-content: center;
  height: 50px; min-width: 100px; padding: 16px 48px;
  font: inherit; font-size: 16px; font-weight: 600; line-height: 1;
  border-radius: 8px; border: 1px solid transparent;
  background: var(--blue); color: #fff; cursor: pointer; text-decoration: none;
  text-align: center; transition: all .2s ease;
}
.btn-cta:hover { background: var(--navy); color: #fff; }

/* Google sign-in button, matched to the R2 mock rather than to `button_cta_01`: neutral
   charcoal so it reads as a third-party sign-in control, and a 13.5px label, which is what
   makes the mock's 258x50 come out (49 + 16 + 8 + 135 + 49). Philippe's call — the style
   guide's 16px label would make it 282 wide. */
.btn-google {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 50px; padding: 0 48px;
  font: inherit; font-size: 13.5px; font-weight: 600; line-height: 1;
  border-radius: 8px; border: 1px solid transparent;
  background: var(--gray-dark); color: #fff;
  cursor: pointer; text-decoration: none; transition: all .2s ease;
}
.btn-google:hover { background: var(--dark); color: #fff; }
.btn-google img { display: block; width: 16px; height: 16px; flex: none; }
@media (max-width: 640px) { .btn-google { padding: 0 28px; } }
/* button_cta_outline_blue — secondary CTA on light backgrounds. */
.btn-cta-outline {
  background: transparent; color: var(--blue);
  border-color: var(--blue); padding: 15px 32px;
}
.btn-cta-outline:hover { background: var(--blue); color: #fff; }
@media (max-width: 1023px) {
  .btn-cta { font-size: 14px; }
}

/* 8px corners and 600 weight, same as `.btn-cta` — the style guide is explicit that the
   pill shape is a reserve and shouldn't be used on new pages, and a pill here next to the
   home page's square-cornered CTA read as two different products. Only the size differs:
   this is the general-purpose button, `.btn-cta` is the 50px-tall hero one. */
.btn {
  display: inline-block; font: inherit; font-size: .9375rem; font-weight: 600;
  padding: .75rem 1.5rem; border-radius: 8px; border: 1px solid transparent;
  background: var(--blue); color: #fff; cursor: pointer; text-decoration: none;
  text-align: center;
}
.btn:hover { background: var(--navy); color: #fff; }
.btn:disabled { background: var(--gray-light); cursor: not-allowed; }
.btn-secondary { background: #fff; color: var(--navy); border-color: var(--border); }
.btn-secondary:hover { background: var(--bg); color: var(--navy);
                       border-color: var(--blue); }
.btn-danger { background: #fff; color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: var(--danger); color: #fff; }
.btn-sm { padding: .375rem .875rem; font-size: .8125rem; }
.actions { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center;
           margin-top: 2rem; }

/* ------------------------------------------------------------ save state */

.savestate {
  position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 30;
  background: var(--dark); color: #fff; font-size: .8125rem; font-weight: 600;
  padding: .5rem 1rem; border-radius: 999px;
  opacity: 0; transition: opacity .25s; pointer-events: none;
}
.savestate.show { opacity: 1; }
.savestate.err { background: var(--danger); }

/* ------------------------------------------------------------------ review */

.answers { border-top: 1px solid var(--border); }
.answer { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;
          padding: .75rem 0; border-bottom: 1px solid var(--border); }
.answer dt { font-size: .875rem; color: var(--gray); margin: 0; }
.answer dd { margin: 0; font-size: .9375rem; font-weight: 600;
             overflow-wrap: anywhere; white-space: pre-line; }
.answer dd.blank { color: var(--gray-light); font-weight: 500; font-style: italic;
                   white-space: normal; }
/* A missing answer is tinted across the whole row, not just the value — at a glance you
   want to spot the row, not read every label to find the red text. */
.answer.missing { background: var(--danger-bg); box-shadow: -.75rem 0 0 var(--danger-bg),
                  .75rem 0 0 var(--danger-bg); }
.answer.missing dd { color: var(--danger); font-weight: 600; font-style: normal; }
@media (max-width: 640px) {
  .answer { grid-template-columns: 1fr; gap: .125rem; }
}
.review-head { display: flex; justify-content: space-between; align-items: baseline;
               gap: 1rem; margin-bottom: 1rem; }
.editlink { font-size: .8125rem; font-weight: 700; white-space: nowrap; }

/* The list of what's still missing, inside the red banner. */
.fixlist { margin: .75rem 0 0; padding-left: 1.25rem; columns: 2; column-gap: 2rem; }
.fixlist li { font-size: .875rem; margin-bottom: .25rem; break-inside: avoid; }
.fixlist a { color: var(--danger); font-weight: 600; }
@media (max-width: 640px) { .fixlist { columns: 1; } }

.reviewbar { display: flex; align-items: center; justify-content: space-between;
             gap: 1rem; flex-wrap: wrap; margin: 1.5rem 0 .5rem; }
.progress { margin: 0; font-size: .875rem; color: var(--gray);
            display: flex; align-items: center; gap: .625rem; flex-wrap: wrap; }
.progress strong { color: var(--dark); }
.progress-track { display: block; width: 9rem; height: 6px; border-radius: 999px;
                  background: var(--off-white); overflow: hidden; }
.progress-fill { display: block; height: 100%; background: var(--ok); border-radius: 999px; }

.submitform { display: inline; }

/* --------------------------------------------------------------- confirmation */

.done-head { text-align: center; margin-bottom: 1.5rem; }
.done-head .lede, .done-head .muted { margin-left: auto; margin-right: auto;
                                      max-width: 34rem; }
.done-head .tick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3.25rem; height: 3.25rem; margin-bottom: .875rem;
  border-radius: 999px; background: var(--ok-bg); color: var(--ok);
  font-size: 1.75rem; font-weight: 800; line-height: 1;
  box-shadow: 0 0 0 6px rgba(27, 127, 75, .07);
}

.countdown .tag-quiet { display: block; margin-top: .5rem; color: var(--off-white);
                        font-weight: 600; letter-spacing: 0; text-transform: none;
                        font-size: .8125rem; }

.steps { margin: 1rem 0 0; padding: 0; list-style: none; counter-reset: step; }
.steps li {
  position: relative; counter-increment: step;
  padding: 0 0 1.25rem 2.75rem; font-size: .9375rem; color: var(--gray);
  border-left: 2px solid var(--off-white); margin-left: .875rem;
}
.steps li:last-child { border-left-color: transparent; padding-bottom: 0; }
.steps li::before {
  content: counter(step);
  position: absolute; left: -.9375rem; top: -.125rem;
  width: 1.75rem; height: 1.75rem; border-radius: 999px;
  background: var(--dark); color: #fff;
  font-size: .8125rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.steps strong { display: block; color: var(--dark); font-weight: 700; }

/* ------------------------------------------------------------------- table */

.tablewrap { overflow-x: auto; background: #fff; border-radius: var(--radius);
             box-shadow: var(--shadow); }
table { border-collapse: collapse; width: 100%; font-size: .875rem; }
th, td { text-align: left; padding: .625rem .75rem; border-bottom: 1px solid var(--border);
         white-space: nowrap; }
th { background: var(--bg); font-weight: 700; font-size: .8125rem;
     color: var(--dark); position: sticky; top: 0; }
tbody tr:hover { background: var(--card); }
td.wrap-cell { white-space: normal; min-width: 14rem; }

.pill { display: inline-block; font-size: .75rem; font-weight: 700;
        padding: .1875rem .5rem; border-radius: 999px; }
.pill-submitted { background: var(--ok-bg); color: var(--ok); }
.pill-draft { background: #FFF4E5; color: #8A5A16; }
.pill-none { background: var(--bg); color: var(--gray); }
.pill-flag { background: var(--danger-bg); color: var(--danger); }

/* The three things on this page you change rather than read: the deadline, one new starter,
   and the whole roster. Three across on a wide screen, and auto-fit reflows them to two or one
   as it narrows without needing a breakpoint. `align-items: start` stops the shortest card
   stretching to match the tallest. */
.adminpanels {
  display: grid; gap: 1.25rem; margin-top: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(17.5rem, 1fr));
  align-items: start;
}
.adminpanels .card { margin-bottom: 0; }
.adminpanels .field { margin-bottom: .875rem; }
/* These panels are narrow, so a control that insists on 12rem would overflow them.
   Checkboxes are excluded: a checkbox stretched to width:100% draws its glyph centred in a
   panel-wide box and shunts its own label onto the next line, which is how the "hide the
   deadline" toggle first shipped. Sized by `.check input` instead, like every other checkbox. */
.adminpanels input:not([type="checkbox"]), .adminpanels select { width: 100%; min-width: 0; }

.stats { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.stat { background: #fff; border-radius: var(--radius); box-shadow: var(--shadow);
        padding: 1rem 1.25rem; min-width: 8rem; }
.stat b { display: block; font-size: 1.75rem; font-weight: 800; color: var(--dark);
          line-height: 1.1; }
.stat span { font-size: .8125rem; color: var(--gray); }

/* The deadline is the one card that isn't a filter — a countdown isn't a set of people. It
   drops the shadow and greys its text so it reads as information sitting beside the controls
   rather than a button that doesn't respond when you click it. */
.stat-static { box-shadow: none; }
.stat-static b { color: var(--gray); }
.stat-static span { color: var(--gray-light); }

/* The counts double as filters. They have to read as pressable without turning into blue
   underlined links — the number is the thing you look at, so the affordance is the lift on
   hover and the blue fill when it's on. */
.stat-link {
  display: block; text-decoration: none; cursor: pointer;
  border: 1px solid transparent;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.stat-link:hover { transform: translateY(-2px); border-color: var(--blue); }
.stat-link:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.stat-link.active { background: var(--blue); border-color: var(--blue); }
.stat-link.active b, .stat-link.active span { color: #fff; }
/* An active card is how you switch the filter back off, so say so on hover. */
.stat-link.active:hover { transform: none; opacity: .9; }
@media (prefers-reduced-motion: reduce) {
  .stat-link { transition: none; }
  .stat-link:hover { transform: none; }
}

.toolbar { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center;
           margin-bottom: 1rem; }
.toolbar input[type="search"], .toolbar select { width: auto; min-width: 12rem; }

/* One row, one height. The search box, the three selects and the buttons each computed their
   own height from their own font-size and padding — 21 / 43 / 34px — so the row read as three
   different rows. A single explicit height with the vertical padding dropped lets each
   control centre its own text instead. */
.toolbar input, .toolbar select, .toolbar .btn { height: 2.5rem; }
.toolbar input, .toolbar select { padding-block: 0; }
.toolbar .btn { padding-block: 0; display: inline-flex; align-items: center; }

.tabs { display: flex; gap: .5rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.tabs a { font-size: .875rem; font-weight: 600; text-decoration: none;
          padding: .5rem 1rem; border-radius: 8px; color: var(--gray); }
.tabs a.active { background: var(--dark); color: #fff; }
.tabs a:not(.active):hover { background: #fff; color: var(--navy); }

/* ------------------------------------------------------------------ centred */

.centre { max-width: 32rem; margin: 4rem auto; text-align: center;
          background: #fff; border-radius: var(--radius); box-shadow: var(--shadow);
          padding: 3rem 2rem; }
.centre h1 { font-size: 1.625rem; }
.centre .btn { margin-top: 1.5rem; }

/* The printed review page is what someone takes to the airport, so it keeps the answers
   and drops every control. */
@media print {
  .topbar, .footer, .sectionnav, .actions, .savestate, .demobar, .noprint,
  .hero, .hero-strip { display: none; }
  body { background: #fff; }
  .card { box-shadow: none; border: 1px solid var(--border);
          break-inside: avoid; page-break-inside: avoid; }
  .banner, .deadline { box-shadow: none; border: 1px solid var(--border);
                       background: #fff; color: var(--dark); }
  .deadline .tag { color: var(--navy); }
  .answer.missing { box-shadow: none; }
  a[href]::after { content: ""; }
}
