/*
components.css — hero, card, callout, connector, button.
Hero, card, callout and button are built. Connector comes later.

Button spec: DataBank Brand System - Guidelines.html, "Dark mode components
→ Buttons". Pulled from the guide's own live button specimens (inspected
directly): inline-flex, --space-2 gap, 11px 18px padding, 14px/1.2 medium
body font, border-radius 4px (a fixed value — buttons are the one plate-ish
thing that does NOT use --radius-ratio), 1px solid border, background/
border-color transition at --motion-duration/--motion-easing. Three
variants by fill: primary (solid --color-blue-base), secondary (transparent,
border only), quiet (transparent, no border, underlined — "the Quiet CTA
button variant, which has no fill or border to mark it as an action," per
the Type section). The hover glow itself ("appears on hover and focus
only... a resting button never glows") couldn't be read off the live
specimen — it didn't expose a real :hover state to scripted inspection — so
the glow values below are my own reasonable interpretation of that
behavior, not an extracted spec. Flag for Scott to confirm or adjust.

Card/callout spec: DataBank Brand System - Guidelines.html, "Structural
devices → Plate and radius" and "Card accent line rules". The rule is
semantic, not visual preference: cards and panels that GROUP several
pieces of content get a line across the TOP; a single text block or
callout gets a line down the LEFT. The line is drawn as an inset shadow
inside the plate's own radius (never a wider border replacing one edge),
so it traces flush with the corner instead of overshooting it.

Hero spec: DataBank Brand System - Guidelines.html, "Applications → Hero by
page type" (the five hero identities — Product/Solution, Case Study,
Industry Landing, Pillar/About, Event) and "Backgrounds and mode" (the five
background types, glow direction per page type, the white-ration rule for
stat cards). technical-project-plan.md §4 documents an earlier 3-background/
4-page-type version of this component; the guidelines doc is ahead of it as
of this revision.
*/

.hero {
  position: relative;
  overflow: hidden;
  background-color: var(--surface-page);
  color: var(--text-primary);
  padding-block: var(--space-9);
}

/* data-mode="dark"/"light" and data-subbrand="..." carry no rules of their
   own here — they just flip the token remaps in tokens.css. Everything
   below only ever reads var(--surface-page), var(--accent), etc. */

.hero__bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Background: solid — just the base surface color set above, no overlay */

/* Background: solid + hero line — website hero bands only, where a reading
   body sits directly below (e.g. Industry Landing → body-narrative.php).
   A 2px accent rule closes the band against that body. */
.hero[data-background="solid-line"] {
  border-bottom: var(--accent-line-weight) solid var(--accent);
}

/* Background: grid — hero and section openers only. The pattern is masked
   into the empty column — it lives on .hero__bg-pattern, a grid item that
   always occupies the same right-hand columns the stat-block aside would
   (see layouts.css), so it can never land under the headline/body text. */
.hero__bg-pattern {
  background-image:
    linear-gradient(var(--line-hairline) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-hairline) 1px, transparent 1px);
  background-size: var(--space-8) var(--space-8);
  pointer-events: none;
}

/* data-glow sets where a gradient/light-glow background originates from,
   per page type (top-right, top-left, top-center) — the two glow
   backgrounds below both read these same two custom properties. */
.hero[data-glow="top-right"]  { --hero-glow-x: 100%; --hero-glow-y: 0%; }
.hero[data-glow="top-left"]   { --hero-glow-x: 0%;   --hero-glow-y: 0%; }
.hero[data-glow="top-center"] { --hero-glow-x: 50%;  --hero-glow-y: 0%; }

/* Background: gradient glow — dark surfaces, top of hierarchy, one per
   section, default when the hero is copy-dense. Always the accent color:
   DataBank blue on brand-wide material, the industry color under a
   sub-brand — which is already what var(--accent) resolves to. */
.hero[data-background="gradient"] .hero__bg {
  background-image: radial-gradient(
    120% 100% at var(--hero-glow-x, 100%) var(--hero-glow-y, 0%),
    color-mix(in srgb, var(--accent) 35%, transparent) 0%,
    transparent 60%
  );
}

/* Background: light glow — event pages only, no other page type uses it.
   Same accent rule as gradient glow, tuned lighter for a light surface. */
.hero[data-background="light-glow"] .hero__bg {
  background-image: radial-gradient(
    120% 100% at var(--hero-glow-x, 0%) var(--hero-glow-y, 0%),
    color-mix(in srgb, var(--accent) 32%, transparent) 0%,
    transparent 48%
  );
}

.hero__grid {
  position: relative;
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: var(--space-6);
}

.hero__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--space-4);
}

/* Brand rule, 2026-10-29: a headline may never end with a single word
   alone on its last line (e.g. "Technology plus human" / "ingenuity."
   breaking off the Why DataBank hero). One rule, applied once here to
   every real headline selector in the theme, rather than a per-page
   fix — covers every h1-h6 regardless of which class sizes it, plus
   the handful of headline-role classes applied to non-heading tags
   (span/p/a). Deliberately excludes .eyebrow (a small label above a
   headline, not a headline itself), .team-card__title/.quote-card__title
   (small attribution text), and every graphics.css diagram label (those
   are already white-space:nowrap and never wrap at all). text-wrap:
   balance balances LINE WIDTH, not word count, so it doesn't strictly
   guarantee this on its own — a resize-aware JS guard in main.js
   re-checks the actual rendered last line on every browser and joins
   the last two words with a non-breaking space on the rare cases
   balance alone still leaves one word stranded. See main.js for the
   full reasoning and its own safety limits. */
h1, h2, h3, h4, h5, h6,
.hero__headline,
.card__title,
.link-card__title,
.numbered-list__title,
.service-link__title,
.capability-tabs__tab-title,
.media-placeholder__title,
.case-study-grid__title,
.case-study-steps__title,
.insights-board__card-title,
.search-result__title,
.site-footer__cta-headline {
  text-wrap: balance;
}

.hero__headline {
  font-family: var(--font-display);
  font-size: var(--type-display-1-size);
  line-height: var(--type-display-1-line);
  letter-spacing: var(--type-display-1-track);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  margin: 0 0 var(--space-5);
}

/* Optional second line, Heading weight — between headline and subhead.
   Added for the homepage hero, which has both; see hero.php's docblock.
   margin-top was `calc(var(--space-5) * -1)` (2026-10-29 audit: cancelled
   almost all of .hero__headline's own margin-bottom, netting a ~0px gap
   and making the headline and this line read as one cramped block instead
   of two distinct lines of hierarchy). Removed — the headline's own
   --space-5 bottom margin now stands as the full, intentional gap. */
.hero__intro {
  font-family: var(--font-display);
  font-size: var(--type-heading-size);
  line-height: var(--type-heading-line);
  letter-spacing: var(--type-heading-track);
  font-weight: var(--type-heading-weight);
  color: var(--text-primary);
  margin: 0 0 var(--space-5);
}

/* Slot: accent-line — a rule in the sub-brand color, under the headline */
.hero__accent-line {
  display: block;
  width: var(--space-8);
  height: var(--accent-rule-weight);
  background-color: var(--accent);
  margin-top: calc(var(--space-5) * -1);
  margin-bottom: var(--space-5);
}

.hero__subhead {
  font-family: var(--font-body);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
  max-width: 46ch;
  margin: 0;
}

/* Stacked subheads (hero.php's array form, added for Who We Are) need a
   gap between paragraphs — a lone subhead is unaffected since there's no
   preceding sibling to match. */
.hero__subhead + .hero__subhead {
  margin-top: var(--space-4);
}

/* below_content — a full-width slot under the content/aside grid, still
   inside the hero's own section (dark/light band, bg). Added for Our
   Locations' US map illustration. Matches .hero__grid's own max-width/
   padding so it lines up with the content above it. */
.hero__below {
  max-width: 1280px;
  margin: var(--space-8) auto 0;
  padding-inline: var(--space-6);
}

/* Breadcrumb — replaces .hero__eyebrow (mutually exclusive, not both) on
   pages one level deep in a hierarchy, e.g. a location-detail page under
   its Our Locations hub. Reuses the exact same --type-label-* tokens as
   .hero__eyebrow, just with --text-secondary for the link segment and
   --text-primary for the current (unlinked) segment, instead of
   --accent — confirmed against the approved design's own computed
   styles, not guessed. Added for Chicago Metro, the first Location
   Detail child page. */
.hero__breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  font-weight: var(--weight-medium);
  margin: 0 0 var(--space-4);
}

.hero__breadcrumb a {
  color: var(--text-secondary);
  text-decoration: none;
}

.hero__breadcrumb a:hover {
  color: var(--text-primary);
}

.hero__breadcrumb-current {
  color: var(--text-primary);
}

/* Slot: baseline-meta — client name / date sitting under the subhead */
.hero__baseline-meta {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: var(--space-7) 0 0;
}

/* Slot: stat-block — right-hand column on the 7/5 grid */
.hero__stat-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.hero__stat {
  container-type: inline-size;
  padding: var(--plate-padding);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  background-color: var(--surface-plate);
}

.hero__stat-figure {
  display: block;
  font-family: var(--font-display);
  font-size: var(--type-stat-md-size);
  line-height: var(--type-stat-line);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.hero__stat-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-top: var(--space-2);
}

/* The white ration (Backgrounds and mode → "The white ration"): on a dark
   hero, only the lead stat earns true white — the rest stay on the plate
   tint. This card is white regardless of hero mode, so its text can't use
   the text-* tokens (they're remapped for the dark surface, not this one) —
   it needs the literal light-mode navy values instead. */
.hero[data-mode="dark"] .hero__stat--lead {
  background-color: var(--color-white);
}

.hero[data-mode="dark"] .hero__stat--lead .hero__stat-figure {
  color: var(--color-navy-base);
}

.hero[data-mode="dark"] .hero__stat--lead .hero__stat-label {
  color: rgba(0, 38, 61, .68);
}

/* Card — groups several pieces of content, so its accent line runs across
   the top. The line is an inset box-shadow: a hard-edged 0-blur shadow
   offset from the top edge reads as a solid band, and (unlike a border)
   it's clipped to border-radius automatically, so it stays flush with
   the corner. */
.card {
  container-type: inline-size;
  background-color: var(--surface-plate);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--plate-padding);
  box-shadow: inset 0 var(--accent-rule-weight) 0 0 var(--accent);
}

.card__label {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--accent-ink);
  margin: 0 0 var(--space-3);
}

.card__title {
  font-family: var(--font-display);
  font-size: var(--type-heading-size);
  line-height: var(--type-heading-line);
  font-weight: var(--type-heading-weight);
  color: var(--text-primary);
  margin: 0 0 var(--space-2);
}

.card__body {
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  line-height: var(--type-body-m-line);
  color: var(--text-secondary);
  margin: 0;
}

/* .card--link-grid — added 2026-10-30 for the Case Studies and Events
   listing grids, the only two places a whole `.card` is also the link
   (previously a bare `.card` with an inline `style="display:block;"`,
   no reset of the sitewide inline-link underline default). `.card` by
   itself stays untouched, since it's reused sitewide for dozens of
   non-link contexts (contact cards, pricing, etc.) that this must not
   affect. */
.card--link-grid {
  display: block;
  text-decoration: none;
}

.card--link-grid:hover .card__title,
.card--link-grid:focus-visible .card__title {
  color: var(--accent-ink);
}

.card--link-grid:focus-visible {
  outline: none;
  box-shadow: inset 0 var(--accent-rule-weight) 0 0 var(--accent), 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* Callout — a single text block, so its accent line runs down the left
   instead of across the top. Same inset-shadow technique, offset on the
   inline axis rather than the block axis. */
.callout {
  container-type: inline-size;
  background-color: var(--surface-plate);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--plate-padding);
  box-shadow: inset var(--accent-rule-weight) 0 0 0 var(--accent);
}

.callout__body {
  font-family: var(--font-body);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--text-primary);
  margin: 0;
}

.callout__attribution {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: var(--space-3) 0 0;
}

/* Narrative body typography — not one of the five named components above,
   but body-narrative.php (the shared body for Product/Solution, Industry
   Landing and Pillar/About) needs a home for the type rules its native
   block-editor content picks up, and there's no dedicated typography.css
   in the file structure. Kept here rather than inline in the PHP, same as
   every other visual rule in this theme. */
.narrative {
  background-color: var(--surface-page);
  color: var(--text-primary);
}

.narrative__intro {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) 0;
  font-family: var(--font-body);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--text-primary);
}

.narrative__content {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--space-7) var(--space-6) var(--space-9);
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

.narrative__content > :is(h2, h3, p, ul, ol, .layout-three-up, .layout-sidebar-3-9, .layout-ragged-9-3, .layout-full-bleed) {
  margin: 0;
}

.narrative__content h2 {
  font-family: var(--font-display);
  font-size: var(--type-display-2-size);
  line-height: var(--type-display-2-line);
  letter-spacing: var(--type-display-2-track);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.narrative__content h3 {
  font-family: var(--font-display);
  font-size: var(--type-heading-size);
  line-height: var(--type-heading-line);
  font-weight: var(--type-heading-weight);
  color: var(--text-primary);
}

.narrative__content p,
.narrative__content li {
  font-family: var(--font-body);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
  max-width: 68ch;
}

/* Hero slot (independent of the 3 named slots): a row of CTA buttons.
   margin-top was --space-2 (2026-10-29 audit: tighter than the --space-4
   gap between stacked subhead paragraphs, so the CTA read as crowding the
   text above it instead of getting its own room). Bumped to --space-6 —
   double the paragraph gap, a clearly larger, intentional break before
   the button. */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

/* Button — three variants by fill, not by size or shape */
.button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 11px 18px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: var(--weight-medium);
  line-height: 1.2;
  border-radius: 4px;
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--motion-duration) var(--motion-easing),
    border-color var(--motion-duration) var(--motion-easing),
    box-shadow var(--motion-duration) var(--motion-easing);
}

.button--primary {
  background-color: var(--accent);
  border-color: var(--accent);
  color: var(--color-white);
}

.button--secondary {
  background-color: transparent;
  border-color: var(--line-rule);
  color: var(--text-primary);
}

/* On a dark hero, the secondary button's border needs real contrast against
   navy — the light-mode --line-rule token is too dark to read there */
[data-mode="dark"] .button--secondary {
  border-color: rgba(255, 255, 255, .4);
  color: var(--color-white);
}

.button--quiet {
  background-color: transparent;
  border-color: transparent;
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

[data-mode="dark"] .button--quiet {
  color: var(--color-white);
}

/* Glow means interactive and nothing else — hover/focus only, never at
   rest. Exact shadow values are my own interpretation (see file header
   comment) — the live specimen didn't expose this to scripted inspection. */
.button--primary:hover,
.button--primary:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}

.button--secondary:hover,
.button--secondary:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

.button--quiet:hover,
.button--quiet:focus-visible {
  color: var(--accent-ink);
}

/* Stat strip — a row of standalone figures, e.g. the homepage's "impact"
   numbers. Not the same as .hero__stat-block: that's scoped to the hero
   and includes the white-ration lead-card treatment for a dark gradient
   background; this is plainer, for use anywhere on a page, not just a
   hero. Deliberately NOT sharing classes with the hero stat-block — the
   two have different enough rules (white ration, card background, lead
   emphasis don't apply here) that sharing would mean fighting the hero's
   rules with overrides. Small duplication accepted over a forced shared
   abstraction for two call sites. */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gutter);
}

.stat-strip > .stat {
  grid-column: span 3;
}

.stat-figure {
  display: block;
  font-family: var(--font-display);
  font-size: var(--type-stat-md-size);
  line-height: var(--type-stat-line);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

.stat-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  line-height: var(--type-label-line);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-top: var(--space-2);
}

@media (max-width: 900px) {
  .stat-strip > .stat {
    grid-column: span 6;
  }
}

@media (max-width: 480px) {
  .stat-strip > .stat {
    grid-column: 1 / -1;
  }
}

/* Site header / footer — rebuilt 2026-10-07 from the approved Claude
   Design homepage. Translated from that design's inline styles into real
   classes here, same as everywhere else in this theme — inline styles in
   header.php/footer.php would work but would break the project's own
   convention of keeping all visual rules in the CSS files. */

.site-header {
  position: relative;
  z-index: 20;
  background-color: var(--color-navy-base);
  color: var(--text-primary);
  border-bottom: var(--border-hairline);
}

.site-header__logo-img {
  display: block;
  height: 26px;
  width: auto;
}

.site-header__utility-inner {
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--space-2) clamp(20px, 5vw, 64px);
  border-bottom: var(--border-hairline);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-5);
}

.site-header__utility-list {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--type-small-size);
}

.site-header__utility-list a {
  color: var(--text-secondary);
  text-decoration: none;
}

.site-header__utility-list a:last-child {
  font-variant-numeric: tabular-nums;
}

.site-header__main {
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--space-4) clamp(20px, 5vw, 64px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-6);
}

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

.site-header__brand-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* Mobile nav toggle — added 2026-10-22. Hidden on desktop; only shown
   inside the existing 780px mobile media query below. See header.php's
   docblock for the real gap this fixes. */
.site-header__nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 36px;
  height: 36px;
  padding: 0;
  background: transparent;
  border: none;
  cursor: pointer;
}

.site-header__nav-toggle-bar {
  display: block;
  width: 22px;
  height: 2px;
  background-color: var(--color-white);
  border-radius: 1px;
  transition:
    transform var(--motion-duration) var(--motion-easing),
    opacity var(--motion-duration) var(--motion-easing);
}

.site-header__nav-toggle.is-active .site-header__nav-toggle-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.site-header__nav-toggle.is-active .site-header__nav-toggle-bar:nth-child(2) {
  opacity: 0;
}

.site-header__nav-toggle.is-active .site-header__nav-toggle-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.site-footer__logo-img {
  display: block;
  height: 24px;
  width: auto;
}

.site-header__nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  font-size: var(--type-body-m-size);
}

.site-header__nav-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-header__nav-list a {
  display: inline-block;
  color: rgba(255, 255, 255, .72);
  text-decoration: none;
  padding-block: var(--space-2);
  border-bottom: 2px solid transparent;
  transition:
    color var(--motion-duration) var(--motion-easing),
    border-color var(--motion-duration) var(--motion-easing);
}

.site-header__nav-list a:hover {
  color: var(--color-white);
  border-bottom-color: var(--accent);
}

/* Primary nav dropdowns — added 2026-10-23, the real gap flagged when
   dev's nav turned out to only show the 5 top-level links (see
   databank_2026_primary_nav_fallback()'s own docblock in theme-setup.php
   for the full story). Each top-level item with real children becomes a
   hover/focus-triggered mega-menu panel on desktop (CSS only, no JS), and
   a tap-to-expand accordion section inside the existing mobile nav panel
   below 780px (JS in main.js toggles .is-open; this is the only part that
   needs it). Reuses the footer sitemap's group-label/link visual language
   (.site-footer__group-label et al) rather than inventing a second
   pattern for the same kind of content. */

.site-header__nav-item {
  position: relative;
  display: flex;
  align-items: center;
}

.site-header__nav-item-toggle {
  display: none;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  padding: var(--space-1);
  margin-inline-start: 2px;
  cursor: pointer;
  color: rgba(255, 255, 255, .72);
}

.site-header__nav-item-toggle svg {
  display: block;
  transition: transform var(--motion-duration) var(--motion-easing);
}

.site-header__dropdown {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translate(-50%, 8px);
  width: max-content;
  max-width: calc(100vw - 40px);
  background-color: var(--color-navy-base);
  border: var(--border-hairline);
  border-radius: 8px;
  padding: var(--space-6);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .35);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--motion-duration) var(--motion-easing),
    transform var(--motion-duration) var(--motion-easing);
  z-index: 30;
}

/* Desktop-only: below 780px the dropdown is a tap-to-expand accordion
   (position: static, driven by .is-open, see the mobile media query),
   not a hover panel — scoped to min-width so this rule's higher
   specificity than the mobile reset below can never win there (a real
   bug caught in preview: without this media-query scope, a mobile
   dropdown's own toggle button receiving focus triggered :focus-within
   here, and its `transform: translate(-50%, 0)` overrode the mobile
   reset's `transform: none` by specificity alone, shoving the open
   accordion off-screen to the left). */
@media (min-width: 781px) {
  .site-header__nav-item:hover > .site-header__dropdown,
  .site-header__nav-item:focus-within > .site-header__dropdown {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
  }
}

.site-header__dropdown-inner {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: minmax(200px, 1fr);
}

.site-header__dropdown-inner[data-cols="4"] {
  grid-template-columns: repeat(4, minmax(200px, 1fr));
}

.site-header__dropdown-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.site-header__dropdown-group-label {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  font-weight: var(--weight-medium);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--color-navy-light);
  text-decoration: none;
  border-bottom: none;
  padding-block: 0 var(--space-1);
  margin-bottom: var(--space-1);
}

.site-header__dropdown-group a:not(.site-header__dropdown-group-label) {
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-secondary);
  text-decoration: none;
  border-bottom: none;
  display: block;
  padding-block: 3px;
}

.site-header__dropdown-group a:hover {
  color: var(--color-white);
}

.site-footer {
  background-color: var(--color-navy-base);
  color: var(--text-primary);
  border-top: var(--border-hairline);
}

.site-footer__cta {
  max-width: 1280px;
  margin-inline: auto;
  padding: clamp(56px, 7vw, 88px) clamp(20px, 5vw, 64px);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-7);
  border-bottom: var(--border-hairline);
}

.site-footer__cta-headline {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--type-display-2-size);
  line-height: var(--type-display-2-line);
  letter-spacing: var(--type-display-2-track);
  color: var(--color-white);
  max-width: 16em;
}

.site-footer__sitemap {
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--space-7) clamp(20px, 5vw, 64px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-7) var(--space-6);
}

.site-footer__column {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}

.site-footer__group {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.site-footer__group-label {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  font-weight: var(--weight-medium);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--color-navy-light);
  text-decoration: none;
  margin-bottom: var(--space-1);
}

.site-footer__link {
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-secondary);
  text-decoration: none;
}

.site-footer__bottom {
  border-top: var(--border-hairline);
}

.site-footer__bottom-inner {
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--space-5) clamp(20px, 5vw, 64px) var(--space-6);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-7);
}

.site-footer__brand {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-5);
}

.site-footer__tagline {
  font-size: var(--type-small-size);
  color: var(--text-secondary);
}

.site-footer__legal {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  font-size: var(--type-small-size);
}

.site-footer__legal span {
  color: var(--text-tertiary);
}

.site-footer__legal a {
  color: var(--text-secondary);
  text-decoration: none;
}

@media (max-width: 780px) {
  .site-header__main {
    flex-direction: column;
    align-items: flex-start;
  }

  .site-header__brand-row {
    width: 100%;
    justify-content: space-between;
  }

  .site-header__nav-toggle {
    display: inline-flex;
  }

  .site-header__nav {
    display: none;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: var(--space-4);
    padding-top: var(--space-4);
  }

  .site-header__nav.is-open {
    display: flex;
  }

  .site-header__nav-list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .site-header__nav-list a {
    width: 100%;
    padding-block: var(--space-3);
    border-bottom: var(--border-hairline);
  }

  .site-header__nav > .button {
    width: 100%;
    text-align: center;
    margin-top: var(--space-2);
  }

  /* Nav dropdowns below 780px: no hover, so each item with real children
     gets a visible chevron toggle that expands/collapses a static block
     in place (JS in main.js), instead of the desktop hover/focus panel. */
  .site-header__nav-item {
    flex-wrap: wrap;
  }

  .site-header__nav-item > a {
    flex: 1;
    width: auto;
  }

  .site-header__nav-item-toggle {
    display: inline-flex;
    width: 40px;
    height: 40px;
  }

  .site-header__nav-item-toggle.is-active svg {
    transform: rotate(180deg);
  }

  .site-header__dropdown {
    position: static;
    width: 100%;
    max-width: none;
    transform: none;
    opacity: 1;
    visibility: visible;
    box-shadow: none;
    border: none;
    border-radius: 0;
    padding: 0 0 var(--space-4) var(--space-4);
    background: transparent;
    display: none;
  }

  .site-header__dropdown.is-open {
    display: block;
  }

  .site-header__dropdown-inner,
  .site-header__dropdown-inner[data-cols="4"] {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }
}

/* Section — a full-bleed content band for bespoke (primary-page)
   templates like the homepage, mode-aware the same way .narrative already
   is for body-narrative.php. Added 2026-10-07 building the homepage: a
   data-mode="dark" section with no explicit background/color just
   inherited the page's light background, since nothing but .hero and
   .narrative had ever set these before — this is the fix, generalized so
   it doesn't recur on the next bespoke page. */
.section {
  background-color: var(--surface-page);
  color: var(--text-primary);
}

.section__inner {
  max-width: 1280px;
  margin-inline: auto;
  padding: var(--space-9) clamp(20px, 5vw, 64px);
}

/* Section-content utilities — built for the homepage 2026-10-07, used inside
   .section__inner. Found 2026-10-08, building Who We Are: these had only
   ever been written into preview/home-preview.html's local <style> block,
   never ported here — meaning the real WordPress homepage template
   (page-templates/template-home.php) has been enqueuing components.css
   without these rules and rendering unstyled on the live dev site. Moved
   here now so both Home and Who We Are (and every page after) share one
   real source, per rollout-plan.md §3's "feed the updated system forward"
   rule — a preview file's local <style> block was never meant to be that
   source of truth. */
.section__inner h2 {
  font-family: var(--font-display);
  font-size: var(--type-display-2-size);
  line-height: var(--type-display-2-line);
  letter-spacing: var(--type-display-2-track);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  margin: 0 0 var(--space-5);
  max-width: 24ch;
}

.section__inner > p.lead {
  font-family: var(--font-body);
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
  max-width: 62ch;
  margin: 0 0 var(--space-7);
}

.section__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.media-placeholder {
  display: flex;
  align-items: stretch;
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  overflow: hidden;
  container-type: inline-size;
  background: var(--surface-plate);
  box-shadow: var(--graphics-shadow-sm);
}

.media-placeholder__frame {
  flex: 1;
  aspect-ratio: 16 / 10;
  background: var(--line-hairline);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  position: relative;
}

.media-placeholder__hover-label {
  position: absolute;
  top: 10px;
  left: 10px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.media-placeholder__caption {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
}

.media-placeholder__caption p {
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  line-height: var(--type-body-m-line);
  color: var(--text-secondary);
  margin: 0;
}

.media-placeholder__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--accent);
}

.media-placeholder__title {
  font-family: var(--font-display);
  font-weight: var(--type-heading-weight);
  font-size: var(--type-heading-size);
  line-height: var(--type-heading-line);
  color: var(--text-primary);
}

/* Logo wall — built dark-mode-only for the homepage's "Trusted by
   regulated organizations" strip. Who We Are's "Who we help" section reuses
   it on a dark section too, so no light-mode variant has been needed yet. */
.logo-wall {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--space-5);
}

.logo-wall__item {
  height: 112px;
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  container-type: inline-size;
  background: repeating-linear-gradient(45deg, rgba(255,255,255,.04), rgba(255,255,255,.04) 8px, transparent 8px, transparent 16px);
  border: var(--border-hairline);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Real-logo variant — once an approved client/partner logo file exists,
   swap .logo-wall__item for this on the same dark sections above. Real
   logos are full-color on transparent backgrounds, so each gets a fixed
   white chip (not a theme token) rather than sitting directly on navy —
   the same "logo on a light card" pattern used industry-wide for dark
   trust walls, chosen because it's the only way a mixed set of full-color
   marks stays legible regardless of the page's light/dark state.
   Padding is --space-2, not --space-3 — at the taller 112px tile height,
   --space-3 still left logos reading small; --space-2 maximizes legible
   logo area while keeping an even margin on every side. */
.logo-wall__item--real {
  background: #fff;
  padding: var(--space-2);
}

.logo-wall__item--real img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

@media (max-width: 900px) {
  .logo-wall {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 480px) {
  .logo-wall {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Partner chip — one shared size for every small inline partner-logo
   mention (was three different ad-hoc sizes: 56×36px on What We Do,
   24px on Why DataBank's partner-recognition row, 20px with no plate
   on Partner Program — all too small to read, fixed 2026-10-29). */
.partner-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: var(--space-2) var(--space-3);
  background: #fff;
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  container-type: inline-size;
}

.partner-chip img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* Partner hero logo — one shared size for the Technology Network
   partner-detail hero cards (was inconsistent inline 150×48px/28px
   per partner, fixed 2026-10-29). Width is intentionally flexible
   (fits-content up to a cap) since wordmarks and square marks need
   different widths to read at the same visual weight; height is the
   constant. */
.partner-hero-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 64px;
  max-width: 220px;
  padding: var(--space-2) var(--space-3);
  background: #fff;
  border: var(--border-hairline);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  container-type: inline-size;
}

.partner-hero-logo img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

.icon-card__icon {
  margin-bottom: var(--space-4);
  color: var(--text-primary);
}

.link-list {
  display: flex;
  flex-direction: column;
  margin-top: var(--space-4);
  border-top: var(--border-hairline);
}

.link-list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  border-bottom: var(--border-hairline);
  font-size: var(--type-body-m-size);
  color: var(--text-primary);
  text-decoration: none;
}

.link-list a:hover {
  color: var(--accent-ink);
}

.numbered-list {
  background: var(--surface-plate);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  box-shadow: var(--graphics-shadow-sm);
}

.numbered-list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5);
  text-decoration: none;
  border-bottom: var(--border-hairline);
}

.numbered-list a:last-child {
  border-bottom: none;
}

.numbered-list__index {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  color: var(--accent);
  margin-right: var(--space-3);
}

.numbered-list__title {
  font-family: var(--font-display);
  font-weight: var(--type-heading-weight);
  font-size: 16px;
  color: var(--text-primary);
}

.numbered-list__desc {
  display: block;
  font-size: var(--type-small-size);
  color: var(--text-secondary);
  font-weight: 400;
  margin-top: 2px;
}

/* Built 2026-10-08 for the Who We Are page (design-handoff/who-we-are.html)
   — genuinely new patterns that page's Claude Design didn't reuse from
   Home. Everything else it needed (.card, .callout, .stat-strip,
   .logo-wall, .layout-three-up/.layout-four-up) was already covered. */

/* Photo placeholder — the brand guide's own convention (DataBank Brand
   System - Guidelines.html, "Placeholders → Treatment"): 3:4 hard crop,
   no overlay, ever. Distinct from .media-placeholder (16:9/16:10, built
   for video and wide image frames) — a portrait crop needed its own ratio
   rather than an aspect-ratio override fighting that component's frame. */
.photo-placeholder {
  aspect-ratio: 3 / 4;
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  background-image: repeating-linear-gradient(45deg, var(--line-hairline) 0, var(--line-hairline) 8px, transparent 8px, transparent 16px);
  border: var(--border-hairline);
  display: flex;
  align-items: flex-end;
  padding: var(--space-3);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Real circular headshot — replaces .photo-placeholder wherever the
   delivered photo is already a circle-cropped portrait on a transparent
   background (leadership roster, client/testimonial headshots), rather
   than forcing a circular source image into the 3:4 rectangular crop
   above, which was sized for a future straight-on photo shoot. */
.people-photo--real {
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
}

.people-photo--real img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Link card — an entire plate that's one clickable link, image on top
   (16:9, same gray placeholder convention), body below. Used for the
   "Explore DataBank" hub grid and the Insights/case-study article grid —
   both are groups of same-shape link-outs, neither is the single-block-vs-
   grouped-content distinction .card's accent line encodes, so this is a
   deliberately separate, line-less plate rather than a .card variant. */
.link-card {
  display: flex;
  flex-direction: column;
  background-color: var(--color-white);
  border: var(--border-hairline);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  overflow: hidden;
  text-decoration: none;
  color: var(--color-navy-base);
}

.link-card__frame {
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: flex-end;
  padding: var(--space-3);
  border-bottom: var(--border-hairline);
  background-image: repeating-linear-gradient(45deg, var(--line-hairline) 0, var(--line-hairline) 6px, var(--color-offwhite) 6px, var(--color-offwhite) 12px);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.link-card__body {
  padding: var(--space-5) var(--space-6) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex: 1;
}

.link-card__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.link-card__title {
  font-family: var(--font-display);
  font-weight: var(--type-heading-weight);
  font-size: var(--type-heading-size);
  line-height: var(--type-heading-line);
  color: var(--color-navy-base);
}

.link-card__body p {
  font-size: var(--type-body-m-size);
  line-height: var(--type-body-m-line);
  color: var(--text-secondary);
  margin: 0;
}

.link-card__cta {
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  color: var(--accent-ink);
  margin-top: auto;
  padding-top: var(--space-2);
  text-decoration: none;
}

/* History timeline — 3 (or more) equal columns under one accent rule that
   spans the full row, each column holding a mono year/era label, a short
   heading and a description. Reuses .card's typographic scale (card__title/
   card__body) for the heading/description rather than inventing new type
   rules for what's visually the same text, but needed its own container
   since there's no plate background or per-column border here — just the
   one shared top rule. */
.timeline {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0 var(--space-6);
  border-top: var(--accent-rule-weight) solid var(--accent);
}

.timeline__item {
  padding: var(--space-5) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.timeline__era {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--accent-ink);
}

@media (max-width: 780px) {
  .timeline {
    grid-template-columns: 1fr;
  }
}

/* Stat strip, described variant — .stat-strip's figure (big tabular
   number) paired with a plain sentence instead of .stat-label's uppercase
   mono tag. Added for "Who we help"'s 4 impact numbers, which read as full
   sentences ("Records processed annually across..."), not short labels —
   forcing that through .stat-label's uppercase/letter-spacing/mono
   treatment would misrepresent it as a tag rather than a description. */
.stat-strip--described > .stat {
  grid-column: span 3;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.stat-desc {
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  line-height: var(--type-body-m-line);
  color: var(--text-secondary);
  max-width: 18em;
}

@media (max-width: 900px) {
  .stat-strip--described > .stat {
    grid-column: span 6;
  }
}

@media (max-width: 480px) {
  .stat-strip--described > .stat {
    grid-column: 1 / -1;
  }
}

/* Service link — a plain top-bordered row used in a 4-up grid (the
   "Related services" pattern), title + arrow on one line, description
   below. Simpler than .numbered-list (no shared plate, no index number) —
   this is a flatter, denser link treatment for a short related-content
   list, not a primary navigational set. */
.service-link {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5) 0;
  border-top: var(--border-hairline);
  text-decoration: none;
  color: var(--text-primary);
}

.service-link__title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-display);
  font-weight: var(--type-heading-weight);
  font-size: 19px;
  line-height: 1.25;
  letter-spacing: var(--type-heading-track);
}

.service-link p {
  font-size: var(--type-small-size);
  line-height: 1.5;
  color: var(--text-secondary);
  margin: 0;
}

/* Avatar placeholder — a round version of the same gray-placeholder
   convention, for a testimonial's attribution photo */
.avatar-placeholder {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  flex: 0 0 auto;
  border: var(--border-hairline);
  background-image: repeating-linear-gradient(45deg, var(--line-hairline) 0, var(--line-hairline) 5px, transparent 5px, transparent 10px);
}

/* Real headshot swapped in for a resolved attribution avatar — keeps the
   same 56px circle footprint, just clips a real photo instead of the
   striped placeholder pattern. */
.avatar-placeholder--real {
  background-image: none;
  overflow: hidden;
}

.avatar-placeholder--real img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Built 2026-10-08 for the What We Do page (design-handoff/what-we-do.html). */

/* Delivery tabs — a clickable list of options where exactly one is active
   at a time, with its full detail shown in a single panel below (reuses
   .card for that panel, so the panel itself needed no new styling). Real
   interactivity (Scott's call, 2026-10-08): the Claude Design export wired
   this to actual click handlers, not just a static layout, so main.js
   implements the same behavior rather than flattening it to a static list.
   JS progressively enhances this — the first tab/panel pair is marked
   correctly in the markup itself, so the section is still coherent with
   JS disabled (just without the ability to switch). */
.delivery-tabs__list {
  display: flex;
  flex-direction: column;
}

.delivery-tabs__tab {
  display: flex;
  align-items: center;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-bottom: var(--border-hairline);
  border-left: 3px solid transparent;
  padding: var(--space-4) var(--space-4);
  font-family: var(--font-display);
  font-weight: var(--type-heading-weight);
  font-size: 19px;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: color var(--motion-duration) var(--motion-easing), border-color var(--motion-duration) var(--motion-easing);
}

.delivery-tabs__tab:hover {
  color: var(--text-primary);
}

.delivery-tabs__tab.is-active {
  border-left-color: var(--accent);
  color: var(--text-primary);
}

.delivery-tabs__index {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  color: var(--text-tertiary);
  margin-right: var(--space-3);
}

.delivery-tabs__tab-arrow {
  margin-left: auto;
  opacity: 0;
  transition: opacity var(--motion-duration) var(--motion-easing);
}

.delivery-tabs__tab.is-active .delivery-tabs__tab-arrow {
  opacity: 1;
}

.delivery-tabs__panel-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  padding: var(--space-4) 0 0;
  border-top: var(--border-hairline);
  list-style: none;
}

.delivery-tabs__panel-list li {
  font-size: var(--type-body-m-size);
  color: var(--text-secondary);
}

/* Icon card, dark plain variant — same plate background/radius/padding as
   .card, but a plain hairline border instead of the accent top-rule. Used
   for single-link-out icon cards (the "Where to start" grid) — .card's
   accent line specifically marks grouped content, which this isn't; it's
   six independent link-outs, not a single group. */
.icon-card--plain {
  background-color: var(--surface-plate);
  border: var(--border-hairline);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--plate-padding);
  box-shadow: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  text-decoration: none;
  color: inherit;
}

.icon-card--plain .link-card__cta {
  margin-top: auto;
}

/* Built 2026-10-08 for the Challenges We Solve page
   (design-handoff/challenges-we-solve.html). */

/* Challenge tabs — two trigger surfaces (the hero's 4 big cards, and the
   small pill row in the section below) both drive ONE shared active index
   and ONE detail panel, with clicking a hero card also scrolling the
   panel into view. Real interactivity (Scott's call, 2026-10-08, same as
   the What We Do delivery-tabs): behavior lives in assets/js/main.js.
   Both trigger surfaces are real buttons (not links) since they only
   change in-page state; the panel's own CTA is the actual link out. */
.challenge-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  text-align: left;
  width: 100%;
  background-color: var(--surface-plate);
  border: var(--border-hairline);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--plate-padding);
  cursor: pointer;
  color: inherit;
  font: inherit;
}

.challenge-card.is-active {
  border-color: var(--accent);
}

.challenge-card__index {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-track);
  color: var(--text-tertiary);
}

/* Pills — a horizontal tab row. Bottom-border active indicator, not a
   rounded pill shape — the brand guide's radius rule is explicit that
   nothing is ever a pill, so the name describes the UI pattern, not the
   shape used to build it. */
.challenge-tabs__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  border-bottom: var(--border-hairline);
  margin-bottom: var(--space-7);
}

.challenge-tabs__pill {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  padding: var(--space-3) 0;
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: color var(--motion-duration) var(--motion-easing), border-color var(--motion-duration) var(--motion-easing);
}

.challenge-tabs__pill:hover {
  color: var(--text-primary);
}

.challenge-tabs__pill.is-active {
  border-bottom-color: var(--accent);
  color: var(--text-primary);
}

.challenge-tabs__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: var(--space-4) 0;
  padding: var(--space-4) 0 0;
  border-top: var(--border-hairline);
  list-style: none;
}

.challenge-tabs__list li {
  font-size: var(--type-body-m-size);
  color: var(--text-secondary);
}

.challenge-tabs__list a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: var(--border-hairline);
  color: var(--text-primary);
  text-decoration: none;
  font-size: var(--type-body-m-size);
}

.challenge-tabs__list a:hover {
  color: var(--accent-ink);
}

/* Callout — the light-blue "what we typically see" box. Distinct from
   .callout (white plate, left accent line): this is a flat accent-tinted
   panel with no line at all, a different visual device for a different
   purpose (a highlighted takeaway, not a quoted/attributed single block). */
.challenge-tabs__callout {
  background-color: var(--accent-light);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--plate-padding-large);
}

/* FAQ accordion — single-open-at-a-time, real interactivity (Scott's call
   2026-10-08). Behavior in assets/js/main.js. */
.faq-accordion {
  border-top: var(--border-hairline);
}

.faq-accordion__item {
  border-bottom: var(--border-hairline);
}

.faq-accordion__question {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: var(--space-5) 0;
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: var(--type-heading-weight);
  font-size: 19px;
  color: var(--text-primary);
}

.faq-accordion__icon {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 20px;
  color: var(--text-tertiary);
}

.faq-accordion__answer {
  margin: 0 0 var(--space-5);
  max-width: 68ch;
  font-size: var(--type-body-size);
  line-height: var(--type-body-line);
  color: var(--text-secondary);
}

/* Built 2026-10-08 for Why DataBank (Pillar/About template group). */

/* Fact list — an icon + statement per row, hairline divider between rows.
   Used in the hero-adjacent "Foundation first" card. Distinct from
   .link-list (which pairs a label with a trailing arrow for navigation)
   and .challenge-tabs__list (plain text or arrow-links) — this one is a
   icon-led list of standalone facts, nothing to click. */
.fact-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
}

.fact-list li {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-top: var(--border-hairline);
  font-size: var(--type-body-m-size);
  color: var(--text-secondary);
}

.fact-list .icon-card__icon {
  flex: 0 0 auto;
  margin-bottom: 0;
}

/* Built 2026-10-08 for Our Story (Pillar/About template group, child page). */

/* Eyebrow — the small mono/uppercase label used above a body-section
   heading (not a hero). Promoted to a real class here: the identical
   inline style had already been hand-repeated 3 times on Our Impact and
   was about to be repeated 3 more times on this page, which is exactly
   the signal to stop duplicating it. Deliberately separate from
   .hero__eyebrow — that one sits on a hero (sometimes dark) and uses
   --accent; this sits in a body section (always light so far) and uses
   --accent-ink for the right contrast there. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--type-label-size);
  letter-spacing: var(--type-label-track);
  text-transform: uppercase;
  color: var(--accent-ink);
  margin: 0 0 var(--space-4);
}

/* Story timeline — a sticky section head (eyebrow + heading + a row of
   year "pills") pinned above a plain vertical list of dated entries.
   Distinct from .timeline (a 3-column grid of 3-4 short eras, used on
   Who We Are) — this is a long-form year-by-year history where each
   entry gets its own full paragraph, so a column grid wouldn't fit more
   than 3 before wrapping awkwardly. The pills are plain anchor links to
   each entry's id (#y0, #y1...); no JS — position: sticky plus native
   in-page anchor jumping does the whole job, and the pills naturally
   un-stick once the list (their own sticky-positioning container) ends. */
.story-timeline__head {
  position: sticky;
  top: var(--space-6);
  background-color: var(--surface-page);
  padding-bottom: var(--space-5);
  margin-bottom: var(--space-2);
}

.story-timeline__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.story-timeline__pill {
  font-family: var(--font-mono);
  font-size: var(--type-small-size);
  color: var(--text-secondary);
  text-decoration: none;
  padding: var(--space-2) var(--space-4);
  border: var(--border-hairline);
  border-radius: var(--radius-max);
  background-color: var(--surface-plate);
  transition: color var(--motion-duration) var(--motion-easing), border-color var(--motion-duration) var(--motion-easing);
}

.story-timeline__pill:hover {
  color: var(--text-primary);
  border-color: var(--accent);
}

.story-timeline__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.story-timeline__item {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: var(--space-6);
  padding: var(--space-6) 0;
  border-top: var(--border-hairline);
  scroll-margin-top: calc(var(--space-6) * 4);
}

.story-timeline__year {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--type-heading-size);
  color: var(--accent-ink);
}

.story-timeline__item h3 {
  margin: 0 0 var(--space-2);
}

.story-timeline__item p {
  margin: 0;
  color: var(--text-secondary);
  max-width: 60ch;
}

@media (max-width: 600px) {
  .story-timeline__item {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* Built 2026-10-08 for Security (Pillar/About template group, child page). */

/* Spec row — a fixed-width label column beside a description column,
   hairline divider between rows. Used for the 5-item certifications list
   (ISO 27001, HIPAA, etc.) where each row is a short name plus a longer
   explanatory sentence — a flat "term: definition" shape that .card and
   .service-link don't fit (no plate per row, and no trailing arrow since
   nothing here is a link). Likely to recur for other spec/certification
   lists elsewhere in the Pillar/About and Partner Detail groups. */
.spec-row {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: var(--space-6);
  padding: var(--space-5) 0;
  border-top: var(--border-hairline);
}

.spec-row__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--type-heading-size);
  color: var(--text-primary);
}

.spec-row__desc {
  margin: 0;
  color: var(--text-secondary);
}

@media (max-width: 600px) {
  .spec-row {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }
}

/* Built 2026-10-08 for Leadership (People Grid template group, child page). */

/* Team card text — name reuses .card__title directly (its 22px/500/
   -.02em display styling matches this design's name text exactly, token
   for token). .team-card__title (the job title under the name) and
   .team-card__link (the LinkedIn out-link) are new: neither matches an
   existing text role (title is smaller/plainer than .card__body's
   15px body copy; the link needs an underline, which no other link
   style on the site currently uses). The photo itself reuses
   .photo-placeholder with an inline aspect-ratio override (4/5 instead
   of the default 3/4) rather than a new class, since every other part
   of that convention — stripe background, hairline border, radius — is
   unchanged. */
.team-card__title {
  font-family: var(--font-body);
  font-size: var(--type-small-size);
  line-height: var(--type-small-line);
  color: var(--text-secondary);
  margin: var(--space-3) 0 var(--space-2);
}

.team-card__link {
  font-size: var(--type-small-size);
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Built 2026-10-08 for Technical Teams (People Grid template group, child page). */

/* Role grid — a 9-item index+label list inside the hero aside card
   ("Who you'll work with"), 3 columns at comfortable widths. Needed a
   real class (not inline styles) because the first inline-only version
   broke: a hero__aside card is a narrow column even at desktop width,
   and 3 columns left too little room for 2-word labels like "Solution
   architects" to wrap — words don't break mid-word by default, so they
   overflowed into the neighboring column instead of wrapping. Fixed by
   making the grid itself responsive (3 columns only above 900px, where
   the hero__aside column is wide enough) rather than fighting it with
   flex-sizing tricks alone. */
.role-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 900px) {
  .role-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.role-grid__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-top: var(--border-hairline);
  min-width: 0;
}

.role-grid__index {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  color: var(--text-secondary);
  width: 20px;
  flex: 0 0 auto;
}

.role-grid__label {
  font-size: var(--type-body-m-size);
  line-height: 1.3;
  flex: 1 1 auto;
  min-width: 0;
}

/* Built 2026-10-08 for Remote Communities (Location Detail template group,
   seventh and final child page — the distributed-workforce counterpart to
   the 6 physical facilities, so it reuses the group's .layout-pinterest-
   board and .photo-placeholder but needed one new card shape). */

/* Quote card — an attributed testimonial as its own plate: a full-bleed
   photo on top, quote and name/title below. Neither .card (padded on every
   edge, no room for a bleeding photo) nor .link-card (photo + body, but
   deliberately no accent rule) fit this — it needs both the full-bleed
   photo AND the .card accent-line identity. Photo reuses .photo-placeholder
   with an inline aspect-ratio override (3/2), same convention as
   Leadership's team photos (4/5 override). */
.quote-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
  background-color: var(--surface-plate);
  border: var(--border-hairline);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  overflow: hidden;
}

.quote-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--accent-line-weight);
  background: var(--accent);
}

.quote-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--plate-padding);
  flex: 1 1 auto;
}

.quote-card__quote {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-primary);
}

.quote-card__footer {
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: var(--border-hairline);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.quote-card__name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.01em;
}

/* Built 2026-10-08 for Mission and Philosophy (Pillar/About template
   group, Our Culture's first child page — a retitled, content-reworked
   version of what was originally scoped as "Our Mission and Vision";
   see this page's branch docblock for the rename note). */

/* Format tag — a small bordered rect for the "every format data arrives
   in" word-list ("Paper," "Scans," "Email," ...). 4px radius, well
   inside the brand guide's normal radius range — not a true pill (the
   guide is explicit nothing on this site ever is), just a compact label
   chip with no existing match (closest, .challenge-tabs__pill, is a
   borderless clickable tab, not a static bordered tag). */
.format-tag {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 var(--space-4);
  border: 1.25px solid var(--color-navy-base);
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* Video module — the ONE shared video component for every video on the
   site (2026-10-30 standardization audit). Replaces .hover-preview-video
   (which had drifted: 4 of its 5 real call sites in template-partner-
   detail.php also carried `controls` and real click-to-play content,
   yet still showed "Hover to preview" and auto-triggered a silent loop
   on hover — fighting with the native control bar underneath) and every
   ad-hoc bare `<video>` sitewide (several had no tag, no play affordance,
   and blended into dark sections with zero contrast).

   Two modes via [data-mode]:
   - "hover": muted, loops on hover/focus, pauses on leave (genuine
     preview — currently only Mission & Philosophy's "The way we think").
     Chip reads "Hover to preview" on hover-capable devices, "Tap to
     play" under (hover: none) — main.js still calls .play()/.pause() on
     tap there since the video itself still plays on touch.
   - "click": real `controls` stays on the <video> as the no-JS/progressive-
     enhancement fallback; our own .video-module__play button sits on top
     until playback starts, calling video.play() directly rather than
     relying on hover. Chip reads "Watch video" and main.js appends the
     real " · M:SS" once loadedmetadata fires (preload="metadata" on
     every instance makes this possible) — never a hardcoded duration
     that could drift from the actual file.

   --video-fit (default "cover") lets a frame whose aspect-ratio doesn't
   exactly match its source (the 3 portrait 9:16 "Get to know DataBank"
   clips in a 16:10 frame) opt into "contain" so the full frame always
   shows — faces and on-screen text are never cropped, at the cost of
   letterboxing. Background stays navy so contain's letterbox bars read
   as an intentional frame, not a layout bug. */
.video-module {
  position: relative;
  aspect-ratio: var(--video-ratio, 16 / 9);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  overflow: hidden;
  background: var(--color-navy-base);
  container-type: inline-size;
}

.video-module video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: var(--video-fit, cover);
  object-position: var(--video-position, center center);
}

.video-module__tag {
  position: absolute;
  left: 12px;
  top: 12px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 6px 10px;
  background: rgba(0, 38, 61, .88);
  border: 1px solid rgba(255, 255, 255, .24);
  border-radius: 4px;
  color: var(--color-white);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 160ms;
  z-index: 2;
}

/* Hover-mode tag text swaps for touch: "hover" means nothing there, so
   the two labels are two spans, toggled by the (hover) media feature
   rather than JS feature-detection (unreliable on hybrid devices). */
.video-module__tag-hover-label { display: none; }
.video-module__tag-tap-label { display: none; }
@media (hover: hover) {
  .video-module[data-mode="hover"] .video-module__tag-hover-label { display: inline; }
}
@media (hover: none) {
  .video-module[data-mode="hover"] .video-module__tag-tap-label { display: inline; }
}

/* Play button overlay — click-to-play's real control (calls video.play()
   directly) and every mode's visible "this plays" affordance until
   playback starts. Solid accent fill rather than a translucent circle:
   guarantees contrast regardless of what's behind it (a dark section, a
   bright poster frame, an unpredictable video thumbnail) rather than
   assuming navy. */
.video-module__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  color: var(--color-white);
  cursor: pointer;
  z-index: 3;
  transition: opacity 160ms, transform 160ms, background-color var(--motion-duration) var(--motion-easing);
}

.video-module__play:hover,
.video-module__play:focus-visible {
  background: var(--color-navy-light);
}

.video-module__play svg {
  width: 18px;
  height: 18px;
  margin-left: 3px; /* optically center the triangle inside the circle */
}

.video-module.is-playing .video-module__play,
.video-module.is-playing .video-module__tag {
  opacity: 0;
  pointer-events: none;
}

/* HubSpot embed variant (.hs-video-widget) — a third-party script
   replaces the placeholder <img> with its own player and play affordance
   once loader.js runs, so we only add the tag for visual consistency,
   never our own play button on top of a control surface we don't own
   (stacking one would intercept clicks meant for HubSpot's player). */
.video-module--embed .video-module__play {
  display: none;
}

.quote-card__title {
  font-size: var(--type-small-size);
  color: var(--text-secondary);
}

/* Built 2026-10-09 for Hyland (Partner Detail template group, first
   partner child page -- establishes the generic long-form partner-page
   shape all remaining partner pages likely share). */

/* Page nav — a sticky "On this page" anchor bar, pinned to the viewport
   top once scrolled to, horizontal-scrolling on narrow widths rather
   than wrapping. New pattern: this is the first page in the project
   long enough to need in-page jump navigation. White background
   (not --surface-page) since it needs to read as chrome sitting above
   the page content regardless of section background underneath it. */
.page-nav {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: var(--color-white);
  border-bottom: var(--border-hairline);
}

.page-nav__inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 64px);
  display: flex;
  align-items: center;
  gap: var(--space-7);
  overflow-x: auto;
  min-height: 56px;
}

.page-nav__label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-secondary);
  white-space: nowrap;
}

.page-nav__link {
  font-size: 14px;
  color: var(--color-navy-base);
  text-decoration: none;
  white-space: nowrap;
  padding: 18px 0;
}

.page-nav__link:hover {
  color: var(--accent-ink);
}

/*
.capability-tabs — a tablist of capability cards sharing one detail
panel (role="tablist"/"tab"/"tabpanel"), plus a "Next: X" pager so a
visitor can step through every capability without hunting for the next
tab. Added 2026-10-19 for Document Scanning Services (Product/Solution
"secondary" template) — the first secondary page, and the pattern every
other secondary page's "what we take on" section reuses. Same click-
swap idea as .delivery-tabs/.challenge-tabs in assets/js/main.js, just
with a pager control added since a capability list can run longer than
a visible row of tabs.
*/

.capability-tabs {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.capability-tabs__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-3);
}

.capability-tabs__tab {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  align-items: center;
  gap: var(--space-4);
  min-height: 76px;
  padding: var(--space-4) var(--space-5);
  background: var(--color-white);
  border: 1px solid var(--line-hairline);
  border-radius: 6px;
  color: var(--color-navy-base);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--motion-duration) var(--motion-easing);
}

.capability-tabs__tab.is-active {
  background: var(--color-lightblue);
  border-color: var(--color-lightblue);
}

.capability-tabs__tab-icon {
  display: block;
  width: 28px;
  height: 28px;
}

.capability-tabs__tab-title {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: 19px;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.capability-tabs__tab-tag {
  display: block;
  margin-top: 6px;
  line-height: 1.3;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-link);
}

.capability-tabs__panel {
  display: none;
}

.capability-tabs__panel.is-active {
  display: block;
}

.capability-tabs__pager {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-7);
  padding-top: var(--space-5);
  border-top: var(--border-hairline);
}

.capability-tabs__pager-count {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  color: var(--text-tertiary);
}

/*
.stage-stepper — the 4-stage Intake/Refine/Manage/Activate forward-
linking strip every Product/Solution "secondary" page ends on, so a
visitor always has a next step rather than a dead end. Added
2026-10-19 for Document Scanning Services, reused unchanged by
Refine/Manage/Activate (only the active stage and its href change).
*/

.stage-stepper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: 0;
  border-top: var(--border-hairline);
  border-left: var(--border-hairline);
}

.stage-stepper__stage {
  display: block;
  padding: var(--space-6) var(--space-5);
  border-right: var(--border-hairline);
  border-bottom: var(--border-hairline);
  color: var(--text-primary);
  text-decoration: none;
}

.stage-stepper__stage.is-current {
  background: var(--color-offwhite);
}

.stage-stepper__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.stage-stepper__meta--current {
  color: var(--text-link);
}

.stage-stepper__name {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: 22px;
  letter-spacing: -0.02em;
  margin: var(--space-3) 0 var(--space-2);
}

.stage-stepper__desc {
  display: block;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/*
.compare-table — added 2026-10-20 for the Industry Use Case tier's "manual
process vs. with DataBank" breakdown (first use: Eligibility and Benefits
Case Documentation). A plain semantic <table>, not a div grid, since this
is genuinely tabular data (one stage per row, two methods per column) —
built as a real reusable component rather than one-off inline styles
because every future Industry Use Case page is expected to carry the same
comparison shape, not just this one.
*/
.compare-table {
  width: 100%;
  border-collapse: collapse;
}

.compare-table th,
.compare-table td {
  text-align: left;
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
  border-top: var(--border-hairline);
  vertical-align: top;
}

.compare-table th {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  border-top: none;
  padding-bottom: var(--space-3);
}

.compare-table td:first-child,
.compare-table th:first-child {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  width: 18%;
  white-space: nowrap;
}

.compare-table td:not(:first-child) {
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.compare-table td:last-child {
  color: var(--text-primary);
}

@media (max-width: 680px) {
  .compare-table, .compare-table thead, .compare-table tbody, .compare-table th, .compare-table td, .compare-table tr {
    display: block;
  }
  .compare-table thead { display: none; }
  .compare-table tr { border-top: var(--border-hairline); padding: var(--space-4) 0; }
  .compare-table td { border-top: none; padding: var(--space-1) 0; }
  .compare-table td:first-child { padding-bottom: var(--space-2); }
}

/*
.role-tabs__pill — added 2026-10-20 for the Industry Use Case tier's "by
role" buying-committee tablist (first use: Eligibility and Benefits Case
Documentation). A real filled/rounded pill (background swap on
.is-active, not an underline tab) — distinct from .challenge-tabs__pill,
which is a flat mono-label underline tab and the wrong visual match for
this shape. Pairs with .delivery-tabs' existing click/panel-swap JS
(same .is-active toggle, same data-tab/data-panel contract) — only the
look is new, not the behavior.
*/
.role-tabs__pill {
  flex: 0 0 auto;
  width: auto;
  white-space: nowrap;
  min-height: 44px;
  padding: 0 var(--space-5);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--color-navy-base);
  background: var(--color-white);
  border: 1px solid var(--line-hairline);
  border-radius: 5px;
  cursor: pointer;
  transition: background var(--motion-duration) var(--motion-easing), border-color var(--motion-duration) var(--motion-easing);
}

.role-tabs__pill:hover {
  border-color: var(--line-rule);
}

.role-tabs__pill.is-active {
  background: var(--accent-light);
  border-color: var(--accent-light);
}

/*
.insight-article — added 2026-10-20 for single.php, the Insights
section rebuild. Wraps the_content() output for real narrative prose
(Article/News/Event/Video posts) so embedded images, blockquotes, and
lists from the block editor match this theme's real typography instead
of unstyled default WordPress output. Base <p>/<h2>/<h3>/<ul> styling
already comes from the global type rules (confirmed working on the
Legal pages' plain prose sections) — this only adds the handful of
tags those pages didn't need: <img>, <blockquote>, <hr>.
*/
.insight-article img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  margin: var(--space-6) 0;
}

/*
.insight-video-embed — wraps databank_render_insight_video()'s output
(single.php's Video branch, added 2026-10-20 for Scott's "tag a video
file into the hub" request). WordPress core's wp_oembed_get() returns a
YouTube/Vimeo <iframe> with fixed width/height attributes; this forces
it (and the <video> fallback for a direct file URL) to a responsive
16:9 regardless of the embed's own attributes.
*/
.insight-video-embed {
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  overflow: hidden;
  margin-bottom: var(--space-6);
}

.insight-video-embed iframe,
.insight-video-embed video {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  display: block;
  border: none;
}

/*
Case Study rebuild components — added 2026-10-21 from the real Claude
Design case study template Scott provided (2 real exports compared:
Massachusetts Registry of Vital Records, an anonymized Healthcare
Provider/PageIQ case study — both share one template shape). The top
key-facts panel and Outcome stats reuse existing components directly
(`.spec-row` for Industry/Challenge/Results rows, `.filter-bar__pill`
for Solution tag-links, `.stat-strip`/`.stat-figure`/`.stat-label` for
the Outcome numbers) rather than new CSS — only 3 genuinely new shapes
were needed, one per distinct list style confirmed across both real
exports:
- Challenges and the Results/Key-takeaways narrative section: a plain
  heading+paragraph grid, NO numbering (`.case-study-grid`).
- The Approach/Implementation section: NUMBERED heading+paragraph items
  (`.case-study-steps`) — confirmed numbered (01-04) in both exports.
- The closing Looking-ahead/Results list: NUMBERED, plain-text-only,
  no titles (`.case-study-plainlist`) — confirmed in both exports.
*/
.case-study-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-7) var(--space-6);
}

.case-study-grid__title {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--type-heading-size);
  color: var(--text-primary);
  margin-bottom: var(--space-2);
}

.case-study-grid__desc {
  color: var(--text-secondary);
  margin: 0;
}

.case-study-steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.case-study-steps__item {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--space-5);
  padding-top: var(--space-6);
  border-top: var(--border-hairline);
}

.case-study-steps__item:first-child {
  border-top: none;
  padding-top: 0;
}

.case-study-steps__index {
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: var(--weight-medium);
  color: var(--accent-ink);
}

.case-study-steps__title {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  font-size: var(--type-heading-size);
  color: var(--text-primary);
  margin-bottom: var(--space-2);
}

.case-study-steps__desc {
  color: var(--text-secondary);
  margin: 0;
}

.case-study-plainlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.case-study-plainlist li {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-top: var(--border-hairline);
  color: var(--text-secondary);
}

.case-study-plainlist li:first-child {
  border-top: none;
  padding-top: 0;
}

.case-study-plainlist__index {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--accent-ink);
}

@media (max-width: 700px) {
  .case-study-grid { grid-template-columns: 1fr; }
  .case-study-steps__item { grid-template-columns: 40px 1fr; }
}

.insight-article blockquote {
  border-left: 3px solid var(--accent);
  padding-left: var(--space-5);
  margin: var(--space-6) 0;
  font-family: var(--font-display);
  font-size: 19px;
  font-style: italic;
  color: var(--text-primary);
}

.insight-article hr {
  border: none;
  border-top: var(--border-hairline);
  margin: var(--space-7) 0;
}

.insight-article ol {
  padding-left: 1.25em;
}

/*
.insights-layout — added 2026-10-20 (revised same day per Scott's
feedback on the first draft). A 2/3 + 1/3 split: the board on the left,
a sticky filter sidebar on the right — Scott's explicit call ("I'd
prefer the tagging system option to appear on the right side, 1/3
column, instead of across the top"), and closer to how an editorial
content hub like McKinsey or HBR actually structures a topic-browse
sidebar alongside a feed, rather than a filter bar stacked above it.
*/
.insights-layout {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-8);
  align-items: start;
}

.insights-sidebar {
  position: sticky;
  top: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
}

.insights-sidebar .filter-bar {
  flex-direction: column;
  align-items: flex-start;
}

@media (max-width: 900px) {
  .insights-layout { grid-template-columns: 1fr; }
  .insights-sidebar { position: static; order: -1; }
}

/*
.insights-board — the main "Pinterest board" mixed-content feed.
Still a CSS-columns masonry, not CSS Grid with manual row-spans — true
variable-height masonry without JS, since a Case Study teaser, a short
News headline, and a 16:9 Video thumbnail are all genuinely different
natural heights. `break-inside: avoid` keeps each card intact instead
of splitting across columns.

**Card containment, revised 2026-10-20 per Scott's direct feedback**
("each content item needs to be contained more — a subtle box with
accent color"): the first editorial pass (a bare top accent rule, no
background) read as too loose. Reverted to this theme's own established
`.card` recipe — `--surface-plate` background, the same inset top-edge
accent rule as every other `.card` on the site (`box-shadow: inset 0
var(--accent-rule-weight) 0 0 var(--accent)`, not a literal border, so
it's a true subtle plate not a heavy outline), and the same radius/
padding tokens — rather than inventing a new "boxed card" look. This is
genuinely the same component contract as `.card` elsewhere in the
project; kept its own class name only because this grid's masonry
column/break-inside rules are specific to it.

**Color-coding by industry**: each card carries a real
`data-subbrand="{industry}"` attribute (set in PHP from the post's real
`industry` taxonomy term) — the exact same `[data-subbrand]` → --accent
system already live sitewide (tokens.css), not a new color system.
Only Public Sector (government teal), Energy (energy amber), and
Commercial Insurance/Healthcare Payers (insurance) have a real distinct
accent; Education, Healthcare Providers, and Regulated Industries
correctly fall through to the standard DataBank Blue accent, same
established precedent as every other page using this token system
(technical-project-plan.md §6) — not a gap to fix here.
*/
.insights-board {
  column-count: 3;
  column-gap: var(--space-6);
}

.insights-board__card {
  container-type: inline-size;
  display: block;
  width: 100%;
  break-inside: avoid;
  margin-bottom: var(--space-6);
  background-color: var(--surface-plate);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--plate-padding);
  box-shadow: inset 0 var(--accent-rule-weight) 0 0 var(--accent);
  /* This card IS the <a> — position in the grid already marks it as a
     control, same as nav/buttons/logo links in the brand guidelines'
     link rule, so no underline at rest (previously unset here, so the
     sitewide inline-link default stood and every line of card text
     rendered underlined). */
  text-decoration: none;
}

.insights-board__card:hover .insights-board__card-title,
.insights-board__card:focus-visible .insights-board__card-title {
  color: var(--accent-ink);
}

.insights-board__card:focus-visible {
  outline: none;
  box-shadow: inset 0 var(--accent-rule-weight) 0 0 var(--accent), 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}

.insights-board__card--featured {
  width: 100%;
  column-span: all;
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--space-7);
  align-items: center;
  padding: var(--plate-padding-large);
  margin-bottom: var(--space-7);
}

/* With the image/video placeholder hidden for launch
   (databank_show_image_placeholders()), a featured post with no real
   featured image has neither child the 2-column grid above expects —
   collapse to one column so the body doesn't sit alone in a half-width
   track with a blank column beside it. */
.insights-board__card--featured:not(:has(.insights-board__card-image)):not(:has(.insights-board__card-image-placeholder)) {
  grid-template-columns: 1fr;
}

.insights-board__card--featured .insights-board__card-title {
  font-size: 32px;
  line-height: 1.15;
}

/*
16:9 (not the previous 16:10) — a 2026-10-30 fix: a real sample of 24
live featured images across Article/News/Event/Case Study posts found
16:9 as the clear majority ratio (17 of 24), with Case Study images a
uniform, deliberate 1020×644 (~8:5) outlier. A fixed-ratio `cover` crop
was slicing text/logo graphics at the edges (e.g. "Box Names DataBank
2025 Partner of the Year" showing as "Box / DataBan") — switched to
`contain` with a background fill so every image shows whole regardless
of its real ratio, landscape frame stays identical on every card (no
more featured-card 4:3 special case either, so the grid lines up), and
the fill color matches the card's own `--surface-plate` so a
non-16:9 image's letterbox bars blend in rather than reading as empty
space. */
.insights-board__card-image {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: contain;
  background-color: var(--surface-plate);
  display: block;
  border-radius: clamp(var(--radius-min), 4cqmin, var(--radius-max));
  margin-bottom: var(--space-4);
}

/*
.insights-board__card-image-placeholder — a real "there will be an
image/video here" placeholder, added 2026-10-20 per Scott's request
("I also wanted image and video placeholders"). Reuses the exact
diagonal-hatch + mono label recipe already established sitewide by
`.photo-placeholder` (Our Impact, Partner Detail, Location Detail,
etc.) rather than inventing a new placeholder look — a 16:9 landscape
ratio to fit this grid instead of `.photo-placeholder`'s 3:4 portrait
crop (matches `.insights-board__card-image`'s own ratio as of
2026-10-30, was 16:10). Shown whenever a post has no real featured
image yet, regardless of content type.
*/
.insights-board__card-image-placeholder {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: clamp(var(--radius-min), 4cqmin, var(--radius-max));
  background-image: repeating-linear-gradient(45deg, var(--line-hairline) 0, var(--line-hairline) 8px, transparent 8px, transparent 16px);
  border: var(--border-hairline);
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  position: relative;
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/*
.insights-board__card-image-placeholder--video — adds a centered play
button over the same hatch backdrop, so a Video-tagged post (real
video URL stored in post meta, see inc/insights-setup.php's Media
Details meta box) reads as "video" at a glance even before a real
thumbnail exists.
*/
.insights-board__card-image-placeholder--video::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background-color: var(--color-white);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}

.insights-board__card-image-placeholder--video::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 8px 0 8px 13px;
  border-color: transparent transparent transparent var(--accent-ink);
  transform: translateX(2px);
}

.insights-board__card-body {
  padding: 0;
}

.insights-board__card-type {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: var(--weight-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: var(--space-3);
}

.insights-board__card-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: var(--weight-medium);
  line-height: 1.3;
  color: var(--text-primary);
  margin-bottom: var(--space-2);
  letter-spacing: -0.01em;
}

.insights-board__card-excerpt {
  font-size: 15px;
  color: var(--text-secondary);
  line-height: 1.6;
  font-family: var(--font-display);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.insights-board__card-meta {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-top: var(--space-3);
}

.insights-board__more {
  display: flex;
  justify-content: center;
  margin-top: var(--space-7);
}

@media (max-width: 960px) {
  .insights-board { column-count: 2; }
}

@media (max-width: 620px) {
  .insights-board { column-count: 1; }
  .insights-board__card--featured { grid-template-columns: 1fr; }
}

/*
.filter-bar — shared across all 4 Insights destinations' taxonomy
filter rows (industry/topic/solution/problem). Real links to real
taxonomy-archive URLs, not JS-only client-side filtering — see
insights-setup.php's docblock for why that distinction matters for SEO.
Default layout is a horizontal wrapping row (still used by Case
Studies' 3 filter rows, which stay full-width above the grid); nested
inside `.insights-sidebar` it switches to a vertical stack (see above).

Industry pills carry the same real `data-subbrand` attribute as the
board cards, with a small color swatch (`::before`) rather than
recoloring the whole pill — keeps the sidebar scannable rather than
turning into a wall of colored buttons.
*/
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-7);
}

.filter-bar__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 13px;
  font-family: var(--font-body);
  color: var(--text-primary);
  text-decoration: none;
  background: var(--color-white);
  border: 1px solid var(--line-hairline);
  border-radius: 999px;
  padding: var(--space-2) var(--space-4);
  white-space: nowrap;
}

.filter-bar__pill[data-subbrand]::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  flex: 0 0 auto;
}

.insights-sidebar .filter-bar__pill {
  width: 100%;
}

.filter-bar__pill:hover {
  border-color: var(--line-rule);
}

.filter-bar__pill.is-active {
  background: var(--accent-light);
  border-color: var(--accent-light);
  font-weight: var(--weight-medium);
}

/*
Search — added 2026-10-22 for search.php and the header type-ahead
(assets/js/main.js). .search-form is the real search box (hero and
header both use it); .search-results/.search-result is a flat,
hairline-divided list rather than a card grid, since results mix real
Pages and real Insights posts (Article/Case Study/News/etc.) in one
feed — a list reads better for mixed, scannable results than a card
grid competing for visual weight. See inc/search-setup.php's docblock
for why body-text matches depend on a real content-sync step.
*/
.search-form {
  display: flex;
  gap: var(--space-3);
  max-width: 34em;
  margin-top: var(--space-6);
}

.search-form__input {
  flex: 1;
  min-width: 0;
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  color: var(--text-primary);
  background: var(--color-white);
  border: var(--border-hairline);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--space-3) var(--space-5);
}

.search-results {
  display: flex;
  flex-direction: column;
}

.search-result {
  padding: var(--space-6) 0;
  border-top: var(--border-hairline);
}

.search-result__meta {
  margin-bottom: var(--space-3);
}

.search-result__title {
  margin: 0 0 var(--space-2);
  font-size: var(--type-heading-size);
}

.search-result__title a {
  color: var(--text-primary);
  text-decoration: none;
}

.search-result__title a:hover {
  text-decoration: underline;
}

.search-result__excerpt {
  color: var(--text-secondary);
  margin: 0;
}

/*
Header type-ahead (.site-header__search) — a button that expands into a
live-suggestions input, replacing the plain utility-bar "Search" link
with real instant results (fetched from the native WP REST API search
endpoint) instead of a full page reload for every keystroke. Hidden
dropdown panel until JS populates it; degrades to a plain link to
search.php if JS fails (progressive enhancement, same standard as every
other interactive component in this theme).
*/
.site-header__search {
  position: relative;
}

.site-header__search-toggle {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--font-body);
  font-size: var(--type-small-size);
  color: var(--text-secondary);
  cursor: pointer;
}

.site-header__search-toggle:hover {
  color: var(--text-primary);
}

.site-header__search-panel {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-3));
  right: 0;
  width: min(360px, 90vw);
  background: var(--color-white);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  box-shadow: var(--graphics-shadow-md, 0 12px 28px rgba(0,0,0,.18));
  padding: var(--space-4);
  z-index: 30;
  --text-primary: var(--color-navy-base);
  --text-secondary: #4A5A6E;
  --text-tertiary: #566878;
  --line-hairline: #D7DEE8;
}
/* .site-header__search-panel re-declares --text-* locally above: this is
   the first light plate ever dropped inside a dark-mode ancestor (the
   header is always data-mode="dark"), so without this, --text-primary
   etc. would inherit the dark header's white/translucent values straight
   through onto this white panel, rendering invisible white-on-white
   text. Caught visually, not by reading the markup. A targeted local
   reset rather than a new sitewide [data-mode="light"] rule, since no
   other component has needed one. */

.site-header__search-panel.is-open {
  display: block;
}

.site-header__search-panel .search-form {
  margin-top: 0;
  max-width: none;
}

.site-header__search-panel .search-form__input {
  color: var(--text-primary);
}

.site-header__search-results {
  margin-top: var(--space-4);
  display: flex;
  flex-direction: column;
  max-height: 320px;
  overflow-y: auto;
}

.site-header__search-results a {
  display: block;
  padding: var(--space-3) 0;
  border-top: var(--border-hairline);
  text-decoration: none;
  color: var(--text-primary);
  font-size: var(--type-small-size);
}

.site-header__search-results a:first-child {
  border-top: none;
}

.site-header__search-results a strong {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
}

.site-header__search-results a span {
  display: block;
  color: var(--text-tertiary);
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .08em;
  margin-top: 2px;
}

.site-header__search-empty,
.site-header__search-footer {
  margin-top: var(--space-4);
  font-size: var(--type-small-size);
  color: var(--text-tertiary);
}

.site-header__search-footer a {
  color: var(--text-link);
}

/*
Real HubSpot form embed — added 2026-10-30 for Connect With an Expert's
hero form card (dark mode). `css: ""` in the hbspt.forms.create() call
disables HubSpot's own default stylesheet, so every visual rule a
HubSpot form needs lives here, scoped to .hs-form-embed, built from this
theme's own tokens rather than copying HubSpot's default look. The
form's own class names (.hs-form, .hs-form-field, .hs-error-msgs, etc.)
are HubSpot's, not ours — stable across HubSpot's v2 embed.
*/
.hs-form-embed .hs-form-field {
  margin-bottom: var(--space-4);
}

.hs-form-embed label {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--type-small-size);
  font-weight: var(--weight-medium);
  color: rgba(255, 255, 255, .85);
}

.hs-form-embed input[type="text"],
.hs-form-embed input[type="email"],
.hs-form-embed input[type="tel"],
.hs-form-embed textarea,
.hs-form-embed select {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  color: var(--color-white);
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .24);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  padding: var(--space-3) var(--space-4);
  box-sizing: border-box;
  transition: border-color var(--motion-duration) var(--motion-easing),
    box-shadow var(--motion-duration) var(--motion-easing);
}

.hs-form-embed textarea {
  min-height: 110px;
  resize: vertical;
}

.hs-form-embed input::placeholder,
.hs-form-embed textarea::placeholder {
  color: rgba(255, 255, 255, .45);
}

.hs-form-embed input:focus,
.hs-form-embed textarea:focus,
.hs-form-embed select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}

.hs-form-embed .hs-error-msgs {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  font-size: var(--type-small-size);
  color: var(--color-accent-exception);
}

.hs-form-embed input.error,
.hs-form-embed textarea.error {
  border-color: var(--color-accent-exception);
}

.hs-form-embed .hs-button {
  width: 100%;
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  font-weight: var(--weight-medium);
  color: var(--color-white);
  background-color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: clamp(var(--radius-min), 6cqmin, var(--radius-max));
  cursor: pointer;
  transition: box-shadow var(--motion-duration) var(--motion-easing);
}

.hs-form-embed .hs-button:hover,
.hs-form-embed .hs-button:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent);
}

.hs-form-embed .submitted-message {
  font-family: var(--font-body);
  font-size: var(--type-body-m-size);
  color: var(--color-white);
}
