/*
 * One stylesheet for the whole site: the Worker-rendered pages (home, shop,
 * about, contact, checkout, thanks) and the three static policy pages, which
 * carry a hand-copied version of the same header/footer markup.
 *
 * Deliberately small and plain. Brand agents will replace the type and colour
 * later; what has to survive that is the accessibility floor -- AA contrast,
 * 44px touch targets, visible focus rings.
 */

:root {
  color-scheme: light dark;
  /* Page ground, one design-review token change (2026-09-15): a barely-off-
     white sunken tone so white cards/surfaces read as raised against it,
     instead of body and card both being flat #ffffff. Same value as
     --surface-sunken below, deliberately -- see the design handoff doc. */
  --bg: #faf8fc;
  --surface: #ffffff;
  --fg: #1a1a1a;
  --muted: #5a5a5a; /* 7.0:1 on white */
  --border: #d9d9d9;
  /* Violet accent, from the 2026-09-14 brand kit's "Violet ink" (the color
     the kit itself names for letters/body-text-on-light -- the same role
     this token plays here). #ffffff on #3A2867 is ~12.5:1; #3A2867 on
     #ffffff the same, so it is safe for both button fills and body-text
     links (was #5b2a86, ~9.9:1, a placeholder that predated the kit). */
  --accent: #3A2867;
  --accent-ink: #ffffff;
  --accent-quiet: #f3ecf9;
  --error: #b00020;
  --focus: #3A2867;
  /* Brand-kit gold/night pair (2026-09-15 design handoff), for the primary
     button ONLY -- not part of the light/dark accent system, so the same
     two values are declared again, unchanged, in the dark :root block
     below rather than left to inherit. Night-on-gold measures ~12:1. */
  --brand-gold: #F5C766;
  --brand-night: #15102A;

  /* Barely-there violet-white and a softer internal rule, for the
     page-header/callout/work-grid components added in the 2026-09-13
     design review. Everything above this line is unchanged. */
  --surface-sunken: #faf8fc;
  --border-quiet: #ece6f2;

  /* Type scale (2026-09-13 design review). System stack unchanged -- no
     webfont added in this pass. */
  --text-xs: 0.8125rem; /* 13px -- hints, meta, footer fine print */
  --text-sm: 0.9375rem; /* 15px -- footer body, .hint */
  --text-base: 1rem; /* 16px -- body */
  --text-lg: 1.125rem; /* 18px -- lede / page-header summary */
  --text-xl: 1.375rem; /* 22px -- h3 / product name */
  --text-2xl: 1.75rem; /* 28px -- h2 */
  --text-3xl: 2.25rem; /* 36px -- h1, interior pages */
  --text-4xl: 2.75rem; /* 44px -- h1, home hero only, >=768px */
  --measure: 68ch; /* the value .lede already used */

  /* Spacing scale (2026-09-13 design review). Used only in new rules below
     -- the existing hand-tuned pixel values elsewhere in this file are not
     rewritten. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  color: var(--fg);
  background: var(--bg);
  line-height: 1.55;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.container {
  max-width: 960px;
  margin: 0 auto;
  padding: 0 16px;
  width: 100%;
}

main {
  flex: 1 0 auto;
  padding: 32px 0 64px;
}

/* The checkout and thanks pages are forms, not layouts: keep them narrow. */
main.checkout .container,
main.thanks .container {
  max-width: 560px;
}

h1 {
  font-size: var(--text-3xl);
  line-height: 1.15;
  margin: 0 0 0.5rem;
  max-width: 20ch;
}

h2 {
  font-size: var(--text-2xl);
  line-height: 1.25;
  margin: 2.5rem 0 0.75rem;
}

h3 {
  font-size: var(--text-xl);
  line-height: 1.3;
  margin: 1.5rem 0 0.5rem;
}

p {
  margin: 0 0 1rem;
}

/*
 * The measure fix (2026-09-13 design review): every page's .container was
 * 960px wide with no cap on the prose inside it, so a paragraph ran the
 * full ~928px content box -- 140+ characters per line, far past the 60-75ch
 * that keeps prose readable. .lede already capped itself at 68ch on the
 * home page only; this generalizes that same cap to every prose paragraph
 * and list on every page that isn't grid-based (shop/checkout/thanks lay
 * out in columns or a narrow form, not prose, so they're excluded).
 */
main:not(.shop):not(.checkout):not(.thanks) p,
main:not(.shop):not(.checkout):not(.thanks) li {
  max-width: var(--measure);
}

a {
  color: var(--accent);
}

a:hover {
  text-decoration: none;
}

/* One visible focus style for everything keyboard-reachable. */
a:focus-visible,
button:focus-visible,
input:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- site header ---------------------------------------------------- */

.site-header {
  position: relative; /* anchors .nav-drawer-panel below, full width */
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.header-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
  padding-top: 12px;
  padding-bottom: 12px;
}

.wordmark {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--fg);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

/*
 * Logo slot (2026-09-13 design review). No asset exists yet -- layout.ts's
 * LOGO_SRC is empty and renders no <img> at all, so this rule sits unused
 * until a logo lands; sizing it here now means adding the file is a
 * one-line change with no CSS to write alongside it.
 */
.logo {
  width: 28px;
  height: 28px;
  display: block;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
}

@media (max-width: 420px) {
  /* Tightens the wrap so the last nav item is less likely to land alone on
     its own line at narrow widths -- cosmetic only. */
  .site-nav {
    gap: 4px 14px;
  }
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
  color: var(--fg);
  font-weight: 400;
  font-size: var(--text-sm);
  text-decoration: none;
}

.site-nav a:hover {
  color: var(--accent);
}

.site-nav a[aria-current="page"] {
  color: var(--accent);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

/* --- mobile nav drawer (<640px) --------------------------------------- */

/* No JS: a native <details>/<summary> disclosure. Hidden entirely at
 * desktop widths, where .site-nav renders instead. */
.nav-drawer {
  display: none;
}

.nav-drawer summary {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 44px;
  height: 44px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  cursor: pointer;
  list-style: none;
}

.nav-drawer summary::-webkit-details-marker {
  display: none;
}

.nav-drawer-bar {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--fg);
}

/* The panel breaks out to the full header width (not just the width of the
 * <details> element, which is only as wide as the hamburger button) by
 * anchoring to .site-header's positioned box instead. */
.nav-drawer-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-top: 1px solid var(--border-quiet);
  padding: 0 16px 16px;
}

.nav-drawer-panel a {
  display: flex;
  align-items: center;
  min-height: 48px;
  border-bottom: 1px solid var(--border-quiet);
  color: var(--fg);
  font-size: var(--text-base);
  text-decoration: none;
}

.nav-drawer-panel a[aria-current="page"] {
  color: var(--accent);
  font-weight: 600;
}

.nav-drawer-panel .btn-primary {
  width: 100%;
  margin: var(--space-4) 0 0;
}

@media (max-width: 639px) {
  .site-nav {
    display: none;
  }

  .nav-drawer {
    display: block;
  }
}

/* --- home ------------------------------------------------------------ */

.hero {
  border-top: 3px solid var(--accent);
  padding: var(--space-6) 0 var(--space-7);
  margin-bottom: var(--space-6);
}

.eyebrow {
  margin: 0 0 var(--space-5);
  font-size: var(--text-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.hero h1 {
  font-size: var(--text-4xl);
  line-height: 1.08;
  letter-spacing: -0.02em;
  max-width: 22ch;
}

@media (max-width: 639px) {
  .hero h1 {
    font-size: 30px;
  }
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.lede {
  font-size: var(--text-lg);
  color: var(--muted);
  max-width: var(--measure);
}

.how ol {
  margin: 0;
  padding-left: 1.25rem;
  max-width: 60ch;
}

.how li {
  margin-bottom: 0.35rem;
}

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

.products {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin: 16px 0 24px;
}

@media (min-width: 640px) {
  /* Covers the home page's lone featured card too: `.featured .products` used
     to restate this same rule with the same value, which changed nothing. */
  .products {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Logo slot, sized up alongside everything else that grows at this
     breakpoint (unused until a logo file exists -- see the .logo rule
     above). */
  .logo {
    width: 32px;
    height: 32px;
  }
}

.product {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
}

.product h2 {
  margin: 0 0 4px;
  font-size: 1.1rem;
}

.product .price {
  margin: 0 0 8px;
  font-size: 1.15rem;
  color: var(--fg);
  font-weight: 600;
}

.product .blurb {
  color: var(--muted);
  font-size: 0.95rem;
  flex: 1 0 auto;
}

.badge {
  display: inline-block;
  align-self: flex-start;
  margin: 0 0 8px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-quiet);
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 600;
}

/*
 * Primary action button (2026-09-15 design handoff): the brand-kit gold
 * fill replaces the violet accent fill for every "Request..." link, the
 * checkout submit button, and the Shop "Buy" button -- one shared rule,
 * so .btn-primary/button#submit/.btn-submit/.buy never drift apart.
 */
.buy,
button#submit,
.btn-submit,
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 20px;
  border: none;
  border-radius: 8px;
  background: var(--brand-gold);
  color: var(--brand-night);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* Neutral secondary button (hero secondary action): outlined, not filled. */
.btn-neutral {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 20px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--fg);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* Text link used inside a card (e.g. "Consulting services" under the
 * "Two ways we work" cards) -- not a filled button. */
.card-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

.product .buy {
  align-self: flex-start;
}

/* --- design-system components (2026-09-13 design review) ------------- */

/* h1 + one-line summary, for every hub/detail page (2026-09-15: added the
 * 3px accent top border and padding, matching .hero's treatment). */
.page-header {
  border-top: 3px solid var(--accent);
  padding: var(--space-5) 0 var(--space-6);
  margin-bottom: var(--space-6);
}

.page-header h1 {
  max-width: 24ch;
}

.page-header .summary {
  font-size: var(--text-lg);
  color: var(--muted);
  max-width: var(--measure);
  margin: 0;
}

/* Sub-page back-link ("Consulting" / "Services"), rendered above the
 * bordered .page-header block, not inside it. */
.breadcrumb {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
}

.breadcrumb a {
  text-decoration: none;
}

/* Card grids: repeat(auto-fit, minmax(...)) collapses to one column on
 * mobile with no extra media query needed. */
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-5);
}

.grid-auto-wide {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

.card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: var(--space-5);
  background: var(--surface);
}

/* Larger radius for the home hero strip and step cards -- combine with
 * .card: class="card card-lg". */
.card-lg {
  border-radius: 14px;
}

/* "How it works" step cards: a numbered accent circle above a heading. */
.step-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: 0 0 var(--space-4);
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--text-sm);
  font-weight: 700;
}

/* A whole card that is itself a link (the Consulting hub's four service
 * cards). Border turns accent on hover/focus so the interactive shape is
 * obvious even though the whole card is one <a>, not a button + a link. */
.link-card {
  display: block;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: var(--space-5);
  background: var(--surface);
  color: var(--fg);
  text-decoration: none;
}

.link-card:hover,
.link-card:focus-within {
  border-color: var(--accent);
}

.link-card h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xl);
  line-height: 1.3;
  color: var(--accent);
}

.link-card p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* Two-column layout for a page that has an `aside` -- a `.callout` today,
 * a "recent work" teaser later. Pages without one never get this wrapper,
 * so they render exactly as before. */
.page-grid {
  display: grid;
  gap: var(--space-7);
}

@media (min-width: 900px) {
  .page-grid[data-has-aside] {
    grid-template-columns: minmax(0, var(--measure)) 1fr;
  }
}

/* "What's included" / "Where this shows up" style lists. */
.section-list {
  list-style: none;
  margin: 0;
  margin-bottom: var(--space-6);
  padding: 0;
  max-width: var(--measure);
  display: grid;
  gap: var(--space-4);
}

.section-list li {
  padding-left: var(--space-5);
  position: relative;
}

.section-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--accent);
}

/* Portfolio grid, with an honest "photo coming soon" state instead of a
 * broken image or a fake stock photo. */
.work-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

@media (min-width: 640px) {
  .work-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 960px) {
  .work-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.work-item {
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}

.work-item .media {
  aspect-ratio: 4 / 3;
  background: var(--surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
}

.work-item .media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.work-item .media.no-image::after {
  content: 'Photo coming soon';
  color: var(--muted);
  font-size: var(--text-sm);
}

.work-item .caption {
  padding: var(--space-4);
}

/* Secondary-action button, alongside the existing primary .buy/#submit. */
.btn-quiet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 20px;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: transparent;
  color: var(--accent);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
}

/*
 * Home page components (2026-09-15 design handoff). The credibility strip
 * and step cards reuse .grid-auto/.card/.card-lg/.step-num, but each needs a
 * heading size the global h2/h3 rules don't give them -- the credibility
 * strip's heading is a plain --text-base label, not a page-level h2, and the
 * step card's h3 is --text-lg rather than the global --text-xl.
 */
/* The prototype's credibility strip pads the whole card-lg strip at
   var(--space-6) (32px) directly, not through .card's own var(--space-5)
   (24px) padding rule -- a scoped override here, not a change to .card
   itself, which every other .card user still needs at 24px. */
.value-grid {
  padding: var(--space-6);
}

.value-grid h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-base);
  letter-spacing: 0.01em;
}

.value-grid p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--muted);
}

.step-card h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-lg);
  line-height: 1.3;
}

.step-card p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--muted);
}

/* "Two ways we work"-style cards: equal-height column so the .card-link
 * lines up across a row regardless of how long each body paragraph is. */
.card-col {
  display: flex;
  flex-direction: column;
}

.card-col p {
  flex: 1 0 auto;
}

/* A section heading with a "View all ..." link on the same line, wrapping
 * to stacked on mobile (home's "Recent work"). */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.section-head h2 {
  margin: 0;
}

/* Troubleshooting accordion: native <details>/<summary>, no JS. One card
 * (.accordion) holding several rows (.accordion-item), each a 56px summary
 * row with a +/- indicator that swaps on the [open] attribute alone. */
.accordion {
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
  max-width: var(--measure);
}

.accordion-item {
  border-bottom: 1px solid var(--border-quiet);
}

.accordion-item:last-child {
  border-bottom: none;
}

.accordion-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 56px;
  padding: var(--space-3) var(--space-5);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.accordion-item summary::-webkit-details-marker {
  display: none;
}

.accordion-item .indicator {
  flex: 0 0 auto;
  color: var(--accent);
  font-size: var(--text-lg);
  font-weight: 700;
}

.accordion-item .indicator-open {
  display: none;
}

.accordion-item[open] .indicator-closed {
  display: none;
}

.accordion-item[open] .indicator-open {
  display: inline;
}

.accordion-panel {
  padding: 0 var(--space-5) var(--space-5);
}

.accordion-panel .symptom-body {
  margin: 0 0 var(--space-4);
  color: var(--muted);
  font-size: var(--text-sm);
}

.accordion-panel .section-list {
  margin-bottom: 0;
}

.accordion-panel .section-list li {
  font-size: var(--text-sm);
}

/* The consultation form's success state: accent-quiet background, accent
 * border -- matches .form-errors' role but in the positive direction. */
.success-panel {
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: var(--space-5);
  background: var(--accent-quiet);
  max-width: var(--measure);
}

.success-panel p {
  margin: 0;
  color: var(--fg);
}

/* Wraps the volunteer-credential paragraph on /about and the
 * /consulting* pages that carry it -- markup only, no copy change. */
.callout {
  /* UI QA fix (2026-09-15): --surface-sunken now equals --bg exactly in
     light mode (the same design-review token change that made the page
     ground "sunken" also removed the one thing that used to set this box
     apart from it), so the aside rendered with no visible fill at all --
     only the 1px --border-quiet outline. The prototype's own light-mode
     tokens have the identical collision (--surface-sunken: #faf8fc ==
     --bg: #faf8fc in Violet Crown Laser Site.dc.html), so this isn't a
     fidelity gap to correct against the design file; it's a token
     interaction the design file also has. --accent-quiet is the fill this
     site already uses for "quiet, secondary" panels (.badge, .success-panel
     use it too), so this reuses an existing token rather than inventing a
     new fill: same luminance family as --surface-sunken but a visible
     violet hue shift against the neutral page ground. Text contrast is
     unaffected either way (--fg on --accent-quiet: 15.06:1 light, 13.46:1
     dark, both far above the 4.5:1 floor); the failure being fixed was
     never body-text contrast, it was "no visible box at all". Border stays
     --border-quiet -- unchanged. */
  background: var(--accent-quiet);
  border: 1px solid var(--border-quiet);
  border-radius: 10px;
  padding: var(--space-5);
  max-width: var(--measure);
}

.callout p {
  margin: 0;
  color: var(--fg);
}

/* --- checkout form --------------------------------------------------- */

.price {
  font-size: 1.25rem;
  margin-top: 0;
}

form label {
  display: block;
  margin-top: 16px;
  margin-bottom: 4px;
  font-weight: 600;
}

form input[type="email"] {
  width: 100%;
  min-height: 44px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 1rem;
  background: var(--surface);
  color: var(--fg);
}

/*
 * The field is read-only for one window only: while a charge is being
 * confirmed. Muting it there is the visible half of that fence -- outside it
 * the field is a plain editable input and this rule never applies.
 */
form input[type="email"][readonly] {
  background: transparent;
  color: var(--muted);
}

/*
 * Generic base for every other text-shaped field (the Rescue Call intake
 * form's text/number/date inputs, its <select>s, and its <textarea>s),
 * matching the look of the email input above. Checkboxes and radios are
 * excluded here and styled separately below -- a 44px-tall checkbox would
 * look absurd, so they get an enlarged clickable ROW instead of an enlarged
 * box.
 */
form input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]),
form select,
form textarea {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
  background: var(--surface);
  color: var(--fg);
  box-sizing: border-box;
}

form textarea {
  min-height: 88px;
}

/*
 * Checkboxes and radios: the clickable target is the whole label ROW, not
 * just the small box, so it clears the 44px touch-target floor without a
 * comically large checkbox. `.checkbox-row` is applied by the intake form's
 * checkbox-group and consent-checkbox markup.
 */
form label.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  margin-top: 8px;
  margin-bottom: 0;
  font-weight: 400;
}

form label.checkbox-row input[type="checkbox"],
form label.checkbox-row input[type="radio"] {
  width: 20px;
  height: 20px;
  min-width: 20px;
  margin: 2px 0 0;
  flex-shrink: 0;
}

/* The honeypot field: visually hidden but present in the accessibility tree
 * and the tab order (`tabindex="-1"` removes it from tab order without
 * `display:none`, which some bots specifically check for and skip). */
.honeypot-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-errors {
  border: 1px solid var(--error);
  border-radius: 6px;
  padding: 12px 16px;
  margin: 16px 0;
  color: var(--error);
}

.form-errors ul {
  margin: 8px 0 0;
  padding-left: 20px;
}

.hint {
  margin: 6px 0 0;
  font-size: 0.85rem;
  color: var(--muted);
}

#payment-element {
  margin-top: 16px;
}

button#submit,
.btn-submit {
  margin-top: 20px;
  width: 100%;
}

button#submit:disabled,
.btn-submit:disabled {
  opacity: 0.6;
  cursor: default;
}

#error-message {
  color: var(--error);
  min-height: 1.2em;
  margin-top: 8px;
  /* The startup-failure message in checkout.js puts the raw Stripe.js text on
     a second line; without this the newline would collapse to a space. */
  white-space: pre-line;
}

/* --- site footer ----------------------------------------------------- */

.site-footer {
  flex: 0 0 auto;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: var(--space-6) 0 var(--space-7);
  font-size: 0.9rem;
  color: var(--muted);
}

/* Two columns (brand/location/support left, policy links right), wrapping
 * to stacked on mobile. */
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-5);
}

.footer-inner p {
  margin: 0 0 4px;
}

.footer-name {
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--fg);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
}

/*
 * Footer links are small by design, so give each one its own 44px-tall
 * tappable box (inline-flex so the height applies at all) without changing
 * how the line reads.
 */
.footer-inner a {
  color: var(--fg);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration: none;
}

main.thanks a[href^="mailto:"] {
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141216;
    --surface: #1c191f;
    --fg: #f2f0f4;
    --muted: #b6b0bd; /* 8.4:1 on --bg */
    --border: #3a343f;
    /* Light violet, from the 2026-09-14 brand kit's "Laser on dark" -- the
       color the kit names for accent text on its own dark surface. ~7.9:1
       on --bg, dark ink sits on top of it at ~7.7:1 (was #c9a6ef, ~9.0:1 and
       ~8.9:1, a placeholder that predated the kit). Both pairs still clear
       AAA (7:1). */
    --accent: #B39BF0;
    --accent-ink: #1b0f2a;
    --accent-quiet: #2c2136;
    --error: #ff8a94;
    --focus: #B39BF0;
    --surface-sunken: #1f1a24;
    --border-quiet: #2a2430;
    /* Same brand-kit gold/night pair as the light block -- the primary
       button does not follow the light/dark accent swap. */
    --brand-gold: #F5C766;
    --brand-night: #15102A;
  }

  .site-nav a {
    color: var(--fg);
  }
}
