/* Reform Assistant console and auth stylesheet.
 * Implements docs/design/design-language.md. Sections follow the spec's numbering:
 *   Fonts, 2 Tokens, 3 Base, 4 Layout, 5 Components, 6 Pages and class map, Auth pages, 7 Accessibility.
 * Rules: one token set (no hex in component rules), one class per rule, no !important except [hidden]
 * and prefers-reduced-motion, weights 400 and 700 only, nothing under 14px.
 */

/* ==========================================================================
   Fonts: Atkinson Hyperlegible Next (self-hosted latin woff2, 400 and 700 only)
   ========================================================================== */

@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/AtkinsonHyperlegibleNext-Regular.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/AtkinsonHyperlegibleNext-Bold.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   2. Tokens
   ========================================================================== */

:root {
  color-scheme: light;

  /* Surfaces and text */
  --bg: #fbf8f4;            /* page canvas (cream) */
  --surface: #ffffff;       /* cards, inputs, dialogs, menus */
  --sunken: #f3eee6;        /* inset blocks, read-only and locked values, hover fill, disabled fill */
  --ink: #1b1814;           /* primary text, focus ring, button labels on orange */
  --ink-2: #4f483f;         /* secondary text */
  --muted: #6b6358;         /* hints, captions, placeholders (5.1:1 or more on every surface) */
  --line: #e6dfd4;          /* decorative dividers and card borders only */
  --line-strong: #857c70;   /* every control border (3.5:1 or more) */

  /* Brand: orange */
  --brand: #ff6b1a;         /* primary button fill, brand mark */
  --brand-hover: #ff8238;
  --brand-press: #e85a0c;
  --brand-edge: #d9540a;    /* button border, selected border, progress fill (4.0:1 on white) */
  --brand-text: #a63f04;    /* links and active text (6.3:1 on white) */
  --brand-tint: #ffede0;    /* selected and active background */
  --brand-tint-2: #ffd8bf;  /* avatar fill, highlight */

  /* Gold: stamps and stamp packages only */
  --gold: #805600;
  --gold-tint: #fff4d6;

  /* Status: each has fg (text and icon), bg (tint), border (decorative), solid (dots, fills with white text) */
  --ok-fg: #276b43;      --ok-bg: #eaf4ee;      --ok-border: #a9d1b8;      --ok-solid: #2f7d4f;
  --warn-fg: #7a4b00;    --warn-bg: #fdf4e7;    --warn-border: #e6cf9f;    --warn-solid: #a86300;
  --danger-fg: #b3261e;  --danger-bg: #fceceb;  --danger-border: #e8a8a4;  --danger-solid: #b3261e;
  --danger-solid-hover: #9f1f19;
  --info-fg: #22505c;    --info-bg: #e9f1f1;    --info-border: #a9c7c9;    --info-solid: #2a6b78;

  /* Disabled and focus */
  --disabled-bg: #f3eee6;
  --disabled-fg: #8a8176;   /* 3.3:1 on sunken: intentionally quieter, exempt from contrast rules */
  --focus: #1b1814;         /* 3px ring, 2px offset */
  --backdrop: rgba(27, 24, 20, 0.48);

  /* Typography */
  --font: 'Atkinson Hyperlegible Next', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-numeric: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; /* money, dates, quantities */

  --fs-display: 34px;  --lh-display: 40px;
  --fs-h1: 28px;       --lh-h1: 34px;
  --fs-h2: 22px;       --lh-h2: 28px;
  --fs-h3: 18px;       --lh-h3: 24px;
  --fs-body: 17px;     --lh-body: 26px;
  --fs-small: 15px;    --lh-small: 22px;
  --fs-caption: 14px;  --lh-caption: 20px;
  --fs-label: 16px;    --lh-label: 22px;
  --fs-figure: 28px;   --lh-figure: 34px;   /* totals, stat values */

  /* Spacing (4px grid) */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 20px;
  --s-6: 24px; --s-8: 32px; --s-10: 40px; --s-12: 48px; --s-16: 64px;

  /* Radius */
  --radius-xs: 4px;     /* inline code, tiny chips */
  --radius-sm: 8px;     /* buttons, inputs, menu items, nav items */
  --radius-md: 12px;    /* cards, notices, popovers, list groups, selectable cards */
  --radius-lg: 16px;    /* dialogs on desktop */
  --radius-xl: 20px;    /* top corners of the phone sheet */
  --radius-pill: 999px; /* badges, avatars, stepper circles, progress bars */

  /* Elevation */
  --shadow-1: 0 1px 2px rgba(27, 24, 20, 0.06), 0 1px 1px rgba(27, 24, 20, 0.04);
  --shadow-2: 0 4px 12px rgba(27, 24, 20, 0.08), 0 1px 3px rgba(27, 24, 20, 0.06);
  --shadow-3: 0 22px 60px rgba(27, 24, 20, 0.18), 0 2px 8px rgba(27, 24, 20, 0.08);

  /* Z-index */
  --z-sticky: 10;  --z-nav: 40;  --z-popover: 60;  --z-skip: 1000;

  /* Motion */
  --dur-fast: 120ms;  --dur-base: 180ms;  --dur-slow: 260ms;  --dur-shimmer: 1.6s;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);

  /* Skeleton (warm) */
  --skeleton-base: #efe9df;
  --skeleton-hi: #f8f4ee;

  /* Layout */
  --header-h: 56px;     /* 64px from 768px */
  --sidebar-w: 220px;
  --tabbar-h: 64px;
  --container-max: 1080px;
  --measure: 65ch;
}

@media (min-width: 768px) {
  :root { --header-h: 64px; }
}

/* ==========================================================================
   3. Base layer
   ========================================================================== */

/* 3.1 Reset, document, focus, motion */

*,
*::before,
*::after {
  box-sizing: border-box;
  overflow-wrap: anywhere;
}

[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
  color: var(--ink);
  font: 400 var(--fs-body)/var(--lh-body) var(--font);
  scroll-padding-top: calc(var(--header-h) + var(--s-4));
  scroll-padding-bottom: calc(var(--s-16) + env(safe-area-inset-bottom));
}

body {
  margin: 0;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body:has(dialog[open]) { overflow: hidden; }

h1,
h2,
h3 {
  margin: 0;
  color: var(--ink);
  text-wrap: balance;
  font-weight: 700;
}

h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); }
h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); }
h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); }

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: var(--brand-text);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}

a:hover {
  color: var(--ink);
  text-decoration-thickness: 2.5px;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* Programmatic focus targets such as page and step headings: never keyboard-reachable controls */
[tabindex="-1"]:focus { outline: none; }

.skip-link {
  position: absolute;
  top: var(--s-2);
  left: var(--s-2);
  z-index: var(--z-skip);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--s-4);
  background: var(--brand);
  color: var(--ink);
  font-weight: 700;
  text-decoration: none;
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
  transition: transform var(--dur-fast) var(--ease-standard);
}

.skip-link:focus { transform: translateY(0); }
.skip-link:focus-visible { outline-offset: 0; }

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

fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

legend { padding: 0; }

@media (max-width: 639px) {
  :root {
    --fs-display: 30px;
    --lh-display: 36px;
    --fs-h1: 26px;
    --lh-h1: 32px;
    --fs-h2: 20px;
    --lh-h2: 26px;
  }
}

/* 3.2 Numeric text: plain zeros and aligned columns for money, dates and quantities */

.is-money,
.total-value,
.order-line dd,
.kv dd,
.buy-summary,
.qty-input,
.plan-option-price,
.plan-option-meta,
.renewal-copy,
.msgs-stamps,
.msgs-time,
.stat-value,
.home-tile-value,
.list-end {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
}

/* ID numbers keep the main face (its zero differs from the letter O) with a little tracking */
.input-id,
.summary-id {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

/* 3.3 Icons: every inline svg is sized and stroked here, so no icon ever renders unsized.
   The shell's hand-written nav, menu and chevron svgs share the same stroke rules. */

.icon,
.nav a > svg,
.mobile-tabs a > svg,
.menu-item > svg,
.account-chevron {
  flex: none;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2px;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon *,
.nav a > svg *,
.mobile-tabs a > svg *,
.menu-item > svg *,
.account-chevron * {
  vector-effect: non-scaling-stroke;
}

.icon-sm,
.account-chevron { width: 16px; height: 16px; }
.icon-lg,
.mobile-tabs a > svg { width: 24px; height: 24px; }

/* 3.4 Layout helpers: components own their inside, parents own the space between */

/* Registered so a modifier (.stack-lg) sets the gap of its own element only, never of nested stacks */
@property --stack-gap {
  syntax: '<length>';
  inherits: false;
  initial-value: 16px;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, var(--s-4));
  min-width: 0;
}

.stack-sm { --stack-gap: var(--s-2); }
.stack-md { --stack-gap: var(--s-3); }
.stack-lg { --stack-gap: var(--s-6); }
.stack-form { --stack-gap: var(--s-5); }   /* between fields */
.stack-cards { --stack-gap: var(--s-4); }  /* between cards on a page */

@media (min-width: 640px) {
  .stack-cards { --stack-gap: var(--s-5); }
}

/* A button, link or chip inside a stack keeps its natural width; .btn-block opts back in to full width */
.stack > :is(.btn, .link-action, .badge, .stamp-tile-wrap) { align-self: flex-start; }
.stack > .btn-block { align-self: stretch; }

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

.inset,
.summary-person {
  padding: var(--s-4);
  background: var(--sunken);
  border-radius: var(--radius-sm);
}

.divider {
  height: 0;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--line);
}

/* ==========================================================================
   4. Layout and responsive (app shell: top bar, sidebar, tab bar, content column)
   Breakpoints: 640 (sm), 768 (md, header 64px), 1024 (lg, sidebar replaces the tab bar)
   ========================================================================== */

.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.main { flex: 1; }

/* Content column; the notices region and the view are stacks, so no component carries an outer margin */
.content {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  max-width: var(--container-max);
  padding: var(--s-6) var(--s-6) var(--s-12);
}

#notices {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

#notices:empty { display: none; }

#view { min-width: 0; }

/* Brand mark */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--ink);
  text-decoration: none;
}

.brand:hover { color: var(--ink); }

.brand .logo {
  display: block;
  flex: none;
  color: var(--brand);
  line-height: 0;
}

.brand .logo svg {
  display: block;
  width: 100%;
  height: 100%;
}

.brand .wordmark {
  font-size: var(--fs-h3);
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}

/* Top bar: logo mark (phone and tablet), page title (the page's h1), action slot, account (phone and tablet) */
.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  height: var(--header-h);
  padding: 0 var(--s-4);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.topbar-brand {
  display: inline-flex;
  flex: none;
  color: var(--brand);
  line-height: 0;
}

.topbar-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.topbar-actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--s-2);
}

.topbar-actions:empty { display: none; }

/* Account menu trigger: sidebar button on desktop, avatar button in the top bar elsewhere */
.account { position: relative; }
.account-top { flex: none; }

.account-btn {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  min-height: 48px;
  padding: 0 var(--s-2);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-standard);
}

.account-btn:hover,
.account-btn[aria-expanded="true"] { background: var(--sunken); }

.account-info {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}

.user-name,
.user-email {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-name {
  font-size: var(--fs-small);
  font-weight: 700;
  line-height: var(--lh-caption);
  color: var(--ink);
}

.user-email {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

.account-chevron {
  stroke: var(--muted);
  transition: transform var(--dur-fast) var(--ease-standard);
}

.account-btn[aria-expanded="true"] .account-chevron { transform: rotate(180deg); }

/* Nav item (sidebar rows and tab bar items): 44px target, 20px icon, 12px gap, current page is marked by
   a tint, ink text and a bar, never by colour alone */
.nav a,
.mobile-tabs a {
  position: relative;
  min-height: 44px;
  color: var(--ink-2);
  text-decoration: none;
}

.nav-label {
  font: 700 var(--fs-label)/var(--lh-label) var(--font);
  white-space: nowrap;
}

.nav a[aria-current="page"],
.mobile-tabs a[aria-current="page"] { color: var(--ink); }

/* Desktop and tablet-up shell is sidebar-only below; the sidebar is hidden until 1024px */
.sidebar { display: none; }

/* Tab bar is shown on phones and tablets only */
.mobile-tabs { display: none; }

/* Desktop (1024px and up): fixed sidebar; the top bar and content sit to its right */
@media (min-width: 1024px) {
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: var(--z-nav);
    display: flex;
    flex-direction: column;
    width: var(--sidebar-w);
    background: var(--bg);
    border-right: 1px solid var(--line);
  }

  /* The brand row is as tall as the top bar so the two borders form one line */
  .sidebar .brand {
    flex: none;
    gap: var(--s-2);
    height: var(--header-h);
    padding: 0 var(--s-4);
    border-bottom: 1px solid var(--line);
  }

  .sidebar .brand .logo {
    width: 28px;
    height: 28px;
  }

  .sidebar .brand .wordmark { font-size: var(--fs-label); }

  .nav {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--s-1);
    padding: var(--s-2);
    overflow-y: auto;
  }

  .nav a {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: 0 var(--s-3);
    border-radius: var(--radius-sm);
    transition: background-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
  }

  .nav a:hover {
    background: var(--sunken);
    color: var(--ink);
  }

  .nav a[aria-current="page"] { background: var(--brand-tint); }

  .nav a[aria-current="page"]::before {
    content: "";
    position: absolute;
    inset: var(--s-2) auto var(--s-2) 0;
    width: 3px;
    background: var(--brand-edge);
    border-radius: var(--radius-pill);
  }

  .sidebar-foot {
    flex: none;
    padding: var(--s-3);
    border-top: 1px solid var(--line);
  }

  .topbar,
  .main { margin-left: var(--sidebar-w); }

  .topbar-brand,
  .account-top { display: none; }
}

/* Tablet (640px to 1023px): the tab bar becomes a sticky row of pills under the top bar */
@media (min-width: 640px) and (max-width: 1023px) {
  html { scroll-padding-top: calc(var(--header-h) + 48px + var(--s-4)); }

  .topbar { padding: 0 var(--s-6); }

  .mobile-tabs {
    position: sticky;
    top: var(--header-h);
    z-index: var(--z-sticky);
    order: 2;
    display: flex;
    align-items: center;
    gap: var(--s-2);
    min-height: 56px;
    padding: 0 var(--s-6);
    background: var(--surface);
    border-bottom: 1px solid var(--line);
  }

  .mobile-tabs a {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    padding: 0 var(--s-4);
    border-radius: var(--radius-pill);
  }

  .mobile-tabs a > svg { width: 20px; height: 20px; }

  .mobile-tabs .nav-label {
    font-size: var(--fs-small);
    line-height: var(--lh-small);
  }

  .mobile-tabs a[aria-current="page"] {
    background: var(--brand-tint);
    box-shadow: inset 0 0 0 1.5px var(--brand-edge);
  }

  .main { order: 3; }
}

/* Phone (under 640px): fixed bottom tab bar, icon 24 over a 14px label */
@media (max-width: 639px) {
  .mobile-tabs {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: var(--z-nav);
    display: flex;
    align-items: stretch;
    justify-content: space-around;
    height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: var(--surface);
    border-top: 1px solid var(--line);
  }

  .mobile-tabs a {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--s-1);
    min-width: 0;
  }

  .mobile-tabs .nav-label {
    font-size: var(--fs-caption);
    line-height: var(--lh-caption);
  }

  /* Current tab: tint pill behind the icon plus a 3px top bar */
  .mobile-tabs a[aria-current="page"]::before {
    content: "";
    position: absolute;
    top: 0;
    right: 25%;
    left: 25%;
    height: 3px;
    background: var(--brand-edge);
    border-radius: 0 0 var(--radius-xs) var(--radius-xs);
  }

  .mobile-tabs a[aria-current="page"] > svg {
    box-sizing: content-box;
    padding: var(--s-1) var(--s-4);
    background: var(--brand-tint);
    border-radius: var(--radius-pill);
  }

  .content {
    padding: var(--s-4) var(--s-4) calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--s-4));
  }

  /* [owner decision] the Set up wizard hides the tab bar so its sticky footer is the only bottom bar */
  body.route-setup .mobile-tabs { display: none; }
  body.route-setup .content { padding-bottom: 0; }
}

/* ==========================================================================
   5. Components
   ========================================================================== */

/* 5.1 Button */

.btn {
  --btn-bg: var(--surface);
  --btn-fg: var(--ink);
  --btn-border: var(--line-strong);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 48px;
  max-width: 100%;
  padding: 0 var(--s-5);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1.5px solid var(--btn-border);
  border-radius: var(--radius-sm);
  font: 700 17px/20px var(--font);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

.btn:hover {
  --btn-bg: var(--sunken);
  --btn-border: var(--ink);
  color: var(--btn-fg);
}

.btn:active { transform: translateY(1px); }
.btn .icon { width: 20px; height: 20px; }

.btn-secondary { /* same as .btn; exists so markup says what it means */ }

.btn-accent {
  --btn-bg: var(--brand);
  --btn-border: var(--brand-edge);
}

.btn-accent:hover {
  --btn-bg: var(--brand-hover);
  --btn-border: var(--brand-edge);
}

.btn-accent:active { --btn-bg: var(--brand-press); }

.btn-ghost {
  --btn-bg: transparent;
  --btn-border: transparent;
}

.btn-ghost:hover {
  --btn-bg: var(--sunken);
  --btn-border: transparent;
}

.btn-danger {
  --btn-bg: var(--danger-solid);
  --btn-fg: #fff;
  --btn-border: var(--danger-solid);
}

.btn-danger:hover {
  --btn-bg: var(--danger-solid-hover);
  --btn-border: var(--danger-solid-hover);
}

.btn-danger-outline {
  --btn-fg: var(--danger-fg);
  --btn-border: var(--danger-fg);
}

.btn-danger-outline:hover {
  --btn-bg: var(--danger-bg);
  --btn-border: var(--danger-fg);
}

.btn-sm {
  min-height: 40px;
  padding: 0 var(--s-4);
  font-size: 15px;
  line-height: 18px;
}

.btn-sm .icon { width: 16px; height: 16px; }

.btn-lg {
  min-height: 56px;
  padding: 0 var(--s-6);
  font-size: 18px;
  line-height: 22px;
}

.btn-block {
  display: flex;
  width: 100%;
}

.btn-icon {
  width: 44px;
  min-height: 44px;
  padding: 0;
}

.btn-icon-sm {
  width: 36px;
  min-height: 36px;
  padding: 0;
}

@media (pointer: coarse) {
  .btn-sm { min-height: 44px; }
  .btn-icon-sm { width: 44px; min-height: 44px; }
}

/* Disabled applies to every variant: a disabled primary is grey, never faded orange */
.btn:disabled,
.btn[aria-disabled="true"] {
  --btn-bg: var(--disabled-bg);
  --btn-fg: var(--disabled-fg);
  --btn-border: var(--line);
  cursor: not-allowed;
  transform: none;
}

/* Loading: aria-busy plus disabled; colours stay normal at 85 percent opacity, no spinner */
.btn[aria-busy="true"]:disabled {
  --btn-bg: var(--brand);
  --btn-fg: var(--ink);
  --btn-border: var(--brand-edge);
  opacity: 0.85;
  cursor: progress;
}

.btn-secondary[aria-busy="true"]:disabled {
  --btn-bg: var(--surface);
  --btn-border: var(--line-strong);
}

.btn-danger[aria-busy="true"]:disabled {
  --btn-bg: var(--danger-solid);
  --btn-fg: #fff;
  --btn-border: var(--danger-solid);
}

/* Link action: an inline action that reads as a link */
.link-action {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--s-1);
  background: none;
  border: 0;
  color: var(--brand-text);
  font: 700 16px/24px var(--font);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  cursor: pointer;
}

.link-action:hover {
  color: var(--ink);
  text-decoration-thickness: 2.5px;
}

/* 5.2 Button group and footer actions: secondary first in the DOM, primary last (right on desktop, on top on phones) */

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-3);
}

.form-actions-start { margin-inline-end: auto; }

/* The confirm pair sits at the start; the safe action is first and holds initial focus */
.remove-confirm { justify-content: flex-start; }

@media (max-width: 639px) {
  .form-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .form-actions .btn { width: 100%; }

  .form-actions-start { margin-inline-end: 0; }
}

/* 5.3 Field: label, optional hint, control, error, 8px apart. A field has no outer margin. */

.field {
  display: grid;
  gap: var(--s-2);
  min-width: 0;
}

.field-label {
  font: 700 var(--fs-label)/var(--lh-label) var(--font);
  color: var(--ink);
}

.field-optional {
  font-weight: 400;
  color: var(--muted);
}

.field-hint {
  margin: 0;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

/* Error: 14/20 bold, a 16px alert icon drawn in CSS, directly under the control; hidden when empty */
.field-error,
.auth-error-field {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0;
  font: 700 var(--fs-caption)/var(--lh-caption) var(--font);
  color: var(--danger-fg);
}

.field-error::before,
.auth-error-field::before {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' \
stroke='%23b3261e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' \
%3E%3Cpath d='M12 3.5l9.5 16.5h-19zM12 10v4.5M12 17.5h.01'/%3E%3C/svg%3E")
    center / 16px no-repeat;
}

.field-error:empty,
.auth-error-field:empty { display: none; }

.field-pair,
.recipient-names {
  display: grid;
  gap: var(--s-5);
}

@media (min-width: 640px) {
  .field-pair,
  .recipient-names { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 5.3.1 Locked value: a value, not a control. It is not focusable and always says why in a hint below. */

.locked-value {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 14px;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
}

.locked-value .icon { color: var(--muted); }

.locked-text {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-body);
}

/* 5.4 Input, select, textarea, combobox */

.input,
.select,
.textarea,
textarea {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  background: var(--surface);
  color: var(--ink);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font: 400 var(--fs-body)/24px var(--font);
  transition: border-color var(--dur-fast) var(--ease-standard);
}

textarea,
.textarea {
  min-height: 120px;
  padding: 12px 14px;
  resize: vertical;
}

.input::placeholder,
textarea::placeholder {
  color: var(--muted);
  opacity: 1;
}

.input:hover,
.select:hover,
textarea:hover { border-color: var(--ink); }

.input:focus-visible,
.select:focus-visible,
textarea:focus-visible { border-color: var(--ink); }

.input[readonly],
textarea[readonly] {
  background: var(--sunken);
  border-color: var(--line);
}

.input:disabled,
.select:disabled,
textarea:disabled {
  background: var(--disabled-bg);
  border-color: var(--line);
  color: var(--disabled-fg);
  cursor: not-allowed;
}

.input[aria-busy="true"],
.select[aria-busy="true"],
textarea[aria-busy="true"] { cursor: progress; }

.input[aria-invalid="true"],
.select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--danger-fg);
  box-shadow: inset 0 0 0 1px var(--danger-fg);
}

.input-id {
  font-weight: 700;
  letter-spacing: 0.04em;
}

.select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 48px;
  background:
    var(--surface)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' \
stroke='%234f483f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' \
%3E%3Cpath d='M6 9.5l6 6 6-6'/%3E%3C/svg%3E")
    right 14px center / 20px no-repeat;
}

/* Combobox (state picker): an .input with role="combobox" plus a listbox */
.combo { position: relative; }

.combo-list {
  position: absolute;
  z-index: var(--z-popover);
  top: calc(100% + var(--s-1));
  right: 0;
  left: 0;
  max-height: 280px;
  margin: 0;
  padding: var(--s-1);
  overflow-y: auto;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
}

.combo-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 44px;
  padding: 0 var(--s-3);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: var(--fs-body);
  cursor: pointer;
}

.combo-option:hover,
.combo-option.is-active { background: var(--brand-tint); }

.combo-option[aria-selected="true"] { font-weight: 700; }

.combo-option[aria-selected="true"]::after {
  content: "";
  flex: none;
  width: 20px;
  height: 20px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' \
stroke='%231b1814' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' \
%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E")
    center / 20px no-repeat;
}

.combo-empty {
  padding: var(--s-3);
  font-size: var(--fs-small);
  color: var(--ink-2);
}

/* Input group (ID number plus Find): the group owns the border, radius and focus ring */
.input-group {
  display: flex;
  align-items: stretch;
  overflow: hidden;
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-sm);
}

.input-group:hover { border-color: var(--ink); }

.input-group:focus-within {
  border-color: var(--ink);
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.input-group:has(.input[aria-invalid="true"]) {
  border-color: var(--danger-fg);
  box-shadow: inset 0 0 0 1px var(--danger-fg);
}

.input-group .input {
  flex: 1;
  min-width: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  outline: 0;
}

.input-group .btn {
  min-height: 0;
  border-width: 0 0 0 1.5px;
  border-radius: 0;
}

.input-find {
  --btn-bg: var(--brand-tint);
  --btn-fg: var(--brand-text);
  min-width: 84px;
}

/* Password field with a show/hide text button (44px target) */
.password-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.password-wrap .input { padding-right: 84px; }

.password-toggle {
  position: absolute;
  right: var(--s-1);
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--s-3);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--brand-text);
  font: 700 var(--fs-small)/var(--lh-small) var(--font);
  cursor: pointer;
}

.password-toggle:hover { color: var(--ink); }

/* 5.5 Checkbox and radio rows: one checkbox, drawn once; the whole row is the target */

.check-row {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
}

.check-input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 24px;
  height: 24px;
  margin: 10px 0 0;
  background: var(--surface) center / 16px no-repeat;
  border: 2px solid var(--line-strong);
  border-radius: 6px;
  cursor: pointer;
}

.check-input:hover { border-color: var(--ink); }

.check-input:checked {
  background-color: var(--brand);
  border-color: var(--brand-edge);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' \
stroke='%231b1814' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' \
%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");
}

.check-input[type="radio"] { border-radius: 50%; }

.check-input[type="radio"]:checked {
  background-image: radial-gradient(circle, var(--ink) 0 5px, transparent 5.5px);
  background-size: 100% 100%;
}

.check-input:disabled {
  background-color: var(--disabled-bg);
  border-color: var(--line);
  cursor: not-allowed;
}

.check-input[aria-invalid="true"] { border-color: var(--danger-fg); }

.confirmation-check {
  display: block;
  flex: 1;
  padding: 10px 0;
  color: var(--ink);
  font-size: var(--fs-label);
  line-height: 24px;
  cursor: pointer;
}

.check-input:disabled + .confirmation-check {
  color: var(--disabled-fg);
  cursor: not-allowed;
}

.confirmation-copy strong { font-weight: 700; }

.confirmation-optional {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

/* 5.6 Selectable card (radio cards): stamp packages (.plan-option) and "which person" choices (.match-choice) */

.selectable {
  position: relative;
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3) var(--s-4);
  min-height: 72px;
  padding: var(--s-4);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-md);
  cursor: pointer;
}

.selectable:hover {
  border-color: var(--ink);
  box-shadow: var(--shadow-1);
}

.selectable:has(input:checked) {
  background: var(--brand-tint);
  border-color: var(--brand-edge);
  box-shadow: inset 0 0 0 1px var(--brand-edge);
}

.selectable:has(input:focus-visible) {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.selectable input:focus-visible { outline: 0; }

.selectable:has(input:disabled) {
  background: var(--disabled-bg);
  border-color: var(--line);
  color: var(--disabled-fg);
  cursor: not-allowed;
}

.selectable .found-check { display: none; }

/* A person choice wraps its avatar and name block; it fills the columns after the radio */
.selectable > .match-body {
  grid-column: 2 / -1;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--s-3);
}

.match-choices {
  display: grid;
  gap: var(--s-3);
}

.match-legend {
  margin-bottom: var(--s-3);
  font: 700 var(--fs-label)/var(--lh-label) var(--font);
  color: var(--ink);
}

/* Package option */
.plan-options,
.package-body,
.skeleton-container {
  display: grid;
  gap: var(--s-3);
}

.package-body { min-height: 156px; } /* two 72px options plus the gap: the step does not jump */

.plan-option-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.plan-option-price {
  font-size: var(--fs-body);
  line-height: 24px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}

.plan-option-copy strong {
  font-size: var(--fs-body);
  line-height: 24px;
  font-weight: 700;
  color: var(--ink);
}

.plan-option-meta {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

/* "Selected" in words, shown only on the chosen package (selection is never colour alone) */
.selected-check { display: none; }

.selectable:has(input:checked) .selected-check {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 0 var(--s-3);
  background: var(--surface);
  border: 1px solid var(--brand-edge);
  border-radius: var(--radius-pill);
  color: var(--brand-text);
  font: 700 var(--fs-caption)/var(--lh-caption) var(--font);
  white-space: nowrap;
}

.package-hint {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.plan-includes {
  padding: var(--s-3) var(--s-4);
  background: var(--sunken);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

/* 5.7 Card and panel: border only, no shadow at rest; the card's own stack supplies the gaps */

.card {
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}

.card-pad,
.setup-panel,
.home-status,
.home-person,
.home-tile,
.receipt-card {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, var(--s-4));
  padding: var(--s-5);
}

@media (min-width: 640px) {
  .card-pad,
  .setup-panel,
  .home-status,
  .home-person,
  .home-tile,
  .receipt-card { padding: var(--s-6); }
}

.card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-3);
}

.card-desc {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.card-body {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

/* The card's 16px gap plus 4px gives the spec's 20px above the rule */
.card-foot {
  margin-top: var(--s-1);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}

/* Link card: the whole card is one anchor */
a.card {
  min-height: 72px;
  color: inherit;
  text-decoration: none;
}

a.card:hover {
  color: inherit;
  box-shadow: var(--shadow-1);
}

/* 5.8 Notice (alert and banner): kind colours the icon, title and action; body text stays ink */

.notice {
  --notice-bg: var(--info-bg);
  --notice-border: var(--info-border);
  --notice-fg: var(--info-fg);
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  column-gap: var(--s-3);
  row-gap: var(--s-1);
  padding: var(--s-3) var(--s-4);
  background: var(--notice-bg);
  border: 1px solid var(--notice-border);
  border-radius: var(--radius-md);
  color: var(--ink);
  font-size: 16px;
  line-height: 24px;
  animation: notice-in var(--dur-base) var(--ease-out);
}

/* Text-only notice (a message with no icon): one plain column */
.notice:not(:has(.icon)) { display: block; }

.notice > .icon {
  grid-column: 1;
  grid-row: 1;
  margin-top: 2px;
  color: var(--notice-fg);
}

.notice > :not(.icon) {
  grid-column: 2;
  margin: 0;
}

.notice-title {
  font-weight: 700;
  color: var(--notice-fg);
}

.notice > a:not(.btn),
.notice-action {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-bottom: -10px;
  font-weight: 700;
  color: var(--notice-fg);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.notice > .btn { justify-self: start; }

.notice-ok {
  --notice-bg: var(--ok-bg);
  --notice-border: var(--ok-border);
  --notice-fg: var(--ok-fg);
}

.notice-warn {
  --notice-bg: var(--warn-bg);
  --notice-border: var(--warn-border);
  --notice-fg: var(--warn-fg);
}

.notice-error {
  --notice-bg: var(--danger-bg);
  --notice-border: var(--danger-border);
  --notice-fg: var(--danger-fg);
}

.notice:empty,
.auth-plan:empty { display: none; }

/* Error region for a form or dialog; holds .notice.notice-error children */
.checkout-errors {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin: 0;
}

.checkout-errors:empty { display: none; }

/* The no-JavaScript message, styled like a warning notice */
.noscript-note {
  max-width: 480px;
  margin: var(--s-12) auto;
  padding: var(--s-4) var(--s-5);
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-md);
  color: var(--ink);
  font-size: var(--fs-body);
}

/* 5.9 Dialog (native <dialog> opened with showModal): centred modal from 640px, bottom sheet under it */

.dialog {
  --dialog-pad: var(--s-6);
  width: calc(100% - 32px);
  max-width: 480px;
  max-height: min(calc(100dvh - 48px), 720px);
  padding: 0;
  overflow: hidden;
  background: var(--surface);
  color: var(--ink);
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}

.dialog-sm { max-width: 400px; }
.dialog-lg { max-width: 640px; }

/* display:flex lives on [open] only, or a closed dialog would stay visible */
.dialog[open] {
  display: flex;
  flex-direction: column;
  animation: dialog-in var(--dur-base) var(--ease-out);
}

.dialog::backdrop { background: var(--backdrop); }

.dialog > form,
.dialog > .dialog-inner,
.details-form {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  margin: 0;
}

.dialog-head {
  display: flex;
  flex: none;
  align-items: flex-start;
  gap: var(--s-4);
  padding: var(--dialog-pad) var(--dialog-pad) var(--s-4);
}

.dialog-head > :first-child {
  flex: 1;
  min-width: 0;
}

.dialog-head h2 {
  margin: 0;
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
}

.dialog-head p {
  margin: var(--s-1) 0 0;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.dialog-close {
  display: grid;
  flex: none;
  place-items: center;
  width: 36px;
  height: 36px;
  margin: -4px -8px 0 0;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink-2);
  cursor: pointer;
}

.dialog-close:hover {
  background: var(--sunken);
  color: var(--ink);
}

@media (pointer: coarse) {
  .dialog-close {
    width: 44px;
    height: 44px;
    margin: -8px -12px 0 0;
  }
}

.dialog-body {
  display: grid;
  flex: 1 1 auto;
  align-content: start;
  gap: var(--s-5);
  min-height: 0;
  padding: 0 var(--dialog-pad) var(--dialog-pad);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.dialog-foot {
  flex: none;
  padding: var(--s-4) var(--dialog-pad);
  padding-bottom: calc(var(--s-4) + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 1px solid var(--line);
}

/* The last block of a dialog body: the two-step destructive control */
.remove-controls {
  display: grid;
  justify-items: start;
  gap: var(--s-3);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
}

.remove-controls .remove-confirm { justify-self: stretch; }

@media (max-width: 639px) {
  .dialog {
    --dialog-pad: var(--s-5);
    width: 100%;
    max-width: 100%;
    max-height: calc(100dvh - 40px);
    margin: auto 0 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  }

  .dialog[open] { animation: sheet-in var(--dur-slow) var(--ease-out); }
}

@keyframes dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

@keyframes sheet-in {
  from { transform: translateY(100%); }
  to { transform: none; }
}

@keyframes notice-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

/* 5.10 Badge: short, non-interactive status label, always text */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 0 var(--s-3);
  background: var(--sunken);
  color: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font: 700 var(--fs-caption)/var(--lh-caption) var(--font);
  white-space: nowrap;
}

.badge .icon { width: 16px; height: 16px; }

.badge-ok {
  background: var(--ok-bg);
  color: var(--ok-fg);
  border-color: var(--ok-border);
}

.badge-warn {
  background: var(--warn-bg);
  color: var(--warn-fg);
  border-color: var(--warn-border);
}

.badge-danger {
  background: var(--danger-bg);
  color: var(--danger-fg);
  border-color: var(--danger-border);
}

.badge-info {
  background: var(--info-bg);
  color: var(--info-fg);
  border-color: var(--info-border);
}

.badge-neutral {
  background: var(--sunken);
  color: var(--ink-2);
  border-color: var(--line);
}

.badge-accent {
  background: var(--brand-tint);
  color: var(--brand-text);
  border-color: var(--brand-tint-2);
}

.badge-gold {
  background: var(--gold-tint);
  color: var(--gold);
  border-color: var(--line);
}

/* 5.11 Stat tile and stamp tile */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--s-3);
}

.stat {
  display: grid;
  gap: var(--s-1);
  padding: var(--s-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}

.stat-label {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.stat-value {
  font-size: var(--fs-figure);
  line-height: var(--lh-figure);
  font-weight: 700;
  color: var(--ink);
}

.stat-note {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

a.stat {
  color: inherit;
  text-decoration: none;
}

a.stat:hover { box-shadow: var(--shadow-1); }

/* The postage stamp tile is the one gold stat: perforated edge, gold text on gold tint */
.stamp-tile-wrap {
  display: inline-block;
  filter: drop-shadow(0 3px 6px rgba(27, 24, 20, 0.08));
}

.stamp-tile {
  --r: 5px;
  --s: 14px;
  position: relative;
  width: 176px;
  padding: 22px var(--s-4) 18px;
  background-color: var(--gold-tint);
  border: 1px solid var(--line);
  border-color: color-mix(in srgb, var(--gold) 25%, transparent);
  text-align: center;
  -webkit-mask:
    radial-gradient(circle var(--r) at calc(var(--s) / 2) 0, #0000 98%, #000 100%) 0 0 / var(--s) 100% repeat-x,
    radial-gradient(circle var(--r) at calc(var(--s) / 2) 100%, #0000 98%, #000 100%) 0 0 / var(--s) 100% repeat-x,
    radial-gradient(circle var(--r) at 0 calc(var(--s) / 2), #0000 98%, #000 100%) 0 0 / 100% var(--s) repeat-y,
    radial-gradient(circle var(--r) at 100% calc(var(--s) / 2), #0000 98%, #000 100%) 0 0 / 100% var(--s) repeat-y;
  -webkit-mask-composite: source-in, source-in, source-in;
  mask:
    radial-gradient(circle var(--r) at calc(var(--s) / 2) 0, #0000 98%, #000 100%) 0 0 / var(--s) 100% repeat-x,
    radial-gradient(circle var(--r) at calc(var(--s) / 2) 100%, #0000 98%, #000 100%) 0 0 / var(--s) 100% repeat-x,
    radial-gradient(circle var(--r) at 0 calc(var(--s) / 2), #0000 98%, #000 100%) 0 0 / 100% var(--s) repeat-y,
    radial-gradient(circle var(--r) at 100% calc(var(--s) / 2), #0000 98%, #000 100%) 0 0 / 100% var(--s) repeat-y;
  mask-composite: intersect;
}

.stamp-value {
  display: block;
  font: 700 44px/1 var(--font);
  color: var(--ink);
}

.stamp-caption {
  display: block;
  margin-top: 6px;
  font: 700 var(--fs-caption)/var(--lh-caption) var(--font);
  color: var(--ink);
}

/* Progress bar (plan stamps used) */
.progress {
  width: 100%;
  height: 8px;
  overflow: hidden;
  background: var(--line);
  border-radius: var(--radius-pill);
}

.progress-bar {
  height: 100%;
  background: var(--brand-edge);
  border-radius: var(--radius-pill);
  transition: width var(--dur-slow) var(--ease-out);
}

.progress-meta {
  display: flex;
  justify-content: space-between;
  gap: var(--s-2);
  margin-bottom: var(--s-1);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-2);
}

/* 5.12 List row: icon or avatar, main text, trailing value, in a card with no padding of its own */

.list,
.msgs-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.list-row,
.msgs-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  min-height: 64px;
  padding: var(--s-3) var(--s-4);
}

.list-row + .list-row,
.msgs-row + .msgs-row { border-top: 1px solid var(--line); }

a.list-row,
button.list-row {
  width: 100%;
  background: none;
  border: 0;
  color: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

a.list-row:hover,
button.list-row:hover { background: var(--sunken); }

.list-icon,
.msgs-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  background: var(--brand-tint);
  color: var(--brand-text);
  border-radius: var(--radius-pill);
}

.msgs-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.list-title,
.msgs-kind {
  font-weight: 700;
  color: var(--ink);
}

.list-meta,
.msgs-time {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.list-end,
.msgs-stamps {
  font-size: var(--fs-small);
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}

/* 5.13 Skeleton: placeholders that reserve the final space and never move it */

.skeleton {
  background: linear-gradient(90deg, var(--skeleton-base) 0%, var(--skeleton-hi) 40%, var(--skeleton-base) 80%);
  background-size: 250% 100%;
  border-radius: var(--radius-xs);
  animation: skeleton-shimmer var(--dur-shimmer) ease-in-out infinite;
}

.skeleton-line { height: 16px; }
.skeleton-box { border-radius: var(--radius-sm); }
.skeleton-container > .skeleton-box { min-height: 72px; }
.msgs-icon.skeleton { border-radius: var(--radius-pill); }

.skeleton-stamp {
  width: 176px;
  height: 96px;
  background: var(--gold-tint);
  animation: none;
}

.skeleton-card { min-height: 120px; }
.skeleton-view { min-height: 480px; }

@keyframes skeleton-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

/* 5.14 Avatar and found card: initials in bold brand-text on brand-tint-2, never a photo or silhouette */

.avatar {
  display: grid;
  flex: none;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: var(--brand-tint-2);
  color: var(--brand-text);
  border: 0;
  border-radius: var(--radius-pill);
  font: 700 var(--fs-caption)/1 var(--font);
  user-select: none;
}

button.avatar {
  position: relative;
  cursor: pointer;
}

/* The 32px avatar button keeps a 44px touch target */
button.avatar::after {
  content: "";
  position: absolute;
  inset: -6px;
}

.found-avatar {
  display: grid;
  flex: none;
  place-items: center;
  width: 40px;
  height: 40px;
  background: var(--brand-tint-2);
  color: var(--brand-text);
  border-radius: var(--radius-pill);
  font: 700 var(--fs-small)/1 var(--font);
}

.found-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-1) var(--s-3);
  padding: var(--s-3) 14px;
  background: var(--ok-bg);
  border: 1px solid var(--ok-border);
  border-radius: var(--radius-md);
}

.found-text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.found-name {
  font-size: var(--fs-body);
  line-height: 24px;
  font-weight: 700;
  color: var(--ink);
}

.found-place {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.found-check {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border: 2px solid var(--ok-solid);
  border-radius: var(--radius-pill);
  color: var(--ok-fg);
}

.found-check .icon {
  width: 16px;
  height: 16px;
}

.found-edit { grid-column: 2 / -1; }

/* 5.15 Menu and popover (account menu). Log out is a normal item; red is for destructive items only. */

.account-popover {
  position: absolute;
  z-index: var(--z-popover);
  bottom: calc(100% + var(--s-2));
  right: 0;
  left: 0;
  padding: var(--s-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
}

.account-popover-down {
  top: calc(100% + var(--s-2));
  bottom: auto;
  left: auto;
  width: 260px;
  max-width: calc(100vw - 32px);
}

.account-popover-head {
  display: grid;
  gap: 2px;
  margin-bottom: var(--s-2);
  padding: var(--s-2) var(--s-3) var(--s-3);
  border-bottom: 1px solid var(--line);
}

.account-popover-label {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

.account-popover-email {
  font: 700 var(--fs-small)/var(--lh-small) var(--font);
  color: var(--ink);
}

.account-items {
  display: grid;
  gap: 2px;
}

.menu-item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--s-3);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink);
  font: 700 var(--fs-label)/var(--lh-label) var(--font);
  text-align: left;
  cursor: pointer;
}

a.menu-item { text-decoration: none; }

.menu-item:hover { background: var(--sunken); }

.menu-item:focus-visible {
  outline-offset: -3px;
  background: var(--sunken);
}

.menu-item:disabled {
  color: var(--disabled-fg);
  cursor: not-allowed;
}

.menu-item > svg,
.menu-item .icon { color: var(--ink-2); }

.menu-item-danger { color: var(--danger-fg); }
.menu-item-danger:hover { background: var(--danger-bg); }

/* 5.16 Empty state: a 56px tint circle with a glyph, title, one sentence, one action only when actionable */

.empty {
  display: grid;
  justify-items: start;
  gap: var(--s-3);
  padding: var(--s-8) var(--s-6);
}

.empty:not(:has(.empty-icon))::before {
  content: "";
  width: 56px;
  height: 56px;
  background: var(--brand-tint);
  border-radius: var(--radius-pill);
}

.empty-icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  background: var(--brand-tint);
  color: var(--brand-text);
  border-radius: var(--radius-pill);
}

.empty h2 {
  font-size: 20px;
  line-height: 26px;
}

.empty p {
  max-width: 45ch;
  color: var(--ink-2);
}

@media (min-width: 640px) {
  .empty {
    justify-items: center;
    text-align: center;
  }
}

/* 5.17 Stepper (setup wizard): three labelled steps with a progress bar; one line of text on phones */

.stepper {
  display: grid;
  gap: var(--s-3);
}

.stepper-compact {
  display: none;
  margin: 0;
  font: 700 var(--fs-small)/var(--lh-small) var(--font);
  color: var(--ink-2);
}

.stepper-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.stepper-item { min-width: 0; }

.stepper-step {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 6px 10px;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink-2);
  font: 400 var(--fs-small)/var(--lh-small) var(--font);
  text-align: left;
  cursor: default;
}

.stepper-step:disabled { opacity: 1; }

.stepper-num {
  display: grid;
  flex: none;
  place-items: center;
  width: 28px;
  height: 28px;
  background: var(--surface);
  color: var(--ink-2);
  border: 2px solid var(--line-strong);
  border-radius: var(--radius-pill);
  font: 700 var(--fs-caption)/1 var(--font);
}

.stepper-label { min-width: 0; }

.stepper-step.is-current { color: var(--ink); }
.stepper-step.is-current .stepper-label { font-weight: 700; }

.stepper-step.is-current .stepper-num {
  background: var(--brand);
  border-color: var(--brand-edge);
  color: var(--ink);
}

.stepper-step.is-done {
  color: var(--ink);
  cursor: pointer;
}

.stepper-step.is-done:hover { background: var(--sunken); }

.stepper-step.is-done .stepper-num {
  background: var(--ok-bg);
  border-color: var(--ok-solid);
  color: var(--ok-fg);
}

.stepper-step .icon {
  width: 16px;
  height: 16px;
  margin-left: auto;
  color: var(--ok-fg);
}

.stepper-bar {
  height: 4px;
  overflow: hidden;
  background: var(--line);
  border-radius: var(--radius-pill);
}

.stepper-bar-fill {
  display: block;
  height: 100%;
  background: var(--brand-edge);
  transition: width var(--dur-base) var(--ease-out);
}

@media (max-width: 639px) {
  .stepper-list { display: none; }
  .stepper-compact { display: block; }
}

/* 5.18 Accordion (FAQ): native details and summary, no JS, no height animation */

.help-faq {
  display: block;
}

.help-faq h2 { margin-bottom: var(--s-4); }

.help-faq details { border-top: 1px solid var(--line); }
.help-faq details:first-of-type { border-top: 0; }

.help-faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 56px;
  padding: var(--s-3) 0;
  font: 700 var(--fs-body)/24px var(--font);
  color: var(--ink);
  list-style: none;
  cursor: pointer;
}

.help-faq summary::-webkit-details-marker { display: none; }

.help-faq summary::after {
  content: "";
  flex: none;
  width: 20px;
  height: 20px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' \
stroke='%231b1814' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' \
%3E%3Cpath d='M6 9.5l6 6 6-6'/%3E%3C/svg%3E")
    center / 20px no-repeat;
  transition: transform var(--dur-base) var(--ease-out);
}

.help-faq details[open] summary::after { transform: rotate(180deg); }

.help-faq details p {
  max-width: var(--measure);
  margin: 0 0 var(--s-4);
  color: var(--ink-2);
}

/* 5.19 Summary panel (order summary) and wrong-person safeguard */

.order-summary {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.summary-intro {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.summary-subtitle {
  font: 700 var(--fs-h3)/var(--lh-h3) var(--font);
  color: var(--ink);
}

/* Recipient block: an .inset, name 17/24 bold, ID with tracking, facility 15/22 */
.summary-person {
  display: grid;
  gap: var(--s-1);
}

.summary-name {
  font: 700 var(--fs-body)/24px var(--font);
  color: var(--ink);
}

.summary-id {
  font-weight: 700;
  color: var(--ink);
}

.summary-facility {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.summary-name.is-placeholder,
.summary-id.is-placeholder,
.summary-facility.is-placeholder {
  font-weight: 400;
  color: var(--ink-2);
}

/* Total row: label 18/24 bold, amount in the figure size, then the breakdown under a rule */
.order-headline {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-2);
}

.order-headline-label {
  width: 100%;
  font: 700 var(--fs-h3)/var(--lh-h3) var(--font);
  color: var(--ink);
}

.total-value {
  font-size: var(--fs-figure);
  line-height: var(--lh-figure);
  font-weight: 700;
  color: var(--ink);
}

.order-headline-period {
  font-size: var(--fs-body);
  color: var(--ink-2);
}

.order-lines {
  display: grid;
  gap: var(--s-3);
  margin: 0;
  padding: var(--s-3) 0 0;
  border-top: 1px solid var(--line);
}

.order-line {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  font-size: var(--fs-body);
  color: var(--ink-2);
}

.order-line dd {
  margin: 0;
  font-weight: 700;
  color: var(--ink);
}

.renewal-copy {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

.payment-trust {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-2);
}

.pay-reason {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-2);
}

/* ==========================================================================
   6. Pages and class map
   Page-specific rules re-expressed with the tokens above. Class-map entries (section 6 of the spec)
   that belong to a component are styled in section 5 (account-items, details-form, dialog-*, form-actions,
   found-text, notice-text, package-body, remove-*, skeleton-container, stepper-*, ...).
   ========================================================================== */

/* Page head: the one-line page intro under the top bar */
.page-head {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.page-head > .badge { align-self: flex-start; }

.page-head p {
  max-width: var(--measure);
  color: var(--ink-2);
}

.page-head .page-greeting {
  color: var(--ink);
  font-size: var(--fs-h2, 24px);
  font-weight: 700;
  line-height: 1.2;
}

.notice-text {
  margin: 0;
  color: var(--ink);
}

/* Set up: one centred column (stepper, the panel in view, the footer) */
.setup-page {
  max-width: 720px;
  margin: 0 auto;
}

.setup-form {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.setup-panels {
  display: grid;
  min-width: 0;
}

.setup-panel.is-entering { animation: setup-step-in var(--dur-base) var(--ease-out); }

@keyframes setup-step-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.setup-helper {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

/* "Saved. Change anything that is wrong." under the helper when a recipient already exists */
.saved-copy {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  font: 700 var(--fs-small)/var(--lh-small) var(--font);
  color: var(--ok-fg);
}

.saved-copy::before {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 3px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' \
stroke='%23276b43' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' \
%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E")
    center / 16px no-repeat;
}

.setup-footer-next {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-3);
  margin-left: auto;
}

.setup-next-reason { text-align: right; }

@media (max-width: 639px) {
  .setup-form { gap: var(--s-4); }

  .setup-footer-next {
    flex-direction: column;
    align-items: stretch;
    margin-left: 0;
  }

  .setup-next-reason { text-align: left; }

  /* The wizard footer is the only bottom bar on phones (the tab bar is hidden on this route) */
  .setup-footer {
    position: sticky;
    bottom: 0;
    z-index: var(--z-sticky);
    margin: 0 calc(-1 * var(--s-4));
    padding: var(--s-3) var(--s-4);
    padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom));
    background: var(--bg);
    border-top: 1px solid var(--line);
    box-shadow: var(--shadow-1);
  }
}

/* Step 1: who it is for. State and ID (with Find attached), one muted line, the result, then the manual fields. */
.recipient-form,
.recipient-manual {
  display: grid;
  gap: var(--s-5);
}

.recipient-row {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

@media (min-width: 640px) {
  .recipient-row { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); }
}

.recipient-hint {
  margin: 0;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

/* Lookup result: a live region that stays in the page; empty it takes no space */
.lookup-status:empty { display: none; }

.recipient-note {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.recipient-note-warn {
  padding: var(--s-3) 14px;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-sm);
  color: var(--ink);
}

/* Home */
.home-status { gap: var(--s-3); }

.status-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  background: var(--brand-tint);
  color: var(--brand-text);
  border-radius: var(--radius-pill);
}

.home-person { align-items: flex-start; }

.person-name {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 700;
  color: var(--ink);
}

.person-meta {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

@media (max-width: 639px) {
  .home-person .btn { align-self: stretch; }
}

@media (min-width: 640px) {
  .home-person {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "title action"
      "name action"
      "meta action";
    align-items: center;
    gap: var(--s-2) var(--s-5);
  }

  .home-person h2 { grid-area: title; }
  .home-person .person-name { grid-area: name; }
  .home-person .person-meta { grid-area: meta; }
  .home-person .btn { grid-area: action; }
}

.home-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-5);
}

.home-alt-link {
  font-size: var(--fs-small);
  font-weight: 700;
}

/* Three summary tiles (stat tiles that link to the page that owns the details) */
.home-tiles {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-3);
}

.home-tile {
  gap: var(--s-1);
  color: var(--ink);
}

.home-tile-label {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.home-tile-value {
  font-size: var(--fs-figure);
  line-height: var(--lh-figure);
  font-weight: 700;
  color: var(--ink);
}

.home-tile-note {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

@media (min-width: 900px) {
  .home-tiles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s-5);
  }
}

/* Messages: header balance, message-history card, day groups, rows (rows use the list-row layout above) */
.msgs-balance {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-1) var(--s-2);
  margin: 0;
  font-size: var(--fs-caption);
  font-weight: 700;
  color: var(--ink);
}

.msgs-balance a { font-weight: 700; }
.msgs-sep { color: var(--ink-2); }

.msgs-card {
  padding: 0;
  overflow: hidden;
}

.msgs-day + .msgs-day { border-top: 1px solid var(--line); }

.msgs-day-label {
  padding: var(--s-4) var(--s-4) var(--s-2);
  font: 700 var(--fs-caption)/var(--lh-caption) var(--font);
  color: var(--ink-2);
}

/* Payment received card */
.receipt-card { border-color: var(--ok-border); }

.receipt-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  background: var(--ok-bg);
  color: var(--ok-fg);
  border-radius: var(--radius-pill);
}

.receipt-recipient { font-weight: 700; }

/* Plan and billing */
.plan-name {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 700;
}

.plan-manage-copy {
  max-width: var(--measure);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.kv {
  display: grid;
  gap: var(--s-3);
  margin: 0;
  padding: 0;
}

.kv > div {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--line);
}

.kv dt { color: var(--ink-2); }

.kv dd {
  margin: 0;
  font-weight: 700;
  color: var(--ink);
}

.billing-plan-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-3);
}

.billing-manage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
}

.billing-manage .plan-manage-copy { flex: 1 1 240px; }

/* "Your stamps" card: heading, balance row (stamp tile left, details right), then the buy block under a rule */
.billing-stamps { --stack-gap: var(--s-6); }

.billing-balance {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-8);
}

.billing-balance-info {
  display: flex;
  flex: 1 1 280px;
  flex-direction: column;
  gap: var(--s-2);
  min-width: 0;
}

.billing-split-plan {
  font-weight: 700;
  margin: 0;
}

.billing-split-extra {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  font-weight: 700;
  margin: 0;
}

.billing-reset {
  margin: 0;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-2);
}

.billing-buy {
  padding-top: var(--s-6);
  border-top: 1px solid var(--line);
}

.billing-setting {
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
}

.billing-setting h2 {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

/* Buy stamps: package and quantity in one row, a summary row, then the button and its note */
.buy-stamps {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.buy-form {
  display: grid;
  gap: var(--s-4);
  max-width: 560px;
}

.buy-form p { margin: 0; }

.buy-fields {
  display: grid;
  gap: var(--s-4);
}

.buy-field-package { min-width: 0; }

@media (min-width: 640px) {
  .buy-fields {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
  }
}

/* Quantity stepper: 48px minus button, 72px input, 48px plus button, 8px apart */
.qty-stepper {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

@media (max-width: 639px) {
  .buy-field-qty { width: 100%; }
  .qty-stepper { justify-content: flex-start; }
}

.qty-btn {
  display: grid;
  flex: none;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  background: var(--surface);
  color: var(--ink);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-sm);
  font: 700 20px/1 var(--font-numeric);
  cursor: pointer;
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard);
}

.qty-btn:hover {
  background: var(--sunken);
  border-color: var(--ink);
}

.qty-btn:active { transform: translateY(1px); }

.qty-btn:disabled {
  background: var(--disabled-bg);
  border-color: var(--line);
  color: var(--disabled-fg);
  cursor: not-allowed;
}

.qty-input {
  flex: none;
  width: 72px;
  min-height: 48px;
  padding: 0;
  background: var(--surface);
  color: var(--ink);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-sm);
  text-align: center;
  font-size: var(--fs-body);
  line-height: 24px;
  font-weight: 700;
  -moz-appearance: textfield;
  appearance: textfield;
}

.qty-input:hover,
.qty-input:focus-visible { border-color: var(--ink); }

.qty-input:disabled {
  background: var(--disabled-bg);
  border-color: var(--line);
  color: var(--disabled-fg);
  cursor: not-allowed;
}

.qty-input::-webkit-outer-spin-button,
.qty-input::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
}

.buy-summary {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-1) var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}

.buy-detail {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.buy-total {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 700;
  color: var(--ink);
}

.buy-error:empty { display: none; }

.buy-btn {
  justify-self: start;
  min-width: 200px;
}

.buy-note {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

@media (max-width: 639px) {
  .buy-btn {
    justify-self: stretch;
    min-width: 0;
    width: 100%;
  }
}

/* Help: the script with Copy, the FAQ (accordion above), contact support */
.script-label {
  display: block;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
}

.tell-script { min-height: 140px; }

.help-script-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
}

.help-script-actions .btn { min-width: 120px; }

.help-copy-status {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--ink-2);
}

.help-contact {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-4) var(--s-6);
}

.help-contact-copy {
  flex: 1 1 280px;
  min-width: 0;
}

.help-contact .btn { flex: none; }

/* ==========================================================================
   Auth pages (/login/, /signup/): same tokens, one centred card
   ========================================================================== */

.lead {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--ink-2);
}

.auth-body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: var(--s-8) var(--s-4);
  background: var(--bg);
}

.auth-shell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-6);
  width: 100%;
  max-width: 480px;
}

.auth-card {
  display: grid;
  gap: var(--s-4);
  width: 100%;
  padding: var(--s-8) var(--s-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}

@media (min-width: 640px) {
  .auth-card { padding: var(--s-8); }
}

.auth-card h1 {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: -0.01em;
}

.auth-form {
  display: grid;
  gap: var(--s-5);
}

.auth-consent,
.auth-alt {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--ink-2);
  text-align: center;
}

.auth-back {
  font-size: var(--fs-small);
  color: var(--ink-2);
}

.auth-back a { text-decoration: none; }

.auth-plan {
  padding: var(--s-3) var(--s-4);
  background: var(--brand-tint);
  color: var(--brand-text);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

/* ==========================================================================
   7. Motion, forced colors and reduced motion
   ========================================================================== */

#view > * { animation: view-enter var(--dur-base) var(--ease-out); }

@keyframes view-enter {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

@media (forced-colors: active) {
  .btn,
  .input,
  .select,
  .card,
  .notice,
  .selectable { border: 1px solid CanvasText; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .skeleton:not(.skeleton-stamp) {
    animation: none;
    background: var(--skeleton-base);
  }
}
