/* ============================================================================
   PRE-AUTH SURFACE SYSTEM — the doors into MinMax Pro.
   ----------------------------------------------------------------------------
   Sign In, Reset Password, the SSO handoff, Book a Visit, Leave a Review and
   the Client Portal sign-in used to be six separately-invented pages: one on a
   pale cyan gradient with no chrome at all, one on a warm grey field with a
   green button left over from the emerald era, one on a black card, one a
   two-tone slab. A person who books a visit, then gets a review link, then
   signs into the portal saw three different products.

   This is the one design they now share, and it is the CONSOLE's design read
   back at a visitor who is not signed in yet:

     · DARK CHROME on top. The console's rail is a lifted graphite panel that
       sits in FRONT of the page; with no rail to put it in, that same graphite
       becomes a bar across the top. It carries the identity and the one or two
       links a signed-out page owes you, and nothing else.
     · LIGHT PAPER below it. The same cool off-white, the same faint blueprint
       grid, the same twin accent glows the console paints behind every page.
     · CYAN as the one accent. --teal (#007c89) wherever it is TEXT, because it
       has to pass on paper; --teal-bright (#00E5FF) wherever it is a fill or a
       glow, because that is the brand colour.

   ── EVERY VALUE IS A TOKEN WITH A FALLBACK ─────────────────────────────────
   Three of these six pages are WHITE-LABEL: a tenant's customer reaches them
   from the tenant's own email, and the brand engine repaints them by writing
   its tokens INLINE on :root. So nothing here may be a literal in a place a
   tenant can repaint — every rule reads var(--pa-*), and the .pa block below is
   the ONE place those resolve, each one pointing at the engine's token first
   and the product's own value only as the fallback. A page that never resolves
   a tenant renders in the product's cyan; a page that does renders in theirs,
   with no rule in this file knowing the difference.

   Consequence worth stating: do not add a #ffffff, a #00E5FF or a rgba() ink to
   a rule below. Add a --pa-* token for it here instead, or a dark-pack tenant
   gets a white card punched through their charcoal page.

   Pages that link this file: login.html, reset-password.html, sso.html,
   booking.html. review.html deliberately does NOT — it is opened on a phone,
   outdoors, on one bar of signal, and a review that cannot be left because a
   stylesheet did not arrive is a worse outcome than an unstyled one; it carries
   its own copy of the handful of rules it needs. The client portal's sign-in
   screen gets the same treatment from portal-skin.css, where the rest of that
   surface already lives.
   ========================================================================== */

/* ── Tokens ────────────────────────────────────────────────────────────────
   Scoped to .pa on <body> rather than :root on purpose: :root is where the
   brand engine writes, and a stylesheet that also writes there would either
   lose to it (inline wins) or have to fight it with !important. One level down,
   these READ the engine's values and can never collide with them. */
.pa {
  /* Chrome — the graphite bar. Fixed and neutral, exactly like the console's
     rail: decoupled from the brand hue so it stays a calm near-black panel in
     front of the page whatever colour the tenant is. A white-label page
     overrides --pa-chrome-base with the tenant's own ink (see booking.html),
     which is the one case where the chrome SHOULD be theirs — it is their
     customer's first sight of them, not of us. */
  --pa-chrome-base: var(--rail-bg, #20242c);
  --pa-chrome:      var(--pa-chrome-base);
  --pa-chrome-2:    color-mix(in srgb, var(--pa-chrome-base) 88%, #fff);
  --pa-chrome-line: rgba(255, 255, 255, .10);
  --pa-chrome-tx:   #eef0f5;
  --pa-chrome-dim:  rgba(238, 240, 245, .68);

  /* Paper — the console's canvas. */
  --pa-paper:   var(--paper, #e4ecf4);
  --pa-card:    var(--card, #ffffff);
  --pa-card-2:  var(--card-2, #f2f7fb);
  --pa-line:    var(--line, #d2dfea);
  --pa-line-soft: var(--line-soft, #e0e9f2);

  /* Ink */
  --pa-tx:      var(--tx, #151b21);
  --pa-tx-soft: var(--tx-soft, #454d58);
  --pa-tx-mute: var(--tx-mute, #5a6068);
  --pa-tx-dim:  var(--tx-dim, #9aa1ad);
  --pa-head:    var(--head, #0d1b20);

  /* Accent. The engine's --brand-primary-text is the tenant's colour already
     stepped down until it passes as TEXT on paper, which is the same job --teal
     does for the product; --brand-primary is the raw brand colour, which is the
     same job --teal-bright does. Pairing them the other way round is what turns
     a lit page muddy and an unlit one illegible. */
  --pa-accent:      var(--brand-primary-text, var(--teal, #007c89));
  --pa-accent-deep: var(--brand-primary-deep, var(--teal-deep, #00626d));
  --pa-accent-fill: var(--brand-primary, var(--teal-bright, #00E5FF));
  --pa-on-accent:   var(--brand-on-primary, var(--on-teal, #ffffff));
  --pa-accent-2:    var(--brand-accent, var(--accent-2, #2EE0A8));

  --pa-ok:   var(--ok, #1f9d57);
  --pa-bad:  var(--bad, #d6492f);
  --pa-gold: var(--gold, #f4b03e);

  /* Type — the console's three families, with the engine's names first so a
     custom-tier pack's fonts arrive here too. */
  --pa-f-head: var(--f-head, 'Bricolage Grotesque', Georgia, serif);
  --pa-f-body: var(--f-body, 'Plus Jakarta Sans', system-ui, sans-serif);
  --pa-f-mono: var(--f-mono, 'JetBrains Mono', ui-monospace, monospace);

  --pa-bar-h: 64px;
  --pa-r:     14px;
  --pa-r-lg:  18px;
  --pa-sh-1:  0 1px 2px rgba(16, 21, 28, .05), 0 1px 3px rgba(16, 21, 28, .04);
  --pa-sh-2:  0 8px 22px -14px rgba(16, 21, 28, .30);
  --pa-sh-3:  0 26px 56px -28px rgba(16, 21, 28, .34);
}

*, *::before, *::after { box-sizing: border-box; }
/* [hidden] is a UA rule of display:none, and ANY author display beats it. Most
   things on these pages carry display:flex or display:grid, so without this the
   tenant lockup and the product marketing both stayed on screen after the brand
   engine hid them. hidden has to mean hidden. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }
body.pa {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: var(--pa-f-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--pa-tx);
  background: var(--pa-paper);
  -webkit-font-smoothing: antialiased;
}

/* ── The ambient wash ───────────────────────────────────────────────────────
   The console's canvas, layer for layer (see the body::before block in
   components.css): a faint blueprint grid, the brand glow from the top right,
   the secondary thread from the bottom left, over a lit fade into the paper.

   It is a FIXED pseudo-element rather than a background on the body. Fixed
   background-attachment forces a full repaint of every layer on each scroll
   frame — it cannot be lifted onto a compositor layer — and the booking page is
   long enough for that to show as scroll jank. */
body.pa::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(84% 62% at 100% -6%, color-mix(in srgb, var(--pa-accent-fill) 16%, transparent), transparent 66%),
    radial-gradient(76% 58% at -8% 104%, color-mix(in srgb, var(--pa-accent-2) 8%, transparent), transparent 68%),
    var(--pa-paper);
}
/* ── The grid, on its own layer, FADING OUT ──────────────────────────────────
   It used to be two more layers inside the wash above, which meant it ran at
   full strength to the bottom of the viewport. A blueprint grid that terminates
   at the fold in a hard edge reads as a background image that failed to tile;
   one that dissolves reads as depth. It needs its own element to be masked,
   because a mask applies to the whole box and not to one background layer. */
body.pa::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(var(--pa-grid, color-mix(in srgb, var(--pa-head) 4%, transparent)) 1px, transparent 1px) 0 0 / 60px 60px,
    linear-gradient(90deg, var(--pa-grid, color-mix(in srgb, var(--pa-head) 4%, transparent)) 1px, transparent 1px) 0 0 / 60px 60px;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 34%, rgba(0, 0, 0, .35) 72%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 34%, rgba(0, 0, 0, .35) 72%, transparent 100%);
}
/* WHY THESE RATIOS. The console runs the same wash at 22%/11% plus a lit 170deg
   sheet, and it is right there: a rail covers the left quarter and dense cards
   cover most of the rest, so the colour only ever shows in the gaps. A pre-auth
   page is one card on an otherwise empty field, and at those numbers the same
   wash stopped being atmosphere and became the subject: the top half of every
   screen went pale cyan and the card floated in it. Turned down and pulled into
   the corners, the page reads as lit from the top right, which is what it was
   always meant to say. Do not raise these back to the console's numbers without
   looking at /login and /review, the two emptiest pages in the set. */
/* A dark-canvas tenant. The ratios are NOT interchangeable with the light ones:
   22% cyan over white is the pale tint that makes the canvas read as lit, and
   the same 22% over near-black is a saturated fog. The grid has to flip outright
   — a faint dark rule on paper is a faint light one on charcoal. Keyed off the
   attribute applyBrand() already stamps, so nothing has to detect anything. */
:root[data-brand-polarity="dark"] body.pa::before {
  background:
    radial-gradient(84% 62% at 100% -6%, color-mix(in srgb, var(--pa-accent-fill) 7%, transparent), transparent 66%),
    radial-gradient(76% 58% at -8% 104%, color-mix(in srgb, var(--pa-accent-2) 4.5%, transparent), transparent 68%),
    var(--pa-paper);
}
:root[data-brand-polarity="dark"] body.pa::after { --pa-grid: rgba(255, 255, 255, .05); }

/* ============================================================================
   1 · THE CHROME BAR
   ========================================================================== */
.pa-bar {
  position: sticky;
  top: 0;
  z-index: 30;
  flex: none;
  min-height: var(--pa-bar-h);
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 0 26px;
  /* Three things make this read as a PANEL IN FRONT of the page rather than a
     black stripe painted on it, and all three are one line each:
       · the vertical gradient, so the bar is lit from above;
       · the inset top highlight, the same 1px catch-light a physical bevel has;
       · a real drop shadow onto the paper below.
     The console's rail earns its depth the same way. Without them the bar was
     flat, and a flat near-black rectangle is the single most common tell of a
     template header. */
  background:
    /* Grain. A fractal-noise tile at 3% over the gradient, so the graphite has
       tooth instead of reading as a printed swatch. WHITE on alpha, never a
       greyscale tile: a greyscale noise needs a blend mode to disappear, and
       blend modes die inside any ancestor that creates a stacking context. */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E") 0 0 / 160px 160px,
    /* The bloom off the leading edge. The console's rail lifts a wide, shallow
       accent glow from just outside its TOP edge; rotate that panel flat and
       the same gesture arrives from just outside the LEFT edge, behind the
       lockup. Added 2026-08-12 so these doors carry the same lit chrome as the
       marketing pages and the console itself. It reads --pa-accent-fill, so a
       white-label tenant gets their own colour here and not ours. */
    radial-gradient(54% 240% at -4% 50%, color-mix(in srgb, var(--pa-accent-fill) 16%, transparent), transparent 78%),
    /* Three stops, not two: lifted at both ends, deeper through the middle,
       along the bar's length. Flat ends read as a printed band. */
    linear-gradient(90deg, var(--pa-chrome-2), var(--pa-chrome) 54%, var(--pa-chrome-2));
  border-bottom: 1px solid var(--pa-chrome-line);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 10px 30px -18px rgba(12, 16, 22, .55);
  color: var(--pa-chrome-tx);
}
/* The accent hairline under the bar — the same thread the console runs along
   the top of its rail. One pixel, and it is the whole reason the bar reads as
   lit rather than as a black strip laid on the page. */
.pa-bar::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in srgb, var(--pa-accent-fill) 55%, transparent) 22%,
    color-mix(in srgb, var(--pa-accent-fill) 20%, transparent) 62%,
    transparent);
  pointer-events: none;
}
.pa-bar-brand { display: flex; align-items: center; gap: 12px; min-width: 0; text-decoration: none; color: inherit; }
.pa-bar-brand img { display: block; }
/* The lockup the brand engine builds. It replaces its own children on every
   repaint with ITS class names, so the monogram has to be styled as .brand-mark
   here — the markup this page shipped does not survive first paint. */
.pa-bar .brand-lockup { display: flex; align-items: center; gap: 11px; min-width: 0; }
.pa-bar .brand-lockup .brand-mark {
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
  display: grid; place-items: center; overflow: hidden;
  font-family: var(--pa-f-head); font-weight: 800; font-size: 17px;
  color: var(--pa-on-accent);
  background: linear-gradient(150deg, var(--pa-accent-fill), var(--pa-accent));
}
.pa-bar .brand-lockup .brand-wrap { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.pa-bar .brand-lockup .brand-wrap b { font-family: var(--pa-f-head); font-weight: 700; font-size: 16px; letter-spacing: -.01em; color: var(--pa-chrome-tx); }
.pa-bar .brand-lockup .brand-wrap small,
.pa-bar .brand-lockup-sub {
  font-family: var(--pa-f-mono); font-size: 10px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--pa-chrome-dim);
}
/* With a real logo the logo IS the identity — the monogram and the typed
   wordmark beside it are the classic tell of a white-labelled template. */
.pa-bar .brand-lockup.has-logo .brand-mark,
.pa-bar .brand-lockup.has-logo .brand-wrap { display: none; }

/* A mono caption beside the identity: which door this is. */
.pa-bar-word {
  font-family: var(--pa-f-mono); font-size: 11px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--pa-chrome-dim);
  padding-left: 18px; margin-left: 2px; border-left: 1px solid var(--pa-chrome-line);
  white-space: nowrap;
}
@media (max-width: 620px) { .pa-bar-word { display: none; } }

.pa-bar-spacer { flex: 1; }
.pa-bar-nav { display: flex; align-items: center; gap: 6px; }
.pa-bar-link {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px;
  border-radius: 9px; border: 1px solid transparent; background: transparent;
  font-family: var(--pa-f-body); font-size: 13px; font-weight: 600;
  color: var(--pa-chrome-dim); text-decoration: none; white-space: nowrap;
  cursor: pointer; transition: background .14s, color .14s, border-color .14s;
}
.pa-bar-link:hover { background: rgba(255, 255, 255, .07); color: var(--pa-chrome-tx); }
.pa-bar-link svg { width: 15px; height: 15px; }
/* The one lit control in the chrome. Border and glow rather than a solid fill:
   a solid cyan pill on a graphite bar is louder than anything on the page below
   it, and the page below it is where the visitor is meant to be looking. */
.pa-bar-cta {
  border-color: color-mix(in srgb, var(--pa-accent-fill) 42%, transparent);
  background: color-mix(in srgb, var(--pa-accent-fill) 12%, transparent);
  color: var(--pa-chrome-tx);
}
.pa-bar-cta:hover {
  border-color: color-mix(in srgb, var(--pa-accent-fill) 72%, transparent);
  background: color-mix(in srgb, var(--pa-accent-fill) 20%, transparent);
  color: #fff;
}
@media (max-width: 520px) {
  .pa-bar { padding: 0 16px; gap: 10px; }
  .pa-bar-link { padding: 0 9px; font-size: 12.5px; }
}

/* ============================================================================
   2 · THE PAGE
   ========================================================================== */
.pa-main { flex: 1; width: 100%; max-width: 1120px; margin: 0 auto; padding: 46px 26px 56px; }
.pa-main.pa-narrow { max-width: 480px; }
.pa-main.pa-wide { max-width: 1180px; }
/* A single card centred in what is left of the viewport once the bar is gone.
   min-height rather than height so a card taller than the fold still scrolls. */
.pa-main.pa-center {
  display: grid; place-items: center;
  min-height: calc(100vh - var(--pa-bar-h) - 64px);
}
@media (max-width: 640px) { .pa-main { padding: 30px 18px 42px; } }

/* Two columns: the story on the left, the thing you came to do on the right.
   The right column is fixed-ish so the form never stretches past a comfortable
   measure on a wide monitor. */
.pa-split { display: grid; grid-template-columns: 1fr 424px; gap: 54px; align-items: center; }
@media (max-width: 1000px) {
  .pa-split { grid-template-columns: 1fr; gap: 34px; max-width: 480px; margin: 0 auto; }
  .pa-split .pa-tell { display: none; }
}

/* ── The telling side ─────────────────────────────────────────────────────── */
.pa-eyebrow {
  font-family: var(--pa-f-mono); font-size: 11.5px; font-weight: 600;
  /* The DEEP step. This is 11.5px mono at .16em on the page canvas, not a link
     on a white card — --pa-accent measured 4.15:1 there and --pa-accent-deep is
     5.5:1 in the same hue. (check-contrast.mjs, 2026-08-11.) */
  letter-spacing: .16em; text-transform: uppercase; color: var(--pa-accent-deep);
  margin-bottom: 18px;
}
/* .pa-tell-h2: the same visual heading on an element that is NOT an <h2>.
   login.html uses it because its marketing panel sits BEFORE the card's <h1>
   in DOM order, and a real h2 there inverts the document outline for
   screen-reader users. Same look, no heading semantics. */
.pa-tell h2, .pa-tell .pa-tell-h2 {
  font-family: var(--pa-f-head); font-weight: 800; font-size: clamp(31px, 3.4vw, 45px);
  line-height: 1.06; letter-spacing: -.025em; color: var(--pa-head); margin: 0 0 18px;
  /* Headings and ledes here are set by a tenant as often as by us, so their
     length is not knowable at design time. Balanced wrapping keeps a three-word
     orphan off the last line of a repainted headline without anyone hand-tuning
     a <br>. Ignored by browsers that do not support it, which lose nothing. */
  text-wrap: balance;
}
/* The lit half of the headline. The ramp runs deep cyan into bright cyan and
   stops there: mixing toward --accent-2 put a mint green at the end of the
   gradient, so the one line of the page carrying the brand read as green. The
   brand pair is cyan AND mint, but the mint is the second thread, not half of
   the primary colour. */
.pa-tell h2 em, .pa-tell .pa-tell-h2 em {
  font-style: normal;
  background: linear-gradient(96deg, var(--pa-accent-deep), color-mix(in srgb, var(--pa-accent-fill) 62%, var(--pa-accent)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pa-tell .pa-sub { font-size: 15.5px; line-height: 1.62; color: var(--pa-tx-soft); max-width: 42ch; margin: 0; }
.pa-rule { height: 2px; width: 56px; margin: 26px 0 22px; border: 0; border-radius: 2px; background: linear-gradient(90deg, var(--pa-accent-fill), color-mix(in srgb, var(--pa-accent-2) 60%, transparent)); }
/* Capped, not full-bleed. The left column is as wide as the page allows, and a
   three-word row stretched across 620px of it reads as a broken table. */
.pa-feats { display: flex; flex-direction: column; gap: 10px; max-width: 430px; }
.pa-feat {
  display: flex; align-items: center; gap: 13px;
  font-size: 14px; font-weight: 500; color: var(--pa-tx-soft);
  padding: 11px 14px; border-radius: var(--pa-r);
  background: color-mix(in srgb, var(--pa-card) 74%, transparent);
  border: 1px solid var(--pa-line-soft);
}
.pa-feat .ic {
  width: 32px; height: 32px; border-radius: 9px; flex-shrink: 0; display: grid; place-items: center;
  background: color-mix(in srgb, var(--pa-accent) 11%, var(--pa-card));
  border: 1px solid color-mix(in srgb, var(--pa-accent) 24%, transparent);
  color: var(--pa-accent);
}
.pa-feat .ic svg { width: 16px; height: 16px; }

/* ── Cards ────────────────────────────────────────────────────────────────── */
.pa-card {
  width: 100%;
  background: var(--pa-card);
  border: 1px solid var(--pa-line);
  border-radius: var(--pa-r-lg);
  box-shadow: var(--pa-sh-1), var(--pa-sh-3);
  padding: 32px 30px;
}
.pa-card.pa-flush { padding: 0; overflow: hidden; }
.pa-card-head { margin-bottom: 24px; }
.pa-card-head h1 { font-family: var(--pa-f-head); font-weight: 800; font-size: 27px; letter-spacing: -.02em; color: var(--pa-head); margin: 0 0 7px; text-wrap: balance; }
.pa-card-head h2 { font-family: var(--pa-f-head); font-weight: 700; font-size: 20px; letter-spacing: -.015em; color: var(--pa-head); margin: 0 0 5px; text-wrap: balance; }
.pa-card-head p { font-size: 14.5px; color: var(--pa-tx-soft); margin: 0; text-wrap: pretty; }
/* The accent strap along the top edge of a card — the console's stat tile wears
   the same mark down its left side. It is what stops a white card on pale paper
   from reading as a blank rectangle. */
.pa-card.pa-strap { position: relative; overflow: hidden; }
.pa-card.pa-strap::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, var(--pa-accent-fill), var(--pa-accent-2), transparent 78%);
}
@media (max-width: 480px) { .pa-card { padding: 26px 20px; } }

/* ── Fields ───────────────────────────────────────────────────────────────── */
.pa-field { margin-bottom: 17px; }
.pa-field label,
.pa-label {
  display: block; font-size: 12px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--pa-tx-soft); margin-bottom: 7px;
}
.pa-input, .pa-select, .pa-textarea {
  width: 100%; height: 48px; padding: 0 14px;
  font-family: inherit; font-size: 15px; color: var(--pa-tx);
  background: var(--pa-card-2);
  border: 1.5px solid var(--pa-line); border-radius: 11px;
  outline: none; transition: border-color .15s, box-shadow .15s, background .15s;
}
.pa-textarea { height: auto; min-height: 84px; padding: 11px 14px; resize: vertical; line-height: 1.55; }
.pa-select { -webkit-appearance: none; appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, var(--pa-tx-mute) 50%), linear-gradient(135deg, var(--pa-tx-mute) 50%, transparent 50%);
  background-position: calc(100% - 18px) 21px, calc(100% - 13px) 21px;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.pa-input::placeholder, .pa-textarea::placeholder { color: var(--pa-tx-dim); opacity: 1; }
.pa-input:focus, .pa-select:focus, .pa-textarea:focus {
  background: var(--pa-card);
  border-color: var(--pa-accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--pa-accent) 15%, transparent);
}
.pa-hint { font-size: 12.5px; color: var(--pa-tx-soft); line-height: 1.5; margin: -6px 0 16px; }
.pa-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 4px 0 22px; }
.pa-check { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--pa-tx-soft); cursor: pointer; user-select: none; }
.pa-check input { width: 17px; height: 17px; accent-color: var(--pa-accent); cursor: pointer; }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.pa-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; height: 50px; padding: 0 20px;
  font-family: inherit; font-size: 15px; font-weight: 700; letter-spacing: .01em;
  border: 1.5px solid transparent; border-radius: 12px; cursor: pointer;
  /* Every button in this file used to be a <button>, so the UA's anchor
     underline never came up. 404.html and the marketing pages style an <a> as a
     button — a link that navigates should be an <a> — and it arrived underlined
     inside its own filled pill. Stated here rather than at each call site. */
  text-decoration: none;
  transition: transform .12s, box-shadow .16s, background .16s, border-color .16s, color .16s;
}
.pa-btn:active:not(:disabled) { transform: translateY(1px); }
.pa-btn:disabled { opacity: .62; cursor: not-allowed; transform: none; }
.pa-btn-primary {
  background: linear-gradient(180deg, var(--pa-accent), var(--pa-accent-deep));
  color: var(--pa-on-accent);
  box-shadow: 0 12px 26px -14px color-mix(in srgb, var(--pa-accent) 80%, transparent);
}
.pa-btn-primary:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 16px 32px -14px color-mix(in srgb, var(--pa-accent) 85%, transparent); }
.pa-btn-ghost { background: var(--pa-card); border-color: var(--pa-line); color: var(--pa-tx); }
.pa-btn-ghost:hover:not(:disabled) { border-color: color-mix(in srgb, var(--pa-accent) 45%, transparent); color: var(--pa-accent); background: color-mix(in srgb, var(--pa-accent) 6%, var(--pa-card)); }
/* ── The demo door ───────────────────────────────────────────────────────────
   A ghost button is the right WEIGHT for a secondary action and the wrong
   VOLUME for this one. The demo is the highest-intent thing a signed-out
   visitor can do — it needs no form, no card and no credentials — and on the
   sign-in screen it was a grey outline inside a dashed panel, which reads as a
   footnote to the password field rather than as the easier way in.

   Lit, but deliberately NOT a second solid fill: the page already has one
   filled control and two of them ask the visitor to choose between two equals.
   An accent wash, a full-strength accent border and the accent as text put it
   one clear step above a ghost and one clear step below the primary. The glow
   is the brand cyan (a fill), the label is the text step. */
.pa-btn-demo {
  background: color-mix(in srgb, var(--pa-accent) 12%, var(--pa-card));
  border-color: color-mix(in srgb, var(--pa-accent) 55%, transparent);
  color: var(--pa-accent-deep);
  box-shadow: 0 10px 22px -14px color-mix(in srgb, var(--pa-accent-fill) 75%, transparent);
}
.pa-btn-demo:hover:not(:disabled) {
  background: color-mix(in srgb, var(--pa-accent) 20%, var(--pa-card));
  border-color: var(--pa-accent);
  color: var(--pa-accent-deep);
  box-shadow: 0 14px 28px -12px color-mix(in srgb, var(--pa-accent-fill) 90%, transparent);
}
.pa-btn-sm { height: 40px; font-size: 13.5px; border-radius: 10px; }
.pa-btn-auto { width: auto; }
.pa-btn .pa-spin {
  width: 18px; height: 18px; border-radius: 50%; display: none;
  border: 2.5px solid color-mix(in srgb, var(--pa-on-accent) 34%, transparent);
  border-top-color: var(--pa-on-accent);
  animation: pa-spin .7s linear infinite;
}
.pa-btn.is-loading .pa-spin { display: block; }
.pa-btn.is-loading .pa-lbl { display: none; }
@keyframes pa-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pa-spin { animation: none; } }

.pa-link { color: var(--pa-accent-deep); font-weight: 600; text-decoration: none; }
.pa-link:hover { text-decoration: underline; }
.pa-back {
  display: inline-flex; align-items: center; gap: 7px;
  background: none; border: 0; padding: 0; margin-bottom: 14px;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--pa-tx-mute); cursor: pointer;
}
.pa-back:hover { color: var(--pa-accent-deep); }
.pa-back svg { width: 14px; height: 14px; }

/* ── Messages ─────────────────────────────────────────────────────────────── */
.pa-msg { display: none; margin-top: 16px; padding: 11px 14px; border-radius: 11px; font-size: 13.5px; line-height: 1.5; }
.pa-msg.show { display: block; }
.pa-msg.err { background: color-mix(in srgb, var(--pa-bad) 10%, var(--pa-card)); color: var(--pa-bad); border: 1px solid color-mix(in srgb, var(--pa-bad) 28%, transparent); }
.pa-msg.ok  { background: color-mix(in srgb, var(--pa-accent) 11%, var(--pa-card)); color: var(--pa-accent-deep); border: 1px solid color-mix(in srgb, var(--pa-accent) 30%, transparent); }
.pa-msg.info { background: color-mix(in srgb, var(--pa-accent) 8%, var(--pa-card)); color: var(--pa-accent-deep); border: 1px solid color-mix(in srgb, var(--pa-accent) 24%, transparent); }

/* ── Note panel (the demo chip, the what-happens-next block) ───────────────── */
.pa-note {
  margin-top: 22px; padding: 15px 16px; border-radius: var(--pa-r);
  border: 1px dashed color-mix(in srgb, var(--pa-accent) 32%, transparent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--pa-accent) 6%, transparent), transparent);
}
.pa-note-top { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 700; color: var(--pa-accent-deep); margin-bottom: 8px; }
.pa-tag {
  font-family: var(--pa-f-mono); font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  background: var(--pa-accent); color: var(--pa-on-accent); padding: 3px 7px; border-radius: 5px;
}
.pa-note p { font-size: 13px; line-height: 1.5; color: var(--pa-tx-soft); margin: 0; }
.pa-note p + p { margin-top: 8px; }
.pa-note .pa-fine { font-size: 11.5px; line-height: 1.45; opacity: .86; }
.pa-note code { font-family: var(--pa-f-mono); font-size: 12.5px; color: var(--pa-tx); background: var(--pa-line-soft); padding: 2px 7px; border-radius: 5px; }

/* ── Footer ───────────────────────────────────────────────────────────────── */
.pa-foot {
  flex: none; padding: 20px 26px 26px;
  font-size: 12.5px; color: var(--pa-tx-mute); text-align: center; line-height: 1.6;
}
.pa-foot a { color: var(--pa-accent-deep); text-decoration: none; }
.pa-foot a:hover { text-decoration: underline; }

/* ── Entrance ────────────────────────────────────────────────────────────────
   ONE orchestrated page load, not a scattering of micro-animations. The chrome
   is already there when the page paints (it is the frame, and a frame that
   slides in reads as a page still loading); the content rises under it in two
   short, overlapping steps. 420ms total, so it is felt rather than watched.

   `backwards` fill is the load-bearing word: without it, an element with a
   120ms delay renders at its FINAL position for those 120ms and then jumps back
   to the start of the animation, which is a visible flicker on every load.

   The reduced-motion block at the foot of this file collapses the duration to
   nothing, and `forwards` means the end state still applies, so a visitor who
   has asked for no motion gets the finished page with no animation at all
   rather than a page stuck at opacity 0. */
.pa-rise { animation: pa-rise .42s cubic-bezier(.22, 1, .36, 1) both; }
.pa-rise-1 { animation-delay: .04s; }
.pa-rise-2 { animation-delay: .13s; }
@keyframes pa-rise { from { opacity: 0; transform: translateY(10px); } }

/* ── Accessibility ───────────────────────────────────────────────────────────
   The ring is the ACCENT AS TEXT (#007c89), not the brand cyan. #00E5FF is a
   glow colour: against a white card it measures about 1.8:1, so the one
   indicator a keyboard user has for where they are was the least visible thing
   on the page. On the dark bar the relationship inverts, and there the bright
   cyan is the readable one, which is why the bar states its own. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--pa-accent);
  outline-offset: 2px;
}
.pa-bar :where(a, button):focus-visible { outline-color: var(--pa-accent-fill); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
