/* ==========================================================================
   Virtual CFO - Client Information Form
   Client-facing, so this is the VCxO house identity: navy #002060, accent
   #1B75BC, light #A8D1F2. Those three are brand and must not be altered.
   Everything else here is a UI addition built on top of them.

   Committed to a light theme on purpose. `color-scheme: light` is declared so
   native controls, scrollbars and autofill render light too, rather than a
   dark-mode browser painting half the form dark against our own light panels.
   ========================================================================== */

:root {
  /* brand */
  --navy: #002060;
  --accent: #1b75bc;
  --accent-soft: #a8d1f2;
  --accent-hover: #155f99;

  /* surfaces */
  --canvas: #f4f6fa;
  --surface: #ffffff;
  --surface-soft: #f7f9fc;
  --hairline: #e1e6ef;
  --hairline-strong: #c8d1e0;

  /* text - every pair below was checked against its own background for AA */
  --ink: #002060;      /* 15.3:1 on white */
  --body: #39424f;     /* 10.1:1 on white */
  --muted: #64708a;    /*  5.1:1 on white, 4.9:1 on --surface-soft */
  --on-navy: #ffffff;
  --on-navy-dim: #b9c6de;

  /* status - not brand tokens; conventional hues tuned to pass AA on white */
  --error: #c0392b;    /* 5.4:1 */
  --error-bg: #fdf2f0;
  --success: #177a4a;  /* 5.4:1 */

  --radius: 8px;
  --radius-sm: 6px;
  --radius-lg: 14px;

  /* one soft shadow, used only on the raised form card */
  --lift: 0 1px 2px rgb(0 32 96 / 6%), 0 12px 32px -12px rgb(0 32 96 / 18%);


  color-scheme: light;
}

/* The server brief records this the hard way: [hidden] loses to any class that
   sets `display`, and a .panel { display: grid } once made a hidden overlay
   swallow every tap in the phone app. Non-negotiable. */
[hidden] {
  display: none !important;
}

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--body);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  font-size: 1rem;
  line-height: 1.55;
  text-underline-offset: 0.15em;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
}

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

.noscript-note {
  margin: 0;
  padding: 1rem 1.25rem;
  background: #fff6e5;
  border-block-end: 1px solid #f0d9a8;
  color: #6b4708;
  font-size: 0.9375rem;
}

/* ============================================================ layout shell

   One long column, not a wide two-column split. The masthead carries the whole
   VCxO group across the top; everything below it is a single centred measure.
   `.wrap` is the shared gutter, so the masthead, the title bar, the section bar
   and the form all line up on the same left and right edges. */

.wrap {
  width: 100%;
  max-width: 60rem;
  margin-inline: auto;
  padding-inline: 2rem;
}

@media (width < 48rem) {
  .wrap {
    padding-inline: 1.25rem;
  }
}

/* ================================================================ masthead */

/* Light, not navy: each practice has its own colour in its mark - CFO blue,
   CHRO deeper blue, CLO maroon, Academy green - and those only read correctly
   on a light ground. Putting the group on navy would flatten the one thing
   that tells them apart. */
.masthead {
  background: var(--surface);
  border-block-end: 1px solid var(--hairline);
}

.masthead-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding-block: 2.25rem 1.75rem;
  text-align: center;
}

.group-logo {
  width: auto;
  height: 4.25rem;
  max-width: 100%;
}

.group-tag {
  margin: 0;
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* The four practices. A plain list, evenly spaced, wrapping on narrow screens
   rather than scrolling - a client should see the whole group at a glance. */
.brands {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: 1.5rem 3rem;
  margin: 1.25rem 0 0;
  padding: 1.5rem 0 0;
  border-block-start: 1px solid var(--hairline);
  width: 100%;
}

.brand {
  display: flex;
  align-items: flex-end;
}

.brand img {
  width: auto;
  display: block;
  transition: height 0.2s ease, opacity 0.2s ease, filter 0.2s ease, scale 0.2s ease;
}

/* Virtual CFO carries no badge. It does not need one: at roughly twice the
   height of the others, and the only mark in full colour at rest, it reads as
   the active practice on sight. A label would only repeat what the size and
   the colour already say. */
.brand.is-active img {
  height: 4.25rem;
}

/* The other three rest muted - close to greyscale so the eye goes straight to
   CFO - then come up to their own colour and size under the cursor. Each one's
   colour is its identity (CHRO blue, CLO maroon, Academy green), so the reveal
   is worth having even before their forms exist. */
.brand.is-muted img {
  height: 2.25rem;
  opacity: 0.5;
  filter: grayscale(0.85) contrast(0.95);
  cursor: help;
}

.brand.is-muted img:hover,
.brand.is-muted img:focus-visible {
  height: 2.75rem;
  opacity: 1;
  filter: none;
  scale: 1.04;
}

/* Hovering the active mark lifts it very slightly too, so the row feels alive
   rather than half-dead. */
.brand.is-active img:hover {
  scale: 1.03;
}

@media (prefers-reduced-motion: reduce) {
  .brand img {
    transition: opacity 0.2s ease, filter 0.2s ease;
  }

  .brand.is-muted img:hover,
  .brand.is-muted img:focus-visible,
  .brand.is-active img:hover {
    height: 2.25rem;
    scale: 1;
  }

  .brand.is-muted img:hover,
  .brand.is-muted img:focus-visible {
    opacity: 1;
    filter: none;
  }
}

@media (width < 48rem) {
  .masthead-inner {
    padding-block: 1.5rem 1.25rem;
  }

  .group-logo {
    height: 3rem;
  }

  .brands {
    gap: 1rem 1.5rem;
  }

  .brand.is-active img {
    height: 3rem;
  }

  .brand.is-muted img {
    height: 1.75rem;
  }

  /* Touch has no hover, so the muted marks would otherwise never reveal. Lift
     them closer to full strength here instead. */
  .brand.is-muted img {
    opacity: 0.72;
    filter: grayscale(0.5);
  }
}

/* =============================================================== title bar */

.titlebar {
  background:
    repeating-linear-gradient(107deg,
      rgb(168 209 242 / 7%) 0 2px,
      transparent 2px 22px),
    radial-gradient(120% 140% at 100% 0%, rgb(27 117 188 / 55%) 0%, transparent 60%),
    linear-gradient(168deg, #002a7d 0%, var(--navy) 55%, #001640 100%);
  color: var(--on-navy);
  padding-block: 2rem;
}

.titlebar-title {
  margin: 0;
  color: #fff;
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.125rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.titlebar-sub {
  margin: 0.625rem 0 0;
  color: var(--on-navy-dim);
  font-size: 0.9375rem;
  max-width: 56ch;
  text-wrap: pretty;
}

.titlebar-note {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
  padding-block-start: 1rem;
  border-block-start: 1px solid rgb(255 255 255 / 14%);
  color: var(--on-navy-dim);
  font-size: 0.8125rem;
  max-width: 62ch;
}

.lock {
  flex: none;
  position: relative;
  width: 0.875rem;
  height: 0.75rem;
  margin-block-start: 0.25rem;
  background: currentcolor;
  border-radius: 2px;
}

.lock::before {
  content: "";
  position: absolute;
  inset-block-start: -0.375rem;
  inset-inline-start: 50%;
  translate: -50% 0;
  width: 0.5rem;
  height: 0.5rem;
  border: 2px solid currentcolor;
  border-block-end: 0;
  border-start-start-radius: 999px;
  border-start-end-radius: 999px;
}

/* ============================================================= section bar

   Sticks to the top of the window so the client always knows where they are in
   a long form, and can jump. This replaces the old sidebar rail; it reuses the
   same data- attributes, so app.js needed no change. */

.sectionbar {
  position: sticky;
  inset-block-start: 0;
  z-index: 5;
  background: rgb(255 255 255 / 92%);
  backdrop-filter: blur(8px);
  border-block-end: 1px solid var(--hairline);
}

.sectionbar-inner {
  padding-block: 0.5rem;
}

.steps {
  list-style: none;
  display: flex;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  /* Narrow screens scroll this strip sideways rather than wrapping it into a
     tall block that would eat the viewport it is meant to sit above. */
  overflow-x: auto;
  scrollbar-width: none;
}

.steps::-webkit-scrollbar {
  display: none;
}

.step {
  flex: none;
}

.step-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.5rem;
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 0.875rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s, color 0.15s;
}

.step-btn:hover {
  background: var(--canvas);
  color: var(--ink);
}

.step-dot {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.step-btn[aria-current="true"] {
  background: var(--canvas);
  color: var(--ink);
  font-weight: 600;
}

.step-btn[aria-current="true"] .step-dot {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}

/* Done sections carry a tick as well as a colour change - state is never
   colour alone, which also keeps them legible in a printed screenshot. */
.step.is-done .step-dot {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-size: 0;
}

.step.is-done .step-dot::after {
  content: "";
  width: 0.4375rem;
  height: 0.25rem;
  border-inline-start: 2px solid currentcolor;
  border-block-end: 2px solid currentcolor;
  transform: rotate(-45deg) translate(1px, -1px);
}

/* On a phone only the current section keeps its label, so the strip stays one
   comfortable row instead of a sideways scroll nobody notices. */
@media (width < 48rem) {
  .step-label {
    display: none;
  }

  .step-btn[aria-current="true"] .step-label {
    display: inline;
  }
}

/* =================================================================== footer */

.pagefoot {
  margin-block-start: 3rem;
  padding-block: 2.5rem 3rem;
  background: var(--surface);
  border-block-start: 1px solid var(--hairline);
  text-align: center;
}

.foot-logo {
  width: auto;
  height: 2.75rem;
  opacity: 0.8;
}

.foot-brands {
  margin: 0.875rem 0 0;
  color: var(--muted);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

.foot-contact {
  margin: 0.5rem 0 0;
  color: var(--muted);
  font-size: 0.8125rem;
}


/* ==========================================================================
   Landing page (intro.html)

   Alternating light and navy bands down a single column, so the four practices
   read as one group rather than four separate pitches. Shares `.wrap`, the
   buttons and the footer with the form, which is why the two pages feel like
   one site.
   ========================================================================== */

.intro-page {
  background: var(--surface);
}

/* --------------------------------------------------------------------- hero */

.hero {
  background:
    repeating-linear-gradient(107deg,
      rgb(168 209 242 / 6%) 0 2px,
      transparent 2px 22px),
    radial-gradient(90% 120% at 100% 0%, rgb(27 117 188 / 18%) 0%, transparent 60%),
    linear-gradient(180deg, #ffffff 0%, #f2f6fc 100%);
  border-block-end: 1px solid var(--hairline);
}

.hero-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-block: 4rem 3.5rem;
}

.hero-logo {
  width: auto;
  height: 6rem;
  max-width: 100%;
}

.hero-tag {
  margin: 1rem 0 0;
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.hero-title {
  margin: 2rem 0 0;
  color: var(--ink);
  font-size: clamp(1.75rem, 1.1rem + 2.4vw, 3rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.hero-lead {
  margin: 1.25rem 0 0;
  max-width: 60ch;
  color: var(--body);
  font-size: 1.0625rem;
  line-height: 1.6;
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-block-start: 2rem;
}

.btn-quiet {
  background: none;
  border-color: var(--hairline-strong);
  color: var(--body);
}

.btn-quiet:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.hero-stat {
  margin: 1.75rem 0 0;
  color: var(--muted);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

.hero-stat strong {
  color: var(--ink);
  font-size: 0.9375rem;
}

/* ------------------------------------------------------- shared section bits */

.eyebrow {
  margin: 0;
  color: var(--accent);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.section-title {
  margin: 0.625rem 0 0;
  color: var(--ink);
  font-size: clamp(1.375rem, 1.1rem + 1.2vw, 1.875rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

/* ------------------------------------------------------------- disciplines */

.disciplines {
  padding-block: 3.5rem;
  background: var(--canvas);
  border-block-end: 1px solid var(--hairline);
  text-align: center;
}

.discipline-cards {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin: 2rem 0 0;
  padding: 0;
}

@media (width < 60rem) {
  .discipline-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (width < 30rem) {
  .discipline-cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

.discipline-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.625rem;
  height: 100%;
  padding: 1.5rem 1rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  text-decoration: none;
  transition: border-color 0.15s, box-shadow 0.15s, translate 0.15s;
}

.discipline-link:hover {
  border-color: var(--accent-soft);
  box-shadow: var(--lift);
  translate: 0 -2px;
}

.discipline-link img {
  width: auto;
  height: 2.25rem;
}

.discipline-name {
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
}

.discipline-tag {
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.45;
  text-wrap: pretty;
}

/* ---------------------------------------------------------------- practices */

.practice {
  padding-block: 3.5rem;
  border-block-end: 1px solid var(--hairline);
}

/* Alternating ground keeps four similar sections from reading as one long
   undifferentiated list. */
.practice:nth-of-type(even) {
  background: var(--canvas);
}

.practice-head {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.practice-logo {
  width: auto;
  height: 2.75rem;
  flex: none;
}

.practice-blurb {
  margin: 0.375rem 0 0;
  max-width: 62ch;
  color: var(--body);
  font-size: 1rem;
  line-height: 1.55;
  text-wrap: pretty;
}

.services {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
  margin: 2rem 0 0;
  padding: 0;
}

.service {
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  /* A short accent rule rather than an icon: it carries the brand without
     inventing iconography the firm does not have. */
  border-block-start: 3px solid var(--accent);
}

.practice:nth-of-type(even) .service {
  background: var(--surface);
}

.service-title {
  margin: 0;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
}

.service-summary {
  margin: 0.5rem 0 0;
  color: var(--body);
  font-size: 0.875rem;
  line-height: 1.5;
  text-wrap: pretty;
}

/* Each practice tints its own accent rule, taken from its logo. */
.practice-chro .service { border-block-start-color: #1b4f9c; }
.practice-clo  .service { border-block-start-color: #8c2f45; }
.practice-academy .service { border-block-start-color: #1e7a5a; }

/* ---------------------------------------------------------------------- CTA */

.cta {
  padding-block: 3.5rem;
  background:
    repeating-linear-gradient(107deg,
      rgb(168 209 242 / 7%) 0 2px,
      transparent 2px 22px),
    radial-gradient(120% 140% at 100% 0%, rgb(27 117 188 / 55%) 0%, transparent 60%),
    linear-gradient(168deg, #002a7d 0%, var(--navy) 55%, #001640 100%);
  color: var(--on-navy);
}

.cta-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.cta-title {
  margin: 0;
  color: #fff;
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.125rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.cta-lead {
  margin: 1rem 0 0;
  max-width: 58ch;
  color: var(--on-navy-dim);
  font-size: 0.9375rem;
  line-height: 1.6;
  text-wrap: pretty;
}

.cta .btn-primary {
  margin-block-start: 2rem;
  background: #fff;
  color: var(--navy);
}

.cta .btn-primary:hover {
  background: var(--accent-soft);
  color: var(--navy);
}

.cta-note {
  margin: 1.25rem 0 0;
  color: var(--on-navy-dim);
  font-size: 0.8125rem;
}

.cta-note a {
  color: #fff;
}

/* The arrow is a button glyph shared with the form; it needs a direction here. */
.btn-arrow {
  width: 0.4375rem;
  height: 0.4375rem;
  border-inline-end: 2px solid currentcolor;
  border-block-start: 2px solid currentcolor;
  rotate: 45deg;
}

@media (width < 48rem) {
  .hero-inner {
    padding-block: 2.5rem 2.25rem;
  }

  .hero-logo {
    height: 4rem;
  }

  .practice-head {
    gap: 1rem;
  }
}

/* ============================================================== form pane */

.pane {
  min-width: 0;
}

.progress {
  position: sticky;
  inset-block-start: 0;
  z-index: 3;
  height: 0.25rem;
  background: var(--hairline);
}

.progress-fill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--accent) 0%, var(--navy) 100%);
  transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Width and gutters now come from `.wrap`, shared with the masthead and the
   section bar so every edge on the page lines up. */
.form {
  padding-block-start: 2.5rem;
}

/* The honeypot must stay in the layout but out of sight. `display: none` and
   `visibility: hidden` are both skipped by the bots worth catching. */
.hp {
  position: absolute;
  inset-inline-start: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ------------------------------------------------------------------ panels */

.panel {
  margin: 0 0 3rem;
  padding: 0;
  border: 0;
  min-inline-size: 0;
  /* Clears the sticky section bar when a section link jumps here. */
  scroll-margin-block-start: 4.5rem;
}

.panel-legend {
  display: block;
  width: 100%;
  padding: 0;
  margin-block-end: 1.25rem;
}

.panel-count {
  display: block;
  color: var(--accent);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.panel-title {
  display: block;
  margin: 0.375rem 0 0;
  color: var(--ink);
  font-size: clamp(1.375rem, 1.2rem + 0.7vw, 1.75rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
}

.panel-blurb {
  display: block;
  margin: 0.5rem 0 0;
  color: var(--muted);
  font-size: 0.9375rem;
  max-width: 52ch;
  text-wrap: pretty;
}

.grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem 1.25rem;
  padding: 1.75rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--lift);
}

@media (width < 48rem) {
  .grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    padding: 1.25rem;
  }
}

/* Two fields side by side rarely have help text of the same height, and a
   plain grid cell would leave their inputs on different baselines. Making the
   field a column and pushing the control to the end lines the inputs up along
   the bottom of the row however long the labels and hints run. */
.field {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Excluding .field-money, which is its own two-column grid below and would
   have the auto margin push its input around inside the row instead. */
.field:not(.field-money) > .input,
.field:not(.field-money) > .select-wrap,
.field:not(.field-money) > .money-wrap {
  margin-block-start: auto;
}

.field-wide {
  grid-column: 1 / -1;
}

/* Money fields read as a column of figures against their labels, which is far
   easier to check than a two-up grid of boxes, so each takes the full width
   with the label on the left and the amount right-aligned on the right.

   Every child is placed by name rather than by flow order. Relying on flow put
   the help text into the control's slot on any field that had help, which
   bumped the input onto the next row at 1fr wide - so the amounts no longer
   lined up with each other, exactly the thing this layout exists to do. */
.field-money {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 14rem;
  grid-template-areas:
    "label control"
    "help  hint"
    "err   err";
  align-items: center;
  column-gap: 1.25rem;
  row-gap: 0.25rem;
}

.field-money > .label {
  grid-area: label;
  margin-block-end: 0;
}

.field-money > .help {
  grid-area: help;
  margin: 0;
}

.field-money > .money-wrap {
  grid-area: control;
}

.field-money > .hint {
  grid-area: hint;
  margin: 0;
  text-align: end;
}

.field-money > .err {
  grid-area: err;
}

@media (width < 48rem) {
  .field-money {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "label"
      "help"
      "control"
      "hint"
      "err";
  }

  .field-money > .label {
    margin-block-end: 0.375rem;
  }

  .field-money > .help {
    margin-block-end: 0.5rem;
  }

  .field-money > .hint {
    text-align: start;
  }
}

/* ------------------------------------------------------------------ labels */

.label {
  display: block;
  margin-block-end: 0.375rem;
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
}

.opt {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.8125rem;
}

/* Sits between label and input, so the Gestalt proximity rule holds: the gap
   below the help text is smaller than the gap between fields. */
.help {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.45;
}

/* Help text inside a yes/no group label, where a block <p> would push the
   toggle out of line. */
.help-inline {
  display: block;
  margin: 0.125rem 0 0;
  font-weight: 400;
}

.hint {
  margin: 0.375rem 0 0;
  color: var(--muted);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.err {
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  margin: 0.375rem 0 0;
  color: var(--error);
  font-size: 0.8125rem;
  font-weight: 500;
}

/* A shape, not just a colour, so the error survives colour-blindness, a
   greyscale print and forced-colors mode. */
.err::before {
  content: "!";
  flex: none;
  display: grid;
  place-items: center;
  width: 1rem;
  height: 1rem;
  margin-block-start: 0.125rem;
  border: 1.5px solid currentcolor;
  border-radius: 50%;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
}

/* ------------------------------------------------------------------ inputs */

.input {
  display: block;
  width: 100%;
  min-height: 3rem;
  padding: 0.6875rem 0.875rem;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--body);
  /* 1rem minimum: anything smaller makes iOS Safari zoom on focus. */
  font: inherit;
  font-size: 1rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}

textarea.input {
  min-height: 5.5rem;
  resize: vertical;
  line-height: 1.5;
}

.input::placeholder {
  color: #93a0b5;
}

.input:hover:not(:focus) {
  border-color: #a9b5c8;
}

.input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgb(27 117 188 / 18%);
}

/* :user-invalid only matches after the client has actually interacted with the
   field or tried to submit, so nothing is flagged red on page load. Baseline
   since Nov 2023. app.js mirrors it into aria-invalid for assistive tech,
   because a pseudo-class is a visual state only. */
.input:user-invalid,
.input[aria-invalid="true"] {
  border-color: var(--error);
  background: var(--error-bg);
}

.input:disabled {
  background: var(--surface-soft);
  color: var(--muted);
  cursor: not-allowed;
}

/* select ------------------------------------------------------------------ */

.select-wrap {
  position: relative;
}

.select {
  appearance: none;
  padding-inline-end: 2.5rem;
  cursor: pointer;
}

.select:invalid {
  color: #93a0b5;
}

.select-arrow {
  position: absolute;
  inset-inline-end: 1rem;
  inset-block-start: 50%;
  width: 0.5rem;
  height: 0.5rem;
  border-inline-end: 2px solid var(--muted);
  border-block-end: 2px solid var(--muted);
  rotate: 45deg;
  translate: 0 -70%;
  pointer-events: none;
}

/* money ------------------------------------------------------------------- */

.money-wrap {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  overflow: hidden;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.money-wrap:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgb(27 117 188 / 18%);
}

.money-wrap:has(.input:user-invalid),
.money-wrap:has(.input[aria-invalid="true"]) {
  border-color: var(--error);
}

.money-cur {
  display: grid;
  place-items: center;
  padding-inline: 0.875rem;
  background: var(--surface-soft);
  border-inline-end: 1px solid var(--hairline);
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.money-wrap .input {
  border: 0;
  border-radius: 0;
  background: none;
  text-align: end;
  font-variant-numeric: tabular-nums;
  font-size: 1.0625rem;
}

.money-wrap .input:focus-visible {
  box-shadow: none;
}

.money-wrap .input:user-invalid,
.money-wrap .input[aria-invalid="true"] {
  background: none;
}

/* segmented yes / no ------------------------------------------------------ */

.yesno-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3rem;
}

.segmented {
  flex: none;
  display: flex;
  gap: 0.25rem;
  padding: 0.1875rem;
  background: var(--surface-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
}

.seg {
  cursor: pointer;
}

/* The canonical visually-hidden recipe. NOT display:none, which would take the
   radio out of the accessibility tree and break keyboard operation entirely. */
.seg input,
.chip input,
.check input {
  position: absolute;
  clip-path: inset(50%);
  overflow: hidden;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  white-space: nowrap;
}

.seg-face {
  display: grid;
  place-items: center;
  min-width: 3.25rem;
  min-height: 2.25rem;
  padding-inline: 0.75rem;
  border-radius: 4px;
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 500;
  transition: background-color 0.15s, color 0.15s;
}

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

.seg input:checked + .seg-face {
  background: var(--navy);
  color: #fff;
  font-weight: 600;
}

.seg input:focus-visible + .seg-face {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* chips ------------------------------------------------------------------- */

.chips-set {
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.chips-set > .label {
  padding: 0;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.chip {
  cursor: pointer;
}

.chip-face {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  /* 44px tall so it clears the minimum tap target on a phone. */
  min-height: 2.75rem;
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--body);
  font-size: 0.875rem;
  line-height: 1.3;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.chip:hover .chip-face {
  border-color: var(--accent);
  color: var(--ink);
}

.chip-tick {
  flex: none;
  position: relative;
  width: 1rem;
  height: 1rem;
  border: 1.5px solid var(--hairline-strong);
  border-radius: 4px;
  transition: background-color 0.15s, border-color 0.15s;
}

.chip input:checked + .chip-face {
  border-color: var(--accent);
  background: #eaf4fd;
  color: var(--ink);
  font-weight: 500;
}

.chip input:checked + .chip-face .chip-tick {
  background: var(--accent);
  border-color: var(--accent);
}

.chip input:checked + .chip-face .chip-tick::after {
  content: "";
  position: absolute;
  inset-block-start: 0.1875rem;
  inset-inline-start: 0.25rem;
  width: 0.4375rem;
  height: 0.25rem;
  border-inline-start: 2px solid #fff;
  border-block-end: 2px solid #fff;
  rotate: -45deg;
}

.chip input:focus-visible + .chip-face {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.other {
  margin-block-start: 0.75rem;
}

.other-label {
  display: block;
  margin-block-end: 0.375rem;
  color: var(--muted);
  font-size: 0.8125rem;
  font-weight: 500;
}


/* ------------------------------------------------- grouped / dependent chips */

.chip-group + .chip-group {
  margin-block-start: 1rem;
}

.chip-group-label {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* The block that fills in from the revenue model. The left rule ties the two
   together visually - it is a consequence of the answer above, not a second
   independent question. */
.chip-group-dependent {
  padding-inline-start: 0.875rem;
  border-inline-start: 2px solid var(--accent-soft);
}

.chip-empty {
  margin: 0;
  color: var(--muted);
  font-size: 0.8125rem;
  font-style: italic;
  max-width: 52ch;
}

/* A cost the client ticked that no longer matches their stated revenue models.
   Kept - never silently removed - but marked, so they can see why it is there
   and drop it if it was a mistake. */
.chip.is-orphan .chip-face {
  border-style: dashed;
}

/* consent checkbox -------------------------------------------------------- */

.consent-field {
  margin-block-start: 0.5rem;
  padding: 1.25rem;
  background: var(--surface-soft);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}

.check {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  cursor: pointer;
}

.check-box {
  flex: none;
  position: relative;
  width: 1.25rem;
  height: 1.25rem;
  margin-block-start: 0.125rem;
  border: 1.5px solid var(--hairline-strong);
  border-radius: 4px;
  background: var(--surface);
  transition: background-color 0.15s, border-color 0.15s;
}

.check input:checked + .check-box {
  background: var(--accent);
  border-color: var(--accent);
}

.check input:checked + .check-box::after {
  content: "";
  position: absolute;
  inset-block-start: 0.25rem;
  inset-inline-start: 0.3125rem;
  width: 0.5rem;
  height: 0.3125rem;
  border-inline-start: 2px solid #fff;
  border-block-end: 2px solid #fff;
  rotate: -45deg;
}

.check input:focus-visible + .check-box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

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

.check-text {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--body);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0.6875rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
}

.btn-primary {
  background: var(--navy);
  color: #fff;
}

.btn-primary:hover {
  background: #003494;
}

.btn-primary:active {
  background: var(--navy);
}

.btn-ghost {
  background: var(--surface);
  border-color: var(--hairline-strong);
  color: var(--body);
}

.btn-ghost:hover {
  border-color: var(--muted);
  color: var(--ink);
}

.btn[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}

.spinner {
  display: none;
  width: 1rem;
  height: 1rem;
  border: 2px solid rgb(255 255 255 / 35%);
  border-block-start-color: #fff;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

.btn.is-busy .spinner {
  display: block;
}

@keyframes spin {
  to { rotate: 360deg; }
}

/* -------------------------------------------------------------- form alert */

.form-alert {
  margin-block-end: 1.5rem;
  padding: 0.875rem 1rem;
  background: var(--error-bg);
  border: 1px solid #f0c8c2;
  border-inline-start: 3px solid var(--error);
  border-radius: var(--radius-sm);
  color: #8c2c20;
  font-size: 0.875rem;
}

.form-alert a {
  color: inherit;
}

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



/* ------------------------------------------------------------------ success */

/* Set on <body> once the submission succeeds. Without it a wheel gesture over
   the success card scrolls the completed form behind it, which looks broken. */
body.is-done {
  overflow: hidden;
}

.done {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background: var(--canvas);
  overflow-y: auto;
}

.done-card {
  max-width: 30rem;
  padding: 2.5rem;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--lift);
  text-align: center;
}

.done-logo {
  width: 9rem;
  height: auto;
  margin-block-end: 1.75rem;
}

.done-mark {
  width: 3.5rem;
  height: 3.5rem;
  margin: 0 auto 1.5rem;
  display: grid;
  place-items: center;
  background: #e8f5ee;
  border-radius: 50%;
}

.done-mark::after {
  content: "";
  width: 1.125rem;
  height: 0.625rem;
  border-inline-start: 2.5px solid var(--success);
  border-block-end: 2.5px solid var(--success);
  rotate: -45deg;
  translate: 0 -0.125rem;
}

.done-title {
  margin: 0 0 0.75rem;
  color: var(--ink);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.25;
  text-wrap: balance;
}

.done-body {
  margin: 0 0 1rem;
  color: var(--body);
  font-size: 0.9375rem;
  text-wrap: pretty;
}

.done-ref {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  background: var(--surface-soft);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  color: var(--ink);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.9375rem;
  letter-spacing: 0.03em;
}

.done-note {
  margin: 0;
  color: var(--muted);
  font-size: 0.8125rem;
}


/* =============================================== single-page form additions */

/* Keyboard users should not have to tab the whole masthead to reach the form. */
.skip {
  position: absolute;
  inset-inline-start: -9999px;
  z-index: 20;
  padding: 0.75rem 1rem;
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius-sm);
  font-weight: 600;
}

.skip:focus {
  inset-inline-start: 1rem;
  inset-block-start: 1rem;
}

.intro {
  margin-block-end: 2rem;
}

.intro-lead {
  margin: 0;
  color: var(--body);
  font-size: 0.9375rem;
  max-width: 62ch;
  text-wrap: pretty;
}

/* The section-bar entry for the section currently in view. Distinct from
   .is-done, which means "every required answer here is in". */
.step.is-active .step-btn {
  background: var(--canvas);
  color: var(--ink);
}

/* --------------------------------------------------------------- submit block */

.panel-submit {
  margin-block-end: 1.5rem;
}

.grid-submit {
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
}

.submit-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
}

.btn-lg {
  min-height: 3.25rem;
  padding-inline: 2rem;
  font-size: 1rem;
}

.submit-note {
  margin: 0;
  color: var(--muted);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

/* A quiet confirmation rather than a green banner - the button is the action,
   this is just the count. Paired with a tick so it is not colour alone. */
.submit-note.is-ready {
  color: var(--success);
  font-weight: 500;
}

.submit-note.is-ready::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.3125rem;
  margin-inline-end: 0.5rem;
  border-inline-start: 2px solid currentcolor;
  border-block-end: 2px solid currentcolor;
  rotate: -45deg;
  translate: 0 -0.15rem;
}

/* The form-level alert sits inside the submit card now, so it needs no
   bottom margin of its own. */
.panel-submit .form-alert {
  margin-block-end: 0;
}

/* A field the client has been told about gets a quiet marker in the margin, so
   a long page can be scanned for what still needs attention rather than
   hunting for red text. */
.field.has-error {
  position: relative;
}

.field.has-error::before {
  content: "";
  position: absolute;
  inset-inline-start: -0.875rem;
  inset-block: 0.125rem;
  width: 3px;
  border-radius: 3px;
  background: var(--error);
}

@media (width < 48rem) {
  .field.has-error::before {
    inset-inline-start: -0.625rem;
  }
}

/* ================================================== motion and preferences */

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

  .progress-fill {
    transition: none;
  }
}

/* Forced colors strips our backgrounds, so the custom controls need a real
   border to remain distinguishable - a background-only checked state would
   vanish completely. */
@media (forced-colors: active) {
  .seg input:checked + .seg-face,
  .chip input:checked + .chip-face,
  .check input:checked + .check-box {
    outline: 2px solid Highlight;
  }

  .titlebar {
    background: Canvas;
    color: CanvasText;
  }

  .input,
  .money-wrap {
    border: 1px solid ButtonBorder;
  }
}

/* ==================================================================== print */

@media print {
  .sectionbar,
  .noscript-note {
    display: none;
  }

  .grid {
    box-shadow: none;
    break-inside: avoid;
  }
}
