/* ============================================================================
   HP design system — event registration
   Built from eventapp/brand/kit. Sources, in precedence order:
     HP Digital Guidelines deck  >  veneer.hp.com v3.151.0  >  Brand Guidelines V.6
   Nothing here is invented; every value traces to one of those three.
   ========================================================================== */

/* Forma DJR UI, variable. Axes: wght 200–800, opsz 9–144.
   The brand mandates the UI cut specifically for digital (Guidelines p.100) because
   it thins strokes at small sizes — that IS the opsz axis, so we let the browser
   drive it via font-optical-sizing rather than pinning it by hand. */
@font-face {
  font-family: 'Forma DJR UI';
  src: url('assets/FormaDJRUI.woff2') format('woff2-variations');
  font-weight: 200 800;
  font-display: swap;
}

:root {
  /* ---- Primitives: electricBlue (veneer.hp.com, == Brand Guidelines p.90) ---- */
  --eb-0:  #E4EEFA;  --eb-1:  #C9E0FC;  --eb-2:  #B2D2FF;  --eb-3:  #8FBAFF;
  --eb-4:  #72A3FF;  --eb-5:  #518CFF;  --eb-6:  #296EF9;  --eb-7:  #024AD8;
  --eb-8:  #103FB2;  --eb-9:  #0E3191;  --eb-10: #0C2877;  --eb-11: #0A2162;
  --eb-12: #0A1D4E;

  /* ---- Primitives: gray (true neutral) ---- */
  --gray-0:  #FAFAFA; --gray-1:  #F5F5F5; --gray-2:  #F0F0F0; --gray-3:  #E8E8E8;
  --gray-4:  #C2C2C2; --gray-5:  #A3A3A3; --gray-6:  #858585; --gray-7:  #636363;
  --gray-8:  #525252; --gray-9:  #3D3D3D; --gray-10: #292929; --gray-11: #212121;
  --gray-12: #1A1A1A;

  /* ---- Primitives: secondary. Keyword highlight in a title or subtitle ONLY — the
     Digital Guidelines deck (DG s59) outranks p.92 for UI: never on buttons, links,
     badges, status or backgrounds. Nothing in this file uses them yet. ---- */
  --ps-6: #568393; --ps-7: #447180;
  --ob-5: #FF5050; --ob-6: #E54041; --ob-7: #CC2D32;

  /* ---- Primitives: Veneer status families. Status only, always with an icon or word. ---- */
  --green-0: #CBFCDE; --green-3: #4BD78F; --green-8: #017043; --green-12: #00351D;
  --red-0:   #FFE5E0; --red-3:   #FE897D; --red-8:   #AE2320; --red-12:   #4B0A09;
  --orange-0: #FFE9D9; --orange-3: #FD9C5C; --orange-8: #9E4501; --orange-12: #491C00;

  /* ---- Layout: Veneer size / cornerRadius primitives ---- */
  --s-0: 0;    --s-1: 4px;  --s-2: 8px;  --s-3: 12px;
  --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-7: 28px; --s-8: 32px;
  --r-1: 4px; --r-2: 8px; --r-3: 12px; --r-4: 16px; --r-full: 999px;

  /* ---- Semantic: light. Structure from Veneer's semantic layer, values
     repointed to current primitives (the shipped bundle still had royalBlue). ---- */
  --fg:            var(--gray-12);
  --fg-medium:     var(--gray-8);
  --fg-light:      var(--gray-7);
  --fg-disabled:   var(--gray-5);
  --bg:            #FFFFFF;
  --bg-container:  var(--gray-0);
  --bg-sunken:     var(--gray-1);
  --stroke:        var(--gray-3);
  --stroke-strong: var(--gray-6);   /* gray-5 measured 2.52:1 — under the 3:1 floor for controls */
  --stroke-focus:  var(--eb-7);

  /* Interaction states follow the deck's rule: hover shifts one step along the
     ramp, active shifts one step again. */
  --primary:        var(--eb-7);
  --primary-hover:  var(--eb-8);
  --primary-active: var(--eb-9);
  --primary-fg:     #FFFFFF;
  --primary-tint:        var(--eb-0);
  --primary-tint-hover:  var(--eb-1);
  --primary-tint-active: var(--eb-2);

  /* Black: secondary buttons, and the primary button on any screen showing a stripe
     (DG s36, s55). Buttons read --action-*, which .stripe-screen repoints here. */
  --neutral:        var(--gray-12);
  --neutral-hover:  var(--gray-9);
  --neutral-active: var(--gray-8);
  --neutral-fg:     #FFFFFF;
  --neutral-tint-hover:  rgb(133 133 133 / .10);
  --neutral-tint-active: rgb(133 133 133 / .20);

  /* Text-on-tint contrast all clears 4.5:1 at 12px. */
  --positive:       var(--green-8);
  --positive-tint:  var(--green-0);
  --attention:      var(--red-8);       /* errors, required */
  --attention-tint: var(--red-0);
  --warning:        var(--orange-8);    /* still to do: needs action, not wrong */
  --warning-tint:   var(--orange-0);
  --info:      var(--gray-7);           /* Veneer info is neutral (DG s59: no Power Storm) */
  --info-tint: var(--gray-1);

  --shadow: 0 1px 2px rgb(0 0 0 / .06), 0 4px 12px rgb(0 0 0 / .06);
  --logo: var(--eb-7);        /* p.69: always HP Blue, in both themes */
  --logo-keyline: none;       /* white key line only where the ground is dark */
  --stripe-angle: -20deg;   /* Guidelines p.72: 20° shear, verticals tilt, horizontals hold */
  --ease: cubic-bezier(0.61, 0.09, 0.17, 0.99);   /* the single brand curve */
}

/* Veneer ships dark for every semantic token and switches on prefers-color-scheme;
   the marketing book is simply silent on it. data-theme lets the toggle win both ways. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fg: #FFFFFF; --fg-medium: var(--gray-3); --fg-light: var(--gray-4);
    --fg-disabled: var(--gray-7);
    --bg: var(--gray-12); --bg-container: var(--gray-11); --bg-sunken: #000000;
    --stroke: var(--gray-9); --stroke-strong: var(--gray-6);
    --primary: var(--eb-4); --primary-hover: var(--eb-3); --primary-active: var(--eb-2);
    /* Veneer keeps strokeFocus identical in both themes, but their dark ground is
       #292A35; on ours (#1A1A1A) Electric Blue 7 measured 2.46:1 — under the 3:1
       floor for a focus indicator. Step it up the ramp to match --primary. */
    --stroke-focus: var(--eb-5);
    --primary-fg: var(--gray-12);
    /* Dark grounds stay neutral, never navy (p.95): selected states tint gray. */
    --primary-tint: var(--gray-10); --primary-tint-hover: rgb(133 133 133 / .20);
    --primary-tint-active: rgb(133 133 133 / .30);
    --neutral: var(--gray-3); --neutral-hover: var(--gray-4); --neutral-active: var(--gray-5);
    --neutral-fg: var(--gray-12);
    --neutral-tint-hover: rgb(133 133 133 / .20); --neutral-tint-active: rgb(133 133 133 / .30);
    --positive: var(--green-3); --positive-tint: var(--green-12);
    --attention: var(--red-3); --attention-tint: var(--red-12);
    --warning: var(--orange-3); --warning-tint: var(--orange-12);
    --info: var(--gray-4); --info-tint: var(--gray-10);
    --logo-keyline: #FFFFFF;
    --shadow: 0 1px 2px rgb(0 0 0 / .4), 0 4px 12px rgb(0 0 0 / .3);
  }
}
:root[data-theme="dark"] {
  --fg: #FFFFFF; --fg-medium: var(--gray-3); --fg-light: var(--gray-4);
  --fg-disabled: var(--gray-7);
  --bg: var(--gray-12); --bg-container: var(--gray-11); --bg-sunken: #000000;
  --stroke: var(--gray-9); --stroke-strong: var(--gray-6);
  --primary: var(--eb-4); --primary-hover: var(--eb-3); --primary-active: var(--eb-2);
  --stroke-focus: var(--eb-5);
  --primary-fg: var(--gray-12);
  --primary-tint: var(--gray-10); --primary-tint-hover: rgb(133 133 133 / .20);
  --primary-tint-active: rgb(133 133 133 / .30);
  --neutral: var(--gray-3); --neutral-hover: var(--gray-4); --neutral-active: var(--gray-5);
  --neutral-fg: var(--gray-12);
  --neutral-tint-hover: rgb(133 133 133 / .20); --neutral-tint-active: rgb(133 133 133 / .30);
  --positive: var(--green-3); --positive-tint: var(--green-12);
  --attention: var(--red-3); --attention-tint: var(--red-12);
  --warning: var(--orange-3); --warning-tint: var(--orange-12);
  --info: var(--gray-4); --info-tint: var(--gray-10);
  --logo-keyline: #FFFFFF;
  --shadow: 0 1px 2px rgb(0 0 0 / .4), 0 4px 12px rgb(0 0 0 / .3);
}

/* Filled buttons read --action-*: Electric Blue by default, black wherever a stripe
   shares the screen so no control is mistaken for the non-interactive stripe
   (DG s36, s55). Put .stripe-screen on the screen that shows the stripe. Links stay blue. */
:root {
  --action: var(--primary); --action-hover: var(--primary-hover);
  --action-active: var(--primary-active); --action-fg: var(--primary-fg);
}
.stripe-screen {
  --action: var(--neutral); --action-hover: var(--neutral-hover);
  --action-active: var(--neutral-active); --action-fg: var(--neutral-fg);
}

/* ============================ base ============================ */
* { box-sizing: border-box; }

/* Any class that sets `display` beats the UA's [hidden] rule, so `el.hidden = true`
   silently does nothing. `.field { display: block }` did exactly that and left two
   versions of the same question on screen at once. One guard, once, for all of them. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: 'Forma DJR UI', Arial, sans-serif;
  font-optical-sizing: auto;
  font-weight: 400;
  /* Body Regular, Typography Small — the phone scale is the default because
     this is a phone-first tool. Larger viewports step up below. */
  font-size: 14px;
  line-height: 24px;
  -webkit-font-smoothing: antialiased;
  text-align: left;          /* Guidelines p.107: never centre-align text */
}

/* Veneer's high-legibility helper switches on Forma DJR UI's OpenType alternates.
   Worth it anywhere a character could be misread: phone numbers, KTNs, codes. */
.high-legibility { font-feature-settings: 'ss01', 'ss02', 'ss03', 'ss04', 'ss05', 'ss07', 'ss08', 'ss09', 'ss19', 'ss20', 'zero', 'tnum'; }

/* ---- Type scale. Veneer publishes three viewport scales and is explicit that
   you must not mix styles across them, so each breakpoint restates the whole set. ---- */
.title-large   { font-size: 44px; line-height: 44px; font-weight: 600; letter-spacing: 0; margin: 0; }
.title-medium  { font-size: 36px; line-height: 36px; font-weight: 600; letter-spacing: 0; margin: 0; }
.title-regular { font-size: 32px; line-height: 32px; font-weight: 600; letter-spacing: 0; margin: 0; }
.title-small   { font-size: 24px; line-height: 24px; font-weight: 600; letter-spacing: 0; margin: 0; }
.subtitle-large   { font-size: 18px; line-height: 24px; font-weight: 600; margin: 0; }
.subtitle-regular { font-size: 16px; line-height: 20px; font-weight: 600; margin: 0; }
.overline-regular { font-size: 12px; line-height: 16px; font-weight: 600; margin: 0; }
.body-extra-large { font-size: 18px; line-height: 24px; margin: 0; }
.body-large       { font-size: 16px; line-height: 24px; margin: 0; }
.body-regular     { font-size: 14px; line-height: 24px; margin: 0; }
/* Global styles — identical at every viewport */
.label-regular { font-size: 16px; line-height: 20px; margin: 0; }
.label-small   { font-size: 12px; line-height: 16px; margin: 0; }
.caption       { font-size: 14px; line-height: 20px; margin: 0; }
.caption-small { font-size: 12px; line-height: 16px; margin: 0; }

@media (min-width: 768px) {          /* Typography Medium — Veneer breakpoint1 */
  body { font-size: 14px; }
  .title-large   { font-size: 56px; line-height: 56px; }
  .title-medium  { font-size: 44px; line-height: 44px; }
  .title-regular { font-size: 36px; line-height: 36px; }
  .title-small   { font-size: 28px; line-height: 28px; }
  .subtitle-large   { font-size: 20px; line-height: 24px; }
  .subtitle-regular { font-size: 18px; line-height: 24px; }
  .overline-regular { font-size: 14px; line-height: 20px; }
  .body-extra-large { font-size: 18px; line-height: 24px; }
  .body-large       { font-size: 16px; line-height: 24px; }
}
@media (min-width: 1024px) {         /* Typography Large — Veneer breakpoint2 */
  body { font-size: 16px; }
  .title-large   { font-size: 72px; line-height: 72px; }
  .title-medium  { font-size: 56px; line-height: 56px; }
  .title-regular { font-size: 44px; line-height: 44px; }
  .title-small   { font-size: 32px; line-height: 32px; }
  .subtitle-large   { font-size: 24px; line-height: 28px; }
  .subtitle-regular { font-size: 20px; line-height: 24px; }
  .overline-regular { font-size: 16px; line-height: 20px; }
  .body-extra-large { font-size: 20px; line-height: 24px; }
  .body-large       { font-size: 18px; line-height: 24px; }
  .body-regular     { font-size: 16px; line-height: 24px; }
}

/* ============================ stripe ============================ */
/* The brand device. Always Electric Blue on white, never the reverse, never with
   copy on top, and capped at 2–3 per view (Guidelines pp.72–81). */
.stripe {
  transform: skewX(var(--stripe-angle));
  background: var(--eb-7);
  flex: none;
}

/* ============================ buttons ============================ */
.btn {
  font: inherit;
  font-weight: 600;
  font-size: 16px;
  line-height: 20px;
  border: 1px solid transparent;
  border-radius: var(--r-1);
  padding: var(--s-3) var(--s-6);
  min-height: 44px;                 /* touch target */
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
  background: var(--action);
  color: var(--action-fg);
}
.btn:hover  { background: var(--action-hover); }
.btn:active { background: var(--action-active); }
.btn:focus-visible { outline: 2px solid var(--stroke-focus); outline-offset: 2px; }
.btn:disabled { background: var(--bg-sunken); color: var(--fg-disabled); cursor: default; }

.btn-secondary {
  background: transparent; color: var(--neutral); border-color: var(--neutral);
}
.btn-secondary:hover  { background: var(--neutral-tint-hover); border-color: var(--neutral-hover); color: var(--neutral-hover); }
.btn-secondary:active { background: var(--neutral-tint-active); border-color: var(--neutral-active); color: var(--neutral-active); }

.btn-ghost { background: transparent; color: var(--fg-medium); }
.btn-ghost:hover { background: var(--bg-sunken); color: var(--fg); }

/* ============================ fields ============================ */
.field { display: block; margin-bottom: var(--s-6); }
.field > .field-label {
  display: block;
  font-size: 16px; line-height: 20px; font-weight: 600;
  margin-bottom: var(--s-1);
}
/* The "why we're asking" line. This is the load-bearing part of a guided form —
   every sensitive field earns its keep by explaining itself before it's answered. */
.field > .field-why {
  display: block;
  font-size: 14px; line-height: 20px;
  color: var(--fg-light);
  margin-bottom: var(--s-2);
}
.field input[type="text"], .field input[type="tel"], .field input[type="email"],
.field input[type="date"], .field select, .field textarea {
  font: inherit; font-size: 16px; line-height: 24px;   /* 16px min: stops iOS zoom-on-focus */
  width: 100%;
  padding: var(--s-3);
  min-height: 44px;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-1);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--fg-medium); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--stroke-focus);
  box-shadow: 0 0 0 1px var(--stroke-focus);
}
.field input::placeholder, .field textarea::placeholder { color: var(--fg-disabled); }
.field textarea { resize: vertical; font-family: inherit; }
.field.is-invalid input { border-color: var(--attention); }
.field .field-error {
  display: flex; gap: var(--s-2); align-items: flex-start;
  font-size: 14px; line-height: 20px;
  color: var(--attention);
  margin-top: var(--s-2);
}
.field .field-error .icon { width: 16px; height: 16px; margin-top: 2px; }

/* ============================ cards ============================ */
.card {
  background: var(--bg-container);
  border: 1px solid var(--stroke);
  border-radius: var(--r-3);
  padding: var(--s-5);
}

/* ============================ stepper ============================ */
/* Veneer's Stepper: "a tracker showing the total number of tasks completed and
   yet to complete." Plain bars: a sheared shape reads as a stripe, and stripes
   don't belong on a form (DG s65). */
.stepper { display: flex; gap: 3px; margin-bottom: var(--s-2); }
.stepper .step {
  height: 6px; flex: 1;
  border-radius: var(--r-full);
  background: var(--stroke);
  transition: background-color .4s var(--ease);
}
.stepper .step.done    { background: var(--primary); }
.stepper .step.current { background: var(--primary); opacity: .55; }

/* ============================ status ============================ */
.status { display: inline-flex; align-items: center; gap: var(--s-1);
          font-size: 12px; line-height: 16px; font-weight: 600;
          padding: var(--s-1) var(--s-2); border-radius: var(--r-full); }
.status-done    { background: var(--positive-tint);  color: var(--positive); }
.status-todo    { background: var(--warning-tint);   color: var(--warning); }
.status-waiting { background: var(--info-tint);      color: var(--info); }

.icon { width: 1em; height: 1em; fill: currentColor; flex: none; }

/* ============================ layout ============================ */
.shell { max-width: 30rem; margin: 0 auto; padding: var(--s-6) var(--s-5) var(--s-8); }
@media (min-width: 768px) { .shell { max-width: 34rem; padding-inline: var(--s-6); } }

/* Sticky because the save status lives here. "Saved as you go" is a promise, and a
   promise you can only see by scrolling to the top of the page is not being kept —
   a failure on step 5 was scrolling out of sight entirely. An explicit background is
   part of being sticky: without one the page shows through as it passes underneath. */
.app-header {
  position: sticky; top: 0; z-index: 5;
  background: var(--bg);
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--stroke);
}
/* The header carries the event's name, which is a proper noun: it gets one line and
   truncates rather than wrapping. A sticky header that changes height shoves the page
   under the reader's thumb. */
.app-header .app-name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.app-header .hp-logo { width: 38px; height: 38px; color: var(--logo); flex: none; }
/* PROVISIONAL: ring width is a guess pending the official key-line asset. */
.app-header .hp-logo .keyline { fill: var(--logo-keyline); }
@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ============================ choices ============================ */
/* Radios and checkboxes as tappable rows. Real inputs underneath — accent-color
   carries the brand into the native control, which keeps keyboard and screen-reader
   behaviour intact rather than rebuilding it badly. */
.choice {
  display: flex; align-items: flex-start; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-1);
  cursor: pointer;
  min-height: 44px;
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.choice:hover { border-color: var(--fg-medium); background: var(--primary-tint); }
.choice input { accent-color: var(--primary); width: 20px; height: 20px; margin: 2px 0 0; flex: none; }
.choice:has(input:checked) { border-color: var(--primary); background: var(--primary-tint); }
.choice:has(input:focus-visible) { outline: 2px solid var(--stroke-focus); outline-offset: 2px; }
.choice .choice-label { font-size: 16px; line-height: 24px; }
.choice .choice-note  { font-size: 14px; line-height: 20px; color: var(--fg-light); }

.choice-list { display: flex; flex-direction: column; gap: var(--s-2); }
.choice-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }
@media (max-width: 380px) { .choice-grid { grid-template-columns: 1fr; } }

/* ---- chips: a compact single-select where the options are short (shirt size) ---- */
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.chip { position: relative; }
.chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.chip span {
  display: grid; place-items: center;
  min-width: 56px; min-height: 44px; padding: 0 var(--s-3);
  border: 1px solid var(--stroke-strong); border-radius: var(--r-1);
  font-size: 16px; line-height: 20px;
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.chip:hover span { border-color: var(--fg-medium); background: var(--primary-tint); }
.chip:has(input:checked) span { border-color: var(--primary); background: var(--primary); color: var(--primary-fg); font-weight: 600; }
.chip:has(input:focus-visible) span { outline: 2px solid var(--stroke-focus); outline-offset: 2px; }

/* ============================ misc step furniture ============================ */
.step-actions { display: flex; gap: var(--s-3); align-items: center; margin-top: var(--s-8); }
.step-actions .grow { flex: 1 }
/* Opting out isn't a peer of Back/Continue — it gets its own line rather than
   competing for width in a row that already wrapped badly at 375px. */
.step-skip { width: 100%; margin-top: var(--s-3); }

.field-row { display: flex; gap: var(--s-3); }
.field-row > * { flex: 1; min-width: 0; }

/* A suggestion the tool makes on your behalf — airports from a postal code. The
   tint marks it as "we worked this out", distinct from something you typed. */
.suggestion {
  background: var(--primary-tint);
  border-radius: var(--r-2);
  padding: var(--s-3) var(--s-4);
  margin-top: var(--s-2);
}

.photo-drop {
  display: grid; place-items: center; gap: var(--s-2);
  padding: var(--s-8) var(--s-5);
  border: 1px dashed var(--stroke-strong);
  border-radius: var(--r-3);
  color: var(--fg-light);
  text-align: center;          /* brand-check: allow-center — the one place centring is right: an empty drop target */
}

/* Crop stage (apps/shared/cropper.js): drag to pan, slider to zoom, the canvas IS
   the live preview. Shared with /headshot.js's #stage in the PWA — one crop
   implementation, two bits of chrome around it. width:min(280px,100%) rather than a
   bare 280px so it still fits with room either side at 375px, the narrowest width
   this tool has to work at. */
.crop-stage {
  width: min(280px, 100%); aspect-ratio: 1 / 1;
  border-radius: var(--r-full); overflow: hidden;
  background: var(--bg-sunken);
  touch-action: none; cursor: grab;
  margin: 0 auto;
}
.crop-stage:active { cursor: grabbing; }
.crop-stage canvas { display: block; width: 100%; height: 100%; }

.crop-zoom {
  display: flex; align-items: center; gap: var(--s-3);
  width: min(280px, 100%); margin: var(--s-4) auto 0;
}
.crop-zoom input[type=range] { flex: 1; accent-color: var(--primary); }
.crop-zoom span { font-size: 18px; line-height: 1; color: var(--fg-light); flex: none; }

/* Autosave indicator. "Saved as you go" is a promise, so it needs to be visible —
   but quietly: this should reassure, never nag. */
.save-status { color: var(--fg-light); transition: color .2s var(--ease); }
.save-status[data-state="saved"] { color: var(--positive); }
.save-status[data-state="error"] { color: var(--attention); }
/* "Saving…" and "Saved" are two words and ride alongside the name. An error is a
   sentence — sometimes one the server wrote — so it takes the full width of a second
   row instead of squeezing the name into three lines. */
.save-status[data-state="error"] { flex-basis: 100%; }

/* Airport picker results. A short, tappable list beats a <datalist>: datalist can't
   be populated from a live search on mobile Safari, and a hardcoded one is wrong for
   everyone who doesn't live where the developer does. */
.picker-results {
  margin-top: var(--s-2);
  border: 1px solid var(--stroke); border-radius: var(--r-2);
  background: var(--bg); overflow: hidden;
  max-height: 16rem; overflow-y: auto;
}
.picker-results button {
  display: block; width: 100%; text-align: left;
  font: inherit; font-size: 16px; line-height: 20px;
  padding: var(--s-3) var(--s-4); min-height: 44px;
  background: transparent; color: var(--fg); border: 0;
  border-bottom: 1px solid var(--stroke); cursor: pointer;
}
.picker-results button:last-child { border-bottom: 0; }
.picker-results button:hover { background: var(--primary-tint); }
.picker-results button:focus-visible { outline: 2px solid var(--stroke-focus); outline-offset: -2px; }
.picker-results .picker-note { padding: var(--s-3) var(--s-4); color: var(--fg-light); font-size: 14px; }
.picker-results .iata { font-weight: 600; margin-right: var(--s-2); }

/* A chosen airport, removable. */
.chip-chosen {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: 36px; padding: 0 var(--s-2) 0 var(--s-3);
  border: 1px solid var(--primary); border-radius: var(--r-1);
  background: var(--primary-tint); color: var(--fg); font-size: 16px;
}
.chip-chosen button {
  font: inherit; line-height: 1; cursor: pointer;
  background: transparent; border: 0; color: var(--fg-medium);
  padding: var(--s-1) var(--s-2); min-height: 32px; border-radius: var(--r-1);
}
.chip-chosen button:hover { color: var(--attention); }

/* Collapsible field group. <details>/<summary> rather than a scripted toggle: it is
   keyboard-accessible, findable by in-page search, and works before JS runs. */
.field-collapse { border: 1px solid var(--stroke); border-radius: var(--r-2); background: var(--bg); }
.field-collapse > summary {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4); min-height: 44px; cursor: pointer;
  font-size: 16px; line-height: 20px; font-weight: 600;
  list-style: none;
}
.field-collapse > summary::-webkit-details-marker { display: none; }
.field-collapse > summary::after {
  content: ''; margin-left: auto; flex: none;
  width: 9px; height: 9px; border-right: 2px solid var(--fg-light); border-bottom: 2px solid var(--fg-light);
  transform: rotate(45deg); transition: transform .2s var(--ease);
}
.field-collapse[open] > summary::after { transform: rotate(-135deg); }
.field-collapse > summary:hover { background: var(--bg-container); }
.field-collapse > summary:focus-visible { outline: 2px solid var(--stroke-focus); outline-offset: -2px; }
.field-collapse .collapse-count {
  font-size: 12px; line-height: 16px; font-weight: 600;
  padding: 2px var(--s-2); border-radius: var(--r-full);
  background: var(--primary); color: var(--primary-fg);
}
.field-collapse .collapse-body { padding: 0 var(--s-4) var(--s-4); }
.field-collapse .collapse-why {
  font-size: 14px; line-height: 20px; color: var(--fg-light);
  padding: 0 var(--s-4) var(--s-3);
}

/* Food-safety notice. Power Storm rather than Orange Bloom: this is information the
   person needs to act on, not an error they have made. */
.safety-notice {
  display: flex; gap: var(--s-3); align-items: flex-start;
  background: var(--info-tint); border-radius: var(--r-2);
  padding: var(--s-4); margin-top: var(--s-4);
}
.safety-notice .icon { width: 20px; height: 20px; color: var(--info); margin-top: 2px; }
.safety-notice p { font-size: 14px; line-height: 20px; color: var(--fg-medium); margin: 0; }

/* ---- Staff page layout (desk, comms, producer, raffle, channel, check-in status…) ----
   Phones: one column, nothing wider than the screen. Laptops: the page uses the width,
   cards sit two (three on very wide screens) to a row, and any card holding a table or
   marked .span-all takes the full row. Tables scroll inside their card rather than
   pushing the page out (staff-shell.js wraps them in .table-scroll). */
.staff-main {
  max-width: 112rem; margin: 0 auto; box-sizing: border-box;
  padding: var(--s-5) max(var(--s-4), env(safe-area-inset-right)) var(--s-8) max(var(--s-4), env(safe-area-inset-left));
}
.staff-main .card, .staff-grid > * { min-width: 0; overflow-wrap: break-word; }
.staff-main code, .staff-main .mono, .staff-main a { overflow-wrap: anywhere; }
/* A select is as wide as its longest option, and grid/flex items won't shrink below
   their content: both pushed desk forms past their card on a phone. */
.staff-main :is(input, select, textarea) { max-width: 100%; min-width: 0; box-sizing: border-box; }
.staff-main :is(label, form > *, .row > *, fieldset) { min-width: 0; max-width: 100%; }
.table-scroll { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll > table { min-width: 100%; }
.table-scroll td, .table-scroll th { overflow-wrap: normal; }
/* Codes and row actions never break mid-word inside a table: the table scrolls instead. */
.table-scroll code, .table-scroll .mono { overflow-wrap: normal; white-space: nowrap; }
.table-scroll td:has(> button, > a.btn) { white-space: nowrap; }
@media (min-width: 75rem) {
  .staff-main { padding-left: var(--s-8); padding-right: var(--s-8); }
  .staff-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); align-items: start; grid-auto-flow: row dense; }
  .staff-grid > * { margin: 0 !important; }
  .staff-grid > .span-all, .staff-grid > :has(table), .staff-grid > :has(.table-scroll) { grid-column: 1 / -1; }
}
@media (min-width: 120rem) {
  .staff-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
