/* Every page outside the delegate app, in the delegate app's system.
 * =============================================================================
 * Registration, delegations, claim codes, terms, privacy and certificate
 * verification all load this one file on top of event/app.css. It replaced a
 * stack of five stylesheets (account.css alone was 86KB of the old light
 * system) that between them put half the site on a paper ground while the app
 * was black. Two files now, cached once, shared by six pages.
 *
 * Originally register.css.
 * =============================================================================
 * The moment someone starts transacting they are inside the product, so this
 * page stops looking like the campaign and starts looking like the account they
 * are about to own. It layers on event/app.css: tokens, the three surfaces, the
 * ink ramp, the two radius tiers and the primitives all come from there, and
 * nothing is redefined here that already exists.
 *
 * The campaign's poster blue does not appear. Measured on this ground it is
 * 1.97:1, which is not a colour, it is a stain.
 */

/* SHELL ---------------------------------------------------------------------- */
.portal-page { background: var(--ground); color: var(--ink); }
.portal-skip {
  position: absolute; left: -9999px;
  padding: var(--s3) var(--s4); border-radius: var(--r-round);
  background: var(--ink); color: var(--ground); font-weight: 500;
}
.portal-skip:focus { left: var(--gutter); top: var(--s3); z-index: var(--z-toast); }
.portal-main { padding-bottom: var(--s6); }
.portal-width { width: 100%; max-width: 34rem; margin-inline: auto; padding-inline: var(--gutter); }
.registration-workspace, .registration-form-shell { display: grid; gap: var(--s5); min-width: 0; }
.registration-workspace > *, .registration-form-shell > *, .flow-rail { min-width: 0; }

/* MASTHEAD — the app's, minus the parts that need an account ------------------ */
.bar { background: var(--ground); border-bottom: 1px solid var(--line); }
.bar__in {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; max-width: 34rem; margin-inline: auto;
  padding: calc(var(--s4) + env(safe-area-inset-top)) var(--gutter) var(--s3);
}
.bar__mark {
  font-family: var(--display); font-weight: 700; font-size: var(--t-meta);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink);
}
.bar__mark i { font-style: normal; color: var(--ink-low); }
.bar__here { font-size: var(--t-label); color: var(--ink-low); }
.bar__cta {
  margin-left: auto; flex: none;
  display: inline-flex; align-items: center; min-height: 36px;
  padding: 0 var(--s4); border-radius: var(--r-round);
  background: var(--raised); color: var(--ink);
  font-size: var(--t-label); font-weight: 500;
}
.bar__nav, .bar__burger { display: none; }   /* the campaign's nav is not this page's job */

/* THE OPENER ------------------------------------------------------------------
 * One statement of each fact. The page used to carry a meta strip, a kicker, a
 * headline, a lede, a deadline box and a When/Where/Packages list, which between
 * them printed the dates three times and the price twice before the first field.
 * Six blocks became four, and the only thing competing for attention now is the
 * deadline, which is the one fact that can cost a delegate money.
 *
 * This is also the one surface allowed a type size above the app's 25px ceiling.
 * The app is a utility a delegate already owns; this page still has to make
 * someone want to come, and a 25px opener cannot do that. Declared here, scoped
 * here, and nowhere else. */
.reg-hero { position: relative; padding-top: var(--s6); }
.reg-hero__inner { display: grid; gap: var(--s4); padding-bottom: var(--s5); }

.reg-hero__seal { display: block; width: 40px; height: auto; opacity: .92; }
.reg-hero__seal img { display: block; width: 100%; height: auto; }

.reg-hero h1 {
  margin: 0;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2.25rem, 11vw, 3.75rem);
  line-height: .98; letter-spacing: -0.035em;
  text-wrap: balance;
}
/* The second line recedes rather than repeats the first at full strength. It is
   the campaign's own device: one statement, two tones. */
.reg-hero h1 em { font-style: normal; color: var(--ink-low); display: block; }

/* Where and when, stated once, directly under the name of the place. It sits
   in the accent because on this page the date is the fact with a deadline
   attached to it, and the gold is what marks time everywhere in this system. */
.reg-hero__where {
  margin: 0; font-size: var(--t-meta); font-weight: 500;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.reg-hero__where span { color: var(--ink-low); padding-inline: var(--s1); }

.reg-hero__lede {
  margin: 0; font-size: var(--t-title); line-height: 1.45;
  color: var(--ink-muted); max-width: 34ch; text-wrap: pretty;
}

/* Gold marks time, and nothing else on this page uses it. No box, no fill: the
   surface panel it used to sit in made a deadline look like a disclaimer. */
.reg-hero__when { margin: 0; display: grid; gap: var(--s1); font-size: var(--t-meta); line-height: 1.5; }
.reg-hero__when b { font-weight: 500; color: var(--ink); font-size: var(--t-title); }
.reg-hero__when span { color: var(--ink-low); }

.reg-hero__group { margin: 0; font-size: var(--t-meta); line-height: 1.5; color: var(--ink-muted); max-width: 40ch; }

/* The ridge. Ekiti is the land of hills, so the horizon is the mark. It closes
   the opener and hands the page to the form, which is exactly what a horizon
   does. Drawn, so it costs bytes in path data rather than in photography. */
/* THE MASSIF ------------------------------------------------------------------
 * Two real rock masses closing the opener, framing a valley between them. The
 * campaign's own cut-outs, which DESIGN.md reserves for the hero and this band.
 *
 * The container is sized so the tallest mass fits whole at every width: the
 * first attempt fixed the height and clipped both summits, which left the
 * rubble at their feet and none of the profile that makes them hills.
 *
 * The bottom fifth of the band is the step rail's own plane, and each mass is
 * masked into it, so they stand on ground rather than being pasted over it. */
.massif {
  position: relative;
  width: 100%; max-width: 34rem; margin-inline: auto;
  height: clamp(195px, 50vw, 272px);
  overflow: hidden;
}
/* Wide enough to read as one ridge with a pass through it. At 62% and 56% they
   sat apart with a straight-edged plane showing between them, which read as two
   photographs on a grey box rather than as a landform. */
.massif picture { position: absolute; bottom: 0; display: block; }
.massif picture:first-of-type { left: -10%; width: 72%; }
.massif picture:last-of-type  { right: -10%; width: 66%; }
.massif img {
  display: block; width: 100%; height: auto;
  /* Desaturated and darkened into a black-and-gold system without going grey,
     then dissolved at the base so the rock meets the plane instead of ending. */
  filter: saturate(.5) brightness(.72) contrast(1.1);
  -webkit-mask-image: linear-gradient(to top, transparent 2%, #000 26%);
  mask-image: linear-gradient(to top, transparent 2%, #000 26%);
}

/* THE STEP RAIL ---------------------------------------------------------------
 * Four equal columns. As pills in a scroller the fourth step sat off the right
 * edge of every phone, so the one step a delegate has not reached yet, the one
 * that tells them a pass is coming, was the one they could not see. */
/* Escapes its parent's gutter so the surface runs edge to edge under the
   ridge, then gives the gutter back to its own children. */
.flow-rail {
  margin-inline: calc(var(--gutter) * -1);
  padding-block: var(--s5);
  background: var(--surface);
  position: relative;
}
.flow-rail > * { padding-inline: var(--gutter); }
.flow-steps {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s2); list-style: none; margin: 0;
}
.flow-steps > li { display: flex; min-width: 0; }
.flow-steps button {
  flex: 1; min-width: 0;
  display: grid; gap: var(--s2); align-content: start;
  padding: var(--s3) 0 0; min-height: 44px;
  border: 0; border-top: 2px solid var(--line); border-radius: 0;
  background: none; color: var(--ink-low);
  font: inherit; font-size: var(--t-label); font-weight: 500;
  text-align: left; cursor: pointer;
  transition: color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
.flow-steps button span { display: none; }        /* the rule carries the order */
.flow-steps button b { font-weight: 500; overflow-wrap: anywhere; }
.flow-steps button small { display: none; }
.flow-steps button:hover { color: var(--ink-muted); }
.flow-steps button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.flow-steps [data-done] { color: var(--ink-muted); border-top-color: var(--mark); }
.flow-steps [aria-current="step"] { color: var(--ink); border-top-color: var(--accent); }

.flow-note { margin-top: var(--s5); font-size: var(--t-meta); color: var(--ink-low); }
.flow-note a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

.help { padding-top: var(--s6); }
.help__title { margin: 0 0 var(--s3); font-size: var(--t-title); font-weight: 500; color: var(--ink); }
.help__list { list-style: none; margin: 0; padding: 0; }
.help__list a {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4);
  min-height: 48px; padding-block: var(--s3);
  border-top: 1px solid var(--line);
  color: var(--ink); text-decoration: none;
}
.help__list li:last-child a { border-bottom: 1px solid var(--line); }
.help__list span { font-size: var(--t-meta); color: var(--ink-muted); }
.help__list b { font-weight: 500; font-size: var(--t-meta); font-variant-numeric: tabular-nums; white-space: nowrap; }
.help__list a:hover b { color: var(--accent); }
.help__list a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px; }
.portal-trust { font-size: var(--t-label); color: var(--ink-low); }
.rule, .rule--onlight { height: 1px; border: 0; background: var(--line); margin-block: var(--s4); }
.linkish, .reg-hero a, .portal-trust a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* Entrance. One sequence on the opener, from a visible resting state so the
   page is complete if this never runs. */
@media (prefers-reduced-motion: no-preference) {
  .reg-hero__seal, .reg-hero h1, .reg-hero__lede, .reg-hero__when, .reg-hero__group {
    animation: reg-rise var(--dur-3) var(--ease) both;
  }
  .reg-hero h1        { animation-delay: 40ms; }
  .reg-hero__lede     { animation-delay: 80ms; }
  .reg-hero__when     { animation-delay: 120ms; }
  .reg-hero__group    { animation-delay: 160ms; }
  @keyframes reg-rise { from { opacity: 0; transform: translateY(8px); } }
}

/* FORM ----------------------------------------------------------------------- */
.form-heading { font-size: var(--t-head); font-weight: 500; letter-spacing: -0.02em; line-height: 1.12; padding-bottom: var(--s4); }
/* The panel headings keep the two-tone device, at form scale. They carried
   these rules jointly with the old intro headline, which no longer exists. */
.form-heading em { font-style: normal; color: var(--ink-low); }
.form-heading br { display: none; }
.form-heading em::before { content: " "; }
.form-heading .portal-kicker { font-size: var(--t-label); font-weight: 500; color: var(--ink-low); letter-spacing: 0; }
.field { display: grid; gap: var(--s2); padding-bottom: var(--s4); }
.field > label, .field__sub { font-size: var(--t-label); color: var(--ink-muted); }
.field__hint { font-size: var(--t-label); color: var(--ink-low); }
.field__note { font-size: var(--t-label); color: var(--ink-muted); }
.field__error, .field__error--consent { font-size: var(--t-label); color: var(--bad); }
.field-grid { display: grid; gap: var(--s4); }
@media (min-width: 30rem) { .field-grid { grid-template-columns: 1fr 1fr; } }
.field--wide { grid-column: 1 / -1; }

.portal-page input[type="text"], .portal-page input[type="email"], .portal-page input[type="tel"],
.portal-page input[type="password"], .portal-page select, .portal-page textarea {
  width: 100%; min-height: 48px; padding: 0 var(--s4);
  border: 0; border-radius: var(--r-round);
  background: var(--raised); color: var(--ink);
  font: inherit; font-size: var(--t-title);
  appearance: none;
}
.portal-page textarea { padding-block: var(--s3); border-radius: var(--r-content); min-height: 96px; }
.portal-page select {
  /* A native arrow on a dark control renders as a light chip on most Androids. */
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%),
                    linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: var(--s6);
}
.portal-page ::placeholder { color: var(--ink-muted); opacity: 1; }
.portal-page :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.password-field { position: relative; }
.password-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  min-height: 40px; padding: 0 var(--s3); border-radius: var(--r-round);
  background: none; color: var(--ink-muted); font-size: var(--t-label); font-weight: 500;
}
.password-strength { font-size: var(--t-label); color: var(--ink-low); margin-top: var(--s2); }

.consent-field { display: flex; align-items: flex-start; gap: var(--s3); padding-block: var(--s3) var(--s4); }
/* Drawn, not left to the browser: a white accent on this black page made
   iPhone Safari paint a ticked box plain white, the same as an empty one, so
   delegates could not see that they had agreed. */
.consent-field input[type="checkbox"] {
  flex: none; width: 24px; height: 24px; margin: 0; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  border: 2px solid var(--ink-muted); border-radius: 6px; background: transparent;
  background-position: center; background-repeat: no-repeat; background-size: 16px 16px;
}
.consent-field input[type="checkbox"]:checked {
  border-color: var(--ink); background-color: var(--ink);
  /* #000 tick: the page is always black, and the box fills with --ink (white). */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3.5 8.5 3 3 6-7'/%3E%3C/svg%3E");
}
.consent-field input[type="checkbox"][aria-invalid="true"] { border-color: var(--bad, #FF6B6B); }
.consent-field { cursor: pointer; }
.consent-field label { font-size: var(--t-meta); color: var(--ink-muted); }

/* PACKAGES — a row, not a card ----------------------------------------------- */
.package-fieldset { border: 0; margin: 0; padding: 0; }
.package-fieldset > legend { font-size: var(--t-label); color: var(--ink-muted); padding-bottom: var(--s3); }
.package-list { display: grid; }
.package-option {
  display: grid; gap: 2px;
  padding: var(--s4) 0 var(--s4) var(--s6);
  border-top: 1px solid var(--line);
  position: relative; cursor: pointer;
}
.package-list > .package-option:last-child { border-bottom: 1px solid var(--line); }
.package-option input[type="radio"] {
  position: absolute; left: 0; top: calc(var(--s4) + 2px);
  width: 20px; height: 20px; accent-color: #FFFFFF; margin: 0;
}
.package-option__top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); font-size: var(--t-title); }
.package-option__top b, .package-option__top strong { font-weight: 500; }
.package-option__details, .package-option__room { font-size: var(--t-meta); color: var(--ink-muted); }
.package-option__room { color: var(--ink-low); }
.package-option:has(input:checked) { background: var(--surface); border-radius: var(--r-content); padding-inline: var(--s6) var(--s4); border-color: transparent; }
.package-option:has(input:checked) + .package-option { border-top-color: transparent; }
.package-option--limited .package-option__room { color: var(--ink-low); }

/* PAYMENT -------------------------------------------------------------------- */
.method-list { display: grid; gap: var(--s2); }
.method-option {
  display: flex; align-items: flex-start; gap: var(--s3);
  padding: var(--s4); border-radius: var(--r-content);
  background: var(--surface); cursor: pointer;
}
.method-option input[type="radio"] { flex: none; width: 20px; height: 20px; accent-color: #FFFFFF; margin-top: 2px; }
.method-option__copy { display: grid; gap: 2px; font-size: var(--t-meta); }
.method-option__copy b { font-size: var(--t-title); font-weight: 500; }
.method-option__state { font-size: var(--t-label); color: var(--ink-low); }
.payment-notice, .checkout-summary {
  background: var(--surface); border-radius: var(--r-content);
  padding: var(--s4); font-size: var(--t-meta); color: var(--ink-muted);
}
.checkout-summary b { color: var(--ink); font-weight: 500; }

/* ROOM ----------------------------------------------------------------------- */
.room-field { display: grid; gap: var(--s2); padding-bottom: var(--s4); }
.room-card { background: var(--surface); border-radius: var(--r-content); padding: var(--s4); display: grid; gap: var(--s2); }
.room-card__label { font-size: var(--t-label); color: var(--ink-muted); }
.room-card__code { font-size: var(--t-head); font-weight: 500; letter-spacing: 0.08em; font-variant-numeric: tabular-nums; }
.room-card__note { font-size: var(--t-label); color: var(--ink-low); }

/* ACTIONS -------------------------------------------------------------------- */
.form-actions { display: grid; gap: var(--s2); padding-top: var(--s2); }
.form-actions--split { grid-auto-flow: row; }
@media (min-width: 30rem) { .form-actions--split { grid-auto-flow: column; grid-auto-columns: 1fr; } }
.portal-button {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 48px; padding: 0 var(--s5);
  border: 0; border-radius: var(--r-round);
  background: var(--ink); color: var(--ground);
  font: inherit; font-size: var(--t-meta); font-weight: 500;
  cursor: pointer; transition: opacity var(--dur-1) var(--ease);
}
.portal-button:active { opacity: .7; }
.portal-button[disabled] { opacity: .35; pointer-events: none; }
/* The campaign's ink and magenta buttons are not colours on this ground. One
   solid fill per screen carries the primary action; everything else recedes. */
.portal-button--magenta { background: var(--ink); color: var(--ground); }
.portal-button--quiet, .portal-button--ink { background: var(--raised); color: var(--ink); }
.portal-button--text { background: none; color: var(--ink-muted); padding-inline: var(--s3); }
.form-status { font-size: var(--t-meta); color: var(--ink-muted); }
.form-status[data-bad], .form-status.is-bad { color: var(--bad); }

/* SUCCESS -------------------------------------------------------------------- */
.form-heading--success { padding-bottom: var(--s3); }
.success-mark { display: grid; place-items: center; width: 56px; height: 56px; border-radius: var(--r-round); background: var(--ink); color: var(--ground); margin-bottom: var(--s4); }
.success-mark svg { width: 26px; height: 26px; }
.success-next { display: grid; gap: var(--s3); font-size: var(--t-meta); color: var(--ink-muted); }
.issued-identifiers { display: grid; gap: var(--s3); }
.install-card { background: var(--surface); border-radius: var(--r-content); padding: var(--s5) var(--s4); display: grid; gap: var(--s3); }
.install-card__acts { display: flex; gap: var(--s2); flex-wrap: wrap; }

/* FOOT ----------------------------------------------------------------------- */
.foot { border-top: 1px solid var(--line); margin-top: var(--s6); }
.foot__top, .foot__base { width: 100%; max-width: 34rem; margin-inline: auto; padding: var(--s5) var(--gutter); }
.foot__base { padding-top: 0; font-size: var(--t-label); color: var(--ink-low); }
.foot a { color: var(--ink-muted); }
.foot__lockup { display: block; width: 100%; max-width: 200px; height: auto; }
.foot__yor { font-size: var(--t-meta); color: var(--ink-low); font-style: italic; }

/* THE SECOND DOOR ------------------------------------------------------------
   Paying is what the page leads to and the only thing that holds a place. But
   a delegate who cannot pay this week should not read the page as "not for
   you" — the account and the confirmed email are worth having on their own, so
   that route is named, explained and given its own block rather than being a
   link tucked beside the real button. */
.portal-button--block { width: 100%; }
.second-door {
  display: grid; gap: var(--s3);
  margin-top: var(--s5); padding: var(--s5) var(--s4);
  background: var(--surface); border-radius: var(--r-content);
}
.second-door__title { font-size: var(--t-title); font-weight: 500; }
.second-door__body { font-size: var(--t-meta); color: var(--ink-muted); max-width: 46ch; }
.second-door__warn { font-size: var(--t-label); color: var(--ink-low); }

/* Appears in place, above the pay button, when the email already has an
   account. Carries the accent rather than the error colour: this is not the
   delegate's mistake, it is us recognising them. */
.existing-account {
  display: grid; gap: var(--s3);
  margin-top: var(--s4); padding: var(--s4);
  background: var(--surface); border-radius: var(--r-content);
  border: 1px solid var(--line);
}
.existing-account__title { font-size: var(--t-title); font-weight: 500; }
.existing-account__body { font-size: var(--t-meta); color: var(--ink-muted); max-width: 46ch; }
.existing-account__body a { color: var(--accent); }

/* The "01 Registration" / "02 Steps" eyebrows and the context strip that
   repeated the dates are both gone from the markup, and their rules with them.
   "Step 01 · Your details" stays: that one is a real sequence. */

/* A fieldset draws a border by default, which on this ground reads as a stray
   white rectangle around the payment choice. */
.portal-page fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.portal-page legend { padding: 0; }

/* What you are about to be charged, as a small ledger. */
.checkout-summary { display: grid; gap: var(--s3); }
.checkout-summary > div { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4); }
.checkout-summary span { color: var(--ink-low); font-size: var(--t-label); }
.checkout-summary strong { font-weight: 500; color: var(--ink); text-align: right; }
.checkout-summary > div:last-child strong { font-size: var(--t-title); }

/* ============================================================================
   THE REST OF THE SITE
   Delegations, claim codes, the policy pages and certificate verification used
   to run on the old light system: a #EDECE8 paper ground, a second typeface, a
   tracked uppercase eyebrow over every fieldset, and 86KB of stylesheet a
   delegate downloaded to read two paragraphs of terms. They are on the app's
   ground now, so nothing in the flow changes colour underneath anyone.
   ========================================================================= */

.registration-page, .policy-page { background: var(--ground); color: var(--ink); }
/* The bar sits in the flow and sticks. It used to be fixed, from a stylesheet
   these pages no longer load, and the body carried a matching padding to clear
   it; with the bar back in flow that padding was a 52px hole above the
   masthead on every page. Sticky needs no padding and still holds the top. */
.has-bar { padding-top: 0; }
.bar { position: sticky; top: 0; z-index: var(--z-tabbar); }

/* The page measure. These pages had it from the old stylesheet's own wrapper;
   on the app's system they need it declared, or the content runs to the very
   edge of the phone with no gutter at all. */
.registration-shell, .policy-main, .groups-width {
  width: 100%; max-width: 34rem; margin-inline: auto; padding-inline: var(--gutter);
}

/* The required marker came through from the old system in poster blue, which
   measures 1.97:1 on this ground. It is a mark beside a label, not a warning. */
.field > label span, .sec span { color: var(--ink-low); font-weight: 400; }

/* The opener these pages share. One statement, then the form. */
.registration-shell { padding-bottom: var(--s6); }
.registration-intro { padding-block: var(--s6) var(--s5); }
.registration-intro__title {
  margin: 0 0 var(--s4);
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2rem, 9.5vw, 3rem);
  line-height: 1.02; letter-spacing: -0.03em; text-wrap: balance;
}
.registration-intro__title em { font-style: normal; color: var(--ink-low); display: block; }
.registration-intro__title br { display: none; }
.registration-intro__lede {
  margin: 0 0 var(--s3); font-size: var(--t-title); line-height: 1.45;
  color: var(--ink-muted); max-width: 36ch; text-wrap: pretty;
}
.registration-intro__lede:last-child { margin-bottom: 0; }

/* Section headings inside a form. Sentence case, no tracked caps: the old
   "WHO IS PAYING" eyebrow is the one thing these pages must not keep. */
.sec {
  margin: var(--s6) 0 var(--s4);
  font-size: var(--t-title); font-weight: 500; letter-spacing: 0;
  text-transform: none; color: var(--ink);
}
.hint { font-size: var(--t-meta); color: var(--ink-muted); max-width: 44ch; }
.err { font-size: var(--t-label); color: var(--bad); }

/* THE SEAT PICKER -----------------------------------------------------------
   A row per package with a stepper on the right. This is the whole point of
   the delegations page: a rep sets how many of each package their school
   needs. It lost its styling when the old stylesheet went and rendered as the
   characters "-0+" run together, with no tap targets and nothing to press. */
.rows { display: grid; gap: 0; margin: 0 0 var(--s5); }
.row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  min-height: 64px; padding-block: var(--s3);
  border-top: 1px solid var(--line);
}
.rows > .row:last-child { border-bottom: 1px solid var(--line); }
.row > div:first-child { min-width: 0; }
.row b { display: block; font-size: var(--t-title); font-weight: 500; color: var(--ink); }
.row__meta { margin: 2px 0 0; font-size: var(--t-meta); color: var(--ink-muted); font-variant-numeric: tabular-nums; }

.stepper { display: flex; align-items: center; gap: var(--s2); flex: none; }
.stepper__btn {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: var(--r-round);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: var(--t-head); line-height: 1;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.stepper__btn:hover { border-color: var(--accent); }
.stepper__btn:active { background: var(--raised); }
.stepper__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.stepper__btn[disabled] { opacity: .35; cursor: default; }
.stepper__value {
  min-width: 3ch; text-align: center;
  font-size: var(--t-title); font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--ink);
}

/* Rows that are a whole tappable control, e.g. a claim code to copy. */
.row--tappable { cursor: pointer; }
.row--tappable:hover b { color: var(--accent); }
.row--tappable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 4px; }

/* An amount or a count sitting at the end of a row. Deliberately not .chip:
   that name belongs to the campaign's photo captions. */
.pill {
  flex: none; padding: var(--s1) var(--s3);
  border-radius: var(--r-round); background: var(--raised);
  font-size: var(--t-label); color: var(--ink-muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* The buttons these pages use. .portal-button is already defined above; .btn
   is the loc/desk name and lands here so the two never drift apart. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 var(--s5);
  border: 0; border-radius: var(--r-round);
  background: var(--raised); color: var(--ink);
  font: inherit; font-size: var(--t-title); font-weight: 500;
  cursor: pointer; text-decoration: none;
  transition: opacity var(--dur-1) var(--ease);
}
.btn--go { background: var(--ink); color: var(--ground); }
.btn:active { opacity: .7; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn[disabled] { opacity: .45; cursor: default; }

.toast {
  position: fixed; left: 50%; bottom: calc(var(--s5) + env(safe-area-inset-bottom));
  transform: translateX(-50%); z-index: var(--z-toast);
  max-width: calc(100% - var(--s5) * 2);
  padding: var(--s3) var(--s5); border-radius: var(--r-round);
  background: var(--raised); color: var(--ink);
  font-size: var(--t-meta); box-shadow: 0 8px 28px rgb(0 0 0 / .5);
}
.toast[data-kind="bad"] { color: var(--bad); }
.toast[data-kind="ok"] { color: var(--accent); }

/* POLICY PAGES --------------------------------------------------------------
   Terms and privacy are read once, usually because something went wrong, so
   they are set for reading: one column, generous leading, real headings. */
.policy-main { padding-block: var(--s6) var(--s6); }
.policy-main h1 em { font-style: normal; color: var(--ink-low); }
.policy-main h1 {
  margin: 0 0 var(--s5);
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2rem, 9vw, 2.75rem); line-height: 1.04;
  letter-spacing: -0.03em; text-wrap: balance;
}
.policy-main h2 {
  margin: var(--s6) 0 var(--s3);
  font-size: var(--t-head); font-weight: 500; letter-spacing: -0.02em; line-height: 1.2;
}
.policy-main h3 { margin: var(--s5) 0 var(--s2); font-size: var(--t-title); font-weight: 500; }
.policy-main p, .policy-main li {
  font-size: var(--t-title); line-height: 1.6; color: var(--ink-muted);
  max-width: 68ch; text-wrap: pretty;
}
.policy-main p { margin: 0 0 var(--s4); }
.policy-main ul, .policy-main ol { margin: 0 0 var(--s4); padding-left: var(--s5); }
.policy-main li { margin-bottom: var(--s2); }
.policy-main a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.policy-main strong, .policy-main b { color: var(--ink); font-weight: 500; }
/* Not yet approved by the committee, and saying so is the honest thing. */
.policy-draft {
  padding: var(--s4); border: 1px solid var(--line); border-radius: var(--r-content);
  background: var(--surface); color: var(--ink-muted); font-size: var(--t-meta);
}

/* CERTIFICATE VERIFICATION --------------------------------------------------
   Someone checking a certificate is usually not a delegate: an employer, a
   registrar, a scholarship office. They get one field and one answer. */
.verify-form { display: grid; gap: var(--s4); padding-block: var(--s5); }
.verify-result {
  margin-top: var(--s5); padding: var(--s5) var(--s4);
  background: var(--surface); border-radius: var(--r-content);
  font-size: var(--t-title); line-height: 1.5;
}
.verify-result[data-state="ok"] { color: var(--ink); }
.verify-result[data-state="bad"] { color: var(--bad); }
.verify-result b { display: block; font-weight: 500; margin-bottom: var(--s2); }

/* A claim code a rep reads out or copies. Tracked and monospaced for the same
   reason the room codes are: these get dictated over a phone line. */
.seat-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--t-title); font-weight: 500;
  letter-spacing: 0.06em; color: var(--ink);
}

/* The verification answer. Whoever is reading this is checking whether a
   certificate is real, so the verdict comes first and large, and the detail
   sits under it as a list they can scan against the document in their hand. */
.verify-result__head { margin: 0 0 var(--s4); font-size: var(--t-head); font-weight: 500; line-height: 1.2; }
.verify-result__facts {
  display: grid; grid-template-columns: minmax(7rem, auto) 1fr;
  gap: var(--s2) var(--s4); margin: 0;
  font-size: var(--t-meta);
}
.verify-result__facts dt { color: var(--ink-low); }
.verify-result__facts dd { margin: 0; color: var(--ink); }
@media (max-width: 26rem) {
  .verify-result__facts { grid-template-columns: 1fr; gap: 0; }
  .verify-result__facts dt { margin-top: var(--s3); }
}

/* The same panel on the register page's last step, where it is the loudest
   thing on the screen: a delegate who has just created an account and not paid
   has exactly one job, and it used to be a single grey line among eight rows. */
.confirm {
  display: grid; gap: var(--s3);
  margin-bottom: var(--s5); padding: var(--s5) var(--s4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-content);
}
.confirm__lead { margin: 0; font-size: var(--t-head); font-weight: 500; line-height: 1.2; color: var(--accent); }
.confirm__body { margin: 0; font-size: var(--t-title); line-height: 1.5; color: var(--ink); }
.confirm__body b { overflow-wrap: anywhere; }
.confirm__hint { margin: 0; font-size: var(--t-meta); color: var(--ink-low); }

/* Footer section headings. They were h4 under the page's h2, which navigating
   by heading reads as a missing level; they are h2 now and keep their size. */
.foot__h { margin: 0 0 var(--s3); font-size: var(--t-meta); font-weight: 500; color: var(--ink); }


/* A PACKAGE BOOKED THROUGH A SCHOOL ------------------------------------------
   The card itself carries no marking: the committee does not want the page
   telling every reader which tiers are out of reach. The explanation appears
   here instead, the moment somebody picks one, which is the only reason the
   unmarked card is defensible. */
.package-aside {
  margin: var(--s3) 0 0; padding: var(--s3) var(--s4);
  border: 1px solid var(--line); border-radius: var(--r-content);
  background: var(--surface);
  font-size: var(--t-meta); line-height: 1.5; color: var(--ink-muted);
  text-wrap: pretty;
}
.package-aside[hidden] { display: none; }
.package-aside a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* A package no longer sold: listed, so nobody wonders where it went, but
   plainly not selectable. */
.package-option--closed { opacity: 0.5; cursor: not-allowed; }
.package-option--closed .package-option__room { color: var(--ink); font-weight: 600; }

/* Registration closed: one line where the form was. */
.reg-closed { display: grid; gap: var(--s3); justify-items: start; padding: var(--s5) 0; }
.reg-closed h2 { font-size: var(--t-head); font-weight: 500; letter-spacing: -0.02em; }
.reg-closed p { color: var(--ink-muted); }
p.reg-closed { color: var(--ink); font-size: var(--t-title); }
[data-account-only] [hidden] { display: none !important; }
