/* ==========================================================
   ht-acc / components.css
   Layer 2. Atoms and the internals of every component.
   No literal colour, font name or pixel value: everything
   reads from tokens.css.

   Section wrappers, their grids and the three breakpoint
   bands are in layout.css.
   ========================================================== */

/* ═ shared primitives ════════════════════════════════════ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  min-block-size: var(--control-lg);
  padding-inline: var(--sp-38);
  border-radius: var(--radius-pill);
  border: 0;
  font-size: var(--fs-btn);
  font-weight: var(--weight-medium);
  line-height: var(--lh-tight);
  white-space: nowrap;
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
}

.btn--solid   { background: var(--fill-accent-text); color: var(--text-on-accent); }
.btn--solid:hover { color: var(--text-on-accent); opacity: var(--hover-opacity); }
.btn--soft    { background: var(--fill-accent-soft); color: var(--text-primary); }
.btn--soft:hover  { color: var(--text-primary); opacity: var(--hover-opacity-soft); }

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  padding-inline: var(--sp-20);
  padding-block: var(--sp-8);
  border-radius: var(--radius-pill);
  border: var(--border-w) solid transparent;
  font-size: var(--fs-pill);
  font-weight: var(--weight-medium);
  line-height: var(--lh-tight);
  white-space: nowrap;
}

.pill--surface { background: var(--bg-card); color: var(--text-primary); }
.pill--soft    { background: var(--fill-accent-soft); color: var(--text-primary); }

.badge--accent {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--badge-md);
  block-size: var(--badge-md);
  border-radius: var(--radius-circle);
  background: var(--fill-accent);
  color: var(--text-on-accent);
  font-size: var(--fs-glyph-sm);
  line-height: var(--lh-solid);
}

.label        { font-size: var(--fs-body-sm); font-weight: var(--weight-medium); color: var(--text-primary); }
.label--muted { color: var(--text-secondary); font-weight: var(--weight-regular); }

.ds-eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: var(--type-eyebrow-transform);
  color: var(--text-secondary);
  line-height: var(--lh-tight);
}

.ds-h2 {
  font-size: var(--fs-h2);
  font-weight: var(--weight-heading);
  line-height: var(--lh-h2);
  letter-spacing: var(--track-tight);
  color: var(--text-primary);
}

.ds-body {
  font-size: var(--fs-body);
  font-weight: var(--weight-regular);
  line-height: var(--lh-body);
  color: var(--text-secondary);
  max-inline-size: var(--measure);
}

.ds-figure {
  font-size: var(--fs-figure);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: var(--text-primary);
}

/* ─ glyphs ──────────────────────────────────────────────────
   Arrows and stars are inline SVG, not characters. Google
   serves Plus Jakarta Sans in four subsets and none of them
   carries U+2190, U+2192, U+2605 or U+2606, so as text these
   fell through to whatever the visitor's system supplied and
   changed shape and weight from platform to platform. As SVG
   they take their colour from currentColor and their size from
   the token, so they are the same mark everywhere.
   ────────────────────────────────────────────────────────── */

.icon {
  inline-size: 1em;
  block-size: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--border-w-strong);
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: 0 0 auto;
}

.icon--star {
  inline-size: var(--fs-star);
  block-size: var(--fs-star);
  stroke-width: var(--border-w);
}

/* ═ header ═══════════════════════════════════════════════ */

.site-header {
  position: sticky;
  top: 0;
  inline-size: 100%;
  padding-block: var(--sp-24);
  background: var(--bg-page);
  border-end-start-radius: var(--radius);
  border-end-end-radius: var(--radius);
  z-index: var(--z-over);
  transition: background var(--dur-base) var(--ease),
              color var(--dur-base) var(--ease);
}

.site-header.is-stuck { background: var(--bg-panel); color: var(--text-inverse); }
.site-header.is-stuck .brand__word { color: var(--text-inverse); }
.site-header.is-stuck .brand__mark { background: var(--bg-page); color: var(--text-primary); }

/* max-inline-size lives in layout.css beside .ds-shell, which
   this element also carries. Declared here it loses: same
   specificity, later file. */
.site-header__inner {
  display: grid;
  grid-template-columns: var(--header-cols);
  align-items: center;
  gap: var(--sp-24);
  min-inline-size: 0;
}

.site-header__inner > * { min-inline-size: 0; }

.brand { display: flex; align-items: center; gap: var(--sp-12); }

.brand__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--brand-mark);
  block-size: var(--brand-mark);
  border-radius: var(--radius-sm);
  background: var(--fill-accent-text);
  color: var(--text-on-accent);
  font-size: var(--fs-h3);
  font-weight: var(--weight-bold);
  line-height: var(--lh-solid);
}

/* The brand column is auto width, so an over-budget wordmark
   would push into the nav rather than reflow. md/SPEC.md budgets
   FIRM_SHORT at 3 to 6 characters and every compliant fill clears
   the nav at every width; this is the guard for the ones that do
   not, and for the unfilled template, whose placeholder string is
   far longer than any real name. It truncates instead of
   colliding, and never fires on a name inside the budget. */
.brand__word {
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-h4);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-tight);
  color: var(--text-primary);
}

/* Plain text, no capsule. It was a grey pill with a solid accent
   pill inside it for the current page; both are gone and the
   links are type on the header's own background. The current
   page is now the accent colour plus the dot that was already in
   the markup for exactly that job. */
.navcap {
  display: flex;
  justify-self: end;
}

.navcap ul { display: flex; align-items: center; gap: var(--sp-4); }

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  min-block-size: var(--control-sm);
  padding-inline: var(--nav-link-pad);
  border-radius: var(--radius-pill);
  font-size: var(--fs-nav);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  white-space: nowrap;
}

.nav__link:hover { color: var(--text-primary); }
.nav__link.is-active,
.nav__link.is-active:hover { color: var(--text-accent); }

/* On the stuck header the links have no capsule under them any
   more, so they read straight off the ink field and need the
   inverse steps. --text-secondary on ink is about 3:1 and is not
   enough for text. */
.site-header.is-stuck .nav__link             { color: var(--text-inverse-soft); }
.site-header.is-stuck .nav__link:hover       { color: var(--text-inverse); }
.site-header.is-stuck .nav__link.is-active,
.site-header.is-stuck .nav__link.is-active:hover { color: var(--text-inverse); }

.nav__dot {
  inline-size: var(--sp-8);
  block-size: var(--sp-8);
  border-radius: var(--radius-circle);
  background: var(--fill-accent);
}

.header__end { display: flex; align-items: center; justify-content: flex-end; gap: var(--sp-16); }

/* ─ hamburger and drawer ────────────────────────────────────
   Everything below 1100, phone and tablet both. The source was
   one page with in-page anchors and hid the capsule below 760
   with nothing in its place, which is survivable on one page and
   not on a site with more than one.

   Sized to --control-lg so the header keeps exactly the height
   it has in the source at every width.
   ────────────────────────────────────────────────────────── */

.nav-hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  inline-size: var(--control-lg);
  block-size: var(--control-lg);
  border-radius: var(--radius-circle);
  background: var(--fill-accent-text);
  color: var(--text-on-accent);
  cursor: pointer;
}

/* One colour in every state: on the light header, on the stuck
   dark header, and on the drawer panel with the drawer open. It
   is the same fill and the same label colour as the solid button
   it replaces below 1100, so the header keeps one accent control
   at every width rather than swapping a grey disc in for a blue
   button. There is no background transition any more because
   there is nothing left for it to cross. */

/* While the drawer is open the header rides above it, so the
   hamburger stays visible, keeps showing its own open state and
   can be pressed again to close. The drawer panel already leaves
   a header's height of padding at the top for exactly this, and
   without the raise the panel covered the button: the only ways
   out were Escape and a scrim tap, and the close animation played
   underneath the panel where nobody could see it.

   The background goes transparent because what sits behind the
   header is now the dark panel, and the brand and the button
   invert for the same reason. Declared after the is-stuck rules
   so it wins at equal specificity when both are on. */
/* The scroll lock. On the root rather than the body, because
   overflow on body makes it a scroll container and the sticky
   header then resolves against that instead of the viewport and
   leaves the screen entirely. base.css carries the same warning
   about overflow-x for the same reason. */
.nav-open {
  overflow-y: hidden;
}

.nav-open .site-header {
  z-index: var(--z-panel-top);
  background: transparent;
  color: var(--text-inverse);
}

.nav-open .site-header .brand__word   { color: var(--text-inverse); }
.nav-open .site-header .brand__mark   { background: var(--bg-page); color: var(--text-primary); }

/* Two phases that overlap. Opening, the bars start crossing and
   the set begins its quarter turn 80ms later, while they are
   still moving, so the two read as one motion rather than as two
   steps. Closing runs it backwards: the set turns back first and
   the bars uncross out of it.

   The delay moves between the two rules rather than sitting on
   one, because a transition uses the delay declared on the state
   it is moving to. Putting it on the open rule for the set and on
   the closed rule for the bars gets both directions from one pair
   of declarations, which is why the bars carry the delay in their
   base rule and 0s when expanded.

   The end state is the ordinary close cross, because a bar at
   45deg turned 90 is a bar at 135 and the X is the same X. Only
   the way it arrives is new, which is the point: the icon stays
   the one people recognise. */
.nav-hamburger__bars {
  display: block;
  transition: transform var(--dur-burger) var(--ease-burger);
}

.nav-hamburger[aria-expanded="true"] .nav-hamburger__bars {
  transform: rotate(var(--hamburger-turn));
  transition-delay: var(--delay-burger);
}

.nav-hamburger__bars span {
  display: block;
  inline-size: var(--hamburger-w);
  block-size: var(--hamburger-bar);
  border-radius: var(--radius-pill);
  background: currentColor;
  transition: transform var(--dur-burger) var(--ease-burger),
              opacity   var(--dur-fast)   var(--ease-burger);
  transition-delay: var(--delay-burger);
}

.nav-hamburger__bars span + span { margin-block-start: var(--hamburger-gap); }

.nav-hamburger[aria-expanded="true"] .nav-hamburger__bars span { transition-delay: 0s; }

.nav-hamburger[aria-expanded="true"] .nav-hamburger__bars span:nth-child(1) {
  transform: translateY(var(--hamburger-shift)) rotate(45deg);
}

.nav-hamburger[aria-expanded="true"] .nav-hamburger__bars span:nth-child(2) {
  opacity: 0;
  transform: scaleX(0);
}

.nav-hamburger[aria-expanded="true"] .nav-hamburger__bars span:nth-child(3) {
  transform: translateY(calc(var(--hamburger-shift) * -1)) rotate(-45deg);
}

.nav-drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-panel);
  display: none;
  background: var(--scrim);
}

.nav-drawer.is-open { display: block; }

.nav-drawer__panel {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  padding: var(--drawer-pad);
  /* Inline padding follows the header, so the drawer's links
     start on the same line as the brand above them. Block padding
     keeps --drawer-pad, because the top value is a clearance:
     --control-lg plus two of it is the header's height, and the
     first link has to sit below the header rather than under it. */
  padding-inline: var(--header-gutter);
  padding-block-start: calc(var(--control-lg) + var(--drawer-pad) * 2);
  background: var(--bg-panel);
  color: var(--text-inverse);
  border-end-start-radius: var(--radius);
  border-end-end-radius: var(--radius);
}

.nav-drawer__list { display: flex; flex-direction: column; gap: var(--drawer-gap); }

.nav-drawer__list a {
  display: flex;
  align-items: center;
  min-block-size: var(--tap-min);
  font-size: var(--drawer-link-size);
  font-weight: var(--weight-medium);
  color: var(--text-inverse);
}

.nav-drawer__list a:hover { color: var(--accent-soft); }
.nav-drawer__list a[aria-current="page"] { color: var(--accent-soft); }

/* ─ sticky call ─────────────────────────────────────────────
   The kit's sticky-action, as a call button. It was omitted on
   this build while the header carried Contact at every width;
   once the drawer took the header's button below 1100 the phone
   band had no visible way to call without opening the drawer or
   scrolling to the footer, and this is that way back.

   Phone band only, and deliberately so: it is a tel: link and a
   tablet cannot place the call. Nothing here needs script.

   The bar is the ink field, so its hairline is the ink one and
   its button takes the inverted wipe in effects.css. A --rule
   hairline here would be a bright line on black, and the
   ordinary ink wipe would make the button vanish into the bar.
   ────────────────────────────────────────────────────────── */

.sticky-call {
  display: none;
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--z-top);
  padding: var(--sticky-pad);
  /* Inline padding follows the header, like the drawer's, so the
     button's edges line up with the brand above it. Block padding
     stays --sticky-pad, because --sticky-h is derived from it and
     the body padding that clears the bar has to match. */
  padding-inline: var(--header-gutter);
  padding-block-end: calc(var(--sticky-pad) + env(safe-area-inset-bottom, 0px));
  background: var(--bg-panel);
  border-block-start: var(--border) solid var(--border-hairline);
}

.sticky-call__link { inline-size: 100%; }

/* One span, not two children: FX/WIPE raises .btn > span above the
   wipe layer, so the icon has to sit inside it or the wipe paints
   over the glyph on hover. */
.sticky-call__link > span {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
}

/* ═ hero ═════════════════════════════════════════════════ */

.hero__deco {
  position: absolute;
  inset: 0 0 calc(var(--step-h) * -1) 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  pointer-events: none;
  z-index: var(--z-base);
}

/* ─ the hero field ─────────────────────────────────────────
   Ruled lines with four figures along them. Decoration only:
   the hero reads identically with this block deleted, which is
   why it carries no content and is hidden from the
   accessibility tree.

   The rules are one repeating gradient rather than N elements,
   so the field has no element count to manage as it narrows.
   The mask is what keeps them off the headline. */

.deco-ledger {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.deco-ledger__field {
  position: absolute;
  inset-block: var(--sp-44);
  inset-inline-end: 0;
  inline-size: var(--ledger-w);
  background: repeating-linear-gradient(to bottom,
      var(--hero-rule) 0 var(--border),
      transparent var(--border) var(--ledger-pitch));
  -webkit-mask-image: var(--ledger-mask);
          mask-image: var(--ledger-mask);
}

/* <i> rather than <div>, so nth-of-type counts only the figures. As
   divs they shared a type with the field above, which sits first, and
   every figure silently took the next one's width while the fourth
   got none at all. */
.deco-ledger__figure {
  position: absolute;
  inset-inline-end: var(--ledger-inset);
  block-size: var(--ledger-bar-h);
  border-radius: var(--radius-xs);
  background: var(--hero-figure);
}

.deco-ledger__figure:nth-of-type(1) { inset-block-start: calc(var(--ledger-pitch) * 3  + var(--sp-44)); inline-size: var(--ledger-fig-1); }
.deco-ledger__figure:nth-of-type(2) { inset-block-start: calc(var(--ledger-pitch) * 5  + var(--sp-44)); inline-size: var(--ledger-fig-2); background: var(--fill-accent-soft); }
.deco-ledger__figure:nth-of-type(3) { inset-block-start: calc(var(--ledger-pitch) * 8  + var(--sp-44)); inline-size: var(--ledger-fig-3); }
.deco-ledger__figure:nth-of-type(4) { inset-block-start: calc(var(--ledger-pitch) * 10 + var(--sp-44)); inline-size: var(--ledger-fig-4); }

.hero__copy {
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: start;
  gap: var(--sp-26);
}

.hero__title {
  font-size: var(--fs-hero);
  font-weight: var(--weight-hero);
  line-height: var(--lh-hero);
  letter-spacing: var(--track-display);
  text-transform: var(--type-hero-transform);
  color: var(--text-primary);
  max-inline-size: var(--hero-copy-w);
}

.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-16); }

/* ═ dark sloped panel ════════════════════════════════════ */


.stats__row2 {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-20);
  padding-block: var(--stats-row2-pad-block);
  text-align: center;
}

.stats__row2 h2 {
  font-size: var(--fs-h2-dark);
  font-weight: var(--weight-heading);
  line-height: var(--lh-h2);
  letter-spacing: var(--track-tight);
  color: var(--text-inverse);
}

.stats__row2 p {
  font-size: var(--fs-body);
  color: var(--text-inverse-soft);
  max-inline-size: var(--measure-sub);
}

.accred {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--accred-gap);
  margin-block-start: var(--sp-26);
}

.accred__item {
  position: relative;
  font-size: var(--fs-h3);
  font-weight: var(--weight-bold);
  letter-spacing: var(--track-eyebrow);
  color: var(--text-inverse);
  line-height: var(--lh-tight);
}

.accred__item + .accred__item::before {
  content: "";
  position: absolute;
  inset-inline-start: calc((var(--accred-gap) / 2) * -1);
  inset-block-start: 50%;
  translate: 0 -50%;
  inline-size: var(--accred-rule-w);
  block-size: var(--accred-rule-h);
  background: var(--border-hairline);
}

/* ═ heading row ══════════════════════════════════════════ */

.headrow__title { font-size: var(--fs-h2-lg); text-align: var(--headrow-title-align); }
.headrow__aside { justify-self: var(--headrow-aside-justify); text-align: var(--headrow-aside-align); }

/* ═ data bento ═══════════════════════════════════════════ */

.datacard {
  background: var(--bg-card);
  border-radius: var(--radius);
  padding: var(--datacard-pad);
  display: flex;
  flex-direction: column;
  gap: var(--datacard-gap);
}

.datacard__head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-20); }
.datacard--right { margin-block-start: var(--bento-right-drop); gap: var(--facts-gap); justify-content: space-evenly; }

.chart {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--chart-gap);
  block-size: var(--chart-h);
  align-items: end;
  margin-block-start: auto;
}

.chart__col { display: grid; grid-template-rows: 1fr auto; gap: var(--sp-8); justify-items: center; block-size: 100%; }
.chart__bar { align-self: end; inline-size: 100%; border-radius: var(--bar-radius); background: var(--fill-idle-strong); }
.chart__bar--peak { background: var(--fill-accent); }

.chart__col:nth-child(1)  .chart__bar { block-size: var(--bar-jan); }
.chart__col:nth-child(2)  .chart__bar { block-size: var(--bar-feb); }
.chart__col:nth-child(3)  .chart__bar { block-size: var(--bar-mar); }
.chart__col:nth-child(4)  .chart__bar { block-size: var(--bar-apr); }
.chart__col:nth-child(5)  .chart__bar { block-size: var(--bar-may); }
.chart__col:nth-child(6)  .chart__bar { block-size: var(--bar-jun); }
.chart__col:nth-child(7)  .chart__bar { block-size: var(--bar-jul); }
.chart__col:nth-child(8)  .chart__bar { block-size: var(--bar-aug); }
.chart__col:nth-child(9)  .chart__bar { block-size: var(--bar-sep); }
.chart__col:nth-child(10) .chart__bar { block-size: var(--bar-oct); }
.chart__col:nth-child(11) .chart__bar { block-size: var(--bar-nov); }
.chart__col:nth-child(12) .chart__bar { block-size: var(--bar-dec); }

.chart__label { font-size: var(--chart-label-size); color: var(--text-secondary); line-height: var(--lh-tight); }
.chart__label__short { display: none; }

.chart__key { display: flex; flex-wrap: wrap; gap: var(--sp-20); font-size: var(--fs-body-sm); color: var(--text-secondary); }
.chart__key span { display: inline-flex; align-items: center; gap: var(--sp-8); }
.chart__key i { inline-size: var(--sp-16); block-size: var(--sp-16); border-radius: var(--radius-xs); background: var(--fill-idle-strong); }
.chart__key i.is-peak { background: var(--fill-accent); }

.fact { display: flex; flex-direction: column; gap: var(--sp-8); }

.fact__value {
  font-size: var(--fact-value-size);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: var(--text-primary);
}

.fact__rating { display: flex; align-items: baseline; gap: var(--sp-12); }
.fact__note   { font-size: var(--fs-body-sm); color: var(--text-secondary); }
.fact__tags   { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin-block-start: var(--sp-4); }

.stars { display: flex; align-items: center; gap: var(--sp-4); color: var(--rating-star-idle); }
.stars.is-rated { color: var(--rating-star); }
.stars .is-filled { fill: currentColor; }

/* ═ services tiles ═══════════════════════════════════════ */

.ledger__head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-20); padding-block-end: var(--sp-64); }

.tile {
  display: flex;
  flex-direction: column;
  gap: var(--sp-16);
  padding: var(--tile-pad);
  border-radius: var(--radius);
  background: var(--bg-card);
  color: var(--text-primary);
}

/* The card itself does not respond. Its arrow carries the hover, so a
   dimming card underneath would be a second answer to one gesture.
   The colour is still pinned, because base.css turns any hovered
   anchor to --text-primary and these two set their own. */
.tile:hover { color: var(--text-primary); }
.tile:nth-child(1) { grid-column: var(--tile-1-col); grid-row: var(--tile-1-row); }
.tile:nth-child(2) { grid-column: var(--tile-2-col); grid-row: var(--tile-2-row); }
.tile:nth-child(3) { grid-column: var(--tile-3-col); grid-row: var(--tile-3-row); }
.tile:nth-child(4) { grid-column: var(--tile-4-col); grid-row: var(--tile-4-row); }
.tile:nth-child(5) { grid-column: var(--tile-5-col); grid-row: var(--tile-5-row); }
.tile:nth-child(6) { grid-column: var(--tile-6-col); grid-row: var(--tile-6-row); }

.tile__name { font-size: var(--tile-name-size); font-weight: var(--weight-heading); line-height: var(--lh-h2); letter-spacing: var(--track-tight); }
.tile__desc { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-secondary); max-inline-size: var(--measure-narrow); }
.tile__foot { margin-block-start: auto; display: flex; justify-content: flex-end; }

.tile__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--control-lg);
  block-size: var(--control-lg);
  border-radius: var(--radius-circle);
  background: var(--fill-accent-text);
  color: var(--text-on-accent);
  font-size: var(--tile-arrow-size);
  line-height: var(--lh-solid);
}

.tile--feature { background: var(--fill-accent-text); color: var(--text-inverse); }
.tile--feature:hover { color: var(--text-inverse); }
.tile--feature .tile__name { font-size: var(--tile-feature-name-size); }
.tile--feature .tile__desc { font-size: var(--tile-feature-desc-size); color: var(--text-inverse); }
.tile--feature .tile__arrow { background: var(--bg-page); color: var(--accent-strong); }

/* ═ split with steps ═════════════════════════════════════ */

.split__copy { min-inline-size: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-24); }
.split__copy .btn { margin-block-start: var(--sp-26); }

.steps { inline-size: 100%; display: flex; flex-direction: column; gap: var(--steps-gap); }

.step {
  display: grid;
  grid-template-columns: var(--step-cols);
  gap: var(--sp-24);
  align-items: baseline;
  padding-block-start: var(--sp-26);
  border-block-start: var(--border) solid var(--rule);
}

.step__num   { inline-size: var(--step-num-w); font-size: var(--fs-body-sm); font-weight: var(--weight-medium); color: var(--accent-strong); letter-spacing: var(--track-wide); }
.step__title { font-size: var(--fs-h3); font-weight: var(--weight-subhead); line-height: var(--lh-tight); color: var(--text-primary); }
.step__body  { margin-block-start: var(--sp-8); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-secondary); max-inline-size: var(--measure); }

/* ═ audience carousel ════════════════════════════════════ */

.serve__title { font-size: var(--fs-h2-lg); font-weight: var(--weight-heading); line-height: var(--lh-h2); letter-spacing: var(--track-tight); color: var(--text-primary); }
.serve__aside { display: flex; flex-direction: column; gap: var(--sp-32); align-items: var(--serve-aside-align); }
.serve__nav   { display: flex; align-items: center; gap: var(--sp-20); inline-size: 100%; max-inline-size: var(--serve-nav-w); }
.serve__track { flex: 1; block-size: var(--serve-track-h); border-radius: var(--radius-pill); background: var(--fill-idle); overflow: hidden; }
.serve__fill  { display: block; block-size: 100%; border-radius: var(--radius-pill); background: var(--fill-accent); transition: inline-size var(--dur-base) var(--ease); }

.serve__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--control-lg);
  block-size: var(--control-lg);
  border-radius: var(--radius-circle);
  border: 0;
  background: var(--fill-accent-text);
  color: var(--text-on-accent);
  font-size: var(--fs-glyph);
  line-height: var(--lh-solid);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              opacity var(--dur-fast) var(--ease);
}

.serve__btn[disabled] { opacity: var(--serve-btn-disabled); cursor: default; }
.serve__btn[disabled]:hover { background: var(--fill-accent-text); }

.serve__viewport { overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none; }
.serve__viewport::-webkit-scrollbar { display: none; }
.serve__rail { display: flex; gap: var(--tiles-gap); inline-size: 100%; }

.serve__card {
  flex: 0 0 var(--serve-card-w);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
  min-block-size: var(--serve-card-h);
  padding: var(--serve-card-pad);
  border-radius: var(--radius);
  background: var(--bg-card);
  color: var(--text-primary);
  transition: background var(--dur-base) var(--ease),
              color var(--dur-base) var(--ease);
}

/* --text-on-soft is --accent-deep, not --accent-strong. The
   strong accent on the soft accent field is 3.28:1 and fails
   AA on a visible numeral; this is the smallest move along the
   same hue that clears it, at 4.82:1. */
.serve__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--serve-badge);
  block-size: var(--serve-badge);
  border-radius: var(--radius-circle);
  background: var(--fill-accent-soft);
  color: var(--text-on-soft);
  font-size: var(--fs-body-sm);
  font-weight: var(--weight-semibold);
  line-height: var(--lh-solid);
  transition: background var(--dur-base) var(--ease),
              color var(--dur-base) var(--ease);
}

.serve__body { margin-block-start: auto; display: flex; flex-direction: column; gap: var(--sp-12); }
.serve__name { font-size: var(--fs-h3); font-weight: var(--weight-heading); line-height: var(--lh-tight); letter-spacing: var(--track-tight); }
.serve__desc { font-size: var(--fs-body-sm); line-height: var(--lh-body); color: var(--text-secondary); transition: color var(--dur-base) var(--ease); }

.serve__card.is-active { background: var(--fill-accent-text); color: var(--text-inverse); }
.serve__card.is-active .serve__desc  { color: var(--text-inverse); }
.serve__card.is-active .serve__badge { background: var(--bg-page); color: var(--accent-strong); }

/* ═ testimonials ═════════════════════════════════════════ */

.band__head .btn { justify-self: end; }
.band__title { font-size: var(--fs-h2-lg); font-weight: var(--weight-heading); line-height: var(--lh-h2); letter-spacing: var(--track-tight); color: var(--text-primary); max-inline-size: var(--band-title-w); }
.band__title span { color: var(--text-secondary); }

.quote {
  display: flex;
  flex-direction: column;
  gap: var(--sp-32);
  margin: 0;
  padding: var(--quote-card-pad);
  border-radius: var(--radius);
  background: var(--bg-page);
  min-block-size: var(--quote-card-h);
}

.quote__who  { display: flex; align-items: center; gap: var(--sp-16); }
.quote__who .avatar { flex: 0 0 auto; }
.quote__id   { flex: 1; display: flex; flex-direction: column; gap: var(--sp-4); }
.quote__id b { font-size: var(--fs-h4); font-weight: var(--weight-semibold); line-height: var(--lh-tight); color: var(--text-primary); }
.quote__id span { font-size: var(--fs-body-sm); color: var(--text-secondary); }

.quote__glyph {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--badge-md);
  block-size: var(--badge-md);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--accent-strong);
  font-size: var(--fs-h3);
  font-weight: var(--weight-bold);
  line-height: var(--lh-solid);
}

.quote__text   { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-secondary); }
.quote__text b { display: block; padding-block-end: var(--sp-8); font-size: var(--fs-h4); font-weight: var(--weight-semibold); color: var(--text-primary); }
.quote__foot   { margin-block-start: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-16); }
.quote__date   { font-size: var(--fs-body-sm); color: var(--text-secondary); }

.avatar {
  display: block;
  inline-size: var(--avatar-md);
  block-size: var(--avatar-md);
  border-radius: var(--radius-circle);
  background: var(--placeholder-fill);
  border: var(--border) solid var(--placeholder-line);
}

/* ═ closing cta ══════════════════════════════════════════ */

.cta { background: var(--bg-panel); color: var(--text-inverse); border-radius: var(--radius); padding: var(--cta-pad-block) var(--cta-pad-inline); }
.cta__grid { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--cta-stack-gap); }

.cta__eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: var(--type-eyebrow-transform);
  color: var(--text-inverse-soft);
}

.cta__line { font-size: var(--fs-h2); font-weight: var(--weight-heading); line-height: var(--lh-h2); letter-spacing: var(--track-tight); color: var(--text-inverse); max-inline-size: var(--cta-line-w); }
.cta__note { font-size: var(--fs-body); color: var(--text-inverse-soft); margin-block-start: calc(var(--cta-stack-gap) * -1 + var(--sp-20)); }

/* ═ footer ═══════════════════════════════════════════════ */

.footer__title { font-size: var(--footer-title-size); font-weight: var(--footer-title-weight); line-height: var(--lh-h2); letter-spacing: var(--track-tight); color: var(--text-inverse); max-inline-size: var(--footer-title-w); }

.finfo { display: flex; flex-direction: column; gap: var(--sp-16); }

.finfo__label {
  font-size: var(--fs-eyebrow);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: var(--type-eyebrow-transform);
  color: var(--text-inverse-soft);
}

.finfo__value { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-inverse); }
.finfo__value dl { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-8) var(--sp-24); margin: 0; }
.finfo__value dt { color: var(--text-inverse-soft); }
a.finfo__value { display: inline-flex; align-items: center; min-block-size: var(--tap-min); color: var(--text-inverse); }
a.finfo__value:hover { color: var(--accent-soft); }

.footer__rule { block-size: var(--border); background: var(--border-hairline); }

.footer__col h2 {
  font-size: var(--fs-eyebrow);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-eyebrow);
  text-transform: var(--type-eyebrow-transform);
  color: var(--text-inverse-soft);
  padding-block-end: var(--sp-16);
}

.footer__col ul { display: flex; flex-direction: column; }
.footer__col a  { display: inline-flex; align-items: center; min-block-size: var(--tap-min); font-size: var(--fs-body); color: var(--text-inverse); }
.footer__col a:hover { color: var(--accent-soft); }
.footer__static { display: inline-flex; align-items: center; min-block-size: var(--tap-min); font-size: var(--fs-body); color: var(--text-inverse); }

.footer__bottom p { margin: 0; }
.footer__bottom a { color: var(--text-inverse-soft); }
.footer__bottom a:hover { color: var(--text-inverse); }
.footer__bottom > :nth-child(2) { text-align: var(--footer-bottom-mid); }
.footer__bottom > :nth-child(3) { text-align: var(--footer-bottom-end); }

/* --text-credit is --accent-lift, not --accent. The base
   accent on the ink field is 4.02:1 and fails AA; three
   hundredths of OKLCH lightness takes it to 4.56:1 and is not
   visible side by side. */
.footer__credit { color: var(--text-inverse-soft); }
.footer__bottom .footer__credit__link { color: var(--text-credit); }
.footer__bottom .footer__credit__link:hover { color: var(--accent-soft); }

/* ═ inner pages ══════════════════════════════════════════
   Three patterns the one-page source had no equivalent of.
   All three are assembled from the vocabulary it does
   establish rather than invented: the page hero is the home
   hero without its field, the form fields are the datacard
   surface at the medium radius, and the prose column is the
   body step on a wider measure.
   ══════════════════════════════════════════════════════ */

/* ─ page hero ───────────────────────────────────────────── */

.page-hero__title {
  font-size: var(--fs-h2-lg);
  font-weight: var(--weight-hero);
  line-height: var(--lh-hero);
  letter-spacing: var(--track-display);
  color: var(--text-primary);
  max-inline-size: var(--measure-sub);
}

.page-hero__lead { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-secondary); max-inline-size: var(--measure-sub); }

/* A link on the card surface, not on paper. --accent-strong is 4.87:1
   on paper and 4.43:1 on --surface, so it clears AA on one and not the
   other. The deep step is 6.53:1 there. Same reason the carousel badge
   uses it: the field underneath decides which step is safe. */
.datacard a { color: var(--text-on-soft); }
.datacard a:hover { color: var(--text-primary); }

/* A standalone email or telephone link inside a card. The footer does
   the same thing to its own, and for the same reason: a 21px line is
   not a 44px target. Inline-flex rather than padding, so the line box
   grows without the text moving. */
.tap-link {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--tap-min);
}

/* A definition list on a light field. .finfo__value is the footer's,
   and its dt is white at an alpha, which is invisible here. */
.factlist {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-8) var(--sp-24);
  margin: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text-primary);
}

.factlist dt { color: var(--text-secondary); }

/* ─ jump list ───────────────────────────────────────────── */

.jump { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
.jump a { display: inline-flex; align-items: center; min-block-size: var(--tap-min); }

/* ─ contact form ────────────────────────────────────────── */

.contact-form { display: flex; flex-direction: column; gap: var(--sp-24); }
.form-row { display: flex; flex-direction: column; gap: var(--sp-8); }
.form-row label { font-size: var(--fs-body-sm); font-weight: var(--weight-medium); color: var(--text-primary); }

/* The field inverts against the card it sits on, and its border
   carries the boundary. --bg-card on --bg-card with a --rule border
   is 1.07:1 against the card, which is a control with no visible
   edge. --grey-mid is 3.13:1 against the card and 3.44:1 against the
   field, so the boundary clears WCAG 1.4.11 from both sides. */
.form-row input,
.form-row select,
.form-row textarea {
  inline-size: 100%;
  min-block-size: var(--tap-min);
  padding: var(--sp-12) var(--sp-16);
  border: var(--border-w) solid var(--fill-idle-strong);
  border-radius: var(--radius-md);
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

.form-row textarea { min-block-size: calc(var(--tap-min) * 3); resize: vertical; }
.form-row input::placeholder,
.form-row textarea::placeholder { color: var(--text-secondary); }
.form-row [aria-invalid="true"] { border-color: var(--accent-deep); }

.form-error { min-block-size: var(--sp-20); font-size: var(--fs-body-sm); color: var(--accent-deep); }
.form-status { font-size: var(--fs-body); color: var(--text-primary); }

/* Honeypot. Parked off-canvas rather than display:none, which
   some form fillers skip. A human never fills a field they
   cannot see. */
.form-hp { position: absolute; inset-inline-start: var(--offscreen); }

/* ─ prose, the regulatory pages ─────────────────────────── */

.prose { display: flex; flex-direction: column; gap: var(--sp-24); max-inline-size: var(--measure-prose); }
.prose h2 { font-size: var(--fs-h2-dark); font-weight: var(--weight-heading); line-height: var(--lh-h2); letter-spacing: var(--track-tight); color: var(--text-primary); margin-block-start: var(--sp-24); }
.prose h3 { font-size: var(--fs-h3); font-weight: var(--weight-subhead); line-height: var(--lh-tight); color: var(--text-primary); }
.prose p  { font-size: var(--fs-body); line-height: var(--lh-prose); color: var(--text-secondary); }
.prose a  { color: var(--accent-strong); text-decoration: underline; text-underline-offset: var(--ring-offset); }
.prose a:hover { color: var(--text-primary); }
.prose ul { display: flex; flex-direction: column; gap: var(--sp-12); }

.prose ul li {
  position: relative;
  padding-inline-start: var(--sp-24);
  font-size: var(--fs-body);
  line-height: var(--lh-prose);
  color: var(--text-secondary);
}

.prose ul li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: calc((var(--lh-prose) * 1em - var(--sp-8)) / 2);
  inline-size: var(--sp-8);
  block-size: var(--sp-8);
  border-radius: var(--radius-xs);
  background: var(--fill-accent);
}

.prose__meta { font-size: var(--fs-body-sm); color: var(--text-secondary); }
