/* ============================================================
   KALVARO DESIGN SYSTEM: COMPONENTS
   Every component required by Web Pack §4, with every listed state.
   ============================================================ */

/* ============================================================
   BUTTONS
   States: default, hover, focus, pressed, disabled, loading.
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: var(--control-h-md);
  padding: 0 var(--space-7);
  border-radius: var(--radius-sm);
  font-size: var(--text-body);
  font-weight: var(--fw-bold);
  line-height: 1;
  text-decoration: none;
  /* Was nowrap with no max-width, which is the single cause of every real
     horizontal overflow on this site: a long label could not shrink, so the
     button punched out of its column and pushed documentElement.scrollWidth
     past the viewport. body { overflow-x: hidden } does not save this, it
     only hides the scrollbar, which is exactly the state that makes iOS
     Safari render the page zoomed out. */
  white-space: normal;
  max-width: 100%;
  overflow-wrap: break-word;
  border: 1.5px solid transparent;
  transition: background-color var(--dur-micro) var(--ease),
              border-color var(--dur-micro) var(--ease),
              color var(--dur-micro) var(--ease),
              box-shadow var(--dur-micro) var(--ease),
              transform var(--dur-micro) var(--ease);
}
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn .icon { flex: none; }

.btn--sm { min-height: var(--control-h-sm); padding: 0 var(--space-5); font-size: var(--text-small); }
.btn--lg { min-height: var(--control-h-lg); padding: 0 var(--space-8); }
.btn--block { width: 100%; }

/* Primary */
.btn--primary {
  background: var(--color-action);
  color: var(--color-action-label);
  box-shadow: var(--shadow-xs);
}
.btn--primary:hover { background: var(--color-action-hover); color: var(--color-action-label); }
.btn--primary:active { background: var(--color-action-pressed); transform: translateY(1px); }

/* Secondary: white/transparent with navy border */
.btn--secondary {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-text);
}
.btn--secondary:hover { background: rgba(15, 29, 46, .04); color: var(--color-text); }
.btn--secondary:active { background: rgba(15, 29, 46, .08); transform: translateY(1px); }

/* Inverse: for use on navy */
.btn--inverse {
  background: var(--k-white);
  color: var(--k-navy-800);
}
.btn--inverse:hover { background: var(--k-off-white); color: var(--k-navy-800); }

.on-dark .btn--secondary,
.section--navy .btn--secondary,
.hero .btn--secondary,
.page-hero .btn--secondary,
.cta-band .btn--secondary {
  color: var(--k-white);
  border-color: rgba(255, 255, 255, .45);
}
.on-dark .btn--secondary:hover,
.section--navy .btn--secondary:hover,
.hero .btn--secondary:hover,
.page-hero .btn--secondary:hover,
.cta-band .btn--secondary:hover { background: rgba(255, 255, 255, .10); color: var(--k-white); }

/* Tertiary / text link button */
.btn--text {
  /* Padded rather than bare, so Edit and Remove reach a usable target size. */
  padding: var(--space-3) var(--space-4);
  margin: calc(var(--space-3) * -1) calc(var(--space-4) * -1);
  min-height: 36px;
  color: var(--color-action-text);
  font-weight: var(--fw-bold);
}
.btn--text:hover { color: var(--color-action-pressed); text-decoration: underline; }

/* Disabled + loading */
.btn:disabled,
.btn[aria-disabled="true"] {
  background: var(--k-grey-200);
  border-color: var(--k-grey-200);
  /* These buttons stay operable so the user can discover why they cannot
     continue, which makes them active controls that must meet 4.5:1. */
  color: var(--k-slate-500);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}
.btn[data-loading="true"] { cursor: progress; pointer-events: none; }
.btn[data-loading="true"] .btn__spinner { display: inline-block; }
.btn__spinner {
  display: none;
  width: 16px; height: 16px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: k-spin .7s linear infinite;
}
@keyframes k-spin { to { transform: rotate(360deg); } }

@media (max-width: 560px) {
}

/* ============================================================
   LINKS
   ============================================================ */
.link {
  color: var(--color-action-text);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  border-bottom: 1.5px solid transparent;
}
.link:hover { border-bottom-color: currentColor; }
.on-dark .link, .section--navy .link, .hero .link, .page-hero .link { color: var(--k-emerald-500); }

.link-arrow { display: inline-flex; align-items: center; gap: var(--space-3); }
.link-arrow svg { transition: transform var(--dur-micro) var(--ease); }
.link-arrow:hover svg { transform: translateX(3px); }

/* ============================================================
   HEADER / NAVIGATION
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--color-surface-inverse);
  border-bottom: 1px solid transparent;
  transition: box-shadow var(--dur-micro) var(--ease);
}
.site-header[data-scrolled="true"] { box-shadow: var(--shadow-lg); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-7);
  min-height: 76px;
}
.site-header[data-scrolled="true"] .site-header__inner { min-height: 64px; }
.site-header__inner { transition: min-height var(--dur-micro) var(--ease); }

.brand { display: inline-flex; align-items: center; gap: var(--space-4); text-decoration: none; }

/* The official horizontal lockup carries the wordmark, so the name is no
   longer set in type. The alt text does the naming for anyone who cannot
   see it. */
.brand__lockup { width: 150px; height: auto; flex: none; display: block; }
@media (max-width: 560px) { .brand__lockup { width: 128px; } }

/* Retained for the mark on its own, where a lockup will not fit. */
.brand__mark { width: 40px; height: auto; flex: none; }

.nav { display: flex; align-items: center; gap: var(--space-8); }
.nav__link {
  color: rgba(255, 255, 255, .86);
  text-decoration: none;
  font-weight: var(--fw-medium);
  font-size: var(--text-small);
  padding: var(--space-3) 0;
  border-bottom: 2px solid transparent;
}
.nav__link:hover { color: var(--k-white); border-bottom-color: rgba(255, 255, 255, .4); }
.nav__link[aria-current="page"] {
  color: var(--k-white);
  font-weight: var(--fw-bold);
  border-bottom-color: var(--k-emerald-500);
}

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--k-white);
}
.nav-toggle:hover { background: rgba(255, 255, 255, .10); }

@media (max-width: 1023px) {
  .nav--desktop { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* Compact primary CTA kept in the header on mobile, so Discuss My Project
   is always reachable without opening the menu. */
.nav--mobile-only { display: none; }
@media (max-width: 1023px) { .nav--mobile-only { display: inline-flex; } }
@media (max-width: 430px)  { .nav--mobile-only { display: none; } }

/* Mobile panel */
.nav-panel {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(360px, 88vw);
  background: var(--color-surface-inverse);
  z-index: var(--z-panel);
  padding: var(--space-7) var(--space-7) var(--space-10);
  transform: translateX(100%);
  /* Hidden from the tab order and the accessibility tree while closed.
     A transform alone leaves six focusable links off screen, which a keyboard
     user tabs through on every page while focus is invisible. */
  visibility: hidden;
  transition: transform var(--dur-panel) var(--ease), visibility var(--dur-panel);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.nav-panel[data-open="true"] { transform: translateX(0); visibility: visible; }
.nav-panel__head { display: flex; justify-content: flex-end; margin-bottom: var(--space-5); }
.nav-panel a.nav__link {
  display: block;
  padding: var(--space-5) var(--space-4);
  min-height: 44px;
  border-bottom: 1px solid var(--color-border-inverse);
  font-size: var(--text-body);
}
.nav-panel .btn { margin-top: var(--space-7); }

.nav-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 21, 33, .5);
  z-index: var(--z-overlay);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-panel) var(--ease), visibility var(--dur-panel);
}
.nav-overlay[data-open="true"] { opacity: 1; visibility: visible; }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  background: var(--color-surface-inverse);
  color: var(--color-text-inverse);
  overflow: hidden;
}
.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-11);
  align-items: center;
  padding-block: clamp(3rem, 2rem + 5vw, 5.5rem);
}
.hero__title { color: var(--k-white); }
.hero__copy { color: var(--color-text-inverse-secondary); font-size: var(--text-lead); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-5); margin-top: var(--space-8); }
/* ---------- Trust rating strip ----------
   Trustpilot's own presentation: the word, five star tiles, the score, the
   wordmark. Only ever rendered from real figures pulled from a real profile
   (see REVIEWS in build.mjs). It renders nothing at all when there is no
   verified rating, which is the state it ships in today. */
.trust-rating {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-7);
  font-size: var(--text-small);
  color: var(--k-white);
}
/* The link or span wrapping the visible parts is the real row: without this
   it is a single block flex item and the parts wrap inside it. */
.trust-rating > a,
.trust-rating > span[aria-hidden] {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.trust-rating__word { font-weight: var(--fw-bold); }
.trust-rating__stars { display: flex; gap: 2px; }
.trust-rating__star {
  width: 22px;
  height: 22px;
  background: #00B67A;              /* Trustpilot green, not the Kalvaro emerald */
  display: grid;
  place-items: center;
}
.trust-rating__star svg { width: 15px; height: 15px; fill: var(--k-white); }
/* A partial final tile shows a fractional score honestly rather than rounding
   it up, which is the whole point of showing a number at all. */
.trust-rating__star--partial { background: rgba(255, 255, 255, .22); position: relative; }
.trust-rating__star--partial::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--fill, 50%);
  background: #00B67A;
}
.trust-rating__star--partial svg { position: relative; }
.trust-rating__score { color: rgba(255, 255, 255, .82); }
.trust-rating__brand { display: inline-flex; align-items: center; gap: 5px; font-weight: var(--fw-semibold); }
.trust-rating__brand svg { width: 16px; height: 16px; fill: #00B67A; }
.trust-rating a { color: inherit; text-decoration: none; }
.trust-rating a:hover { text-decoration: underline; }

@media (max-width: 560px) {
  .trust-rating { gap: var(--space-3); font-size: 0.875rem; }
  .trust-rating__star { width: 19px; height: 19px; }
}

/* ---------- Hero photograph ----------
   From 901px up the photograph bleeds off the right edge of the viewport and
   dissolves into the navy, so it reads as part of the page rather than a card
   placed on it.

   It is a sibling of .hero__inner, not a child: a child of the container can
   never reach the edge of the viewport. Three layers, bottom to top:
     0  the photograph, absolute against .hero
     1  .hero::after, two gradients painted in the exact page background
     2  .hero__inner, the words

   Gradients rather than mask-image, because a mask a browser does not support
   fails to a hard-edged photograph sitting behind the headline, which would
   wreck the contrast. A gradient that fails simply does not paint. */
.hero__media {
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
  aspect-ratio: 4 / 3;
  background: var(--k-navy-700);
}
.hero__media img,
.hero__media picture { display: block; width: 100%; height: 100%; }
.hero__media img { object-fit: cover; }

@media (min-width: 901px) {
  .hero { min-height: clamp(30rem, 24rem + 16vw, 38rem); display: flex; align-items: center; }
  .hero__media {
    position: absolute;
    inset: 0 0 0 auto;
    width: 62%;
    aspect-ratio: auto;
    border-radius: 0;
    box-shadow: none;
    background: none;
    z-index: 0;
  }
  .hero::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    /* Four layers, listed topmost first. The horizontal ramp is long and has
       an extra stop through the middle, because a two-stop fade over this
       distance shows a visible band where it starts. The flat tint at the
       bottom of the stack pulls the whole photograph into the palette so it
       sits in the page rather than on it. */
    background:
      linear-gradient(to right,
        var(--k-navy-800) 0,
        var(--k-navy-800) 36%,
        rgba(15, 29, 46, .93) 44%,
        rgba(15, 29, 46, .72) 52%,
        rgba(15, 29, 46, .40) 62%,
        rgba(15, 29, 46, .14) 72%,
        rgba(15, 29, 46, 0) 82%),
      linear-gradient(to bottom,
        rgba(15, 29, 46, .55) 0,
        rgba(15, 29, 46, 0) 14%),
      linear-gradient(to bottom,
        rgba(15, 29, 46, 0) 60%,
        rgba(15, 29, 46, .5) 84%,
        var(--k-navy-800) 100%),
      linear-gradient(rgba(15, 29, 46, .18), rgba(15, 29, 46, .18));
  }
  /* The photograph is absolute at this width, so the second column has no
     occupant and only squeezes the text. hero__body owns the measure. */
  .hero__inner { position: relative; z-index: 2; width: 100%; grid-template-columns: minmax(0, 1fr); }
  /* Keep the words clear of the point where the fade is still translucent. */
  .hero__body { max-width: 32rem; }
}

@media (max-width: 900px) {
  /* One column, TEXT BEFORE IMAGE, and the photograph goes back to being a
     plain card: a faded image behind text on a narrow screen is exactly where
     contrast goes wrong. */
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: var(--space-9); }
  .hero__media {
    width: calc(100% - (2 * var(--gutter)));
    max-width: var(--container);
    margin: 0 auto clamp(3rem, 2rem + 5vw, 5.5rem);
    aspect-ratio: 16 / 10;
  }
  .hero__inner { padding-bottom: var(--space-9); }
}
@media (max-width: 560px) {
  .hero__actions .btn { width: 100%; }
}

/* Compact page hero for interior pages */
.page-hero {
  background: var(--color-surface-inverse);
  color: var(--color-text-inverse);
  padding-block: clamp(2.5rem, 2rem + 4vw, 4.5rem);
}
.page-hero h1 { color: var(--k-white); }
.page-hero p { color: var(--color-text-inverse-secondary); }

/* ============================================================
   BREADCRUMB
   ============================================================ */
.breadcrumb { font-size: var(--text-small); margin-bottom: var(--space-5); }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--space-3); list-style: none; padding: 0; }
.breadcrumb a { color: rgba(255, 255, 255, .7); text-decoration: none; }
.breadcrumb a:hover { color: var(--k-white); text-decoration: underline; }
.breadcrumb li::after { content: "/"; margin-left: var(--space-3); color: rgba(255, 255, 255, .35); }
.breadcrumb li:last-child::after { content: none; }
.breadcrumb [aria-current="page"] { color: rgba(255, 255, 255, .5); }

/* ============================================================
   CARDS
   ============================================================ */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-7);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--dur-micro) var(--ease),
              transform var(--dur-micro) var(--ease),
              border-color var(--dur-micro) var(--ease);
}
.card--inverse {
  background: var(--color-surface-inverse-alt);
  border-color: var(--color-border-inverse);
  color: var(--color-text-inverse);
}

/* Whole-card link */
.card--link { position: relative; padding: 0; overflow: hidden; }
.card--link:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--color-border-strong); }
.card--link:focus-within { box-shadow: var(--focus-ring); }
.card__stretch::after { content: ""; position: absolute; inset: 0; }
.card__stretch { text-decoration: none; color: var(--color-text); }
.card--link:hover .card__stretch { color: var(--color-action-text); }
/* The outline is suppressed on the stretched link only because the parent
   card already paints the focus ring via :focus-within. Removing that
   parent rule would leave this element with no visible focus at all. */
.card__stretch:focus-visible { outline: none; }

/* Service card */
.service-card__body { padding: var(--space-6); display: flex; gap: var(--space-5); align-items: flex-start; }
.service-card__body h3 { font-size: 1.0625rem; margin-bottom: var(--space-2); }
.service-card__body p { font-size: var(--text-small); color: var(--color-text-secondary); line-height: var(--lh-base); }

/* Icon badge */
.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px; height: 48px;
  flex: none;
  border-radius: var(--radius-full);
  background: var(--color-action-subtle);
  color: var(--color-action-text);
}
.icon-badge--sm { width: 40px; height: 40px; }
.on-dark .icon-badge, .section--navy .icon-badge, .card--inverse .icon-badge,
.hero .icon-badge, .page-hero .icon-badge {
  background: rgba(23, 178, 106, .16);
  color: var(--k-emerald-500);
}

/* Benefit card */
.benefit { text-align: left; }
.benefit h3 { font-size: 1.0625rem; margin: var(--space-5) 0 var(--space-3); }
.benefit p { font-size: var(--text-small); color: var(--color-text-secondary); line-height: var(--lh-base); }

/* ============================================================
   TRUST STRIP
   ============================================================ */
.trust-strip {
  position: relative;
  margin-top: calc(var(--space-10) * -1);
  z-index: 2;
}
.trust-strip__inner {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  overflow: hidden;
}
.trust-strip__item {
  display: flex;
  gap: var(--space-5);
  align-items: flex-start;
  padding: var(--space-7);
  border-right: 1px solid var(--color-border);
}
.trust-strip__item:last-child { border-right: none; }
.trust-strip__item h3 { font-size: 1rem; margin-bottom: var(--space-2); }
.trust-strip__item p { font-size: var(--text-small); color: var(--color-text-secondary); line-height: var(--lh-base); }

@media (max-width: 900px) {
  .trust-strip { margin-top: var(--space-9); }
  .trust-strip__inner { grid-template-columns: minmax(0, 1fr); }
  .trust-strip__item { border-right: none; border-bottom: 1px solid var(--color-border); }
  .trust-strip__item:last-child { border-bottom: none; }
}

/* ============================================================
   STEPS (How It Works)
   ============================================================ */
.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-7);
  counter-reset: step;
}
.step { position: relative; text-align: center; }
.step__icon { margin-inline: auto; }
.step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: var(--radius-full);
  background: var(--color-action);
  color: var(--color-action-label);
  font-size: 0.8125rem;
  font-weight: var(--fw-bold);
  margin-right: var(--space-3);
  margin-top: 2px;
  flex: none;
}
.step h3 {
  font-size: 1.0625rem;
  margin: var(--space-6) 0 var(--space-3);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  text-align: left;
  min-height: 2.7em;
}
.step p { font-size: var(--text-small); color: var(--color-text-secondary); line-height: var(--lh-base); margin-inline: auto; }

/* Connector line between steps on desktop */
.steps--connected .step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 24px;
  left: calc(50% + 34px);
  /* The 34px clears the icon badge; subtracting the grid gap corrects for
     column centres being one gap further apart than 50% of a column implies.
     Without it every dash stops a gap short of the next badge. */
  right: calc(-50% + 34px - var(--space-7));
  border-top: 2px dashed var(--color-border-strong);
}

@media (max-width: 900px) {
  /* Horizontal timeline becomes vertical; step numbers stay visible */
  .steps { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
  .step { text-align: left; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--space-6); }
  .step__icon { grid-row: span 2; margin-inline: 0; }
  .step h3 { justify-content: flex-start; margin-top: 0; }
  .step p { margin-inline: 0; }
  .steps--connected .step:not(:last-child)::after { content: none; }
}

/* ============================================================
   ACCORDION (FAQ)
   ============================================================ */
.accordion { border: 1px solid var(--color-border); border-radius: var(--radius-md); background: var(--color-surface); overflow: hidden; }
.accordion + .accordion { margin-top: var(--space-4); }
.accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  width: 100%;
  min-height: 56px;
  padding: var(--space-5) var(--space-6);
  text-align: left;
  font-weight: var(--fw-semibold);
  font-size: var(--text-body);
  color: var(--color-text);
}
.accordion__trigger:hover { background: var(--color-surface-inset); }
.accordion__trigger:focus-visible { outline: none; box-shadow: inset var(--focus-ring); }
.accordion__icon { flex: none; transition: transform var(--dur-micro) var(--ease); color: var(--color-action-text); }
.accordion__trigger[aria-expanded="true"] .accordion__icon { transform: rotate(45deg); }
.accordion__panel { padding: 0 var(--space-6) var(--space-6); }
.accordion__panel p { font-size: var(--text-small); color: var(--color-text-secondary); }
.accordion__panel[hidden] { display: none; }

/* ============================================================
   FORM CONTROLS
   ============================================================ */
.field {
  /* A flex column with the control pushed to the bottom, so that two fields
     sitting side by side in a grid keep their inputs on the same line even
     when one has a two-line hint and the other has none. */
  display: flex;
  flex-direction: column;
  margin-bottom: var(--space-7);
}
.field > .input,
.field > .textarea,
.field > .select { margin-top: auto; }
.field__label {
  display: block;
  font-size: var(--text-small);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  margin-bottom: var(--space-3);
}
.field__required { color: var(--color-error); margin-left: 2px; }
/* "Optional" reads as guidance, not as an error, so it is muted and small
   rather than picking up the red of the required marker. */
.field__optional {
  color: var(--color-text-muted);
  font-weight: 400;
  font-size: var(--text-small);
  margin-left: var(--space-2);
}
.field__hint {
  display: block;
  font-size: var(--text-small);
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
  line-height: var(--lh-base);
}

.input, .textarea, .select {
  width: 100%;
  min-height: var(--control-h-md);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface);
  border: 1.5px solid var(--color-border-control);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-xs);
  color: var(--color-text);
  transition: border-color var(--dur-micro) var(--ease), box-shadow var(--dur-micro) var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--color-text-muted); }
.input:hover, .textarea:hover, .select:hover { border-color: var(--k-slate-400); }
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--color-action);
  box-shadow: var(--focus-ring);
}
.textarea { min-height: 132px; resize: vertical; line-height: var(--lh-base); padding-block: var(--space-4); }

.select {
  appearance: none;
  padding-right: var(--space-10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23475467' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-5) center;
}

.input:disabled, .textarea:disabled, .select:disabled {
  background: var(--color-surface-inset);
  color: var(--color-text-muted);
  cursor: not-allowed;
  border-color: var(--color-border);
}

/* Error state: border, icon and message, never colour alone */
.field[data-invalid="true"] .input,
.field[data-invalid="true"] .textarea,
.field[data-invalid="true"] .select {
  border-color: var(--color-error-border);
  background: var(--color-error-bg);
}
.field[data-invalid="true"] .input:focus,
.field[data-invalid="true"] .textarea:focus,
.field[data-invalid="true"] .select:focus { box-shadow: var(--focus-ring), 0 0 0 3px rgba(180, 35, 24, .25); }
.field__error {
  display: none;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
  font-size: var(--text-small);
  font-weight: var(--fw-medium);
  color: var(--color-error);
}
.field[data-invalid="true"] .field__error { display: flex; }

.field__counter { display: block; margin-top: var(--space-3); font-size: var(--text-small); color: var(--color-text-muted); }
.field__counter[data-under="true"] { color: var(--color-warning); font-weight: var(--fw-semibold); }

/* Checkbox */
.checkbox { display: flex; gap: var(--space-4); align-items: flex-start; cursor: pointer; padding: var(--space-2) 0; }
.checkbox input[type="checkbox"] {
  appearance: none;
  width: 20px; height: 20px;
  flex: none;
  margin-top: 2px;
  border: 1.5px solid var(--color-border-control);
  border-radius: 5px;
  background: var(--color-surface);
  cursor: pointer;
  transition: background var(--dur-micro) var(--ease), border-color var(--dur-micro) var(--ease);
}
.checkbox input[type="checkbox"]:checked {
  background: var(--color-action) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center no-repeat;
  border-color: var(--color-action);
}
.checkbox input[type="checkbox"]:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.checkbox__label { font-size: var(--text-small); line-height: var(--lh-base); color: var(--color-text-secondary); }

/* Choice card: whole card clickable, selection never by colour alone */
.choice-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5); }
@media (max-width: 900px) { .choice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .choice-grid { grid-template-columns: minmax(0, 1fr); } }

.choice {
  position: relative;
  display: block;
  border: 1.5px solid var(--color-border-control);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
  cursor: pointer;
  transition: border-color var(--dur-micro) var(--ease),
              box-shadow var(--dur-micro) var(--ease),
              transform var(--dur-micro) var(--ease);
}
.choice:hover { border-color: var(--k-slate-400); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.choice input { position: absolute; opacity: 0; pointer-events: none; }
.choice:has(input:focus-visible) { outline: none; box-shadow: var(--focus-ring); }
/* display:block is load-bearing. This is a <span>, and aspect-ratio has no
   effect on a non-replaced inline element, so without it the media box takes
   its height from the photograph and pushes the label out of the card. */
.choice__media { display: block; aspect-ratio: 16 / 10; background: var(--k-grey-100); overflow: hidden; }
.choice__media picture { display: block; width: 100%; height: 100%; }
.choice__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* A slow, subtle push in on hover. The card already lifts; this stops the
   photograph feeling pinned while the card moves. */
.choice__media--photo img { transition: transform 400ms var(--ease); }
.choice:hover .choice__media--photo img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .choice:hover .choice__media--photo img { transform: none; }
}
.choice__body {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  font-weight: var(--fw-semibold);
  font-size: var(--text-small);
}
.choice__tick {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px; height: 24px;
  flex: none;
  border-radius: var(--radius-full);
  border: 1.5px solid var(--color-border-control);
  color: transparent;
  transition: all var(--dur-micro) var(--ease);
}
.choice:has(input:checked) { border-color: var(--color-action); border-width: 2.5px; box-shadow: var(--shadow-md); }
.choice:has(input:checked) .choice__tick {
  background: var(--color-action);
  border-color: var(--color-action);
  color: var(--k-white);
}

/* File uploader */
.uploader {
  border: 2px dashed var(--color-border-control);
  border-radius: var(--radius-lg);
  background: var(--color-surface-inset);
  padding: var(--space-11) var(--space-7);
  text-align: center;
  transition: border-color var(--dur-micro) var(--ease), background var(--dur-micro) var(--ease);
}
.uploader[data-dragover="true"] { border-color: var(--color-action); background: var(--color-action-subtle); }
.uploader h3 { font-size: 1.0625rem; margin-bottom: var(--space-3); }
.uploader p { font-size: var(--text-small); color: var(--color-text-secondary); margin-inline: auto; }
.uploader__browse { margin-top: var(--space-6); }

.file-list { list-style: none; padding: 0; margin-top: var(--space-6); display: grid; gap: var(--space-4); }
.file-item {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.file-item__name { font-size: var(--text-small); font-weight: var(--fw-semibold); }
.file-item__meta { font-size: var(--text-small); color: var(--color-text-muted); }
.file-item[data-state="error"] { border-color: var(--color-error-border); background: var(--color-error-bg); }
.file-item[data-state="error"] .file-item__meta { color: var(--color-error); }
.progress-bar { height: 6px; border-radius: var(--radius-full); background: var(--k-grey-200); overflow: hidden; margin-top: var(--space-3); }
.progress-bar__fill { height: 100%; background: var(--color-action); border-radius: var(--radius-full); transition: width var(--dur-panel) var(--ease); }

/* ============================================================
   ALERTS
   ============================================================ */
.alert {
  display: flex;
  gap: var(--space-5);
  align-items: flex-start;
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: var(--text-small);
  line-height: var(--lh-base);
}
.alert h4 { font-size: var(--text-small); margin-bottom: var(--space-2); }
.alert p { max-width: none; }
.alert__icon { flex: none; margin-top: 1px; }
.alert--success { background: var(--color-success-bg); border-color: var(--k-emerald-100); color: var(--color-action-text-tint); }
.alert--info    { background: var(--color-info-bg);    border-color: var(--color-info-border);             color: var(--color-info); }
.alert--warning { background: var(--color-warning-bg); border-color: var(--color-warning-border);             color: var(--color-warning); }
.alert--error   { background: var(--color-error-bg);   border-color: var(--color-error-border); color: var(--color-error); }
.alert h4 { color: inherit; }

/* ============================================================
   PROGRESS (journey steps)
   ============================================================ */
.progress { padding-block: var(--space-6); }
.progress__steps { display: flex; align-items: center; gap: var(--space-2); list-style: none; padding: 0; }
.progress__step { flex: 1; display: flex; flex-direction: column; align-items: center; gap: var(--space-3); min-width: 0; }
.progress__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: var(--radius-full);
  background: var(--k-grey-200);
  color: var(--k-slate-500);
  font-size: 0.8125rem;
  font-weight: var(--fw-bold);
  flex: none;
}
.progress__label {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.progress__step[data-state="current"] .progress__dot { background: var(--color-action); color: var(--color-action-label); }
.progress__step[data-state="current"] .progress__label { color: var(--color-text); font-weight: var(--fw-bold); }
.progress__step[data-state="done"] .progress__dot { background: var(--k-emerald-100); color: var(--color-action-text-tint); }
.progress__step[data-state="done"] .progress__label { color: var(--color-text-secondary); }
@media (max-width: 767px) { .progress__label { display: none; } }

/* ============================================================
   STATUS PILLS (admin): label + colour, never colour alone
   ============================================================ */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: 3px var(--space-4);
  border-radius: var(--radius-full);
  font-size: 0.75rem;
  font-weight: var(--fw-bold);
  border: 1px solid;
  white-space: nowrap;
}
.pill--new     { background: var(--color-info-bg);    border-color: var(--color-info-border);                   color: var(--color-info); }
.pill--review  { background: var(--color-warning-bg); border-color: var(--color-warning-border);                   color: var(--color-warning); }
.pill--ready   { background: var(--color-success-bg); border-color: var(--k-emerald-100);      color: var(--color-action-text-tint); }
.pill--closed  { background: var(--color-surface-inset); border-color: var(--color-border);    color: var(--color-text-secondary); }

/* ============================================================
   TABLES
   ============================================================ */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
/* Given tabindex="0" in the markup so it can be scrolled by keyboard. */
.table-wrap:focus-visible { box-shadow: var(--focus-ring); }
.table { font-size: var(--text-small); min-width: 560px; }
.table th, .table td { padding: var(--space-5) var(--space-6); text-align: left; vertical-align: top; }
.table thead th { background: var(--color-surface-inset); font-weight: var(--fw-bold); border-bottom: 1px solid var(--color-border); white-space: nowrap; }
.table tbody tr + tr td { border-top: 1px solid var(--color-border); }

/* ============================================================
   CTA BANDS
   ============================================================ */
.cta-band {
  background: var(--color-surface-inverse);
  color: var(--color-text-inverse);
  border-radius: var(--radius-xl);
  padding: clamp(2rem, 1.5rem + 3vw, 3.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) auto;
  gap: var(--space-9);
  align-items: center;
}
.cta-band h2 { color: var(--k-white); }
.cta-band p { color: var(--color-text-inverse-secondary); }
@media (max-width: 767px) {
  .cta-band { grid-template-columns: minmax(0, 1fr); }
  .cta-band .btn { width: 100%; }
}

.final-cta { text-align: center; }
.final-cta p { margin-inline: auto; }
.final-cta .cluster { justify-content: center; margin-top: var(--space-8); }
@media (max-width: 560px) { .final-cta .cluster .btn { width: 100%; } }

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer {
  background: var(--k-navy-900);
  color: var(--color-text-inverse-secondary);
  padding-block: var(--space-12) var(--space-8);
  font-size: var(--text-small);
}
.site-footer__grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(4, 1fr);
  gap: var(--space-9);
  padding-bottom: var(--space-10);
  border-bottom: 1px solid var(--color-border-inverse);
}
@media (max-width: 1023px) { .site-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .site-footer__grid { grid-template-columns: minmax(0, 1fr); } }

.site-footer h2 {
  font-size: 0.75rem;
  font-weight: var(--fw-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--k-white);
  margin-bottom: var(--space-5);
}
.site-footer ul { list-style: none; padding: 0; display: grid; gap: var(--space-1); }
/* Footer links are the smallest touch targets on the site. Padding lifts each
   one to a comfortable 40px without changing how the footer looks, since the
   list gap shrinks by the same amount. */
.site-footer li a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding-block: var(--space-2);
}
.site-footer a { color: var(--color-text-inverse-secondary); text-decoration: none; }
.site-footer a:hover { color: var(--k-white); text-decoration: underline; }
.site-footer p { color: var(--color-text-inverse-secondary); }

.social { display: flex; gap: var(--space-4); margin-top: var(--space-7); }
.social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-inverse);
  color: var(--color-text-inverse-secondary);
}
.social a:hover { background: var(--color-surface-inverse-alt); color: var(--k-white); }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-8);
  justify-content: space-between;
  align-items: center;
  padding-top: var(--space-7);
  font-size: 0.8125rem;
}

/* ============================================================
   COOKIE BANNER: Reject and Accept equally accessible
   ============================================================ */
.cookie-banner {
  position: fixed;
  left: var(--gutter);
  right: var(--gutter);
  bottom: var(--gutter);
  z-index: var(--z-toast);
  max-width: 900px;
  margin-inline: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: var(--space-7);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-7);
  align-items: center;
}
.cookie-banner p { font-size: var(--text-small); }
.cookie-banner .cluster .btn { flex: 1; }
@media (max-width: 767px) {
  .cookie-banner { grid-template-columns: minmax(0, 1fr); }
  .cookie-banner .cluster .btn { width: 100%; }
}

/* ============================================================
   JOURNEY LAYOUT
   ============================================================ */
.journey { background: var(--color-bg); min-height: 70vh; padding-block: var(--space-9) var(--space-12); }
.journey__layout {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: var(--space-9);
  align-items: start;
}
@media (max-width: 900px) {
  .journey__layout { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
}
.journey__panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: clamp(1.5rem, 1rem + 2.5vw, 2.5rem);
}
.journey__actions {
  display: flex;
  justify-content: space-between;
  gap: var(--space-5);
  margin-top: var(--space-9);
  padding-top: var(--space-7);
  border-top: 1px solid var(--color-border);
}
@media (max-width: 560px) {
  /* Was column-reverse, which painted Continue above Back while the DOM order
     stayed Back then Continue, so Tab moved up the screen instead of down.
     Reorder visually and leave the focus order matching what is seen. */
  .journey__actions { flex-direction: column; }
  .journey__actions [data-next],
  .journey__actions [data-submit],
  .journey__actions [data-continue] { order: -1; }
  .journey__actions .btn { width: 100%; }
}

.reassure {
  display: flex;
  gap: var(--space-5);
  align-items: flex-start;
  padding: var(--space-6);
  background: var(--color-surface-inset);
  border-radius: var(--radius-md);
  font-size: var(--text-small);
  color: var(--color-text-secondary);
  line-height: var(--lh-base);
}

/* ============================================================
   DESIGN SYSTEM REFERENCE PAGE ONLY
   ============================================================ */
.ds-nav {
  position: sticky;
  top: 76px;
  z-index: 10;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding-block: var(--space-4);
}
.ds-nav ul { display: flex; flex-wrap: wrap; gap: var(--space-3); list-style: none; padding: 0; }
.ds-nav a {
  display: inline-block;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-full);
  background: var(--color-surface-inset);
  color: var(--color-text-secondary);
  font-size: var(--text-small);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}
.ds-nav a:hover { background: var(--color-action-subtle); color: var(--color-action-text); }

.ds-block { padding-block: var(--space-10); border-top: 1px solid var(--color-border); }
.ds-block > h2 { margin-bottom: var(--space-3); }
.ds-block > .lead { margin-bottom: var(--space-9); }
.ds-label {
  font-size: 0.75rem;
  font-weight: var(--fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-5);
}
.ds-row { display: flex; flex-wrap: wrap; gap: var(--space-5); align-items: center; margin-bottom: var(--space-8); }
.ds-panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  margin-bottom: var(--space-8);
}
.ds-panel--navy { background: var(--color-surface-inverse); border-color: var(--color-border-inverse); }

.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: var(--space-5); }
.swatch { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; background: var(--color-surface); }
.swatch__chip { height: 76px; }
.swatch__meta { padding: var(--space-4) var(--space-5); }
.swatch__name { font-size: var(--text-small); font-weight: var(--fw-bold); }
.swatch__hex { font-size: 0.75rem; color: var(--color-text-muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.type-spec { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-5); padding-block: var(--space-5); border-bottom: 1px solid var(--color-border); }
.type-spec__meta { font-size: 0.75rem; color: var(--color-text-muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; margin-left: auto; white-space: nowrap; }



/* ============================================================
   ILLUSTRATIONS
   Bespoke SVG scenes from src/partials/illustrations.html.
   These are brand artwork, not photography, and never pretend
   to be a photograph of a partner's completed work.
   ============================================================ */
.illus {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--k-navy-800);
  line-height: 0;
}
.illus svg {
  display: block;
  width: 100%;
  height: auto;
  /* The scenes are composed with breathing room. A small scale-up lets them
     fill the frame without cropping, because the artwork's own background
     rectangle scales with it and no gap can appear at the edges. */
  transform: scale(1.06);
  transform-origin: center;
}

.illus--hero { box-shadow: var(--shadow-xl); }

/* Inside a card, the illustration is the media band, so it follows
   the card's own corner radius rather than carrying its own. */
.illus--card {
  border-radius: 0;
  aspect-ratio: 16 / 10;
}
.illus--card svg { width: 100%; height: 100%; object-fit: cover; }

.illus--tile {
  border-radius: var(--radius-lg);
  aspect-ratio: 4 / 3;
}
.illus--tile svg { width: 100%; height: 100%; object-fit: cover; }

/* Photography in the same slots. The SVG rules above do not apply to a
   <picture>, so the frame has to be re-established for it. No scale-up
   here: that trick existed to hide the artwork's own edges, and cropping
   a real photograph by 6 percent for no reason would only lose detail. */
.illus > picture { display: block; width: 100%; line-height: 0; }
.illus > picture > img { display: block; width: 100%; height: auto; }

/* Inside a fixed-aspect slot the photo fills and crops from the centre. */
.illus--card > picture,
.illus--tile > picture { height: 100%; }
.illus--card > picture > img,
.illus--tile > picture > img { height: 100%; object-fit: cover; }

/* A caption sitting over the artwork, for the honest photography note. */

/* ============================================================
   SCROLL REVEAL
   Enhancement only. Without JavaScript, or with reduced motion,
   everything is visible and static.
   ============================================================ */
[data-reveal] {
  opacity: 1;
  transform: none;
}
.js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============================================================
   STAGGERED REVEAL
   When a reveal target is a grid, its children arrive in sequence
   rather than the block arriving as one slab. The container itself
   is never hidden, so nothing is withheld if the sequence fails.
   The transition is removed once finished, which hands the cards
   back their stock hover lift.
   ============================================================ */
.js [data-reveal][data-stagger] { opacity: 1; transform: none; }

.js [data-reveal][data-stagger]:not(.is-done) > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 420ms var(--ease-out), transform 420ms var(--ease-out);
  transition-delay: var(--stagger-delay, 0ms);
}
.js [data-reveal][data-stagger].is-revealed > * {
  opacity: 1;
  transform: none;
}
.js [data-reveal][data-stagger].is-done > * { transition: none; }

/* ============================================================
   SCROLL-DRAWN PROCESS LINE
   An emerald fill laid exactly over the dashed connector in
   .steps--connected, plus activation on each numbered dot.
   Purely decorative: with no JavaScript the fill stays at
   scaleX(0) and the stock dashed connector carries on alone,
   so the process is never dependent on motion to be legible.
   ============================================================ */
.steps--connected { position: relative; }

.steps__line {
  position: absolute;
  /* Matches .steps--connected .step::after: first and last column
     centres, inset by the 34px badge gap. The 25px is 34px minus the
     9px by which true column centres sit inside 12.5%, from the gaps. */
  top: 24px;
  left: calc(12.5% + 25px);
  right: calc(12.5% + 25px);
  height: 2px;
  border-radius: var(--radius-full);
  pointer-events: none;
}
.steps__fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: var(--k-emerald-500);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform;
}
/* The fill passes behind the icon badges, exactly as the dashes do. */
.steps--connected .step__icon { position: relative; z-index: 1; }

/* Numbered dots stay neutral until the line reaches them. The emerald
   layer is a pseudo-element animated on opacity only, so the digit
   stays white and passes contrast against both fills. */
.js .steps--connected .step__num {
  position: relative;
  isolation: isolate;
  background: var(--k-slate-500);
}
.js .steps--connected .step__num::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-full);
  background: var(--color-action);
  opacity: 0;
  z-index: -1;
  transition: opacity 200ms var(--ease);
}
.js .steps--connected .step__num.is-active::after { opacity: 1; }

@media (max-width: 900px) {
  /* The connector is not drawn on the stacked layout, so nor is the fill.
     Dot activation still runs, which suits the vertical rhythm. */
  .steps__line { display: none; }
}

/* ============================================================
   READING PROGRESS
   Only added by the script, and only on pages long enough to
   warrant it. Fixed above the sticky header, transform-scaled
   so it can never cause layout shift.
   ============================================================ */
.read-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: calc(var(--z-header) + 1);
  pointer-events: none;
  background: transparent;
}
.read-progress__fill {
  display: block;
  height: 100%;
  background: var(--k-emerald-500);
  transform: scaleX(0);
  transform-origin: 0 50%;
  will-change: transform;
}

/* ============================================================
   Reduced motion switches all three off and leaves everything
   visible. The script bails too; this is belt and braces for a
   preference changed mid-session.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal][data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .steps__line,
  .read-progress { display: none !important; }
  .js .steps--connected .step__num { background: var(--color-action); }
  .js .steps--connected .step__num::after { opacity: 0 !important; }
}


/* ============================================================
   LEGAL PAGES
   Long-form prose. base.css strips list styling and margins from
   everything, so these pages need their own typography rather than
   inheriting the marketing-page rhythm.
   ============================================================ */
.legal { max-width: 68ch; }
.legal h2 {
  font-size: var(--text-h3);
  margin-top: var(--space-11);
  margin-bottom: var(--space-5);
  scroll-margin-top: 96px;
}
.legal h2:first-child { margin-top: 0; }
.legal h3 {
  font-size: var(--text-h4);
  margin-top: var(--space-8);
  margin-bottom: var(--space-4);
}
.legal p { margin-bottom: var(--space-5); line-height: var(--lh-loose); }
.legal ul, .legal ol { margin: 0 0 var(--space-5) var(--space-7); }
.legal li { margin-bottom: var(--space-3); line-height: var(--lh-loose); }
.legal ul { list-style: disc; }
.legal ol { list-style: decimal; }
.legal dl { margin-bottom: var(--space-5); }
.legal dt { font-weight: var(--fw-semibold); margin-top: var(--space-4); }
.legal dd { margin: 0 0 var(--space-3) 0; color: var(--color-text-secondary); }
.legal__updated {
  font-size: var(--text-small);
  color: var(--color-text-secondary);
  padding-bottom: var(--space-7);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-9);
}
.legal__toc { margin-bottom: var(--space-10); }
.legal__toc ul { list-style: none; margin-left: 0; }
.legal__toc li { margin-bottom: var(--space-2); }
