/* ==========================================================================
   CBC — Site components
   Every motif here traces back to Master Pitch Deck v3.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--content-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.shell--narrow {
  max-width: var(--content-default);
}

.section {
  padding-block: clamp(var(--space-16), 8vw, var(--space-32));
}

.section--tight {
  padding-block: clamp(var(--space-10), 4vw, var(--space-16));
}

.section--offset {
  background: var(--color-surface-2);
}

.stack > * + * {
  margin-top: var(--space-4);
}
.stack-6 > * + * {
  margin-top: var(--space-6);
}
.stack-10 > * + * {
  margin-top: var(--space-10);
}

.grid {
  display: grid;
  gap: clamp(var(--space-6), 1.8vw, var(--space-8));
}
.grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid--split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--space-8), 5vw, var(--space-20));
}

@media (max-width: 900px) {
  .grid--3,
  .grid--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 620px) {
  .grid--2,
  .grid--3,
  .grid--4,
  .grid--split {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --------------------------------------------------------------------------
   2. TYPOGRAPHY
   -------------------------------------------------------------------------- */

/* The eyebrow — Questrial, spaced caps. Sits above every title in the deck. */
.eyebrow {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-faint);
  line-height: var(--lh-snug);
}

.eyebrow--rust {
  color: var(--color-primary);
}
.eyebrow--inverse {
  color: rgb(255 255 255 / 0.85);
}

/* The signature headline: light-weight wide-tracked caps, two-tone.
   Deck reference: "BUILT FOR  STRATEGY."  */
.display {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-2xl);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  line-height: var(--lh-tight);
  color: var(--color-display-lead);
  text-wrap: balance;
}

.display--hero {
  font-size: var(--text-3xl);
}

.display--sm {
  font-size: var(--text-xl);
}

.display .accent {
  color: var(--color-primary);
}

.display--inverse {
  color: rgb(255 255 255 / 0.72);
}
.display--inverse .accent {
  color: #ffffff;
}

/* Section title — one step down, sentence-case, body font */
.title {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-xl);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.subtitle {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-lg);
  color: var(--color-text);
}

/* Rust sub-head — spaced semibold caps, used above content blocks */
.subhead {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-primary);
}

.lede {
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  max-width: 60ch;
}

.prose {
  max-width: var(--content-prose);
}
.prose p + p {
  margin-top: var(--space-4);
}
.prose strong {
  font-weight: var(--weight-medium);
  color: var(--color-text);
}

.muted {
  color: var(--color-text-muted);
}
.faint {
  color: var(--color-text-faint);
}
.rust {
  color: var(--color-primary);
}
.meta {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* Inline text link */
.link {
  color: var(--color-primary);
  border-bottom: 1px solid color-mix(in oklab, var(--color-primary) 35%, transparent);
  padding-bottom: 1px;
}
.link:hover {
  color: var(--color-primary-hover);
  border-bottom-color: var(--color-primary-hover);
}

/* --------------------------------------------------------------------------
   3. THE RUST RULE — the deck's defining structural device
   -------------------------------------------------------------------------- */

.rule {
  height: var(--rule-height);
  background: var(--color-primary);
  border: 0;
  width: 100%;
}

.rule--full {
  margin-inline: calc(50% - 50vw);
  width: 100vw;
}

.rule--short {
  width: 56px;
  height: 3px;
}

.hairline {
  height: 1px;
  background: var(--color-divider);
  border: 0;
  width: 100%;
}

/* --------------------------------------------------------------------------
   4. PAGE HEADER BLOCK (eyebrow + display headline + full rust rule)
   -------------------------------------------------------------------------- */

.pagehead {
  padding-top: clamp(var(--space-12), 6vw, var(--space-24));
}

.pagehead .eyebrow {
  margin-bottom: var(--space-3);
}

.pagehead__rule {
  margin-top: clamp(var(--space-8), 4vw, var(--space-12));
}

/* --------------------------------------------------------------------------
   4b. RUST GRADIENT SURFACES
   One base class carries the gradient + diagonal hatch. Hero, page heads,
   stat bands and the CTA band are all variants of the same surface so the
   rust reads identically everywhere.
   -------------------------------------------------------------------------- */

.rustsurface {
  position: relative;
  background: var(--gradient-rust);
  color: #ffffff;
  overflow: hidden;
}

/* Rust surfaces are a clean gradient — no diagonal hairlines anywhere. */

.rustsurface > * {
  position: relative;
  z-index: 1;
}

.rustsurface--deep {
  background: var(--gradient-rust-deep);
}

/* Hero — home page. Sits flush beneath the sticky header. */
.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  align-items: center;
  gap: clamp(var(--space-8), 4vw, var(--space-16));
  padding-block: clamp(var(--space-16), 6vw, var(--space-24));
}

.hero__lede {
  margin-top: clamp(var(--space-5), 2.5vw, var(--space-8));
  max-width: 54ch;
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  line-height: var(--lh-relaxed);
  color: rgb(255 255 255 / 0.9);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: clamp(var(--space-7), 3vw, var(--space-10));
}

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: clamp(var(--space-8), 4vw, var(--space-12));
  padding-top: var(--space-5);
  border-top: 1px solid rgb(255 255 255 / 0.25);
}

.hero__metaitem {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.82);
}

.hero__graphic {
  justify-self: end;
  width: 100%;
  /* The plate carries its own drafting margin inside the viewBox, so it needs a
     larger box than a flush graphic would to balance the headline column. */
  max-width: 580px;
}

.hero__graphic svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

@media (max-width: 900px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1fr);
  }
  .hero__graphic {
    justify-self: start;
    max-width: 360px;
  }
}

/* Rust page head — every page except home. A short band: one line of title,
   one line of subtitle, never a button and never a graphic. */
.pagehead--rust {
  padding-block: clamp(var(--space-16), 7vw, var(--space-20));
}

.pagehead--rust .display {
  max-width: none;
  white-space: nowrap;
}

.pagehead--rust .pagehead__lede {
  margin-top: var(--space-4);
  max-width: none;
  white-space: nowrap;
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  color: rgb(255 255 255 / 0.9);
  line-height: var(--lh-relaxed);
}

/* Below the point where a single line can hold the copy, let it wrap. */
@media (max-width: 900px) {
  .pagehead--rust .display,
  .pagehead--rust .pagehead__lede {
    white-space: normal;
    text-wrap: balance;
  }
}

@media (max-width: 560px) {
  .pagehead--rust .display {
    font-size: var(--text-xl);
  }
  .pagehead--rust .pagehead__lede {
    font-size: var(--text-base);
  }
}

/* --------------------------------------------------------------------------
   5. BUTTONS
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  padding: 0.7em 1.5em;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  white-space: nowrap;
}

.btn--primary {
  background: var(--color-primary);
  color: #ffffff;
  border-color: var(--color-primary);
}
.btn--primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
}

/* Dark theme lifts rust to #D0796B for legibility on near-black, which is too
   light to carry white text. Filled buttons flip to ink instead. */
[data-theme='dark'] .btn--primary {
  color: #17100e;
}
[data-theme='dark'] .btn--primary:hover {
  color: #17100e;
}

.btn--ghost {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-border);
}
.btn--ghost:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* Sits on a rust band in both themes, so its colors are fixed, not tokenised. */
.btn--inverse {
  background: #ffffff;
  color: #6f312b;
  border-color: #ffffff;
}
.btn--inverse:hover {
  background: rgb(255 255 255 / 0.88);
}

.btn--inverse-ghost {
  background: transparent;
  color: #ffffff;
  border-color: rgb(255 255 255 / 0.45);
}
.btn--inverse-ghost:hover {
  border-color: #ffffff;
  background: rgb(255 255 255 / 0.1);
}

/* Long labels must never push the page wide on a phone. */
@media (max-width: 620px) {
  .btn {
    white-space: normal;
    text-align: center;
    justify-content: center;
  }
  .btn-row {
    flex-direction: column;
    align-items: stretch;
  }
  .hero__actions .btn {
    flex: 1 1 100%;
  }
}

/* Rows of sibling buttons read as a set only when they share a width. This
   floors the width and centres the label; longer labels still grow past it. */
.btn--equal {
  justify-content: center;
  /* Sized to the longest CTA label on the site ("Explore Industries", 276px)
     so every button in every CTA band renders at an identical width. If a
     longer label is ever added, raise this — do not let text set the width. */
  min-width: 17.5rem;
}

@media (max-width: 440px) {
  .btn--equal {
    min-width: 0;
    width: 100%;
  }
}

.btn--lg {
  font-size: var(--text-base);
  padding: 0.85em 1.9em;
}

/* Shape modifier only. A pill reads as an invitation rather than a control,
   so it suits a single standalone action on a statement band where a squared
   button would compete with the surrounding rules. Combine with any of the
   colour modifiers above; nothing else about the component changes. */
.btn--pill {
  border-radius: var(--radius-full);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* Arrow link — borrows the inward-arrow motif from the CBC mark */
.arrowlink {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  gap: var(--space-2);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
}
.arrowlink svg {
  transition: transform var(--transition-interactive);
}
.arrowlink:hover {
  color: var(--color-primary-hover);
}
.arrowlink:hover svg {
  transform: translateX(4px);
}

/* --------------------------------------------------------------------------
   6. CARDS
   -------------------------------------------------------------------------- */

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: clamp(var(--space-7), 1.9vw, var(--space-9));
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  height: 100%;
}

.card__title {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--lh-snug);
  color: var(--color-text);
}

.card:hover .card__title {
  color: var(--color-primary);
}

.card__body {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  line-height: var(--lh-relaxed);
}

/* Linked card — the whole tile is a target */
a.card {
  transition:
    border-color var(--transition-interactive),
    box-shadow var(--transition-interactive),
    transform var(--transition-interactive);
}
a.card:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
a.card:hover .card__title {
  color: var(--color-primary-hover);
}

/* Card with the slate left-edge bar (deck motif) */
.card--edge {
  border-left: 3px solid var(--color-slate);
}
.card--edge-rust {
  border-left: 3px solid var(--color-primary);
}

/* Emphasis card — rust border, wash fill. The deck's "Our Model" panel. */
.card--emphasis {
  border-color: var(--color-primary);
  background: var(--color-primary-wash);
}

/* Numbered card */
.card__num {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   7. STAT BAND — full-bleed rust band with the diagonal deck texture
   -------------------------------------------------------------------------- */

.statband {
  position: relative;
  background: var(--gradient-rust);
  color: #ffffff;
  overflow: hidden;
}

.statband__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: auto 1px repeat(3, minmax(0, 1fr));
  align-items: center;
  gap: clamp(var(--space-5), 3vw, var(--space-10));
  padding-block: var(--space-10);
}

.statband__label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-sm);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  line-height: var(--lh-snug);
}

.statband__divider {
  background: rgb(255 255 255 / 0.4);
  align-self: stretch;
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}

.stat__figure {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-2xl);
  line-height: 1;
  letter-spacing: var(--track-tight);
}

.stat__caption {
  font-size: var(--text-xs);
  line-height: var(--lh-normal);
  color: rgb(255 255 255 / 0.9);
  max-width: 20ch;
}

@media (max-width: 900px) {
  .statband__inner {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .statband__label,
  .statband__divider {
    display: none;
  }
}
@media (max-width: 560px) {
  .statband__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   8. SIDE PANEL SECTION DIVIDER (deck's left-edge rust band)
   -------------------------------------------------------------------------- */

.panelhead {
  position: relative;
  display: grid;
  grid-template-columns: clamp(60px, 13vw, 160px) minmax(0, 1fr);
  min-height: clamp(200px, 26vw, 320px);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.panelhead__band {
  background: var(--gradient-rust-soft);
  position: relative;
}
.panelhead__band::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    115deg,
    rgb(255 255 255 / 0.06) 0px,
    rgb(255 255 255 / 0.06) 1px,
    transparent 1px,
    transparent 44px
  );
}

.panelhead__body {
  padding: clamp(var(--space-6), 4vw, var(--space-12));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3);
}

/* --------------------------------------------------------------------------
   9. TAGS / CHIPS — the Insights tagging system
   -------------------------------------------------------------------------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  padding: 0.35em 0.85em;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
  background: var(--color-surface);
}

a.chip:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.chip--type {
  background: transparent;
  border-color: color-mix(in oklab, var(--color-primary) 40%, transparent);
  color: var(--color-primary);
}

[data-theme='dark'] .chip--type {
  color: var(--color-primary-active);
}

.chip--domain {
  background: transparent;
  border-color: var(--color-border);
  color: var(--color-text-muted);
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* --------------------------------------------------------------------------
   10. TABLES — rust-tint header, slate-tint stripes
   -------------------------------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.table {
  min-width: 640px;
  font-size: var(--text-sm);
}

.table thead th {
  background: var(--color-primary-tint);
  color: var(--color-primary-active);
  font-weight: var(--weight-medium);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  white-space: nowrap;
}

[data-theme='dark'] .table thead th {
  color: var(--color-primary-active);
}

.table tbody td {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-divider);
  color: var(--color-text-muted);
  vertical-align: top;
}

.table tbody tr:nth-child(even) {
  background: var(--color-surface-2);
}

.table tbody td:first-child {
  color: var(--color-text);
  font-weight: var(--weight-medium);
}

/* --------------------------------------------------------------------------
   11. FORMS
   -------------------------------------------------------------------------- */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.field label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.field input,
.field select,
.field textarea {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0.75em 0.9em;
  font-size: var(--text-sm);
  color: var(--color-text);
  width: 100%;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--color-text-faint);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary) 15%, transparent);
}

.field textarea {
  min-height: 8.75rem;
  resize: vertical;
}

.field__hint {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.field__error {
  font-size: var(--text-xs);
  color: var(--color-error);
}

/* --------------------------------------------------------------------------
   12. GLOBAL HEADER + NAVIGATION
   -------------------------------------------------------------------------- */

.header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  background: #ffffff;
  border-bottom: 1px solid #d9ddde;
  box-shadow: var(--shadow-sm);
  transition: none;
}

/* Only the homepage transitions between its hero overlay and the opaque state.
   Every interior page uses the white header above with no surface transition. */
body[data-nav='home'] .header {
  transition:
    background var(--transition-interactive),
    box-shadow var(--transition-interactive),
    border-color var(--transition-interactive);
}

body[data-nav='home'] .header:not(.header--scrolled) {
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}

.header--scrolled,
.nav-open .header {
  background: #ffffff;
  border-bottom-color: #d9ddde;
  box-shadow: var(--shadow-sm);
}

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  height: var(--header-height);
  max-width: var(--content-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* --- Logo lockup ------------------------------------------------------- */

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.brand__mark {
  width: 52px;
  height: auto;
}

/* Lockup with wordmark — used in the footer (the header shows the mark alone) */
.brand__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.brand__name {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text);
  line-height: var(--lh-tight);
  white-space: nowrap;
}

.brand__tag {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  line-height: var(--lh-tight);
  white-space: nowrap;
}

/* The mark is a rust PNG — invert it so it reads on the dark surface */
[data-theme='dark'] .brand__mark {
  filter: brightness(0) invert(1);
  opacity: 0.92;
}




/* --- Desktop nav ------------------------------------------------------- */

.nav {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-left: auto;
}

.nav__item {
  position: relative;
}

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  appearance: none;
  background: transparent;
  border: 0;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  padding: var(--space-2) var(--space-3);
  color: var(--color-text);
  border-radius: var(--radius-sm);
  position: relative;
  cursor: pointer;
}

.nav__link:not(a):not(button) {
  cursor: default;
}

.nav__link::after {
  content: '';
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: 2px;
  height: 2px;
  background: var(--color-primary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--transition-interactive);
}

.nav__link:hover::after,
.nav__link[aria-current='page']::after {
  transform: scaleX(1);
}

.nav__link:hover,
.nav__link[aria-current='page'] {
  color: var(--color-primary);
}

.nav__caret {
  width: 9px;
  height: 9px;
  transition: transform var(--transition-interactive);
  opacity: 0.6;
}

.nav__item:hover .nav__caret {
  transform: rotate(180deg);
}

/* --- Mega dropdown ---------------------------------------------------- */

.mega {
  position: absolute;
  top: calc(100% + 12px);
  left: 50%;
  transform: translate(-50%, 6px);
  min-width: 680px;
  background: #FFFFFF;
  border: 1px solid #D9DDDE;
  border-top: 2px solid var(--color-primary);
  border-radius: 0;
  box-shadow: 0 30px 70px rgb(0 0 0 / 0.13);
  padding: var(--space-6) var(--space-7) var(--space-5);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    transform var(--transition-interactive),
    visibility var(--transition-interactive);
  transition-delay: 0s;
}

/* No notch. The rust top edge already ties the panel to the bar, and a
   triangle would break the flat glass plane. */

.nav__item:hover .mega {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate(-50%, 0);
  transition-delay: 90ms; /* hover intent — no flash when sweeping the bar */
}

/* Escape dismiss must outrank the hover/focus rule above */
.nav__item:hover .mega[data-dismissed='true'] {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition-delay: 0s;
}

/* Invisible bridge so the pointer can travel from link to panel */
.nav__item::before {
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 16px;
}

.mega__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
}

.mega__col-title {
  display: block;
  text-align: left;
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid #D9DDDE;
}

.mega__list {
  list-style: none;
  display: flex;
  flex-direction: column;
}

/* Every row starts on the same left edge as its column title. No inset,
   no negative bleed, no leading glyph -- one clean column of text. */
.mega__list a {
  position: relative;
  display: block;
  font-size: var(--text-sm);
  color: #000000;
  text-align: left;
  padding: 10px var(--space-3);
  margin-inline: calc(var(--space-3) * -1);
  border-radius: var(--radius-sm);
  border-bottom: 0;
  transition:
    color var(--transition-interactive),
    background var(--transition-interactive);
}

.mega__list a:hover,
.mega__list a:focus-visible {
  color: var(--color-primary);
  background: rgb(166 74 64 / 0.08);
}

/* The hub link in the panel foot is clickable too, so it gets the same
   shaded plate rather than a bare colour change. */
.mega__foot a {
  padding: 8px var(--space-3);
  margin-inline: calc(var(--space-3) * -1);
  border-radius: var(--radius-sm);
  transition:
    color var(--transition-interactive),
    background var(--transition-interactive);
}

.mega__foot a:hover,
.mega__foot a:focus-visible {
  background: rgb(166 74 64 / 0.08);
}

[data-theme='dark'] .mega__list a:hover,
[data-theme='dark'] .mega__list a:focus-visible,
[data-theme='dark'] .mega__foot a:hover,
[data-theme='dark'] .mega__foot a:focus-visible {
  background: rgb(208 121 107 / 0.14);
}

.mega__foot {
  margin-top: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  display: flex;
}

.mega__hub {
  font-size: var(--text-xs);
}

/* Between the mobile breakpoint and roughly 1180px there is not enough room
   left of the trigger for a centred 680px panel, so it anchors to the right
   edge of the nav instead of to the link. Pre-existing at the old 600px
   width too -- the wider glass pane just made it show sooner. */
@media (max-width: 1180px) {
  .nav {
    position: relative;
  }
  .nav__item {
    position: static;
  }
  .mega {
    left: auto;
    right: 0;
    transform: translate(0, 6px);
  }
  .nav__item:hover .mega {
    transform: translate(0, 0);
  }
  .nav__item::before {
    left: auto;
    right: 0;
    width: 100%;
  }
}

/* Just above the mobile breakpoint even a right-anchored 680px pane runs
   past the left gutter, so it steps down to fit. */
@media (max-width: 980px) {
  .header__inner {
    position: relative;
  }
  .nav {
    position: static;
  }
  .mega {
    left: var(--gutter);
    right: var(--gutter);
    min-width: 0;
    width: auto;
    max-width: 680px;
    margin-left: auto;
    padding: var(--space-5) var(--space-5) var(--space-4);
  }
}

/* Mega menus stay opaque white in both themes for predictable contrast. */
[data-theme='dark'] .mega {
  background: #FFFFFF;
  border-color: #D9DDDE;
  border-top-color: #A64A40;
  box-shadow: 0 30px 70px rgb(0 0 0 / 0.22);
}

[data-theme='dark'] .mega__col-title {
  border-bottom-color: #D9DDDE;
  color: #A64A40;
}

[data-theme='dark'] .mega__list a:hover,
[data-theme='dark'] .mega__list a:focus-visible {
  color: #A64A40;
}

/* --- Header actions --------------------------------------------------- */

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
  margin-left: var(--space-4);
}

/* In the header the Contact CTA sits in a row of nav links, so it drops the
   uppercase + tracking treatment and rides a tighter box. Elsewhere .btn keeps
   its full-size spaced-caps form. The bar CTA is a pill on every page: it is
   the one invitation in a row of plain links, and the shape separates it from
   the squared icon controls beside it. Shape comes from the existing pill
   token, so it is the same radius the .btn--pill modifier uses. */
.header__actions > .btn {
  font-size: var(--text-sm);
  text-transform: none;
  letter-spacing: 0;
  height: 38px;
  padding: 0 1.15em;
  align-items: center;
  border-radius: var(--radius-full);
}

.iconbtn {
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}
.iconbtn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.navtoggle {
  display: none;
}

/* --- Mobile nav ------------------------------------------------------- */

.mobilenav {
  position: fixed;
  inset: var(--header-height) 0 0 0;
  z-index: 99;
  background: var(--color-bg);
  overflow-y: auto;
  padding: var(--space-6) var(--gutter) var(--space-20);
  transform: translateY(-8px);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--transition-interactive),
    transform var(--transition-interactive),
    visibility var(--transition-interactive);
}

.mobilenav[data-open='true'] {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.mobilenav details {
  border-bottom: 1px solid var(--color-divider);
}

.mobilenav summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) 0;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  cursor: pointer;
  list-style: none;
}
.mobilenav summary::-webkit-details-marker {
  display: none;
}

.mobilenav summary svg {
  width: 11px;
  height: 11px;
  opacity: 0.5;
  transition: transform var(--transition-interactive);
}
.mobilenav details[open] summary svg {
  transform: rotate(180deg);
}
.mobilenav details[open] summary {
  color: var(--color-primary);
}

.mobilenav__group {
  padding-bottom: var(--space-4);
}

.mobilenav__group-title {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: var(--space-2);
}

.mobilenav__group + .mobilenav__group {
  margin-top: var(--space-4);
}

.mobilenav__group a {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  padding: var(--space-2) 0;
}
.mobilenav__group a:hover {
  color: var(--color-primary);
}

/* Hub row echoes the desktop panel footer. Two classes so it outranks
   the `.mobilenav__group + .mobilenav__group` margin above. */
.mobilenav__group + .mobilenav__group--hub {
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  padding-bottom: var(--space-1);
  border-top: 1px solid var(--color-divider);
}

.mobilenav__group--hub a {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
}

.mobilenav__flat {
  display: block;
  padding: var(--space-4) 0;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  border-bottom: 1px solid var(--color-divider);
}

.mobilenav__cta {
  margin-top: var(--space-8);
}

/* Below 600px the bar CTA is hidden and this is the navigation's Contact
   button, so it takes the same pill shape. Its colour is left alone: it is a
   standard filled `.btn--primary` on the panel surface, and the panel follows
   the site theme rather than the bar's always-light palette. */
.mobilenav__cta > .btn {
  border-radius: var(--radius-full);
}

@media (max-width: 900px) {
  .nav {
    display: none;
  }
  .navtoggle {
    display: inline-grid;
  }
  .header__actions {
    margin-left: auto;
  }
}

/* Below this width the Contact CTA lives inside the mobile panel instead,
   so the header keeps the mark, the theme toggle, and the menu button. */
@media (max-width: 600px) {
  .header__actions > .btn {
    display: none;
  }
}

@media (min-width: 901px) {
  .mobilenav {
    display: none;
  }
}

@media (max-width: 420px) {
  .brand__mark {
    width: 42px;
  }
}

/* --------------------------------------------------------------------------
   12b. TRANSPARENT-TO-WHITE HEADER
   Every page starts beneath one transparent fixed bar. Scrolling or opening
   the mobile navigation resolves it to the same opaque white surface.
   -------------------------------------------------------------------------- */

/* Clear the fixed bar without collapsing the gradient behind it. Applies to
   the home hero and to the shorter rust page head on every interior page. */
body[data-header='overlay'] .hero .hero__inner {
  padding-top: calc(var(--header-height) + clamp(var(--space-10), 5vw, var(--space-20)));
}

body[data-header='overlay'] .pagehead--photo,
body[data-header='overlay'] .pagehead--rust {
  padding-top: calc(var(--header-height) + clamp(var(--space-10), 4vw, var(--space-16)));
}

/* --- Nav CTA -----------------------------------------------------------
   The bar button is a filled rust pill: the single primary action on the site
   and the only filled control on the bar, so it does not compete with the nav
   links or read as another outline. It holds that treatment on every page and
   in every bar state — transparent, scrolled-opaque and nav-open — except on
   the home page, where the bar starts transparent over the dark photographic
   hero and the CTA keeps its white overlay outline until the bar resolves to
   white (see the home block below). Font size is left at the nav's own size.

   --nav-cta-bg is a local hook so the dark theme can re-point the fill without
   restating the rule. */
.header__actions .btn--primary {
  --nav-cta-bg: var(--color-primary);
  --nav-cta-bg-hover: var(--color-primary-hover);
  background: var(--nav-cta-bg);
  border-color: var(--nav-cta-bg);
  color: #ffffff;
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  letter-spacing: 0;
  text-transform: none;
  transition:
    background var(--transition-interactive),
    border-color var(--transition-interactive),
    color var(--transition-interactive);
}

/* Hover and keyboard focus land on the same darker rust, matching every other
   filled rust control on the site. The focus ring traces the pill rather than
   the base 8px radius the global :focus-visible rule assumes. */
.header__actions .btn--primary:hover,
.header__actions .btn--primary:focus-visible {
  background: var(--nav-cta-bg-hover);
  border-color: var(--nav-cta-bg-hover);
  color: #ffffff;
}

.header__actions > .btn:focus-visible {
  border-radius: var(--radius-full);
}

/* The bar's opaque state is deliberately white in both site themes, and its
   transparent state only ever sits over a light or photographic head, so the
   CTA stays on the light-surface rust in dark mode like every other control on
   the bar. Dark-theme rust (#d0796b) is too light to carry white text — 3.2:1,
   below AA — where the light-surface rust holds 5.7:1. */
[data-theme='dark'] .header__actions .btn--primary {
  --nav-cta-bg: #a64a40;
  --nav-cta-bg-hover: #823a32;
  color: #ffffff;
}

/* --- White treatment while the transparent bar sits over a hero -------- */

body[data-nav='home'] .header:not(.header--scrolled) .brand__mark {
  filter: brightness(0) invert(1);
}

body[data-nav='home'] .header:not(.header--scrolled) .nav__link,
body[data-nav='home'] .header:not(.header--scrolled) .nav__link:hover,
body[data-nav='home'] .header:not(.header--scrolled) .nav__link[aria-current='page'] {
  color: #ffffff;
}

body[data-nav='home'] .header:not(.header--scrolled) .nav__link::after {
  background: #ffffff;
}

body[data-nav='home'] .header:not(.header--scrolled) .iconbtn {
  border-color: rgb(255 255 255 / 0.4);
  color: #ffffff;
}

body[data-nav='home'] .header:not(.header--scrolled) .iconbtn:hover {
  border-color: #ffffff;
  background: rgb(255 255 255 / 0.12);
}

/* The home CTA is the one exception to the filled rust bar button. While the
   bar is transparent over the dark photographic hero it keeps the white
   overlay outline it shares with the hero's own buttons — a rust fill there
   would sit as a coloured block on the photograph and break the hero's
   composition. It still takes the pill shape from `.header__actions > .btn`.
   `:not(.nav-open)` matters: opening the mobile panel resolves the bar to
   white without adding `.header--scrolled`, and a white outline on a white bar
   is invisible. Once the bar is white — scrolled or nav-open — the CTA falls
   through to the shared filled rust pill, which is the correct treatment on
   that surface. */
body[data-nav='home']:not(.nav-open) .header:not(.header--scrolled) .btn--primary {
  background: transparent;
  border-color: rgb(255 255 255 / 0.4);
  color: #ffffff;
}

body[data-nav='home']:not(.nav-open) .header:not(.header--scrolled) .btn--primary:hover,
body[data-nav='home']:not(.nav-open) .header:not(.header--scrolled) .btn--primary:focus-visible {
  background: rgb(255 255 255 / 0.12);
  border-color: #ffffff;
  color: #ffffff;
}

/* A rust focus ring is close to invisible on the dark hero photograph, so the
   overlay state rings in white. */
body[data-nav='home']:not(.nav-open) .header:not(.header--scrolled) .header__actions > .btn:focus-visible {
  outline-color: #ffffff;
}

/* The employee spotlight and internal style guide open on white rather than a
   dark/photo hero. Their bar stays transparent, but uses the standard dark
   control treatment until it becomes opaque. */
body[data-header='static'] .header:not(.header--scrolled) .brand__mark,
body[data-nav='none'] .header:not(.header--scrolled) .brand__mark {
  filter: none;
  opacity: 1;
}

body[data-header='static'] .header:not(.header--scrolled) .nav__link,
body[data-header='static'] .header:not(.header--scrolled) .nav__link:hover,
body[data-header='static'] .header:not(.header--scrolled) .nav__link[aria-current='page'],
body[data-nav='none'] .header:not(.header--scrolled) .nav__link,
body[data-nav='none'] .header:not(.header--scrolled) .nav__link:hover,
body[data-nav='none'] .header:not(.header--scrolled) .nav__link[aria-current='page'] {
  color: #171717;
}

body[data-header='static'] .header:not(.header--scrolled) .nav__link::after,
body[data-nav='none'] .header:not(.header--scrolled) .nav__link::after {
  background: var(--color-primary);
}

body[data-header='static'] .header:not(.header--scrolled) .iconbtn,
body[data-nav='none'] .header:not(.header--scrolled) .iconbtn {
  border-color: #bfc7c9;
  color: #4f5e61;
}

/* No CTA rule here: the static/utility bar is a light surface, so the shared
   filled rust pill from the Nav CTA block above is already correct. */

/* The opaque state is deliberately white in both site themes. Keep every
   control on the corresponding light-surface palette. */
.header--scrolled .brand__mark,
.nav-open .header .brand__mark,
[data-theme='dark'] .header--scrolled .brand__mark,
[data-theme='dark'] .nav-open .header .brand__mark {
  filter: none;
  opacity: 1;
}

.header--scrolled .nav__link,
.header--scrolled .nav__link:hover,
.header--scrolled .nav__link[aria-current='page'],
.nav-open .header .nav__link,
.nav-open .header .nav__link:hover,
.nav-open .header .nav__link[aria-current='page'] {
  color: #171717;
}

.header--scrolled .nav__link::after,
.nav-open .header .nav__link::after {
  background: var(--color-primary);
}

.header--scrolled .iconbtn,
.nav-open .header .iconbtn {
  border-color: #bfc7c9;
  color: #4f5e61;
}

.header--scrolled .iconbtn:hover,
.nav-open .header .iconbtn:hover {
  border-color: var(--color-primary);
  background: rgb(166 74 64 / 0.1);
  color: var(--color-primary);
}

/* Header CTA: outlined rust pill at rest, filled rust on hover. The existing
   home-transparent rule above (body[data-nav='home']:not(.nav-open)
   .header:not(.header--scrolled) .btn--primary) still governs that state. */
.header .header__actions .btn--primary {
  background: transparent;
  color: var(--color-primary);
  border-color: var(--color-primary);
}
.header .header__actions .btn--primary:hover,
.header .header__actions .btn--primary:focus-visible {
  background: var(--color-primary);
  color: #ffffff;
  border-color: var(--color-primary);
}

/* Fixed headers no longer create a layout gap. Utility openings that do not
   supply a full-bleed hero receive content clearance without introducing a
   visible band between the navigation and their first section. */
body:not([data-header='overlay']) .pagehead {
  padding-top: calc(var(--header-height) + clamp(var(--space-12), 6vw, var(--space-24)));
}

/* Mega panels keep their own opaque surface, so no inversion needed there. */

/* --------------------------------------------------------------------------
   13. CTA BAND — identical on every page, always points to /contact
   -------------------------------------------------------------------------- */

/* Every closing band uses the approved Transformations treatment: flat CBC
   rust, white copy, and white outlined pill controls. */
.cta.cta--operations-rust,
[data-theme='dark'] .cta.cta--operations-rust {
  position: relative;
  background-color: #a64a40;
  background-image: none;
  color: #ffffff;
  overflow: hidden;
}

.cta--operations-rust::before,
.cta--operations-rust::after,
.cta--operations-rust .cta__cv {
  display: none;
}

.cta__cv {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: none; z-index: 0;
  pointer-events: none;
}

.cta__inner {
  position: relative;
  z-index: 1;
  max-width: 78rem;
  margin-inline: auto;
  text-align: center;
  padding-block: clamp(var(--space-16), 7vw, var(--space-24));
}

/* The CTA headline sits on one line at desktop widths, but must be allowed to
   wrap — a nowrap line wider than its container overflows to the RIGHT only,
   which reads as a broken centre alignment.

   Sized a step below the page-hero `.display` scale so every CTA headline on the
   site clears the content measure on one line from 900px up — the same width at
   which the rest of the page collapses to a single column. The longest headline
   holds ~3% clearance at 900px. Below that the band wraps and balances. */
.cta__title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.05rem + 1.95vw, 2.75rem);
  font-weight: 500;
  letter-spacing: 0.055em;
  text-transform: none;
  white-space: normal;
  text-wrap: balance;
}

.cta--operations-rust .cta__title,
.cta--operations-rust .cta__title .accent {
  color: #ffffff;
}

/* One line for the title and one for the lede. Above 768px the type is
   sized so the longest of either fits the shell without wrapping; below
   that the copy is allowed to wrap rather than shrink to nothing. */
@media (min-width: 768px) {
  .cta__title,
  .cta__lede { white-space: nowrap; }
}

@media (min-width: 768px) and (max-width: 1023.98px) {
  .cta__title { font-size: calc(3.55vw - 0.5px); }
}

.cta__lede {
  margin-top: var(--space-6);
  margin-inline: auto;
  max-width: min(100%, 72ch);
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  line-height: var(--lh-relaxed);
  text-wrap: balance;
  color: rgb(255 255 255 / 0.88);
}

.cta--operations-rust .cta__lede {
  color: rgb(255 255 255 / 0.88);
}

.cta__actions {
  margin-top: clamp(var(--space-8), 3vw, var(--space-10));
  justify-content: center;
}

.cta__actions.cta__actions--pill .btn {
  min-height: 44px;
  gap: var(--space-3);
  padding: 10px 20px;
  font-family: var(--font-eyebrow);
  font-size: 0.82rem;
  letter-spacing: var(--track-caps-sm);
}

.cta__actions.cta__actions--pill .btn::after {
  content: "\2192";
  display: inline-block;
  flex: 0 0 auto;
  font-family: Arial, sans-serif;
  font-size: 1.2em;
  line-height: 1;
  transform: translateX(0);
  transition: transform var(--dur-2) var(--ease-standard);
}

.cta__actions.cta__actions--pill .btn:hover::after,
.cta__actions.cta__actions--pill .btn:focus-visible::after {
  transform: translateX(4px);
}

.cta__actions.cta__actions--pill .btn:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 3px;
}

.cta--operations-rust .cta__actions.cta__actions--pill .btn {
  border-radius: var(--radius-full);
  border-color: rgb(255 255 255 / 0.45);
  background: transparent;
  color: #ffffff;
  backdrop-filter: none;
  box-shadow: none;
}

.cta--operations-rust .cta__actions.cta__actions--pill .btn:hover,
.cta--operations-rust .cta__actions.cta__actions--pill .btn:focus-visible {
  border-color: #ffffff;
  background: rgb(255 255 255 / 0.1);
  color: #ffffff;
  backdrop-filter: none;
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .cta__actions.cta__actions--pill .btn::after,
  .cta__actions.cta__actions--pill .btn:hover::after,
  .cta__actions.cta__actions--pill .btn:focus-visible::after {
    transform: none;
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   14. FOOTER
   -------------------------------------------------------------------------- */

.footer {
  background: var(--color-surface-offset);
  border-top: 1px solid var(--color-border);
  padding-block: clamp(var(--space-12), 5vw, var(--space-20)) var(--space-8);
}








/* --------------------------------------------------------------------------
   15. ABSTRACT GRAPHIC MOTIFS (in place of photography)
   -------------------------------------------------------------------------- */

.motif {
  color: var(--color-primary);
}
.motif--slate {
  color: var(--color-slate);
}

.motif-frame {
  position: relative;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: var(--space-8);
  aspect-ratio: 4 / 3;
}

/* Hairline diagonal field — the deck's slide texture, as a web surface */
.hatch {
  background-image: repeating-linear-gradient(
    115deg,
    color-mix(in oklab, var(--color-primary) 9%, transparent) 0px,
    color-mix(in oklab, var(--color-primary) 9%, transparent) 1px,
    transparent 1px,
    transparent 22px
  );
}

/* Dot field */
.dotfield {
  background-image: radial-gradient(
    color-mix(in oklab, var(--color-slate) 34%, transparent) 1px,
    transparent 1px
  );
  background-size: 16px 16px;
}

/* --------------------------------------------------------------------------
   16. SCROLL REVEAL
   -------------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--transition-slow),
    transform var(--transition-slow);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

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

/* --------------------------------------------------------------------------
   17. SKIP LINK
   -------------------------------------------------------------------------- */

.skiplink {
  position: absolute;
  left: var(--space-4);
  top: var(--space-2);
  z-index: 200;
  background: var(--color-primary);
  color: #ffffff;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  transform: translateY(-160%);
}
.skiplink:focus {
  transform: none;
}

/* --------------------------------------------------------------------------
   18. STYLE-GUIDE-ONLY HELPERS
   -------------------------------------------------------------------------- */

.swatch {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
}
.swatch__chip {
  height: 84px;
}
.swatch__meta {
  padding: var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.swatch__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.swatch__hex {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  color: var(--color-text-faint);
}

.spec {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-6);
  background: var(--color-surface);
  display: grid;
  grid-template-columns: minmax(0, 1fr) 200px;
  gap: var(--space-6);
  align-items: center;
}
.spec__note {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
  line-height: var(--lh-relaxed);
  text-align: right;
}
@media (max-width: 720px) {
  .spec {
    grid-template-columns: minmax(0, 1fr);
  }
  .spec__note {
    text-align: left;
  }
}

.guide-toc {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.guide-toc a {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  padding: 0.4em 1em;
}
.guide-toc a:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* --------------------------------------------------------------------------
   20. HOME PAGE COMPONENTS
   -------------------------------------------------------------------------- */

/* Section header: eyebrow + short rust rule + title, used to open each band */
.sectionhead {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: clamp(var(--space-10), 4vw, var(--space-16));
  max-width: 72ch;
}

.sectionhead--split {
  flex-direction: row;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-8);
  max-width: none;
}

/* Section heads now end in a button rather than an arrow link. It sits on the
   text baseline of the lede, so it needs no extra alignment nudge. */
.sectionhead__cta {
  flex-shrink: 0;
}

.sectionhead__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 62ch;
}

/* Section subtitles run as a single line at desktop width. Copy is written
   to fit the 1100px shell; below that they wrap normally. */
.sectionhead__text .lede { text-wrap: pretty; }

.sectionhead { max-width: none; }
.sectionhead > .lede,
.sectionhead__text > .lede { max-width: none; }

@media (max-width: 720px) {
  .sectionhead--split {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Pull quote — the deck's founding-idea statement */
.pullquote {
  align-self: start;
  border-left: var(--rule-height) solid var(--color-primary);
  padding-left: clamp(var(--space-5), 3vw, var(--space-10));
}

.pullquote__text {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-xl);
  line-height: var(--lh-snug);
  color: var(--color-text);
  text-wrap: balance;
}

.pullquote__attr {
  margin-top: var(--space-5);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* Solution matrix — two dimensions of the firm by five solutions each,
   read as one 10-cell grid rather than two separate menus. */
/* A small gap separates the two dimensions without breaking the block into
   two visually independent sections. */
.matrix {
  display: grid;
  gap: clamp(var(--space-5), 1.8vw, var(--space-8));
  border-top: 1px solid var(--color-text);
}

.matrixrow {
  border-bottom: 1px solid var(--color-divider);
  --row-accent: var(--color-primary);
  --row-accent-strong: var(--color-primary-hover);
}

.matrixrow__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) clamp(var(--space-4), 2vw, var(--space-6));
  border-bottom: 1px solid var(--color-divider);
  padding-block: clamp(var(--space-5), 1.8vw, var(--space-7));
}

.matrixrow__domain {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--row-accent-strong);
  white-space: nowrap;
}

.matrixrow__promise {
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  max-width: 56ch;
  text-wrap: pretty;
}

/* The dimension link is pushed to the far right of the head row and holds the
   same baseline as the domain title. */
.matrixrow__link {
  margin-left: auto;
  flex-shrink: 0;
}

/* The two dimension links sit together beneath the whole grid, so the block
   reads as one register with one exit point per side. */
.matrix__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) clamp(var(--space-8), 3vw, var(--space-12));
  padding-top: clamp(var(--space-5), 1.8vw, var(--space-7));
}

.arrowlink--rust { color: var(--color-primary-hover); }

/* --- the five cells --------------------------------------------------- */
.matrixrow__cells {
  --cell-pad-x: clamp(var(--space-4), 1.6vw, var(--space-6));
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  /* Four shared row tracks -- index, name, note, arrow -- inherited by each cell
     through subgrid below. A two-line solution name would otherwise drop its own
     note and arrow a line below the single-line cells beside it, which is very
     visible on a row of five hairline-separated cells. Cells that omit the arrow
     simply leave the fourth track empty. */
  grid-auto-rows: auto auto auto auto;
  margin-inline: calc(var(--cell-pad-x) * -1);
}

.cell {
  position: relative;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4;
  row-gap: var(--space-3);
  align-content: start;
  padding-block: clamp(var(--space-6), 2vw, var(--space-8));
  padding-inline: var(--cell-pad-x);
  color: var(--color-text);
  transition: color var(--transition-interactive);
}

/* Hairlines between cells only, so the row reads as a grid and not as boxes. */
.cell + .cell::after {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 1px;
  background: var(--color-divider);
}

/* The hover wash sits behind the content and bleeds slightly past the cell. */
.cell::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--row-accent) 7%, transparent);
  opacity: 0;
  transition: opacity var(--transition-interactive);
}

.cell > * {
  position: relative;
}

.cell__idx {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  color: var(--color-text-faint);
  transition: color var(--transition-interactive);
}

.cell__name {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  text-wrap: pretty;
}

.cell__note {
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.cell__arrow {
  display: inline-flex;
  margin-top: auto;
  padding-top: var(--space-4);
  color: var(--row-accent);
  transition: transform var(--transition-interactive);
}

.cell:hover {
  color: var(--row-accent-strong);
}

.cell:hover::before,
.cell:focus-visible::before {
  opacity: 1;
}

.cell:hover .cell__idx {
  color: var(--row-accent);
}

.cell:hover .cell__arrow,
.cell:focus-visible .cell__arrow {
  transform: translateX(4px);
}

/* The stage you are already on. It is a div, not a link, so it takes the rust
   the other cells only borrow on hover, and it carries no arrow and no wash.
   It reads exactly as a hovered cell does: the name takes the deeper rust
   (--row-accent-strong) and the index takes the standard rust, so the page
   you are on and the page you are pointing at are marked the same way. */
.cell--now {
  color: var(--row-accent-strong);
  cursor: default;
}

.cell--now .cell__name {
  color: var(--row-accent-strong);
}

.cell--now .cell__idx {
  color: var(--row-accent);
}

/* Not a link, so it must not react to the pointer. .cell:hover would
   otherwise win on specificity and darken the text as though it were one. */
.cell--now:hover {
  color: var(--row-accent-strong);
}

.cell--now::before {
  content: none;
}

@media (prefers-reduced-motion: reduce) {
  .cell:hover .cell__arrow,
  .cell:focus-visible .cell__arrow {
    transform: none;
  }
}

@media (max-width: 1180px) {
  .matrixrow__cells {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .cell:nth-child(3n + 1)::after {
    display: none;
  }

  .cell:nth-child(n + 4) {
    border-top: 1px solid var(--color-divider);
  }
}

@media (max-width: 760px) {
  .matrixrow__cells {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .cell:nth-child(3n + 1)::after {
    display: block;
  }

  .cell:nth-child(2n + 1)::after {
    display: none;
  }

  .cell:nth-child(n + 3) {
    border-top: 1px solid var(--color-divider);
  }
}

@media (max-width: 460px) {
  .matrixrow__cells {
    grid-template-columns: minmax(0, 1fr);
  }

  /* One column means one cell per row, so shared tracks would size every cell to
     the tallest name on the page and leave a gap under the short ones. */
  .cell {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  /* Once the cells stack there are no vertical hairlines. The nth-child
     selector has to be repeated here: the display:block it sets in the 760px
     query above outranks a bare .cell::after on specificity, and media
     queries contribute none. Without it, cell 4 keeps a stray 1px rule. */
  .cell::after,
  .cell:nth-child(3n + 1)::after {
    display: none;
  }

  .cell:nth-child(n + 2) {
    border-top: 1px solid var(--color-divider);
  }

  .cell__arrow {
    padding-top: var(--space-3);
  }
}

/* Delivery model — the deck's Strategic Execution Model, three stacked roles */
.model {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  align-items: stretch;
  gap: var(--space-4);
}

@media (max-width: 940px) {
  .model {
    grid-template-columns: minmax(0, 1fr);
  }
}

.model__role {
  position: relative;
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-slate);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Chevron in the gutter, so the three layers read as a flow into the result */
.model__role::after {
  content: '';
  position: absolute;
  right: -11px;
  top: 50%;
  width: 7px;
  height: 7px;
  border-top: 1.5px solid var(--color-primary);
  border-right: 1.5px solid var(--color-primary);
  transform: translateY(-50%) rotate(45deg);
}

@media (max-width: 940px) {
  .model__role::after {
    display: none;
  }
}

.model__role:nth-child(1) {
  border-left-color: var(--color-primary);
}
.model__role:nth-child(2) {
  border-left-color: var(--color-primary-hover);
}

.model__label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
}

.model__desc {
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

.model__out {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6);
  border-radius: var(--radius-md);
  background: var(--gradient-rust);
  color: #ffffff;
  min-width: 190px;
}

.model__out-label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.8);
}

.model__out-value {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-lg);
  letter-spacing: var(--track-tight);
  text-transform: uppercase;
  line-height: var(--lh-tight);
}

/* Industry index — dense, evenly weighted grid of all ten industries */
.industrygrid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-4);
}

@media (max-width: 1000px) {
  .industrygrid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 620px) {
  .industrygrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.industry {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-4);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 6rem;
  transition:
    background var(--transition-interactive),
    border-color var(--transition-interactive),
    transform var(--transition-interactive);
}

.industry:hover {
  background: var(--color-primary-wash);
  border-color: var(--color-primary);
  transform: translateY(-2px);
}

.industry__name {
  font-size: var(--text-base);
  font-weight: var(--weight-regular);
  color: var(--color-text);
  line-height: var(--lh-snug);
}

.industry:hover .industry__name {
  color: var(--color-primary);
}

.industry__side {
  margin-top: auto;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* Engagement type card with a duration badge */
.engagement__term {
  align-self: flex-start;
  margin-top: auto;
  padding-top: var(--space-4);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-slate);
}

/* Insight teaser card */
.teaser__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.teaser__title {
  margin-top: var(--space-4);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--lh-snug);
  color: var(--color-text);
}

a.card:hover .teaser__title {
  color: var(--color-primary);
}

.teaser__foot {
  margin-top: auto;
  padding-top: var(--space-5);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* Approach pillar — numbered, hairline separated, no card frame */
.pillars {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-6), 3vw, var(--space-10)) clamp(var(--space-6), 4vw, var(--space-12));
}

@media (max-width: 900px) {
  .pillars {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 620px) {
  .pillars {
    grid-template-columns: minmax(0, 1fr);
  }
}

.pillar {
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.pillar__num {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

.pillar__title {
  margin-top: var(--space-3);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  line-height: var(--lh-snug);
}

.pillar__body {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   21. HOME — INDUSTRY SETS + STORY / INSIGHT CARDS
   -------------------------------------------------------------------------- */

.industryset + .industryset {
  margin-top: clamp(var(--space-10), 4vw, var(--space-16));
}

.industryset__label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: var(--space-4);
}

.industrynote {
  margin-top: clamp(var(--space-10), 4vw, var(--space-16));
  text-align: center;
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  max-width: 62ch;
  margin-inline: auto;
}

.industrynote a {
  color: var(--color-primary);
  font-weight: var(--weight-medium);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

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

/* --- Story / insight cards with abstract motifs ------------------------ */

/* Client Impact Stories run as full-width rows: thumbnail left, copy right,
   arrow far right. Rows absorb a fourth or fifth story without any layout
   change, which a three-up grid cannot. */
.storyrows {
  border-top: 1px solid var(--color-text);
}

/* A near-white full-bleed rule is too loud on the dark surface. */
[data-theme='dark'] .storyrows {
  border-top-color: var(--color-border);
}

.storyrow {
  display: grid;
  grid-template-columns: clamp(220px, 22vw, 300px) minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(var(--space-6), 2.4vw, var(--space-12));
  padding-block: clamp(var(--space-6), 1.8vw, var(--space-8));
  border-bottom: 1px solid var(--color-divider);
}

.storyrow__visual {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--color-surface-offset);
}

.storyrow__visual img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.storyrow__visual::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    200deg,
    color-mix(in oklab, var(--color-primary) 12%, transparent) 0%,
    transparent 55%
  );
}

a.storyrow:hover .storyrow__visual img {
  transform: scale(1.04);
}

.storyrow__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.storyrow__title {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  text-wrap: pretty;
  transition: color var(--transition-interactive);
}

a.storyrow:hover .storyrow__title {
  color: var(--color-primary);
}

.storyrow__arrow {
  display: flex;
  align-items: center;
  color: var(--color-primary);
  transition: transform var(--transition-interactive);
}

a.storyrow:hover .storyrow__arrow {
  transform: translateX(4px);
}

/* Below tablet the thumbnail goes full width above the copy and the trailing
   arrow is dropped, since the whole row is the tap target. */
@media (max-width: 780px) {
  .storyrow {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
  }

  .storyrow__arrow {
    display: none;
  }
}

.storygrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-6), 1.8vw, var(--space-8));
}

@media (max-width: 940px) {
  /* Client Impact Stories run as full-width rows: thumbnail left, copy right,
   arrow far right. Rows absorb a fourth or fifth story without any layout
   change, which a three-up grid cannot. */
.storyrows {
  border-top: 1px solid var(--color-text);
}

/* A near-white full-bleed rule is too loud on the dark surface. */
[data-theme='dark'] .storyrows {
  border-top-color: var(--color-border);
}

.storyrow {
  display: grid;
  grid-template-columns: clamp(220px, 22vw, 300px) minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(var(--space-6), 2.4vw, var(--space-12));
  padding-block: clamp(var(--space-6), 1.8vw, var(--space-8));
  border-bottom: 1px solid var(--color-divider);
}

.storyrow__visual {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--color-surface-offset);
}

.storyrow__visual img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.storyrow__visual::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    200deg,
    color-mix(in oklab, var(--color-primary) 12%, transparent) 0%,
    transparent 55%
  );
}

a.storyrow:hover .storyrow__visual img {
  transform: scale(1.04);
}

.storyrow__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.storyrow__title {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  text-wrap: pretty;
  transition: color var(--transition-interactive);
}

a.storyrow:hover .storyrow__title {
  color: var(--color-primary);
}

.storyrow__arrow {
  display: flex;
  align-items: center;
  color: var(--color-primary);
  transition: transform var(--transition-interactive);
}

a.storyrow:hover .storyrow__arrow {
  transform: translateX(4px);
}

/* Below tablet the thumbnail goes full width above the copy and the trailing
   arrow is dropped, since the whole row is the tap target. */
@media (max-width: 780px) {
  .storyrow {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
  }

  .storyrow__arrow {
    display: none;
  }
}

.storygrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 620px) {
  /* Client Impact Stories run as full-width rows: thumbnail left, copy right,
   arrow far right. Rows absorb a fourth or fifth story without any layout
   change, which a three-up grid cannot. */
.storyrows {
  border-top: 1px solid var(--color-text);
}

/* A near-white full-bleed rule is too loud on the dark surface. */
[data-theme='dark'] .storyrows {
  border-top-color: var(--color-border);
}

.storyrow {
  display: grid;
  grid-template-columns: clamp(220px, 22vw, 300px) minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(var(--space-6), 2.4vw, var(--space-12));
  padding-block: clamp(var(--space-6), 1.8vw, var(--space-8));
  border-bottom: 1px solid var(--color-divider);
}

.storyrow__visual {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--color-surface-offset);
}

.storyrow__visual img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.storyrow__visual::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    200deg,
    color-mix(in oklab, var(--color-primary) 12%, transparent) 0%,
    transparent 55%
  );
}

a.storyrow:hover .storyrow__visual img {
  transform: scale(1.04);
}

.storyrow__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.storyrow__title {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  text-wrap: pretty;
  transition: color var(--transition-interactive);
}

a.storyrow:hover .storyrow__title {
  color: var(--color-primary);
}

.storyrow__arrow {
  display: flex;
  align-items: center;
  color: var(--color-primary);
  transition: transform var(--transition-interactive);
}

a.storyrow:hover .storyrow__arrow {
  transform: translateX(4px);
}

/* Below tablet the thumbnail goes full width above the copy and the trailing
   arrow is dropped, since the whole row is the tap target. */
@media (max-width: 780px) {
  .storyrow {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-5);
  }

  .storyrow__arrow {
    display: none;
  }
}

.storygrid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.storycard {
  --motif: var(--color-primary);
  --motif-wash: var(--color-primary-wash);
  --rule: var(--color-primary);
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition:
    border-color var(--transition-interactive),
    box-shadow var(--transition-interactive);
}

a.storycard {
  transition:
    border-color var(--transition-interactive),
    box-shadow var(--transition-interactive),
    transform var(--transition-interactive);
}

a.storycard:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.storycard__visual {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--color-divider);
  background: var(--color-surface-offset);
}

.storycard__visual img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* A whisper of the brand rust over every photograph, so the imagery
   reads as one set and never fights the palette. */
.storycard__visual::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    200deg,
    color-mix(in oklab, var(--color-primary) 12%, transparent) 0%,
    transparent 55%
  );
}

a.storycard:hover .storycard__visual img {
  transform: scale(1.04);
}

@media (prefers-reduced-motion: reduce) {
  .storycard__visual img {
    transition: none;
  }

  a.storycard:hover .storycard__visual img {
    transform: none;
  }
}

.motif {
  display: block;
  width: 100%;
  height: auto;
}

.storycard__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: clamp(var(--space-6), 1.9vw, var(--space-8));
  flex: 1;
}

.storycard__kicker {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
}

.storycard__title {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--lh-normal);
  color: var(--color-text);
  text-wrap: pretty;
}

a.storycard:hover .storycard__title {
  color: var(--color-primary);
}

.storycard__excerpt {
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

.storycard__foot {
  margin-top: auto;
  padding-top: var(--space-4);
}

.storycard__soon {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.footer__address {
  margin-top: var(--space-5);
  font-style: normal;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

/* Wide feature variant — one story carrying the section on its own */
.storycard--wide {
  flex-direction: row;
  align-items: stretch;
}

.storycard--wide .storycard__visual {
  flex: 0 0 40%;
  border-bottom: 0;
  border-right: 1px solid var(--color-divider);
  align-self: stretch;
}

.storycard--wide .storycard__foot {
  margin-top: var(--space-2);
}

.storycard--wide .storycard__body {
  justify-content: center;
  padding: clamp(var(--space-7), 2.4vw, var(--space-10));
  gap: var(--space-4);
}

.storycard__title--lg {
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  line-height: var(--lh-snug);
}

@media (max-width: 760px) {
  .storycard--wide {
    flex-direction: column;
  }
  .storycard--wide .storycard__visual {
    flex: none;
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
  }
}

/* --------------------------------------------------------------------------
   22. HOME — ENGAGEMENT + WHY CBC CARD VARIANTS
   -------------------------------------------------------------------------- */

/* One card recipe for the whole home page: a hairline frame, generous padding,
   and rust reserved for the label, the link and the hover state. No fills, no
   coloured top bars — the whitespace does the separating. */
.card {
  transition:
    border-color var(--transition-interactive),
    box-shadow var(--transition-interactive),
    transform var(--transition-interactive);
}

.card:hover {
  border-color: var(--color-primary);
}

a.card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* Cards that state something rather than lead somewhere. Nothing here is
   clickable, so a hover response only promises a target that is not there.
   Scoped to the grid so linked cards elsewhere keep their affordance. */
.grid--inert .card {
  transition: none;
}
.grid--inert .card:hover {
  border-color: var(--color-border);
  box-shadow: none;
  transform: none;
}
.grid--inert .card:hover .card__title {
  color: var(--color-text);
}

/* Short rust rule — the deck's accent mark, used where a card needs an opener */
.card__rule {
  display: block;
  width: 32px;
  height: 2px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  margin-bottom: var(--space-4);
}

.card__foot {
  margin-top: auto;
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-divider);
}

.card--why .card__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
}

/* Two-up story grid for the case-study section */
.storygrid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 940px) {
  .storygrid--2 {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 1140px) {
  .grid--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .grid--4 {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --------------------------------------------------------------------------
   23. SECTION FOOT, INDUSTRY REGISTER, METRICS, FOOTER CONTACT BUTTONS
   -------------------------------------------------------------------------- */

/* The section link-out now sits below the content it summarizes, which is
   where the eye lands after reading the cards. */
.sectionfoot {
  display: flex;
  margin-top: clamp(var(--space-8), 3vw, var(--space-12));
}
.sectionfoot--split {
  gap: clamp(var(--space-8), 4vw, var(--space-16));
  flex-wrap: wrap;
}
.sectionfoot .btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}
.sectionfoot .btn svg {
  transition: transform var(--transition-interactive);
}
.sectionfoot .btn:hover svg {
  transform: translateX(4px);
}

/* --- Industry register: two columns of text rows, no boxes ---------------- */
.indcols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 clamp(var(--space-10), 5vw, var(--space-20));
}

.indcol__label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-text);
  margin-bottom: var(--space-1);
}
[data-theme='dark'] .indcol__label {
  border-bottom-color: var(--color-border);
}

.indrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-5);
  padding-block: var(--space-4);
  border-bottom: 1px solid var(--color-divider);
}

.indrow__name {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  transition: color var(--transition-interactive);
}
.indrow:hover .indrow__name {
  color: var(--color-primary);
}

.indrow__note {
  display: block;
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  margin-top: var(--space-1);
  text-wrap: pretty;
}

.indrow__arrow {
  display: flex;
  align-items: center;
  color: var(--color-primary);
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity var(--transition-interactive),
    transform var(--transition-interactive);
}
.indrow:hover .indrow__arrow {
  opacity: 1;
  transform: translateX(0);
}

/* --- Closing band: turns the buried "other industries" line into a real CTA */
.indband {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-6) var(--space-10);
  margin-top: clamp(var(--space-10), 4vw, var(--space-16));
  padding: clamp(var(--space-6), 2.4vw, var(--space-8)) clamp(var(--space-6), 3vw, var(--space-10));
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.indband__text {
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  max-width: 52ch;
  text-wrap: pretty;
}

.indband__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.indband__actions .btn--ghost {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}
.indband__actions .btn--ghost svg {
  transition: transform var(--transition-interactive);
}
.indband__actions .btn--ghost:hover svg {
  transform: translateX(4px);
}

/* --- Inert cards: no affordances, since there is nothing to click --------- */
.storyrow--static,
.storycard--static {
  cursor: default;
}
.storyrow--static .storyrow__visual img,
.storycard--static .storycard__visual img {
  transition: none;
}

/* --- Footer contact buttons ---------------------------------------------- */

.contactbtns {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-4);
}

.contactbtn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-bg);
  color: var(--color-text);
  font-size: var(--text-sm);
  line-height: 1;
  transition:
    border-color var(--transition-interactive),
    color var(--transition-interactive),
    background-color var(--transition-interactive);
}
.contactbtn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-wash);
}
[data-theme='dark'] .contactbtn:hover {
  background: var(--color-surface-offset);
}

.contactbtn__icon {
  display: flex;
  flex-shrink: 0;
  color: var(--color-primary);
}
.contactbtn__icon svg {
  width: 18px;
  height: 18px;
}

.contactbtn__label {
  white-space: nowrap;
}

@media (max-width: 1040px) {
  .indcols {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(var(--space-10), 4vw, var(--space-16)) 0;
  }
}
@media (max-width: 720px) {
  .indband {
    flex-direction: column;
    align-items: flex-start;
  }
  .indband__actions,
  .indband__actions .btn,
  .sectionfoot,
  .sectionfoot .btn {
    width: 100%;
    justify-content: center;
  }
  .indband__actions {
    flex-direction: column;
    align-items: stretch;
  }
}
@media (max-width: 480px) {
  .contactbtn__label {
    white-space: normal;
    word-break: break-word;
  }
}

/* Names the two disciplines without shouting; no synthesized bold, no underline. */
.hero__key {
  font-style: normal;
  font-weight: var(--weight-medium);
  color: #ffffff;
}

/* Two audience-routing buttons of identical width. */
/* Three equal-weight routes out of the hero. An inline grid with equal auto
   columns sizes every button to the widest label, so the row reads as one
   control group rather than a primary with two afterthoughts. */
.hero__actions--trio {
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}
.hero__actions--trio .btn {
  justify-content: center;
  min-width: 11.75rem;
}
/* The home hero copy column was widened for the longer positioning statement,
   so three buttons now fit in a single row across this band. Kept as a guard
   for any hero that still uses the narrower default column. */
@media (min-width: 901px) and (max-width: 1279px) {
  .hero__inner:not(:has(.hero__lede--wide)) .hero__actions--trio {
    display: grid;
    grid-auto-flow: row;
    grid-template-columns: minmax(0, 22rem);
  }
  .hero__inner:not(:has(.hero__lede--wide)) .hero__actions--trio .btn {
    min-width: 0;
    width: 100%;
  }
}
@media (max-width: 900px) {
  .hero__actions--trio .btn {
    min-width: 10.5rem;
  }
}
@media (max-width: 900px) {
  .hero__actions--trio {
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
  }
}
@media (max-width: 560px) {
  .hero__actions--trio {
    display: grid;
    width: 100%;
    grid-auto-flow: row;
    grid-auto-columns: auto;
    grid-template-columns: minmax(0, 1fr);
  }
  .hero__actions--trio .btn {
    min-width: 0;
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   24. HERO LINES · MINIMAL INDUSTRY FOOT · FOOTER FLOW
   -------------------------------------------------------------------------- */

/* Three deliberate lines rather than a wrapped paragraph. */
.hero__lede--lines {
  max-width: none;
}
.hero__line {
  display: block;
}
.hero__line + .hero__line {
  margin-top: var(--space-1);
}



@media (max-width: 640px) {
  .indfoot {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* --------------------------------------------------------------------------
   25. CENTRED FOOTER
   -------------------------------------------------------------------------- */

/* One centred column: mark, address, contact actions, legal. No site nav —
   the header and the in-page link-outs already carry navigation. */
.footer__center {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(var(--space-6), 2.4vw, var(--space-8));
}

.footer__brand {
  display: inline-flex;
}
.footer__brand .brand__mark {
  width: clamp(5rem, 6vw, 6.5rem);
  height: auto;
}

.footer__brand .footer__wordmark {
  width: clamp(15rem, 26vw, 22rem);
  height: auto;
  display: block;
}

.footer__address {
  font-style: normal;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

.footer__center .contactbtns {
  justify-content: center;
}

.footer__sub {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  margin-top: var(--space-2);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-divider);
  width: min(100%, 34rem);
}
.footer__copy {
  margin-top: calc(var(--space-4) * -1);
}
.footer__sub a,
.footer__copy {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.footer__sub a:hover {
  color: var(--color-primary);
}

/* Industry close-out now uses the same button pair as every other section. */
.indfoot {
  margin-top: clamp(var(--space-10), 4.2vw, var(--space-16));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5) clamp(var(--space-8), 4vw, var(--space-16));
  flex-wrap: wrap;
}
.indfoot__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.indfoot__actions .btn svg {
  transition: transform var(--transition-interactive);
}
.indfoot__actions .btn:hover svg {
  transform: translateX(4px);
}

@media (max-width: 760px) {
  .indfoot {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* --------------------------------------------------------------------------
   16. SOLUTION STORY LAYOUTS
   Two purpose-built layouts that explain WHY each practice is structured the
   way it is. Construction reads as a three-tier delivery stack; enterprise
   reads as a five-question sequence. Both are built from the same card
   vocabulary as the rest of the site.
   -------------------------------------------------------------------------- */

/* ---- 16a. Tier stack (construction) ------------------------------------ */

.tierstack {
  display: grid;
  gap: 0;
}

.tier__label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: var(--space-4);
}

.tier__label::before {
  content: '';
  width: 18px;
  height: 2px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
}

.tier__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
}

.tier__grid--single {
  grid-template-columns: minmax(0, 1fr);
}

.tiercard {
  position: relative;
  display: block;
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  text-decoration: none;
  transition: border-color var(--transition-interactive);
}

.tiercard:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-wash);
}

.tiercard__num {
  margin: 0 0 var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-faint);
}

.tiercard__arrow {
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
  display: flex;
  color: var(--color-primary);
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity var(--transition-interactive),
    transform var(--transition-interactive);
}

.tiercard:hover .tiercard__arrow,
.tiercard:focus-visible .tiercard__arrow {
  opacity: 1;
  transform: translateX(0);
}

.tiercard__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  color: var(--color-primary);
  margin: 0;
}

.tiercard__body {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
}

/* Connector between tiers — hairline, centred caps label, hairline. */
.tierlink {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-6);
  margin-block: var(--space-6);
}

.tierlink::before,
.tierlink::after {
  content: '';
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-primary));
  opacity: 0.45;
}

.tierlink::after {
  background: linear-gradient(90deg, var(--color-primary), transparent);
}

.tierlink__label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  white-space: nowrap;
}

/* ---- 16b. Question sequence (enterprise) -------------------------------- */

.steplist {
  display: grid;
  gap: var(--space-4);
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 0.3fr) 1px minmax(0, 1fr);
  gap: var(--space-7);
  align-items: stretch;
  padding: var(--space-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  text-decoration: none;
  transition: border-color var(--transition-interactive);
}

.step:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-wash);
}

.step__arrow {
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
  display: flex;
  color: var(--color-primary);
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity var(--transition-interactive),
    transform var(--transition-interactive);
}

.step:hover .step__arrow,
.step:focus-visible .step__arrow {
  opacity: 1;
  transform: translateX(0);
}

.step__num,
.step__q,
.step__title,
.step__body {
  display: block;
}

.step__num {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-light);
  line-height: 1;
  color: var(--color-primary);
  margin: 0;
}

.step__q {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  font-style: italic;
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
}

.step__rule {
  width: 1px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
}

.step__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  color: var(--color-primary);
  margin: 0;
}

.step__body {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
}

/* ---- 16c. Closing difference strip -------------------------------------- */

.difference {
  margin-top: var(--space-6);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-divider);
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
}

/* Drops the divider above the closing line. The grid's own cells already carry a
   top rule each, so a full-width rule directly beneath them read as a third
   horizontal band in a row. Without it the line has to stand on space alone, so
   the margin absorbs what the padding used to contribute. */
.difference--noline {
  padding-top: 0;
  border-top: 0;
  margin-top: var(--space-9);
}

.difference__label {
  color: var(--color-primary);
  font-weight: var(--weight-medium);
}

/* ---- 16d. Responsive ----------------------------------------------------- */

@media (max-width: 860px) {
  .tier__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .step {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
  }

  .step__rule {
    width: 100%;
    height: 1px;
  }
}

@media (max-width: 560px) {
  .tierlink {
    gap: var(--space-4);
  }

  .tierlink__label {
    white-space: normal;
  }
}


/* --------------------------------------------------------------------------
   17. NARRATIVE INTRO + ENGAGEMENT HOVER CARDS
   -------------------------------------------------------------------------- */

.narrative {
  max-width: 74ch;
  display: grid;
  gap: var(--space-5);
}

.narrative p {
  margin: 0;
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-muted);
}

.narrative .narrative__lead {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}


/* ---- Engagement models: 2x2 hairline matrix, hover reveal --------------
   Same rule language as the Client Outcomes matrix: one heavy rule across
   the top, cells carrying their own right and bottom dividers so the grid
   costs no gaps, outer edges flush to the shell.

   The description and the reveal are placed on the SAME single grid cell,
   so each cell is only as tall as the taller of the two rather than the
   sum of both, and hovering cross-fades one for the other. That is what
   keeps the section at ~520px while carrying a full description.
   ---------------------------------------------------------------------- */

.mx {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--color-text);
}

.mx__c {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 22px clamp(24px, 2.4vw, 38px) 24px;
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}
.mx__c:nth-child(2n) {
  border-right: 0;
}
.mx__c:nth-child(2n + 1) {
  padding-left: 0;
}
/* Every line the live cell owns or touches turns rust. Geometry, given no
   grid gaps and border-box cells: the top line always sits at y -1 to 0
   (the grid's heavy rule for row one, the cell above's bottom border for
   row two); a right-hand cell's left line is its neighbour's border-right,
   also at -1 to 0. So one overlay inset to top/left -1px and right/bottom 0
   lands its four borders exactly on the four existing hairlines without
   touching layout. Outer edges are flush by design and carry no line, so
   the overlay drops that border on the corresponding column. */
.mx__edge {
  position: absolute;
  /* all four offsets are -1px because an absolutely positioned child is
     offset from its container's PADDING box, not its border box. The cells
     carry border-right and border-bottom, so right/bottom 0 would land the
     overlay one pixel inside those two hairlines instead of on them. */
  top: -1px;
  left: -1px;
  right: -1px;
  bottom: -1px;
  border: 1px solid var(--color-primary);
  /* the top line is drawn by .mx__rule, which wipes rather than fades */
  border-top: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 300ms ease;
}
.mx__c:nth-child(2n) .mx__edge {
  border-right: 0;
}
.mx__c:nth-child(2n + 1) .mx__edge {
  border-left: 0;
}
.mx__c:hover .mx__edge,
.mx__c:focus-within .mx__edge {
  opacity: 1;
  /* lets the top rule's wipe lead, so the outline reads as one gesture
     travelling around the cell rather than four lines blinking on */
  transition-delay: 90ms;
}

/* the rust marker that lands over the live cell, drawn on top of that
   cell's own top rule so no layout is disturbed */
.mx__rule {
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--color-primary);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.mx__c:hover .mx__rule,
.mx__c:focus-within .mx__rule {
  transform: scaleX(1);
}

.mx__n {
  display: block;
  margin-bottom: var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

.mx__head {
  display: block;
  margin-bottom: var(--space-3);
}
.mx__name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-light);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  transition: color var(--transition-interactive);
}
.mx__c:hover .mx__name,
.mx__c:focus-within .mx__name {
  color: var(--color-primary);
}

/* both blocks land on the one grid cell */
.mx__body {
  display: grid;
}
.mx__body > * {
  grid-area: 1 / 1;
}

/* 44ch lands around a 69-character line. 56ch resolved to 616px in this
   cell width, almost edge to edge, which is far too long a measure. */
.mx__desc {
  display: block;
  max-width: 44ch;
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  text-wrap: pretty;
  /* never interactive, and at rest it sits over the link */
  pointer-events: none;
  transition: opacity 240ms ease;
}
.mx__c:hover .mx__desc,
.mx__c:focus-within .mx__desc {
  opacity: 0;
}

.mx__reveal {
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 300ms ease,
    transform 380ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.mx__c:hover .mx__reveal,
.mx__c:focus-within .mx__reveal {
  opacity: 1;
  transform: none;
}

.mx__lbl {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.mx__lead {
  display: block;
  max-width: 44ch;
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.mx__link {
  display: block;
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  /* rust like the frame: this is a line the live cell owns, and it only ever
     appears while that cell is live, so it takes the accent outright */
  border-top: 1px solid var(--color-primary-tint);
  text-decoration: none;
}
.mx__link:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}
/* wider than the prose blocks on purpose: the inline label plus the
   sentence has to stay on one line, and this row reads as a ledger line
   under the full-width hairline rather than as prose */
.mx__linkrow {
  display: block;
  max-width: 56ch;
}
.mx__lbl--inline {
  display: inline;
  margin-bottom: 0;
  margin-right: var(--space-3);
  white-space: nowrap;
}
.mx__linktext {
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text);
  transition: color var(--transition-interactive);
}
.mx__link:hover .mx__linktext {
  color: var(--color-primary);
}
.mx__arrow {
  display: inline-block;
  margin-left: var(--space-2);
  color: var(--color-primary);
  transition: transform var(--transition-interactive);
}
.mx__link:hover .mx__arrow {
  transform: translateX(4px);
}

/* .mx--static: same hairline matrix, but each cell carries one narrative
   paragraph and no hover reveal. The rust top-rule wipe, the rust outline
   and the rust name still fire, so the interaction language matches the
   engagement matrix; only the cross-fade is dropped because there is
   nothing to fade to. */
.mx--static .mx__desc,
.mx--static .mx__c:hover .mx__desc,
.mx--static .mx__c:focus-within .mx__desc {
  opacity: 1;
}
.mx--static .mx__desc {
  /* 36ch is the widest measure that still caps before the COLUMN does at
     901px, the narrowest two-across width. Anything wider and the column
     governs there instead, characters per line drops to ~53 while it is ~66
     at 1440px, and no single character count can render as four lines at
     both ends. At 36ch the line holds ~52 characters at every width. */
  max-width: 36ch;
}

/* The four seat names are long enough that --text-xl wrapped two of them at
   every two-across width, which left the paragraphs in a row starting at
   different heights. 1.125rem holds all four on one line from 901px up
   (measured at 901, 950, 1000, 1024, 1100, 1200, 1280, 1440, 1512, 1600 and
   1920), so no height reservation is needed on the head. rem is already
   viewport-scaled here, so this still ranges 18px to 20.2px on its own. */
.mx--static .mx__name {
  font-size: 1.125rem;
}

/* below the two-across breakpoint there is no hover to rely on, so both
   blocks show outright and the shared grid cell has to unstack into flow */
@media (max-width: 900px) {
  .mx {
    grid-template-columns: minmax(0, 1fr);
  }
  .mx__c,
  .mx__c:nth-child(2n),
  .mx__c:nth-child(2n + 1) {
    padding-left: 0;
    padding-right: 0;
    border-right: 0;
  }
  /* no hover to respond to here, and the flush single column means the
     overlay's right border would draw a line that does not exist */
  .mx__edge {
    display: none;
  }
  .mx__body {
    display: block;
  }
  .mx__body > * {
    grid-area: auto;
  }
  /* :focus-within has to be listed too, or tabbing to a link on a phone
     fades out a description that is meant to be permanent there */
  .mx__desc,
  .mx__c:hover .mx__desc,
  .mx__c:focus-within .mx__desc {
    opacity: 1;
  }
  .mx__reveal {
    display: block;
    opacity: 1;
    transform: none;
    margin-top: var(--space-4);
  }
  .mx__name {
    color: var(--color-text);
  }
}

@media (prefers-reduced-motion: reduce) {
  .mx__c,
  .mx__rule,
  .mx__edge,
  .mx__reveal,
  .mx__desc,
  .mx__arrow {
    transition-duration: 1ms;
    transition-delay: 0ms;
  }
}

/* --------------------------------------------------------------------------
   18. WHAT WE DO — FIRM FACTS, DOMAIN FORK, ALTERNATIVES TABLE
   -------------------------------------------------------------------------- */

/* --- Firm proof points under the approach narrative ---------------------- */
.approachgrid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(15rem, 22vw, 18rem);
  gap: clamp(var(--space-10), 5vw, var(--space-20));
  align-items: start;
}

.factrail {
  display: grid;
  gap: clamp(var(--space-6), 2.5vw, var(--space-8));
  padding-left: clamp(var(--space-6), 3vw, var(--space-10));
  border-left: 1px solid var(--color-divider);
}

.fact__num {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-light);
  line-height: 1;
  letter-spacing: var(--track-tight);
  color: var(--color-primary);
}

.fact__label {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

/* --- The domain fork ------------------------------------------------------ */
.fork {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(var(--space-6), 2.5vw, var(--space-10));
}

.forkpanel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: clamp(var(--space-6), 2.5vw, var(--space-8));
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.forkpanel__name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.forkpanel__body {
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.forkpanel__meta {
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  font-size: var(--text-xs);
  line-height: var(--lh-relaxed);
  color: var(--color-text-faint);
  text-wrap: pretty;
}

.forkpanel__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-8);
  margin-top: auto;
  padding-top: var(--space-2);
}

.arrowlink--quiet {
  color: var(--color-text-muted);
}
.arrowlink--quiet:hover {
  color: var(--color-primary);
}

/* --- Alternatives comparison table --------------------------------------- */
.compare-wrap {
  background: var(--color-bg);
}

.compare {
  width: 100%;
  border-collapse: collapse;
}

.compare thead th + th {
  text-align: center;
  width: 13%;
}

.compare tbody th {
  text-align: left;
  font-weight: var(--weight-regular);
  color: var(--color-text);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-divider);
  font-size: var(--text-sm);
}

.compare tbody td {
  text-align: center;
  vertical-align: middle;
}

.compare thead th.compare__cbc,
[data-theme='dark'] .compare thead th.compare__cbc {
  background: var(--color-primary);
  color: #fff;
}

.compare td.compare__cbc {
  background: var(--color-primary-wash);
}
[data-theme='dark'] .compare td.compare__cbc {
  background: var(--color-primary-wash);
}

.compare__yes {
  display: inline-flex;
  color: var(--color-primary);
}

.compare__no {
  color: var(--color-text-faint);
}

@media (max-width: 1040px) {
  .approachgrid { grid-template-columns: 1fr; gap: clamp(var(--space-8), 4vw, var(--space-12)); }
  .factrail {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding-left: 0;
    padding-top: var(--space-6);
    border-left: 0;
    border-top: 1px solid var(--color-divider);
  }
}

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

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

/* ======================================================================
   19. SOLUTION ROW — lateral accordion (construction practice)
   ====================================================================== */

.solrow {
  display: flex;
  height: 13rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg);
}

.solpanel {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  text-decoration: none;
  padding: var(--space-5) var(--space-5);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-right: 1px solid var(--color-divider);
  background: var(--color-bg);
  transition: flex 0.5s cubic-bezier(0.4, 0, 0.2, 1), background 0.4s ease, padding 0.5s ease;
}

.solpanel:last-child { border-right: 0; }

.solrow:hover .solpanel,
.solrow:focus-within .solpanel {
  flex: 0 0 74px;
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}

.solrow .solpanel:hover,
.solrow .solpanel:focus-visible {
  flex: 1 1 auto;
  background: var(--gradient-rust);
  padding-left: var(--space-7);
  padding-right: var(--space-7);
  outline: none;
}

.solpanel__num {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
  transition: color 0.35s ease;
}

.solpanel:hover .solpanel__num,
.solpanel:focus-visible .solpanel__num { color: rgba(255, 255, 255, 0.72); }

.solpanel__mid { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.solpanel__title {
  display: flex;
  flex-direction: column;
  margin-top: var(--space-3);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: var(--weight-light);
  line-height: 1.3;
  color: var(--color-text);
  transition: color 0.35s ease, font-size 0.35s ease, opacity 0.22s ease;
}

.solrow:hover .solpanel:not(:hover) .solpanel__title,
.solrow:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title { opacity: 0; }

.solpanel:hover .solpanel__title,
.solpanel:focus-visible .solpanel__title {
  flex-direction: row;
  gap: 0.32em;
  white-space: nowrap;
  opacity: 1;
  color: #fff;
  font-size: 1.5rem;
  margin-top: var(--space-2);
}

.solpanel__body {
  display: none;
  margin-top: var(--space-3);
  font-size: 0.92rem;
  line-height: 1.62;
  color: rgba(255, 255, 255, 0.92);
  max-width: none;
}

.solpanel:hover .solpanel__body,
.solpanel:focus-visible .solpanel__body { display: block; }

.solpanel__foot {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 1.625rem;
}

.solpanel__tier {
  font-family: var(--font-eyebrow);
  font-size: 0.625rem;
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
  transition: color 0.35s ease, opacity 0.22s ease;
}

.solrow:hover .solpanel:not(:hover) .solpanel__tier,
.solrow:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__tier { opacity: 0; }

.solpanel:hover .solpanel__tier,
.solpanel:focus-visible .solpanel__tier { color: rgba(255, 255, 255, 0.7); }

.solpanel__tags { display: none; gap: var(--space-2); flex-wrap: wrap; }

.solpanel:hover .solpanel__tags,
.solpanel:focus-visible .solpanel__tags { display: flex; }

.solpanel__tag {
  font-family: var(--font-eyebrow);
  font-size: 0.625rem;
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: var(--radius-full);
  padding: 5px 12px;
  white-space: nowrap;
}

.solpanel__arrow { display: none; margin-left: auto; color: #fff; }

.solpanel:hover .solpanel__arrow,
.solpanel:focus-visible .solpanel__arrow { display: block; }

@media (prefers-reduced-motion: reduce) {
  .solpanel, .solpanel__title { transition: none; }
}

/* Stacked fallback — touch devices and narrow viewports */
@media (hover: none), (max-width: 980px) {
  .solrow { display: block; height: auto; }
  .solpanel { border-right: 0; border-bottom: 1px solid var(--color-divider);
    padding: var(--space-5) var(--space-6); }
  .solpanel:last-child { border-bottom: 0; }
  .solrow:hover .solpanel, .solrow:focus-within .solpanel,
  .solrow .solpanel:hover, .solrow .solpanel:focus-visible {
    flex: none; background: var(--color-bg);
    padding-left: var(--space-6); padding-right: var(--space-6);
  }
  .solpanel__title, .solpanel:hover .solpanel__title, .solpanel:focus-visible .solpanel__title {
    flex-direction: row; gap: 0.32em; white-space: normal; opacity: 1;
    color: var(--color-text); font-size: 1.15rem; margin-top: var(--space-2);
  }
  .solpanel__num, .solpanel:hover .solpanel__num { color: var(--color-primary); }
  .solpanel__body, .solpanel:hover .solpanel__body {
    display: block; color: var(--color-text-muted); max-width: 60ch;
  }
  .solpanel__tier, .solpanel:hover .solpanel__tier { color: var(--color-text-faint); opacity: 1; }
  .solpanel__tags, .solpanel:hover .solpanel__tags { display: none; }
  .solpanel__arrow, .solpanel:hover .solpanel__arrow { display: block; color: var(--color-primary); }
  .solpanel__foot { margin-top: var(--space-4); }
}

/* ======================================================================
   19b. SOLUTION ROW — enterprise variant
   Same structure as the construction row: capability name at rest, band
   label in the foot. Enterprise names are multi-word, so the title wraps
   naturally rather than one word per line. The question appears on hover.
   ====================================================================== */

.solrow--ent { height: 13rem; }

.solrow--ent .solpanel__title {
  display: block;
  white-space: normal;
}

.solrow--ent .solpanel:hover .solpanel__title,
.solrow--ent .solpanel:focus-visible .solpanel__title {
  display: block;
  white-space: nowrap;
  font-size: 1.5rem;
}

.solrow--ent .solpanel__q {
  display: none;
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: var(--weight-light);
  font-style: italic;
  color: rgba(255, 255, 255, 0.72);
}

.solrow--ent .solpanel:hover .solpanel__q,
.solrow--ent .solpanel:focus-visible .solpanel__q { display: block; }

.solrow--ent .solpanel__body { margin-bottom: var(--space-3); }

/* Stacked fallback */
@media (hover: none), (max-width: 980px) {
  .solrow--ent { height: auto; }
  .solrow--ent .solpanel__title,
  .solrow--ent .solpanel:hover .solpanel__title,
  .solrow--ent .solpanel:focus-visible .solpanel__title {
    display: block; white-space: normal; font-size: 1.15rem;
    color: var(--color-text); margin-top: var(--space-2);
  }
  .solrow--ent .solpanel__q,
  .solrow--ent .solpanel:hover .solpanel__q {
    display: block; color: var(--color-text-muted); font-style: italic;
    margin-top: var(--space-1);
  }
}

/* ======================================================================
   21. SOLUTION DETAIL PAGE — reusable template for all ten solution pages
   ====================================================================== */

/* ---- breadcrumb -------------------------------------------------------- */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--color-divider);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.crumbs a {
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color var(--transition-interactive);
}
.crumbs a:hover,
.crumbs a:focus-visible { color: var(--color-primary); }
.crumbs__sep { color: var(--color-text-faint); }
.crumbs__here { color: var(--color-primary); }

/* ---- overview: narrative + signals ------------------------------------ */
.overview {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr);
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: start;
}
.overview__lead {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: clamp(1.4rem, 1.1rem + 0.85vw, 1.85rem);
  line-height: 1.28;
  color: var(--color-text);
  margin-bottom: var(--space-6);
  max-width: 32ch;
}
.overview__body { display: grid; gap: var(--space-5); max-width: 62ch; }
.overview__body p {
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}
.signals {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  padding: clamp(var(--space-6), 2vw, var(--space-8));
}
.signals__label {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: var(--space-5);
}
.signals__list { display: grid; gap: 0; list-style: none; margin: 0; padding: 0; }
.signals__list li {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  padding-block: var(--space-4);
  border-top: 1px solid var(--color-divider);
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}
.signals__list li:first-child { border-top: 0; padding-top: 0; }
.signals__list li::before {
  content: '';
  width: 7px; height: 7px;
  margin-top: 0.55em;
  border-radius: var(--radius-full);
  background: var(--color-primary);
}

/* ---- phase list -------------------------------------------------------- */
.phaselist {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(var(--space-6), 2.6vw, var(--space-10));
}
.phase { border-top: 1px solid var(--color-text); padding-top: var(--space-5); }
.phase__num {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  color: var(--color-primary);
  display: block;
  margin-bottom: var(--space-4);
}
.phase__title {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: 1.24rem;
  line-height: var(--lh-snug);
  color: var(--color-text);
  margin-bottom: var(--space-3);
}
.phase__body {
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

/* ---- outcomes ---------------------------------------------------------- */
.outcomes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-5), 1.8vw, var(--space-7));
}
.outcome {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: clamp(var(--space-6), 2vw, var(--space-8));
  display: flex; flex-direction: column; gap: var(--space-3);
}
.outcome__title {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: 1.14rem;
  line-height: var(--lh-snug);
  color: var(--color-text);
}
.outcome__body {
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

/* ---- sibling solutions ------------------------------------------------- */
.siblings {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--color-text);
}


/* ---- clickable chips --------------------------------------------------- */
.chiplinks { display: flex; flex-wrap: wrap; gap: var(--space-3); }
a.chip {
  text-decoration: none;
  transition: color var(--transition-interactive), border-color var(--transition-interactive),
    background-color var(--transition-interactive);
}
a.chip:hover,
a.chip:focus-visible {
  color: var(--color-primary);
  border-color: var(--color-primary);
  background: var(--color-primary-wash);
}

/* ---- responsive -------------------------------------------------------- */
@media (max-width: 1080px) {
  .phaselist { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .siblings { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .siblings .cell:nth-child(odd) { border-left: 0; }
  .outcomes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .overview { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .phaselist { grid-template-columns: minmax(0, 1fr); }
  .siblings { grid-template-columns: minmax(0, 1fr); }
  .siblings .cell { border-left: 0 !important; }
  .outcomes { grid-template-columns: minmax(0, 1fr); }
}

/* --- intro sub-head (market need -> how we fill it) ------------------- */
.overview__subhead {
  margin-block: var(--space-8) var(--space-4);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-divider);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
}

/* ======================================================================
   22. SOLUTION DETAIL — page-specific patterns
   ====================================================================== */

/* --- intro pull line --------------------------------------------------- */
.overview__pull {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  color: var(--color-text);
}

/* --- four-up sibling cells (matches the home solutions matrix) ---------
   This variant reflows 4 -> 2 -> 1 at its own breakpoints, which do not line up
   with the base grid's 5 -> 3 -> 2 -> 1. The base hairline and row-divider
   rules are keyed to those base breakpoints, so they have to be restated here
   per column count -- otherwise they land on the wrong cells (stray vertical
   rules on stacked cells, dividers missing above wrapped rows). */
.matrixrow__cells--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* 4 columns, one row: a hairline before every cell but the first, no dividers. */
@media (min-width: 1181px) {
  .matrixrow__cells--4 .cell + .cell::after { display: block; }
  .matrixrow__cells--4 .cell { border-top: 0; }
}

/* 2 columns: hairline before the right-hand cell only, divider above row 2. */
@media (max-width: 1180px) and (min-width: 641px) {
  .matrixrow__cells--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .matrixrow__cells--4 .cell::after { display: none; }
  .matrixrow__cells--4 .cell:nth-child(2n)::after { display: block; }
  .matrixrow__cells--4 .cell { border-top: 0; }
  .matrixrow__cells--4 .cell:nth-child(n + 3) {
    border-top: 1px solid var(--color-divider);
  }
}

/* Stacked: no vertical hairlines, a divider above every cell but the first. */
@media (max-width: 640px) {
  .matrixrow__cells--4 { grid-template-columns: 1fr; }
  .matrixrow__cells--4 .cell { display: flex; flex-direction: column; gap: var(--space-3); }
  .matrixrow__cells--4 .cell::after { display: none; }
  .matrixrow__cells--4 .cell:nth-child(n + 2) {
    border-top: 1px solid var(--color-divider);
  }
}

/* --- phase variant of the lateral accordion ---------------------------- */
.solrow--phase { height: 19.125rem; }
.solrow--phase .solpanel__foot { gap: var(--space-3); }

.solrow--phase .solpanel { cursor: default; }

/* Title reads on one wrapping line at rest, not one word per line. */
.solrow--phase .solpanel__title {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.32em;
  font-size: var(--text-lg);
  text-wrap: pretty;
}

/* Short description is visible at rest. */
.solrow--phase .solpanel__body {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  transition: opacity 0.22s ease;
}

.solrow--phase:hover .solpanel:not(:hover) .solpanel__body,
.solrow--phase:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__body {
  opacity: 0;
}

/* Hovered panel: rust, bigger title, short line drops out, detail appears. */
.solrow--phase .solpanel:hover .solpanel__title,
.solrow--phase .solpanel:focus-visible .solpanel__title {
  white-space: normal;
  font-size: 1.5rem;
}

.solrow--phase .solpanel:hover .solpanel__body,
.solrow--phase .solpanel:focus-visible .solpanel__body { display: none; }

.solpanel__detail {
  display: none;
  margin-top: var(--space-3);
  font-size: 0.95rem;
  line-height: var(--lh-relaxed);
  color: rgba(255, 255, 255, 0.94);
  max-width: 84ch;
}

.solrow--phase .solpanel:hover .solpanel__detail,
.solrow--phase .solpanel:focus-visible .solpanel__detail { display: block; }

/* Revealed deliverables: what the owner actually receives. */
.solpanel__gets { display: none; }

.solrow--phase .solpanel:hover .solpanel__gets,
.solrow--phase .solpanel:focus-visible .solpanel__gets {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--space-8);
  row-gap: var(--space-2);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.solpanel__get {
  display: block;
  position: relative;
  padding-left: var(--space-4);
  color: rgba(255, 255, 255, 0.88);
  font-size: 0.875rem;
  line-height: var(--lh-normal);
}

.solpanel__get::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 8px;
  height: 1px;
  background: rgba(255, 255, 255, 0.55);
}

@media (hover: none), (max-width: 980px) {
  .solrow--phase { height: auto; }
  .solrow--phase .solpanel__title,
  .solrow--phase .solpanel:hover .solpanel__title { font-size: var(--text-lg); }
  .solrow--phase .solpanel__body,
  .solrow--phase .solpanel:hover .solpanel__body { display: none; }
  .solrow--phase .solpanel__detail,
  .solrow--phase .solpanel:hover .solpanel__detail {
    display: block; color: var(--color-text-muted);
  }
  .solrow--phase .solpanel__gets,
  .solrow--phase .solpanel:hover .solpanel__gets {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-2);
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-divider);
  }
  .solrow--phase .solpanel__get { color: var(--color-text-muted); }
  .solrow--phase .solpanel__get::before { background: var(--color-primary); }
  .solrow--phase .solpanel__foot { display: none; }
}

/* --- client outcomes: hairline matrix --------------------------------
   A 3x2 field divided by single rules, read like a drawing schedule.
   Cells carry their own dividers, so the grid has no gaps to pay for.
   -------------------------------------------------------------------- */
.ocgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Row tracks are declared on the container and inherited by each cell below,
     so a title that wraps to two lines lifts the title band for its whole row
     instead of pushing its own description a line lower than its neighbours'. */
  grid-auto-rows: auto auto auto;
  border-top: 1px solid var(--color-text);
}

.ocitem {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  min-width: 0;
  padding: clamp(16px, 1.5vw, 22px) clamp(22px, 2.2vw, 34px);
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}

.ocitem:nth-child(3n) { border-right: 0; }
.ocitem:nth-child(3n + 1) { padding-left: 0; }

.ocitem__n {
  display: block;
  margin-bottom: var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

.ocitem__t {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.ocitem__d {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

/* two across: dividers and flush edges have to re-key to the new count */
@media (max-width: 1080px) {
  .ocgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ocitem:nth-child(3n) { border-right: 1px solid var(--color-divider); }
  .ocitem:nth-child(2n) { border-right: 0; }
  .ocitem:nth-child(3n + 1) { padding-left: clamp(22px, 2.2vw, 34px); }
  .ocitem:nth-child(2n + 1) { padding-left: 0; }
}

/* single column: no vertical rules, everything flush to the shell */
@media (max-width: 640px) {
  .ocgrid { grid-template-columns: minmax(0, 1fr); }
  /* One column would otherwise stretch every cell to the tallest title on the
     page, opening a gap under each short one. */
  .ocitem { display: flex; flex-direction: column; }
  .ocitem,
  .ocitem:nth-child(3n),
  .ocitem:nth-child(3n + 1),
  .ocitem:nth-child(2n),
  .ocitem:nth-child(2n + 1) {
    padding-left: 0;
    padding-right: 0;
    border-right: 0;
  }
}



/* --- related insights: overlay feature + thumbnail rail --------------- */
.inrow {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  column-gap: clamp(var(--space-10), 4.5vw, var(--space-16));
  align-items: stretch;
}

.infeat {
  position: relative;
  display: block;
  overflow: hidden;
  height: 100%;
  min-height: 18.75rem;
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  text-decoration: none;
}

.infeat__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.01);
  transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1);
}

.infeat__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(18, 14, 13, 0.95) 0%, rgba(18, 14, 13, 0.9) 42%, rgba(18, 14, 13, 0.72) 66%, rgba(18, 14, 13, 0.5) 82%, rgba(18, 14, 13, 0.26) 92%, rgba(18, 14, 13, 0) 100%);
  transition: opacity var(--transition-interactive);
}

.infeat__body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: var(--space-10);
}

.infeat__kicker {
  display: block;
  margin-bottom: var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: #E9C8C5;
}

.infeat__title {
  display: block;
  margin-bottom: var(--space-3);
  font-family: var(--font-display);
  font-size: 1.62rem;
  font-weight: var(--weight-light);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: #fff;
  /* Every feature card reads as two lines of title over two lines of
     standfirst, whatever the length of the record behind it, so the block
     sits at the same height on every page it appears on. */
  max-width: 34ch;
  text-wrap: pretty;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.infeat__excerpt {
  display: block;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: rgba(255, 255, 255, 0.82);
  max-width: 58ch;
  text-wrap: pretty;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.infeat__more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-6);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: #fff;
}

.infeat__more svg { transition: transform var(--transition-interactive); }
.infeat:hover .infeat__img { transform: scale(1.05); }
.infeat:hover .infeat__more svg { transform: translateX(4px); }

/* Two lines is a desktop composition. A phone is too narrow to hold a
   headline in two lines, so below 700px the card is allowed to grow rather
   than cut a sentence in half. */
@media (max-width: 700px) {
  .infeat__title { -webkit-line-clamp: 4; line-clamp: 4; }
  .infeat__excerpt { -webkit-line-clamp: 4; line-clamp: 4; }
}

/* The rail sits beside a full-height feature card. Letting the rows share the
   column height keeps the last hairline level with the bottom of the feature
   whether the page lists two related insights or three. */
.inrail {
  display: grid;
  grid-auto-rows: minmax(min-content, 1fr);
  align-content: stretch;
}

/* A rail with nothing in it hands its column back to the feature card; a rail
   with a single item sits at the top of the column instead of floating in the
   middle of two stretched rows. */
.inrow:has(.inrail--empty) { grid-template-columns: minmax(0, 1fr); }
.inrail--empty { display: none; }
.inrail--one { align-content: start; grid-auto-rows: min-content; }

.inrail__i {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  column-gap: var(--space-5);
  align-items: center;
  padding: var(--space-6) 0;
  border-bottom: 1px solid var(--color-divider);
  text-decoration: none;
}

.inrail__i:first-child { border-top: 1px solid var(--color-divider); }

.inrail__th {
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
}

.inrail__th img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1);
}

.inrail__c { display: block; }

.inrail__k {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.inrail__t {
  display: block;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: var(--weight-light);
  line-height: var(--lh-snug);
  color: var(--color-text);
  transition: color var(--transition-interactive);
  text-wrap: pretty;
}

.inrail__i:hover .inrail__t { color: var(--color-primary); }
.inrail__i:hover .inrail__th img { transform: scale(1.06); }

@media (max-width: 1080px) {
  .inrow { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-10); }
  .infeat { min-height: 23.75rem; }
}

@media (max-width: 620px) {
  .infeat { min-height: 20rem; }
  .infeat__body { padding: var(--space-6); }
  .infeat__title { font-size: 1.32rem; }
  .inrail__i { grid-template-columns: 76px minmax(0, 1fr); column-gap: var(--space-4); }
}

@media (prefers-reduced-motion: reduce) {
  .infeat__img, .inrail__th img, .infeat__more svg { transition: none; }
  .infeat:hover .infeat__img, .inrail__i:hover .inrail__th img { transform: none; }
}



/* ============================================================
   §23  GAP / FIX SYMMETRIC SPLIT  (solution detail intro)
   ============================================================ */
.gapfix {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: auto auto 1fr auto;
  column-gap: clamp(var(--space-10), 7vw, var(--space-24));
}
.gapfix__l { grid-column: 1; }
.gapfix__r { grid-column: 2; }

.gapfix__e {
  grid-row: 1;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  margin: 0 0 var(--space-6);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.gapfix__e::after {
  content: "";
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.35;
}
.gapfix__e--gap { color: var(--color-text-faint); }
.gapfix__e--fix { color: var(--color-primary); }

.gapfix__s {
  grid-row: 2;
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  color: var(--color-text);
  margin: 0 0 var(--space-6);
  max-width: none;
  white-space: nowrap;
}
.gapfix__n {
  grid-row: 3;
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  margin: 0;
  max-width: 54ch;
}
.gapfix__k {
  grid-row: 4;
  margin: var(--space-8) 0 0;
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: 1.12rem;
  line-height: var(--lh-snug);
}
.gapfix__k--gap { color: var(--color-text-faint); }
.gapfix__k--fix { color: var(--color-primary); }

@media (max-width: 1160px) {
  .gapfix {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }
  .gapfix__l, .gapfix__r { grid-column: 1; }
  .gapfix__e, .gapfix__s, .gapfix__n, .gapfix__k { grid-row: auto; max-width: none; }
  .gapfix__k--gap { margin-bottom: var(--space-10); }
}
@media (max-width: 620px) {
  .gapfix__s { white-space: normal; }
}

/* keep proper nouns from breaking across lines */
.nowrap { white-space: nowrap; }
@media (max-width: 400px) { .nowrap { white-space: normal; } }

/* Home hero lede: measured empirically — the 244-character positioning
   statement needs 730px to resolve to three lines at 19px, so the copy column
   is pinned to 47.25rem (756px), a ~3.5% safety margin. Pinning the column to
   the measure instead of using a fraction means every pixel the copy does not
   need is handed to the graphic automatically, at every viewport width. */
.hero__lede--wide {
  max-width: 47.25rem;
  font-size: clamp(1.0625rem, 0.94rem + 0.45vw, 1.1875rem);
}
.hero__inner:has(.hero__lede--wide) {
  grid-template-columns: minmax(0, 47.25rem) minmax(0, 1fr);
}

/* Stacked layout: the plate sits under the copy, so it is held to 360px to
   keep the rust band from running long. */
.hero__inner:has(.hero__lede--wide) .hero__graphic {
  max-width: 22.5rem;
}

/* Side-by-side only once the leftover column can carry a plate worth showing.
   With the copy pinned at 756px that happens at 1241px, which also removes the
   starved 200px plate the old 1080px breakpoint left behind. */
@media (max-width: 1240px) {
  .hero__inner:has(.hero__lede--wide) {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* 28.5rem (456px) is the point at which the cropped viewBox makes the plate
   exactly as tall as the copy block beside it — so it reads ~50% larger while
   the rust band keeps its original height and the next section stays on the
   fold. Any wider and the plate, not the headline, sets the hero's height. */
@media (min-width: 1241px) {
  .hero__inner:has(.hero__lede--wide) .hero__graphic {
    max-width: 28.5rem;
  }
}


/* ======================================================================
   PREMISE -- industries hub intro
   Article format: the claim on the left, the argument on the right. No fill,
   no frame, no rules -- the two columns and their shared top and bottom edges
   carry the structure on their own.

   Both columns spread rather than only one. Whichever side is intrinsically
   shorter distributes its own free space, so the first lines align at the row
   top and the last lines align at the row bottom -- measured at 0px off on both
   edges from 1201px to 2560px, and it holds if the copy is later edited.

   Stretching only the claim column would work, but only while the prose happens
   to be the taller of the two. Which column is taller flips with how the title
   wraps, so that assumption breaks on its own at some widths.
   ====================================================================== */
.premise {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: clamp(var(--space-8), 4vw, var(--space-16));
  align-items: stretch;
}
.premise__claim,
.premise__body {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.premise__eb {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
  margin: 0 0 var(--space-5);
}

/* The site's own section-title curve. A larger face made the claim column
   intrinsically taller than the prose at most widths, which forced the prose to
   spread and opened a 92px hole between its paragraphs. At this size the two
   sides sit within a couple of pixels naturally, so the spread only rounds off. */
.premise__title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.3rem, 0.82rem + 1.85vw, 2.5rem);
  line-height: 1.08;
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  margin: 0;
}
.premise__title .rust { color: var(--color-primary); }

.premise__meta {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
  margin: var(--space-8) 0 0;
}

/* No measure cap. In a split like this the column is the measure; a 34em cap
   only leaves a dead strip against the right margin. */
.premise__p {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-5);
}
.premise__p:last-child { margin-bottom: 0; }

/* Stacks at 1200, the same point the industry cells below already collapse, so
   the page has one breakpoint rather than two. Held two-column any lower and the
   claim column gets narrow enough that the spread has to absorb 70px or more.
   Media queries add no specificity, so every property is re-declared. */
@media (max-width: 1200px) {
  .premise {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }
  .premise__claim,
  .premise__body { display: block; }
  .premise__meta { margin-top: var(--space-6); }
  .premise__p { max-width: 30em; }
}


/* ==========================================================================
   INDUSTRY CELLS -- Who We Serve
   Fixed five-column grid. The reveal fills the cell it is already in; the cell
   never grows and neighbouring cells never move. Separate from .solrow /
   .solpanel on purpose -- those still drive the expanding accordion on the
   solutions pages.
   ========================================================================== */
.indrow {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border-top: 1px solid var(--color-text);
  border-bottom: 1px solid var(--color-divider);
}

.indcell {
  position: relative;
  display: block;
  overflow: hidden;
  height: 16.5rem;
  text-decoration: none;
  border-right: 1px solid var(--color-divider);
}

.indcell:last-child { border-right: 0; }

/* Four-across variant. Used by the data centers How We Help band, where there
   are four seats rather than five industries. Wider columns mean the same body
   copy takes fewer lines, so the cell can be shorter than the five-up row. */
.indrow--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.indrow--4 .indcell { height: 16.25rem; }
/* Unlike the hub cells, the four-up rest face carries its own short
   description so a visitor can place themselves without hovering. The two
   faces hold different copy: the rest face names the segment, the rust face
   says what we do for it. */
.indrow--4 .indcell__rest .indcell__body { display: block; margin-top: var(--space-3); }
/* Seat names differ in length from one industry to the next. Measured across
   all ten industry pages, none of them wrap at 1440 and above, so reserving a
   second line there only opens a hole under every name on the rest face and
   makes the copy jump upward when the rust face fades in. The reservation is
   scoped to the 1201-1439 band below, where names on five of the pages really
   do wrap, and it is applied to both faces there so the two stay registered. */
.indrow--4 .indcell__reveal { gap: var(--space-3); }
.indcell:focus { outline: none; }
.indcell:focus .indcell__reveal { opacity: 1; }

.indcell__rest,
.indcell__reveal {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-5);
}

.indcell__rest { z-index: 1; }
/* The rest face carries the description for the stacked state only. */
.indcell__rest .indcell__body { display: none; }
.indcell__rest .indcell__title { margin-top: var(--space-3); }
.indcell__rest .indcell__attr { margin-top: auto; }

.indcell__reveal {
  z-index: 2;
  gap: var(--space-3);
  background: var(--gradient-rust);
  opacity: 0;
  transition: opacity 200ms cubic-bezier(0.16, 1, 0.3, 1);
}

.indcell:hover .indcell__reveal,
.indcell:focus-visible .indcell__reveal { opacity: 1; }
.indcell:focus-visible { outline: none; }

.indcell__num {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

.indcell__title {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.indcell__title span { display: block; }

.indcell__body {
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.indcell__attr {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.indcell__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: auto;
}

.indcell__arrow { color: #fff; }

/* Foreground on the rust ground. 0.92 alpha measures about 5.0:1 against
   #a64a40; 0.8 measures 4.28:1 and fails the 4.5:1 floor. */
.indcell__reveal .indcell__num { color: rgba(255, 255, 255, 0.92); }
.indcell__reveal .indcell__title { color: #fff; }
.indcell__reveal .indcell__body { color: rgba(255, 255, 255, 0.92); }
.indcell__reveal .indcell__attr { color: rgba(255, 255, 255, 0.92); }

@media (prefers-reduced-motion: reduce) {
  .indcell__reveal { transition: none; }
}

/* Five cells do not divide into an intermediate column count without leaving
   an orphan slot and a stray hanging hairline, so this goes straight from five
   across to one. Below the breakpoint there is no pointer to reveal anything,
   so the cells stack and show the description at rest. */
/* Between the stack point and the full-width layout the cells are narrower, so
   the same copy takes more lines and the cell has to be taller to contain it.
   The height is still fixed at any given viewport -- hovering never changes it.

   The boundary is 1440, not 1400, because the content cap does not bind until
   the viewport clears 1600 minus the 96px of gutter. Between 1401 and 1439 the
   columns are still narrow enough to push the longest body to five lines, so
   they belong in the taller band. Measured worst case in this band is 18.71rem
   at 1201px; above 1440 it settles at 16.20rem and stays there to 2560. */
@media (min-width: 1201px) and (max-width: 1439px) {
  .indcell { height: 19rem; }
}

@media (min-width: 1201px) and (max-width: 1439px) {
  .indrow--4 .indcell { height: 20.5rem; }
  /* Both faces, so the description and the rust-face body start on the same
     baseline and nothing shifts on hover. */
  .indrow--4 .indcell__title { min-height: calc(2 * var(--lh-snug) * 1em); }
}

@media (max-width: 1200px) {
  .indrow, .indrow--4 { grid-template-columns: 1fr; }
  .indrow--4 .indcell { height: auto; }
  .indcell {
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
  }
  .indcell:last-child { border-bottom: 0; }
  .indcell__rest {
    position: static;
    padding: var(--space-5) 0;
  }
  .indcell__rest .indcell__body { display: block; margin-top: var(--space-2); }
  .indcell__rest .indcell__attr { margin-top: var(--space-3); }
  .indcell__reveal { display: none; }
}


/* ======================================================================
   23. PHOTO PAGE HEAD -- industry detail pages
   A full-bleed photograph carrying the rust gradient as a translucent overlay
   rather than a flat fill. The .rustsurface gradient stays on the section
   itself as the fallback paint, so a failed image request degrades to the
   ordinary rust page head instead of white-on-white.
   ====================================================================== */
/* Padding-block deliberately matches .pagehead--rust so the photo band on an
   industry page stands exactly as tall as the flat rust band on a solution
   page. This declaration comes after section 4b, so it must repeat the same
   value rather than rely on the --rust rule winning. */
.pagehead--photo {
  padding-block: clamp(var(--space-16), 7vw, var(--space-20));
  isolation: isolate;
}

/* .rustsurface > * already assigns position: relative and z-index: 1 to every
   direct child, which would stack the photo on top of the copy. Both of these
   carry the same specificity as that rule, so they only win by coming later in
   the sheet -- keep this block after section 4b. */
.pagehead__img {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Biased above centre: the halls sit in the upper two thirds of the frame, so
     a centred crop on a short band cuts them and shows mostly apron and scrub. */
  object-position: 50% 38%;
}

/* One near-black ramp, no rust in the overlay at all. The warmth in this band is
   the photograph's own -- case-datacenter.webp is a dusk frame that already sits
   at R-B +48 -- so tinting the scrim rust on top of it only muddied the halls
   into a single pink wash. A neutral ramp lets the dusk light read as dusk light
   and keeps the type side dense enough to hold contrast.
   Carried over verbatim from the approved band in mockups/intro-v3.html. */
.pagehead__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    78deg,
    rgb(20 16 15 / 0.92) 0%,
    rgb(20 16 15 / 0.78) 46%,
    rgb(20 16 15 / 0.34) 100%
  );
}

.pagehead__inner {
  position: relative;
  z-index: 2;
}

/* === 4c. PAGE HEAD -- PROOF VARIANT ======================================
   An industry head that carries the page title alongside four pieces of real
   work, instead of a photographic band with the work deferred to a rail near
   the footer. Geometry is taken from the approved mock: a 37.7% text column, a
   10.1% channel, and a 52.5% tile column, with the three small tiles' outer
   edges landing exactly on the featured tile's.

   There is no photograph in the band itself -- the images live only inside the
   tiles, and the band is the rust wash on near-black. A page using this head
   drops its Latest Insights section, since the head has taken that job.

   Must stay after 4b so the .pagehead base rules are already in play.
   ====================================================================== */
/* ---------------------------------------------------------------------------
   Proof hero. Ratios lifted from the mock: 37.7 / 10.1 / 52.5 across the
   content width, tiles bottom-heavy inside the band, small tiles sharing the
   featured tile's outer edges so the right side reads as one aligned unit.
   --------------------------------------------------------------------------- */
.pagehead--proof {
  position: relative;
  background: #14100f;
  padding-block: 104px 40px;   /* 80px of header clearance, then the mock's tight top */
  overflow: hidden;
}
/* The mock's band is a single flat fill. Dead flat at this size reads cheap,
   so a rust wash rakes across the type column and clears before the tiles --
   the tiles supply the colour from here. */
.ph__wash {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(102deg,
      rgb(111 49 43 / .96) 0%,
      rgb(141 63 54 / .82) 22%,
      rgb(166 74 64 / .34) 38%,
      rgb(166 74 64 / .08) 48%,
      rgb(166 74 64 / 0) 56%),
    radial-gradient(120% 90% at 8% 0%, rgb(180 87 76 / .30), transparent 62%);
}
.pagehead--proof .ph__inner {
  position: relative;
  display: grid;
  grid-template-columns: 37.7% 52.5%;
  justify-content: space-between;   /* leaves the mock's 10.1% channel */
  align-items: center;
  gap: 0;
}

.ph__say .eyebrow { margin-bottom: 18px; }
.pagehead--proof .display {
  font-size: clamp(2.4rem, 1.2rem + 3.4vw, 4.2rem);
  line-height: .98;
  font-weight: 300;
  margin: 0;
}
.ph__lede {
  margin: 26px 0 0;
  max-width: 30em;
  font-size: 1.125rem;
  line-height: 1.55;
  color: rgb(255 255 255 / .82);
}

/* --- the tile unit ------------------------------------------------------- */
.ph__proof { display: grid; gap: 18px; }
.ph__row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.ptile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-sm);
  text-decoration: none;
  isolation: isolate;
}
.ptile img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 50% 44%;
  transition: transform .6s cubic-bezier(.2, .7, .2, 1);
}
.ptile:hover img { transform: scale(1.035); }
/* Copy sits inside the tile, as in the mock, so it needs a floor to sit on. */
/* The tag sits roughly 55px off the tile floor. The first pass ramped from
   .30 at 42% to .78 at 78%, which put the tag at about .45 -- invisible over a
   bright sky. The ramp now reaches .62 by the midpoint and .90 by 80%. */
.ptile__veil {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg,
    rgb(20 16 15 / 0) 0%,
    rgb(20 16 15 / .16) 28%,
    rgb(20 16 15 / .62) 56%,
    rgb(20 16 15 / .90) 80%,
    rgb(20 16 15 / .96) 100%);
}
/* Measured: with the full-tile veil alone, the tag's backdrop came in at 89
   and 98 against a ceiling of 34, because the tag is the topmost element of
   the block and sits where the veil is still weak. The body therefore carries
   its own ramp, sized to its own height rather than the tile's, so the tag is
   covered no matter how tall the copy runs. */
.ptile__body {
  position: absolute; inset: auto 0 0 0;
  display: block;
  padding: 30px 22px 20px;
  color: #fff;
  background: linear-gradient(180deg,
    rgb(20 16 15 / 0) 0%,
    rgb(20 16 15 / .34) 18%,
    rgb(20 16 15 / .74) 40%,
    rgb(20 16 15 / .88) 66%,
    rgb(20 16 15 / .93) 100%);
}
.ptile__title {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.2;
}
.ptile__note {
  display: block;
  margin-top: 10px;
  max-width: 34em;
  font-size: .9375rem;
  line-height: 1.5;
  color: rgb(255 255 255 / .78);
}

/* Featured tile: the mock's 1.62:1 relaxed to a cinematic crop so the whole
   unit fits a sane band height. */
.ptile--lead { aspect-ratio: 2.42 / 1; }
.ptile--lead .ptile__title { font-size: 1.6875rem; max-width: 22em; }
.ptile--lead .ptile__body { padding: 30px 30px 26px; }

/* Small tiles: near-square in the mock, widened here. Three lines fit inside
   the tile at this height; the clamp is a backstop against a longer title
   arriving later, not the working limit. */
/* 1.68:1 left a three-line title 13px short of fitting at 1512 and 29px short
   at 1280 once the chip was added. Slightly taller, with tighter internal
   padding, and it clears at every width. */
.ptile--sm { aspect-ratio: 1.55 / 1; }
.ptile--sm .ptile__body { padding: 22px 18px 18px; }

.ptile--sm .ptile__title {
  font-size: 1rem;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Small tiles carry the same three lines in a third of the height, so the
   floor has to come up higher still. */
.ptile--sm .ptile__veil {
  background: linear-gradient(180deg,
    rgb(20 16 15 / .06) 0%,
    rgb(20 16 15 / .34) 22%,
    rgb(20 16 15 / .74) 48%,
    rgb(20 16 15 / .93) 74%,
    rgb(20 16 15 / .97) 100%);
}

@media (max-width: 1100px) {
  .pagehead--proof .ph__inner {
    grid-template-columns: 1fr;
    gap: 40px;
    align-items: start;
  }
  .ph__lede { max-width: 46em; }
  /* Stacked, the tile column takes the full content width. Holding the desktop
     ratios here would make the featured tile 536px tall on its own and push the
     band past 1100px, so both ratios flatten. */
  .ptile--lead { aspect-ratio: 2.9 / 1; }
  .ptile--sm { aspect-ratio: 1.9 / 1; }
  .ptile--lead .ptile__title { font-size: 1.5rem; }
}
@media (max-width: 1400px) and (min-width: 1101px) {
  /* At 1280 the three-line titles leave only 13px of slack inside a 117px
     tile. Dropping a step buys the breathing room back. */
  .ptile--sm .ptile__title { font-size: .9375rem; }
  /* 1px of slack at 1280 is not slack. */
  .ptile--sm { aspect-ratio: 1.44 / 1; }
}
@media (max-width: 700px) {
  .pagehead--proof { padding-block: 104px 36px; }
  .ph__row { grid-template-columns: 1fr; }
  .ptile--sm { aspect-ratio: 2.4 / 1; }
  /* One column wide, a 2.9:1 featured tile is only 121px tall and its title
     plus note need 216. Taller crop, and the note goes -- the headline is the
     part that has to survive. */
  .ptile--lead { aspect-ratio: 16 / 9; }
  .ptile--lead .ptile__title { font-size: 1.25rem; }
  .ptile--lead .ptile__note { display: none; }
  .ptile--lead .ptile__body { padding: 30px 22px 20px; }
}

/* --- the statement --------------------------------------------------------
   Sentence case, not the tracked caps of .display. A two-clause sentence set in
   caps reads as shouting at this size, and the whole point of the band is that
   the sentence sounds like something a person would say. The two tones carry
   the emphasis instead of a weight or colour change. */
.statement {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: clamp(1.375rem, 0.78rem + 2.05vw, 2.85rem);
  line-height: 1.14;
  letter-spacing: var(--track-tight);
  /* Held under the home hero's own display size so the hierarchy between the
     front page and an industry page stays the right way round. */
  max-width: 21em;
  margin: 0;
  /* Back to 0.62. This was pushed to 0.70 to buy contrast against the brighter
     frame that used to sit behind it, where 0.62 measured only 3.07:1. The dusk
     frame and its near-black ramp made that unnecessary: 0.62 now measures
     5.3:1 at 1920 and 3.8:1 at 390, its worst point. */
  color: rgb(255 255 255 / 0.62);
  text-wrap: pretty;
}

.statement__b { color: #ffffff; }

.pagehead__hr {
  display: block;
  height: 1px;
  margin-top: clamp(var(--space-8), 3.5vw, var(--space-10));
  background: rgb(255 255 255 / 0.28);
}

/* --- the marks row -------------------------------------------------------
   Four industry markers rather than a lede. On a page whose whole argument is
   that the schedule is set by procurement and proved by testing, naming those
   things in the first screen does more than another sentence would. */
.marks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) clamp(var(--space-6), 4vw, var(--space-12));
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}

.marks__i {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.82);
}

@media (max-width: 760px) {
  /* Each clause takes its own line. Left inline, the two clauses collide
     mid-line -- "design was. Everything after it" -- and the tone change
     between the muted clause and the white one stops reading as a turn in the
     sentence and starts reading as a highlighted fragment. */
  .statement__b { display: block; }
}

@media (max-width: 560px) {
  .statement { font-size: var(--text-xl); }
  .marks { gap: var(--space-3) var(--space-6); }
}


/* ======================================================================
   24. AUDIENCE GRID -- how we help, by the seat the client sits in
   Four equal cells on one hairline. Every cell holds a number, a title, a
   one-line condition and a four-item list, and those four bands have to line
   up across all four cells or the row stops reading as a grid.

   Subgrid does that structurally: the outer grid owns the four row tracks and
   each cell inherits them, so the tallest title in the row sets the title band
   for every cell. The alternative is min-heights guessed per breakpoint, which
   drift the moment a word is edited.
   ====================================================================== */
.aud {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto auto auto auto;
  border-top: 1px solid var(--color-text);
}

.aud__i {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4;
  row-gap: var(--space-3);
  min-width: 0;
  padding: clamp(18px, 1.6vw, 24px) clamp(22px, 2.2vw, 34px);
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}

/* First cell in each row sits flush to the shell margin, last carries no rule,
   so the row's outer edges are the page's own margins and not a box. */
.aud__i:nth-child(4n) { border-right: 0; }
.aud__i:nth-child(4n + 1) { padding-left: 0; }

.aud__n {
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

.aud__t {
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  margin: 0;
}

.aud__l {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  margin: 0;
}

.aud__gs {
  margin: 0;
  padding: 0;
  list-style: none;
  align-self: start;
}

/* A short rust rule instead of a bullet. Bullets on four stacked lists across
   four cells put sixteen dots on the row and the grid stops being the thing you
   see first. */
.aud__g {
  position: relative;
  padding-left: var(--space-5);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--text-sm);
  line-height: var(--lh-snug);
  color: var(--color-text);
}

.aud__g + .aud__g { margin-top: var(--space-3); }

.aud__g::before {
  content: '';
  position: absolute;
  left: 0;
  /* Centred on the first line's optical middle rather than its box, so the rule
     reads as sitting on the line and not floating above it. */
  top: 0.62em;
  width: 10px;
  height: 1px;
  background: var(--color-primary);
}

/* Two across, then one. Both restate every side, since media queries add no
   specificity and the 4n rules above would otherwise keep applying. */
@media (max-width: 1200px) and (min-width: 681px) {
  .aud { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .aud__i:nth-child(4n),
  .aud__i:nth-child(4n + 1) { border-right: 1px solid var(--color-divider); padding-left: clamp(22px, 2.2vw, 34px); }
  .aud__i:nth-child(2n) { border-right: 0; }
  .aud__i:nth-child(2n + 1) { padding-left: 0; }
}

@media (max-width: 680px) {
  .aud { grid-template-columns: minmax(0, 1fr); }
  .aud__i {
    border-right: 0;
    padding-left: 0;
    padding-right: 0;
  }
  /* Row tracks shared across a single column would stretch every cell to the
     tallest title on the page, leaving gaps under the short ones. */
  .aud__i {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }
}

/* Where subgrid is unavailable the cells fall back to independent tracks. The
   bands no longer align across cells, so the title gets a two-line floor to
   keep the drift to one line rather than several. */
@supports not (grid-template-rows: subgrid) {
  .aud__i { grid-template-rows: auto auto auto auto; }
  .ocitem { display: flex; flex-direction: column; }
  .cell { display: flex; flex-direction: column; gap: var(--space-3); }
  .aud__t { min-height: 2.7em; }
  .aud__l { min-height: 3.4em; }
}

/* ======================================================================
   HOW WE HELP — seat variant (industries/data-centers)
   Same lateral accordion as the solution pages. Segment names are longer
   than phase names, so the title stacks over two lines at rest and joins
   onto one line when the panel opens.
   ====================================================================== */
.solrow--seat { height: 22.5rem; }

/* On open, the rest-state body is replaced by two paragraphs of roughly equal
   length sitting side by side under a hairline, filling the open panel. */
.solrow--seat .solpanel__detail { max-width: none; }
.solrow--seat .solpanel:hover .solpanel__mid,
.solrow--seat .solpanel:focus-visible .solpanel__mid {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: var(--space-5);
}
.solrow--seat .solpanel__narr { display: none; }
.solrow--seat .solpanel:hover .solpanel__narr,
.solrow--seat .solpanel:focus-visible .solpanel__narr {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-9);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.28);
}
.solrow--seat .solpanel__narrp {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.9);
}

/* At rest the two title spans stack; on open they join onto one line. */
.solrow--seat .solpanel__title {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 0;
  font-size: var(--text-lg);
  line-height: 1.26;
}
.solrow--seat .solpanel:hover .solpanel__title,
.solrow--seat .solpanel:focus-visible .solpanel__title {
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 0.32em;
  white-space: nowrap;
  font-size: 1.5rem;
}

/* Between the stack breakpoint and ~1300px the panels are too narrow to hold
   these segment names at --text-lg: the titles fracture to three and four
   lines and strand an ampersand. Step the type down and give the row the
   height the longer bodies need. */
/* Row height is governed by the rest-state body, which grows as the panels
   narrow. Step it in bands so no width carries excessive dead space. */
@media (min-width: 1301px) and (max-width: 1460px) {
  .solrow--seat { height: 24rem; }
}
@media (min-width: 1151px) and (max-width: 1300px) {
  .solrow--seat { height: 24rem; }
}

@media (min-width: 981px) and (max-width: 1300px) {
  .solrow--seat .solpanel__title { font-size: var(--text-base); }
  .solrow--seat .solpanel:hover .solpanel__narr,
  .solrow--seat .solpanel:focus-visible .solpanel__narr {
    padding: var(--space-4) var(--space-5);
  }
  .solrow--seat .solpanel:hover .solpanel__narr,
  .solrow--seat .solpanel:focus-visible .solpanel__narr {
    column-gap: var(--space-6);
  }
}
@media (min-width: 981px) and (max-width: 1150px) {
  .solrow--seat { height: 26.5rem; }
}

@media (hover: none), (max-width: 980px) {
  .solrow--seat { height: auto; }
  .solrow--seat .solpanel__narr,
  .solrow--seat .solpanel:hover .solpanel__narr,
  .solrow--seat .solpanel:focus-visible .solpanel__narr {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-4);
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-divider);
  }
  .solrow--seat .solpanel__narrp { color: var(--color-text-muted); }
  .solrow--seat .solpanel__title,
  .solrow--seat .solpanel:hover .solpanel__title,
  .solrow--seat .solpanel:focus-visible .solpanel__title {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.32em;
    white-space: normal;
    font-size: var(--text-lg);
    line-height: 1.3;
    color: var(--color-text);
  }
}

/* ======================================================================
   APPROACH (data centers) -- a hairline 2x2 matrix of the work itself sits
   left, the statement anchors right, and four attribute cards close the
   Matrix rows are 1fr each inside a stretched grid item, so the matrix
   bottoms out level with the statement column. All type is on the
   shared token scale: titles read as .ocitem__t, copy as .ocitem__d.
   ====================================================================== */
.apr-split {
  display: grid;
  grid-template-columns: 1.18fr 0.82fr;
  gap: clamp(var(--space-8), 3.4vw, var(--space-12));
  align-items: stretch;
}

.apr-mx {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: 1fr 1fr;
  border-top: 1px solid var(--color-text);
}

.apr-cell {
  min-width: 0;
  padding: clamp(16px, 1.5vw, 22px) clamp(22px, 2.2vw, 34px);
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}

.apr-cell:nth-child(2n) {
  border-right: 0;
  padding-right: 0;
}

.apr-cell:nth-child(2n + 1) {
  padding-left: 0;
}

.apr-ico {
  display: block;
  color: var(--color-primary);
}

.apr-cell__t {
  margin: var(--space-4) 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.apr-cell__d {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--lh-normal);
  color: var(--color-text-muted);
  text-wrap: balance;
}

.apr-say {
  display: flex;
  flex-direction: column;
  align-self: stretch;
}

.apr-state {
  margin: var(--space-4) 0 0;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-light);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  text-wrap: pretty;
}

.apr-rule {
  width: 3rem;
  height: 2px;
  background: var(--color-primary);
  border: 0;
  margin: var(--space-6) 0 0;
}

/* The body sits a fixed distance below the rule rather than being pushed to
   the bottom of the stretched column. Bottom-anchoring left a void of varying
   between the rule and the paragraph that read as a layout fault rather than
   as deliberate whitespace, and the size of it changed with every statement.
   The measure runs the full width of the statement column rather than a 42ch
   cap: a narrower cap left the paragraph's right edge short of the statement
   above it, and the extra lines it forced pushed the matrix into a taller
   stretch, opening a void under every cell. */
.apr-bodywrap { margin: var(--space-6) 0 0; }

.apr-body {
  margin: 0;
  max-width: none;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.apr-body + .apr-body { margin-top: var(--space-4); }

/* Stacked, the statement column runs the full shell. Left as one block the
   statement took a 1200px measure and the paragraph hung as a narrow ribbon
   with half the row empty beside it, so the column splits in two on the same
   midline the matrix above it uses. */
@media (max-width: 1320px) {
  .apr-split { grid-template-columns: 1fr; }
  .apr-mx { grid-template-rows: auto auto; }
  .apr-say {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(44px, 4.4vw, 68px);
    align-items: start;
  }
  /* Side by side, the rule no longer has to separate the statement from the
     paragraph -- the column gap does that -- so it moves up under the eyebrow
     and reads as a masthead rule instead of hanging off the bottom. */
  .apr-say > .eyebrow { grid-column: 1; grid-row: 1; margin: 0; }
  .apr-rule { grid-column: 1; grid-row: 2; margin: var(--space-3) 0 0; }
  .apr-state { grid-column: 1; grid-row: 3; margin: var(--space-4) 0 0; }
  .apr-bodywrap {
    grid-column: 2;
    grid-row: 1 / span 3;
    margin: 0;
  }
}

@media (max-width: 860px) {
  .apr-say { display: block; }
  .apr-state { margin: var(--space-4) 0 0; }
  .apr-rule { margin: var(--space-6) 0 0; }
  .apr-bodywrap { margin: var(--space-6) 0 0; }
}

@media (max-width: 640px) {
  .apr-mx { grid-template-columns: 1fr; grid-template-rows: auto; }
  .apr-cell { border-right: 0; padding-left: 0; padding-right: 0; }
  .apr-cell:nth-child(2n) { padding-right: 0; }
}

/* --------------------------------------------------------------------------
   30. ABOUT PAGE
   Story plate, values row, difference matrix, team carousel, latest columns.
   Nothing here is used anywhere else on the site.
   -------------------------------------------------------------------------- */

/* --- 30.1 our story ----------------------------------------------------- */
/* Portrait plate left, prose right, both columns exactly the same height. The
   row is sized by the prose, the figure stretches to it, and the photograph
   fills the figure -- so the bottom of the plate lands on the same line as the
   bottom of the signature block instead of stopping short of it. That means
   the crop ratio is not fixed; the subjects sit inside the middle 60% of the
   frame, so a tighter-than-4:5 crop still clears them on both sides. */
.story {
  display: grid;
  grid-template-columns: minmax(0, 0.58fr) minmax(0, 1fr);
  gap: clamp(var(--space-10), 4.5vw, var(--space-20));
  align-items: stretch;
}

.story__fig {
  margin: 0;
  min-height: 0;
}

.story__img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
  border-radius: var(--radius-md);
  background: var(--color-surface-offset);
}

.story__text {
  max-width: 62ch;
}

.story__p {
  margin: 0;
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

.story__p + .story__p {
  margin-top: var(--space-5);
}

/* The opening paragraph carries the section, so it gets display weight. */
.story__p:first-child {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);
  font-size: var(--text-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

/* --- 30.2 signature ----------------------------------------------------- */
.sig {
  margin-top: var(--space-10);
  padding-top: var(--space-7);
  border-top: 1px solid var(--color-divider);
}

.sig__mark {
  display: block;
  width: clamp(178px, 15vw, 226px);
  height: auto;
  color: var(--color-text);
}

.sig__name {
  margin: var(--space-4) 0 0;
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.sig__role {
  margin: var(--space-1) 0 0;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* --- 30.3 values -------------------------------------------------------- */
/* Values reuses `.indrow--4 .indcell` wholesale (see section 24) so it reads
   in the same construction as the client-segment rows on the industry pages.
   The only difference is that a value is not a destination: the cell is a div
   rather than a link and carries no arrow, so it needs a text cursor and no
   pointer affordance. Everything else -- fixed heights, the rust reveal, the
   sub-1200 collapse -- comes for free from the shared component. */
.indcell--static {
  cursor: default;
}

.indcell--static:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

/* --- 30.4 the canadian breaks difference -------------------------------- */
/* Six cells reading as one hairline plate. The heavy top rule matches the
   values row above it so the two blocks share a construction. */
.dmx {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--color-text);
}

.dcell {
  min-width: 0;
  padding: clamp(var(--space-6), 2vw, var(--space-8)) clamp(var(--space-6), 2.4vw, var(--space-10));
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}

.dcell:nth-child(3n) {
  border-right: 0;
  padding-right: 0;
}

.dcell:nth-child(3n + 1) {
  padding-left: 0;
}

.dcell__n {
  display: block;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  color: var(--color-primary);
}

.dcell__t {
  margin: var(--space-4) 0 var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-regular);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  text-wrap: balance;
}

.dcell__d {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
  text-wrap: pretty;
}

/* --- 30.5 team carousel ------------------------------------------------- */
/* Nav sits under the track, on the right, so the eye finishes the row of
   faces before it finds the control rather than being sent back up to the
   headline. */
.carnav {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: var(--space-6);
  flex-shrink: 0;
}

.carbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  transition:
    border-color var(--transition-interactive),
    background-color var(--transition-interactive),
    color var(--transition-interactive);
}

.carbtn:hover:not(:disabled) {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: #fff;
}

.carbtn:disabled {
  opacity: 0.32;
  cursor: default;
}

/* The carousel now lives inside `.shell` rather than beside it. The viewport
   is what clips, and the viewport edges are the content edges, so card one
   starts on the same vertical line as every headline on the page and the last
   visible card always ends flush -- no card is ever shown part-cut.

   Paging is a transform on the track, not a scroll offset, because a scroll
   container has to render whatever sits past its edge and that is exactly the
   half-card the clipped viewport is here to prevent. With JS off the viewport
   falls back to a plain scroll region (see `.car__vp` overflow-x below), so
   every card is still reachable. */
.car {
  margin-top: clamp(var(--space-8), 3vw, var(--space-10));
}

.car__vp {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

/* JS took over: the track is positioned by transform, so the scrollport must
   stop scrolling or the two mechanisms fight each other. */
.car[data-car-ready] .car__vp {
  overflow: hidden;
}

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

.car__vp:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 4px;
}

.car__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 3 * var(--space-6)) / 4);
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
  transform: translate3d(0, 0, 0);
  transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1);
}

.tcard {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}

.tcard__ph {
  display: block;
  aspect-ratio: 900 / 700;
  overflow: hidden;
  background: var(--color-surface-offset);
}

.tcard__ph img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The caption bar is the reference card's signature: solid rust, name over
   title, firm mark held to the right edge. */
.tcard__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: #A64A40;
  min-height: 68px;
}

.tcard__id {
  display: block;
  min-width: 0;
}

.tcard__name {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: #fff;
}

.tcard__role {
  display: block;
  margin-top: 2px;
  font-size: var(--text-xs);
  line-height: var(--lh-snug);
  color: rgba(255, 255, 255, 0.88);
}

.tcard__mark {
  flex: 0 0 auto;
  width: 42px;
  height: auto;
  opacity: 0.92;
}

/* An open seat: same footprint, obviously unfilled, nothing invented. */
.tcard--empty {
  border-style: dashed;
  background: var(--color-surface-2);
}

.tcard__ph--empty {
  display: grid;
  place-items: center;
  background: var(--color-surface-offset);
  border-bottom: 1px dashed var(--color-border);
}

/* The placeholder mark has to beat `.tcard__ph img` on specificity, or it
   inherits the full-bleed cover sizing meant for a real headshot. Desaturated
   so an open seat reads as a waiting slot rather than a second brand moment. */
.tcard__ph--empty .tcard__ghost {
  width: 27%;
  height: auto;
  object-fit: contain;
  filter: grayscale(1);
  opacity: 0.18;
}

/* Empty (photo-less) team cards share the rust caption bar of the photographed
   cards so the name and title read at the same weight across the roster. The
   dashed border and ghost CBC mark still mark them as awaiting a headshot. */
.tcard--empty .tcard__bar {
  background: #A64A40;
  border-top: 0;
}

.tcard--empty .tcard__name {
  color: #fff;
  font-weight: var(--weight-medium);
}

.tcard--empty .tcard__role {
  color: rgba(255, 255, 255, 0.88);
}

/* --- 30.5b roster ------------------------------------------------------- */
/* People whose headshot has not been taken yet. A ruled name list rather than
   a screen of dashed plates: it names everyone at full strength and costs a
   fraction of the height. Rules sit on top of each cell so the grid reads as
   one ledger, and the last row closes with a rule on the container. */
.roster {
  margin-top: clamp(var(--space-10), 3.5vw, var(--space-16));
}

.roster__lab {
  margin: 0 0 var(--space-6);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.roster__g {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 clamp(var(--space-8), 3vw, var(--space-16));
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--color-divider);
}

.roster__i {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-divider);
}

.roster__n {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}

.roster__r {
  flex: 0 0 auto;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

@media (max-width: 900px) {
  .roster__g {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .roster__g {
    grid-template-columns: minmax(0, 1fr);
  }

  .roster__i {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
}

/* --- 30.6 latest at canadian breaks ------------------------------------- */
.lcols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(var(--space-10), 4vw, var(--space-16));
}

.lcol {
  min-width: 0;
}

.lcol__label {
  margin: 0 0 var(--space-2);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-text);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text);
}

.lrow {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  align-items: center;
  gap: var(--space-5);
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--color-divider);
  text-decoration: none;
}

.lrow__th {
  display: block;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--color-surface-offset);
}

.lrow__th img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}

.lrow:hover .lrow__th img {
  transform: scale(1.05);
}

.lrow__c {
  display: block;
  min-width: 0;
}

.lrow__k {
  display: block;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-primary);
}

.lrow__t {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: var(--lh-snug);
  color: var(--color-text);
  text-wrap: pretty;
  transition: color var(--transition-interactive);
}

.lrow:hover .lrow__t {
  color: var(--color-primary);
}

/* --- 30.7 three-up cta -------------------------------------------------- */
.cta__actions--trio {
  flex-wrap: wrap;
}

/* --- 30.8 responsive ---------------------------------------------------- */
@media (max-width: 1320px) {
  .vals {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(var(--space-8), 3vw, var(--space-10));
  }

  .car__track {
    grid-auto-columns: calc((100% - 2 * var(--space-6)) / 3);
  }
}

@media (max-width: 1100px) {
  .story {
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
    gap: clamp(var(--space-8), 4vw, var(--space-12));
  }

  .dmx {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .dcell:nth-child(3n) {
    border-right: 1px solid var(--color-divider);
    padding-right: clamp(var(--space-6), 2.4vw, var(--space-10));
  }

  .dcell:nth-child(3n + 1) {
    padding-left: clamp(var(--space-6), 2.4vw, var(--space-10));
  }

  .dcell:nth-child(2n) {
    border-right: 0;
    padding-right: 0;
  }

  .dcell:nth-child(2n + 1) {
    padding-left: 0;
  }
}

@media (max-width: 900px) {
  /* The plate can no longer sit beside the prose without squeezing both. */
  .story {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-10);
  }

  .story__fig {
    position: static;
    max-width: 380px;
  }

  .story__text {
    max-width: none;
  }

  .car__track {
    grid-auto-columns: calc((100% - var(--space-6)) / 2);
  }

  .lcols {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-12);
  }
}

@media (max-width: 720px) {
  .vals {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }

  .dmx {
    grid-template-columns: minmax(0, 1fr);
  }

  .dcell,
  .dcell:nth-child(3n),
  .dcell:nth-child(3n + 1),
  .dcell:nth-child(2n),
  .dcell:nth-child(2n + 1) {
    border-right: 0;
    padding-left: 0;
    padding-right: 0;
  }

  .car__track {
    grid-auto-columns: 76%;
  }

  .lrow {
    grid-template-columns: 96px minmax(0, 1fr);
    gap: var(--space-4);
  }

  .cta__actions--trio .btn {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lrow__th img {
    transition: none;
  }

  .lrow:hover .lrow__th img {
    transform: none;
  }

  .car__track {
    transition: none;
  }
}

/* ==========================================================================
   31. CAREERS PAGE
   Sticky jump ribbon, overview register, benefits grid, process ledger.
   The Why Work Here and Interview Tips blocks reuse `.dmx` from section 30.4
   wholesale -- both are six items of the same shape, so they get the same
   construction rather than a second grid that looks almost like the first.
   -------------------------------------------------------------------------- */

/* --- 31.1 sticky jump ribbon -------------------------------------------- */
/* Parks itself under the fixed header the moment the hero clears. The rules
   above and below are full-bleed while the links sit on the shell measure, so
   the ribbon reads as a band across the page rather than a floating pill. */
.ribbon {
  position: sticky;
  /* The header box measures --header-height plus its bottom rule, so the
     ribbon is pinned one pixel under that rule rather than under the token. */
  top: calc(var(--header-height) + 1px);
  z-index: 30;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-divider);
}

.ribbon__list {
  display: flex;
  gap: clamp(var(--space-6), 3vw, var(--space-12));
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scroll-padding-inline: var(--space-4);
  scrollbar-width: none;
}

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

.ribbon__l {
  display: block;
  padding: var(--space-5) 0;
  border-bottom: 2px solid transparent;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--color-text-faint);
  transition:
    color var(--transition-interactive),
    border-color var(--transition-interactive);
}

.ribbon__l:hover {
  color: var(--color-text);
}

.ribbon__l.is-current {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
}

/* Anchored sections have to clear both the header and the ribbon, or the
   jump lands with the section title hidden behind the two bands. The section's
   own top padding already supplies most of that clearance, so it is subtracted
   back out -- otherwise a jump lands with roughly 260px of empty band above the
   eyebrow. What is left is a constant ~28px of air under the ribbon at every
   width. `--sec-pad` mirrors the `padding-block` on `.section`; if that value
   ever changes, change it here too. */
.csec {
  --sec-pad: clamp(var(--space-16), 8vw, var(--space-32));
  scroll-margin-top: calc(var(--header-height) + 91px - var(--sec-pad));
}

/* --- 31.2 overview: employee spotlight panel ----------------------------- */
/* One featured person at full height with the caption over the photo, three
   more listed beside them. Every tile is a link to that person's spotlight on
   the insights page, so all four carry the same hover the insight rows use:
   the photo scales inside a fixed frame. */
.spotp {
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  gap: clamp(var(--space-8), 3vw, var(--space-12));
  border-top: 1px solid var(--color-text);
  padding-top: clamp(var(--space-6), 2vw, var(--space-8));
  align-items: stretch;
}

/* --- featured ------------------------------------------------------------ */
/* No fixed aspect ratio: the photo stretches to whatever height the three
   rows beside it come to, so the two columns always bottom out level. */
.spotf {
  position: relative;
  display: block;
  height: 100%;
  margin: 0;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  text-decoration: none;
}

.spotf__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 12%;
  transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}

.spotf:hover .spotf__img,
.spotf:focus-visible .spotf__img {
  transform: scale(1.04);
}

.spotf:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

/* The mark sits in the bottom corner, inside the scrim and level with the
   caption baseline. Over the photo itself it would land on whatever the frame
   happens to hold; down here it always has dark ground behind it. */
.spotf__mark {
  position: absolute;
  right: clamp(var(--space-6), 2.4vw, var(--space-9));
  bottom: clamp(var(--space-6), 2.4vw, var(--space-9));
  z-index: 1;
  width: 54px;
  height: auto;
  opacity: 0.9;
  pointer-events: none;
}

/* The scrim only covers the lower part of the frame, so it darkens the caption
   ground without dulling the face above it. */
.spotf__c {
  position: absolute;
  inset: auto 0 0 0;
  display: block;
  padding: clamp(var(--space-16), 9vw, var(--space-24))
    clamp(var(--space-6), 2.2vw, var(--space-8))
    clamp(var(--space-6), 2.2vw, var(--space-8));
  background: linear-gradient(to top, rgb(0 0 0 / 86%) 0%, rgb(0 0 0 / 80%) 22%,
      rgb(0 0 0 / 62%) 44%, rgb(0 0 0 / 26%) 72%, rgb(0 0 0 / 0%) 100%);
}

.spotf__lab {
  display: block;
  margin: 0 0 var(--space-3);
  color: #fff;
  opacity: 0.9;
}

.spotf__n {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-light);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: #fff;
}

.spotf__r {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--text-base);
  line-height: 1.4;
  color: rgb(255 255 255 / 78%);
}

/* --- the other three ------------------------------------------------------ */
.spot {
  display: grid;
  grid-auto-rows: 1fr;
  align-self: stretch;
  min-width: 0;
}

.spotr {
  display: grid;
  grid-template-columns: clamp(150px, 14.5vw, 220px) minmax(0, 1fr) auto;
  gap: clamp(var(--space-6), 2.4vw, var(--space-9));
  align-items: center;
  margin: 0;
  padding: clamp(var(--space-7), 2.4vw, var(--space-9)) 0;
  border-bottom: 1px solid var(--color-divider);
  text-decoration: none;
}

.spotr:first-of-type {
  padding-top: 0;
}

/* The rows are anchors where the spotlight exists and spans where it does
   not, and :first-of-type counts each tag separately, so it would zero the
   padding on two rows instead of one. Position in the panel is what matters
   here, not the tag. */
.spot > .spotr:first-child { padding-top: 0; }
.spot > .spotr:not(:first-child) {
  padding-top: clamp(var(--space-7), 2.4vw, var(--space-9));
}

.spotr:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

/* A plain square `cover` crop leaves the face at about a third of the frame,
   so the frame clips and the image is scaled up inside it. */
.spotr__f {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
}

.spotr__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
  transform: scale(1.3);
  transform-origin: 50% 30%;
  transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}

.spotr:hover .spotr__img,
.spotr:focus-visible .spotr__img {
  transform: scale(1.38);
}

.spotr__c {
  display: block;
  min-width: 0;
}

.spotr__lab {
  display: block;
  margin: 0 0 var(--space-3);
}

.spotr__n {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  transition: color 200ms ease;
}

.spotr:hover .spotr__n,
.spotr:focus-visible .spotr__n {
  color: var(--color-primary);
}

.spotr__r {
  display: block;
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  line-height: 1.4;
  color: var(--color-text-faint);
}

.spotr__go {
  display: flex;
  align-items: center;
  color: var(--color-primary);
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 260ms ease, transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

.spotr:hover .spotr__go,
.spotr:focus-visible .spotr__go {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .spotf__img,
  .spotr__img,
  .spotr__go {
    transition: none;
  }

  .spotf:hover .spotf__img,
  .spotr:hover .spotr__img {
    transform: scale(1.3);
  }

  .spotf:hover .spotf__img {
    transform: none;
  }
}

/* --- 31.2b why work here: three-across reveal cells --------------------- */
/* The same `.indcell` component Our Values uses, run 3x2 instead of 4x1.
   Wider columns than the four-up, so the same copy takes fewer lines and the
   cell can be shorter. */
.indrow--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Measured: the tallest of the twelve faces needs 13.38rem at 1512 and 13.0rem
   at 1440, so the cell is sized to the copy rather than to a round number. */
.indrow--3 .indcell { height: 13.75rem; }
.indrow--3 .indcell:nth-child(3n) { border-right: 0; }
.indrow--3 .indcell:nth-child(3n + 1) { border-right: 1px solid var(--color-divider); }
/* Two rows, so the first three need a floor of their own. */
.indrow--3 .indcell:nth-child(-n + 3) { border-bottom: 1px solid var(--color-divider); }
/* The resting face stays title and attribute only -- the body belongs to the
   rust face. It is still in the markup on both faces so the stacked layout,
   which has no hover, can show it. */
.indrow--3 .indcell__reveal { gap: var(--space-3); }

/* Narrower columns push the body to more lines before the stack point. */
/* 13rem measured at both 1280 and 1201. */
@media (min-width: 1201px) and (max-width: 1439px) {
  .indrow--3 .indcell { height: 13.25rem; }
}

@media (max-width: 1200px) {
  .indrow--3 { grid-template-columns: minmax(0, 1fr); }
  .indrow--3 .indcell,
  .indrow--3 .indcell:nth-child(3n + 1) {
    height: auto;
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
  }
  .indrow--3 .indcell:last-child { border-bottom: 0; }
}

/* --- 31.3 benefits grid -------------------------------------------------- */
/* Four across, two rows, one hairline plate. Row tracks live on the container
   so a title that wraps to two lines lifts the whole row's description line
   instead of dropping its own cell out of alignment with its neighbours. */
.bgrid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: auto auto auto;
  border-top: 1px solid var(--color-text);
}

.bcell {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  min-width: 0;
  padding: clamp(var(--space-6), 2vw, var(--space-8)) clamp(var(--space-5), 2vw, var(--space-8));
  border-right: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}

.bcell:nth-child(4n) {
  border-right: 0;
  padding-right: 0;
}

.bcell:nth-child(4n + 1) {
  padding-left: 0;
}

.bcell__ico {
  display: flex;
  align-items: flex-start;
  color: var(--color-primary);
}

/* The shared glyphs are drawn at 22 for the four-icon approach matrices.
   Here they sit alone above a title, so they carry a little more size. */
.bcell__ico svg {
  width: 26px;
  height: 26px;
}

.bcell__t {
  margin: var(--space-5) 0 var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--track-tight);
  color: var(--color-text);
  text-wrap: balance;
}

.bcell__d {
  /* The column is 440px wide at 1512 but only 347px at 1201, so an unbounded
     measure makes the same sentence fill two lines on a small screen and
     trail off after one and a half on a large one. Capping the measure keeps
     the line length -- and therefore the two-line block -- constant. */
  max-width: 23em;
  margin: 0;
  align-self: start;
  font-size: var(--text-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

/* --- 31.4 interview process matrix --------------------------------------- */
/* The same hairline plate as section 30.4, at two across. Four steps fill a
   2x2 exactly, so there is no spacer cell and the bottom rule runs unbroken.
   The nth-child rules below have to restate the edge cases because the base
   plate is written for three columns. */
.dmx--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dmx--2 .dcell {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--color-divider);
  padding-right: clamp(var(--space-6), 2.4vw, var(--space-10));
  padding-left: clamp(var(--space-6), 2.4vw, var(--space-10));
}

.dmx--2 .dcell:nth-child(2n) {
  border-right: 0;
  padding-right: 0;
}

.dmx--2 .dcell:nth-child(2n + 1) {
  padding-left: 0;
}

/* Large outlined numeral, carried over from the ledger this replaced. */
.dcell__n--big {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 3.2vw, 3rem);
  font-weight: var(--weight-light);
  line-height: 0.82;
  letter-spacing: var(--track-tight);
  color: transparent;
  -webkit-text-stroke: 1px var(--color-border);
}

.dmx--2 .dcell__t {
  margin-top: var(--space-5);
}

/* --- 31.5 cta buttons with glyphs ---------------------------------------- */
.btn--ico .btn__ico {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  margin-right: 0.15em;
}

/* --- 31.6 responsive ------------------------------------------------------ */
/* `.apr-split--mirror` outranks the unprefixed stacking rule on `.apr-split`,
   so the stack has to be restated here at the same breakpoint the industry
   pages use. Once stacked, the panel rows size to their content instead of
   splitting the column three ways. */
@media (max-width: 1000px) {
  .spotp {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }

  /* Stacked, the photo has nothing to match its height to, so it takes a
     fixed crop instead. */
  .spotf {
    height: auto;
    aspect-ratio: 1 / 1;
  }

  /* The wider crop needs to sit higher or it clips the top of the head. */
  .spotf__img {
    object-position: 50% 8%;
  }

  /* Narrower frame puts the eyebrow over a brighter part of the shirt, so the
     scrim needs a little more weight here than it does on a wide screen. */
  .spotf__c {
    background: linear-gradient(to top, rgb(0 0 0 / 88%) 0%, rgb(0 0 0 / 84%) 24%,
        rgb(0 0 0 / 70%) 48%, rgb(0 0 0 / 30%) 74%, rgb(0 0 0 / 0%) 100%);
  }

  .spotf__mark {
    width: 44px;
  }

  .spot {
    grid-auto-rows: auto;
  }

  .spotr:first-of-type {
    padding-top: clamp(var(--space-5), 1.6vw, var(--space-7));
    border-top: 1px solid var(--color-divider);
  }
}

/* Six items rather than eight: three across reads better than a row of four
   over a row of two. Scoped above the stack point so it does not fight the
   two-column and one-column rules below. */
@media (min-width: 1201px) {
  .bgrid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .bgrid--3 .bcell:nth-child(4n),
  .bgrid--3 .bcell:nth-child(4n + 1) {
    padding-inline: clamp(var(--space-5), 2vw, var(--space-8));
    border-right: 1px solid var(--color-divider);
  }

  .bgrid--3 .bcell:nth-child(3n) {
    border-right: 0;
    padding-right: 0;
  }

  .bgrid--3 .bcell:nth-child(3n + 1) {
    padding-left: 0;
  }
}

@media (max-width: 1200px) {
  .bgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .bcell:nth-child(4n),
  .bcell:nth-child(4n + 1) {
    padding-inline: clamp(var(--space-5), 2vw, var(--space-8));
    border-right: 1px solid var(--color-divider);
  }

  .bcell:nth-child(2n) {
    border-right: 0;
    padding-right: 0;
  }

  .bcell:nth-child(2n + 1) {
    padding-left: 0;
  }
}

@media (max-width: 700px) {
  .dmx--2 {
    grid-template-columns: minmax(0, 1fr);
  }

  .dmx--2 .dcell {
    border-right: 0;
    padding-left: 0;
    padding-right: 0;
  }

  .dcell__n--big {
    font-size: 2rem;
  }
}

@media (max-width: 620px) {
  .bgrid {
    grid-template-columns: minmax(0, 1fr);
  }

  .bcell,
  .bcell:nth-child(4n),
  .bcell:nth-child(4n + 1),
  .bcell:nth-child(2n),
  .bcell:nth-child(2n + 1) {
    padding-inline: 0;
    border-right: 0;
  }

  .ribbon__list {
    gap: var(--space-6);
  }

  /* The arrow needs its own track here too, or it wraps onto a second grid
     row and opens a gap under every entry. */
  .spotr {
    grid-template-columns: 96px minmax(0, 1fr) auto;
    gap: var(--space-5);
  }
}


/* ============================================================
   §32  INSIGHTS INDEX  (insights/index.html)
   ============================================================ */

/* --- 32.1 filter bar ----------------------------------------------------- */
/* Four equal controls on one line -- industry, solution, type, keyword. Boxy
   and hairline, like everything else on the site, and sticky under the header
   so the controls stay reachable while you read down 50 cards. */
.ifbar {
  position: sticky;
  top: calc(var(--header-height) + 1px);
  z-index: 40;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
  padding-block: var(--space-4);
  border-top: 1px solid var(--color-text);
  border-bottom: 1px solid var(--color-divider);
  background: var(--color-bg);
}

.ifsearch,
.ifsel {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
}

.ifsearch__ico,
.ifsel__ico {
  position: absolute;
  width: 20px;
  height: 20px;
  pointer-events: none;
  color: var(--color-text-faint);
}

.ifsearch__ico { left: 0.7rem; }
.ifsel__ico { right: 0.7rem; }

.ifsearch__in,
.ifsel__in {
  width: 100%;
  height: 2.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text);
  transition: border-color var(--transition-interactive);
}

.ifsearch__in {
  padding: 0 0.85rem 0 2.4rem;
}

.ifsel__in {
  padding: 0 2.4rem 0 0.85rem;
  appearance: none;
  cursor: pointer;
  text-overflow: ellipsis;
}

.ifsel__in option { color: var(--color-text); background: var(--color-bg); }

.ifsearch__in::placeholder { color: var(--color-text-faint); }
.ifsearch__in:hover,
.ifsel__in:hover { border-color: var(--color-text-muted); }
.ifsearch__in:focus,
.ifsel__in:focus { outline: none; border-color: var(--color-primary); }
.ifsearch__in:focus-visible,
.ifsel__in:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ifsearch__in::-webkit-search-cancel-button { cursor: pointer; }

.ifcount {
  margin-top: var(--space-5);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
  min-height: 1rem;
}

/* --- 32.2 card grid ------------------------------------------------------ */
.igrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(var(--space-6), 2.4vw, var(--space-8));
  row-gap: clamp(var(--space-8), 3vw, var(--space-10));
  margin-top: var(--space-6);
}

/* Everything lives on the picture. The tile is the link, so a click anywhere
   opens the article, and the text sits over a permanent dark scrim so it stays
   readable no matter how bright the photo underneath is. On hover the rust
   gradient washes over the image and the read cue opens up beneath the title. */
.icard {
  position: relative;
  display: block;
  overflow: hidden;
  /* Own query container: the kicker, the two-line title and the two-line
     description size from the card, not the viewport, so the
     characters-per-line budget is the same in a three-column row, a
     two-column row and a single full-bleed column. */
  container-type: inline-size;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  text-decoration: none;
  isolation: isolate;
}

/* Employee spotlights use an unembellished editorial portrait treatment. */
.icard[data-type="spotlight"] {
  border-radius: 0;
}

.icard[data-type="spotlight"] .icard__img {
  border-radius: 0;
}

/* .icard sets display, which outranks the browser default for [hidden].
   Filtering sets the attribute, so restate it here or nothing ever hides. */
.icard[hidden] { display: none; }

.icard__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Two layers in one element: the resting scrim is painted by the element, the
   rust wash by its ::after, so the rust can fade in over the top of the scrim
   without either one being rebuilt on hover. */
.icard__wash {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgb(12 8 7 / 0.86) 0%,
    rgb(12 8 7 / 0.62) 30%,
    rgb(12 8 7 / 0.18) 62%,
    rgb(12 8 7 / 0) 100%
  );
}

.icard__wash::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gradient-rust-deep);
  opacity: 0;
  transition: opacity 420ms cubic-bezier(0.16, 1, 0.3, 1);
}

.icard__body {
  position: absolute;
  inset: auto 0 0 0;
  display: block;
  padding: clamp(var(--space-5), 2vw, var(--space-6));
}

.icard__k {
  display: block;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  /* Literal, not the theme token: the inside of a card is dark in both themes,
     so the dark-mode value of --color-primary-tint would vanish here. */
  color: #e9c8c5;
  transition: color var(--transition-interactive);
}

/* Standardized two-line card text blocks. Title and description each reserve
   exactly two line boxes computed from their own line-height, so every card in
   a row aligns. The line composition is authored in
   tools/editorial_portfolio.py and emitted as two `.cardline` spans: no
   truncation, no ellipsis, no hidden third line, no per-card font override. */
.icard__t {
  display: block;
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: clamp(0.875rem, 4cqw, 1.15rem);
  font-weight: var(--weight-light);
  line-height: 1.28;
  min-height: calc(1.28em * 2);
  max-height: calc(1.28em * 2);
  letter-spacing: var(--track-tight);
  color: #fff;
  overflow: hidden;
}

.icard__d {
  display: block;
  margin-top: clamp(6px, 1.6cqw, 10px);
  font-family: var(--font-body);
  font-size: clamp(0.72rem, 3.1cqw, 0.9rem);
  font-weight: var(--weight-regular);
  line-height: 1.42;
  height: calc(1.42em * 2);
  color: rgb(255 255 255 / 0.82);
}

.icard__t .cardline,
.icard__d .cardline {
  display: block;
}

/* Tags and the read cue share one collapsing block. 0fr -> 1fr lets the row
   open to whatever height the tags actually need, which varies -- one card
   carries two solutions and wraps to a second line, another carries one. */
.icard__more {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 380ms cubic-bezier(0.16, 1, 0.3, 1);
}

.icard__morein {
  overflow: hidden;
  min-height: 0;
}

.icard__cta {
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 240ms ease,
    transform 380ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* The tags ride at the top of the picture, clear of the title block, and drop
   in from above so the two reveals move away from each other. */
.icard__tags {
  position: absolute;
  inset: 0 0 auto 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: clamp(var(--space-5), 2vw, var(--space-6));
  opacity: 0;
  transform: translateY(-8px);
  transition:
    opacity 240ms ease,
    transform 380ms cubic-bezier(0.16, 1, 0.3, 1);
}

.icard__tag {
  display: inline-block;
  padding: 0.25rem 0.55rem;
  border: 1px solid rgb(255 255 255 / 0.42);
  border-radius: 999px;
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  line-height: 1.25;
  color: rgb(255 255 255 / 0.92);
  white-space: nowrap;
}

.icard__cta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: #fff;
}

.icard__cta svg { flex: none; }

.icard:hover .icard__img,
.icard:focus-visible .icard__img { transform: scale(1.05); }

.icard:hover .icard__wash::after,
.icard:focus-visible .icard__wash::after { opacity: 0.95; }

.icard:hover .icard__k,
.icard:focus-visible .icard__k { color: rgb(255 255 255 / 0.8); }

.icard:hover .icard__more,
.icard:focus-visible .icard__more { grid-template-rows: 1fr; }

.icard:hover .icard__cta,
.icard:focus-visible .icard__cta {
  opacity: 1;
  transform: none;
}

/* Insight card tag pills are hidden site-wide. The markup stays in place for
   filter data attributes on .icard, but the visible pill chips no longer
   render on the card at rest, on hover, on focus, or on touch devices. */
.icard__tags { display: none; }

/* --- 32.3 canonical insight card promotion ------------------------------- */
/* All insight cards across the site adopt the homepage story-card visual
   language: taller 8/7 frame with a bottom-anchored dark panel, a light
   scrim across the whole image, and a 44px circular arrow cue in the top
   right that fills on hover. Markup stays canonical (.icard / .igrid etc.);
   these rules only override the visual layer. */

.igrid {
  gap: clamp(16px, 1.6vw, 24px);
  column-gap: clamp(16px, 1.6vw, 24px);
  row-gap: clamp(16px, 1.6vw, 24px);
}

.icard {
  aspect-ratio: 8 / 7;
  min-height: 390px;
  border-radius: 0;
  background: #111111;
  color: #ffffff;
}

.icard[data-type="spotlight"] {
  border-radius: 0;
}

/* Employee-spotlight cards use the square portrait as the source image. The
   card frame is a slightly landscape 8:7 rectangle, so anchor the image to
   the top edge and let the neck / shoulders be the part that gets cropped
   off the bottom — the entire face stays inside the frame regardless of
   how the browser scales the container. */
.icard[data-type="spotlight"] .icard__img {
  object-position: center top;
}

/* Full-image transform and softer transition curve, matching the homepage. */
.icard__img {
  transform: scale(1.01);
  transition:
    filter 420ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Replace the heavy bottom-gradient scrim with the softer top-to-bottom
   scrim used on the homepage story cards. Hover no longer washes the
   whole image in rust; the image itself dims via filter instead. */
.icard__wash {
  background: linear-gradient(
    180deg,
    rgb(0 0 0 / 0.03) 5%,
    rgb(0 0 0 / 0.14) 38%,
    rgb(0 0 0 / 0.94) 100%
  );
}
.icard__wash::after { display: none; content: none; }

/* The body already anchors to the bottom of the card (inset: auto 0 0 0);
   keep it there and just refresh its padding to match the homepage panel. */
.icard__body {
  padding: clamp(22px, 2.1vw, 34px);
}

/* The circular arrow cue in the TOP RIGHT of the card. We attach the two
   pseudo-elements to .icard itself (not .icard__body, which is only the
   bottom strip) so they can reach the top of the frame. z-index sits above
   the wash and body but the whole card is still the link. */
.icard::before,
.icard::after {
  position: absolute;
  z-index: 2;
  top: clamp(18px, 1.65vw, 26px);
  right: clamp(18px, 1.65vw, 26px);
  display: grid;
  width: 44px;
  height: 44px;
  place-items: center;
  border-radius: 50%;
  transition:
    color var(--transition-interactive),
    background-color var(--transition-interactive);
  pointer-events: none;
}

.icard::before {
  content: "";
  border: 1px solid #ffffff;
}

.icard::after {
  content: "\2192";
  color: #ffffff;
  font-family: Arial, sans-serif;
  font-size: 1.35rem;
  line-height: 1;
}

/* Kicker matches the homepage story-card kicker exactly. */
.icard__k {
  margin-bottom: var(--space-3);
  color: rgb(255 255 255 / 0.82);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  line-height: 1.3;
  text-transform: uppercase;
}

/* Title and excerpt: same measures as .hcl-story-card__title / __excerpt. */
.icard__t {
  max-width: 36ch;
  height: auto;
  margin-top: 0;
  color: #ffffff;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.icard__d {
  max-width: 42ch;
  height: auto;
  margin-top: var(--space-3);
  color: rgb(255 255 255 / 0.76);
  font-size: var(--text-sm);
  line-height: 1.45;
}

/* The old inline "Read Article →" CTA is replaced by the corner arrow, so
   collapse the reveal row entirely. Tags stay, still revealing on hover. */
.icard__more { display: none; }

/* Hover: dim + zoom the image, fill the arrow-circle white with a dark glyph. */
.icard:hover .icard__img,
.icard:focus-visible .icard__img {
  filter: brightness(0.82);
  transform: scale(1.045);
}

.icard:hover .icard__wash::after,
.icard:focus-visible .icard__wash::after { opacity: 0; }

.icard:hover::before,
.icard:focus-visible::before { background: #ffffff; }

.icard:hover::after,
.icard:focus-visible::after { color: #111111; }

.icard:hover .icard__k,
.icard:focus-visible .icard__k { color: rgb(255 255 255 / 0.82); }

/* Responsive: match .hcl-card-grid breakpoints. */
@media (max-width: 1024px) {
  .igrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .igrid { grid-template-columns: minmax(0, 1fr); }
  .icard { min-height: 350px; aspect-ratio: 16 / 13; }
  .icard__body { padding: 22px; }
  .icard::before,
  .icard::after { top: 18px; right: 18px; width: 40px; height: 40px; }
}

/* The cue trails the tags by a beat so the row reads top to bottom. */
.icard:hover .icard__cta,
.icard:focus-visible .icard__cta { transition-delay: 90ms; }

.icard:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 4px; }

/* No hover on a touch screen, so the read cue is simply always open there. */
@media (hover: none) {
  .icard__more { grid-template-rows: 1fr; }
  /* Everything is open all the time here, so the scrim has to carry taller
     copy and reach further up the picture to keep the tags legible. */
  .icard__wash {
    background:
      linear-gradient(
        to bottom,
        rgb(12 8 7 / 0.82) 0%,
        rgb(12 8 7 / 0.6) 26%,
        rgb(12 8 7 / 0.24) 52%,
        rgb(12 8 7 / 0) 74%
      ),
      linear-gradient(
        to top,
        rgb(12 8 7 / 0.9) 0%,
        rgb(12 8 7 / 0.68) 34%,
        rgb(12 8 7 / 0.22) 62%,
        rgb(12 8 7 / 0) 100%
      );
  }
  .icard__tags,
  .icard__cta { opacity: 1; transform: none; }
}

/* --- 32.3 empty state and paging ----------------------------------------- */
.ifempty {
  margin-top: var(--space-10);
  padding-block: clamp(var(--space-10), 5vw, var(--space-16));
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  text-align: center;
}

.ifempty__t {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  color: var(--color-text);
}

.ifempty__b {
  margin-top: var(--space-3);
  margin-bottom: var(--space-6);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.ifmore {
  display: flex;
  justify-content: center;
  margin-top: clamp(var(--space-10), 4vw, var(--space-12));
}

/* Same trap as .icard: a display rule outranks the browser default for the
   [hidden] attribute, so Show More stayed on screen with nothing left to show. */
.ifmore[hidden] { display: none; }

.ifmore svg { transition: transform var(--transition-interactive); }
.ifmore .btn:hover svg { transform: translateX(4px); }

/* --- 32.4 responsive ------------------------------------------------------ */
/* The grid drops a column earlier than it used to. A card now carries its tags,
   kicker and title inside a fixed 4:3 frame, so it needs real width -- three
   long solution tags on a 330px card push a third row into the title. */
@media (max-width: 1240px) {
  .igrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Tighter pills at every width below three columns. */
  .icard__tags {
    gap: var(--space-1);
    padding: var(--space-4);
  }

  .icard__tag {
    padding: 0.18rem 0.45rem;
    letter-spacing: 0.04em;
  }
}

/* Four controls need real width to stay readable, so they fold to a tidy 2x2
   rather than shrinking into truncated labels. */
@media (max-width: 1100px) {
  .ifbar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Header plus a two-row bar is too much fixed chrome on a short screen, so the
   bar stops sticking once it wraps. */
@media (max-width: 900px) {
  .ifbar { position: static; }
}

@media (max-width: 760px) {
  .igrid { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-8); }
}

@media (max-width: 560px) {
  .ifbar { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
}

@media (prefers-reduced-motion: reduce) {
  .icard__img, .icard__wash::after, .icard__more,
  .icard__tags, .icard__cta, .ifmore svg { transition: none; }
  .icard:hover .icard__img, .icard:focus-visible .icard__img { transform: none; }
}


/* ============================================================
   §33  CONTACT  (contact/index.html)
   ============================================================ */

/* --- 33.1 the two-column frame -------------------------------------------- */
/* Form on the left because it is what most people came for. Direct channels
   on the right for the ones who would rather pick up the phone. */
.cgrid {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: clamp(var(--space-10), 5vw, var(--space-20));
  align-items: start;
}

.cform__title,
.cdirect__title {
  margin-top: var(--space-3);
}

/* Both columns open on the same hairline at the same height, so the form and
   the channel list read as one pair rather than two stacked ideas. */
.cform__body,
.clist {
  margin-top: clamp(var(--space-8), 3vw, var(--space-10));
  border-top: 1px solid var(--color-text);
  padding-top: clamp(var(--space-6), 2.5vw, var(--space-8));
}

.cform__body {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
}

/* --- 33.2 fields ---------------------------------------------------------- */
.cfield--full { grid-column: 1 / -1; }

.cfield__label {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text);
}

.cfield__req { color: var(--color-primary); }

.cfield__hint {
  margin-left: var(--space-2);
  color: var(--color-text-faint);
  text-transform: none;
  letter-spacing: 0;
}

.cfield__in {
  display: block;
  width: 100%;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text);
  transition: border-color var(--transition-interactive);
}

textarea.cfield__in {
  resize: vertical;
  min-height: 9rem;
}

.cfield__in::placeholder { color: var(--color-text-faint); }
.cfield__in:hover { border-color: var(--color-text-muted); }
.cfield__in:focus { outline: none; border-color: var(--color-primary); }
.cfield__in:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.cfield.is-bad .cfield__in { border-color: var(--color-primary); }

.cfield__err {
  margin-top: var(--space-2);
  font-size: var(--text-2xs);
  line-height: 1.4;
  color: var(--color-primary);
  min-height: 0;
}
.cfield__err:empty { display: none; }

/* --- 33.3 submit and status ----------------------------------------------- */
.cform__foot {
  grid-column: 1 / -1;
  padding-top: var(--space-2);
}

.cform__note {
  max-width: 34rem;
  margin-top: var(--space-4);
  font-size: var(--text-xs);
  line-height: 1.65;
  color: var(--color-text-muted);
}
.cform__note a { color: var(--color-text-muted); text-decoration: underline; }
.cform__note a:hover { color: var(--color-primary); }

.cform__status {
  grid-column: 1 / -1;
  padding: var(--space-4) var(--space-5);
  border-left: 2px solid var(--color-primary);
  background: var(--color-surface-2);
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text);
}
.cform__status a { color: var(--color-primary); text-decoration: underline; }

/* --- 33.4 direct channels ------------------------------------------------- */
.clist {
  list-style: none;
  padding-inline: 0;
  padding-bottom: 0;
}

.crow:first-child .crow__link { padding-top: 0; }

.crow { border-bottom: 1px solid var(--color-divider); }

.crow__link {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding-block: var(--space-5);
  color: inherit;
  text-decoration: none;
  transition: color var(--transition-interactive);
}

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

.crow__ico {
  flex: 0 0 auto;
  display: block;
  width: 20px;
  height: 20px;
  margin-top: 0.15rem;
  color: var(--color-text-faint);
  transition: color var(--transition-interactive);
}
.crow__ico svg { width: 100%; height: 100%; display: block; }
a.crow__link:hover .crow__ico { color: var(--color-primary); }

.crow__body { display: block; min-width: 0; }

.crow__label {
  display: block;
  margin-bottom: var(--space-1);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.crow__value {
  display: block;
  font-size: var(--text-sm);
  line-height: 1.55;
  overflow-wrap: anywhere;
}

/* --- 33.5 responsive ------------------------------------------------------ */
/* The form needs its full two-up width before the aside gets a column, so the
   aside drops under the form rather than squeezing both. */
@media (max-width: 1020px) {
  .cgrid { grid-template-columns: minmax(0, 1fr); }
  .cdirect { max-width: 34rem; }
}

@media (max-width: 620px) {
  .cform__body { grid-template-columns: minmax(0, 1fr); }
  .cform__foot .btn { width: 100%; justify-content: center; }
}

/* ======================================================================
   INSIGHT ARTICLES
   One page per insight, four templates. The masthead is the site's standard
   photo plate carrying the insight's own image, so an article never looks
   like it came from somewhere else.
   ====================================================================== */

/* An insight head is the same band as every other page head on the site:
   same padding, same eyebrow, same uppercase display face, same tracking,
   same weight. It differs in two ways, both forced by the content:

     - the title is set two lines deep instead of one, because an insight
       title is a sentence and every other page title is one or two words;
     - the size drops from --text-2xl so the longest title in the set still
       fits those two lines.

   The title reserves the full two lines whether it needs them or not, so a
   short title and a long one produce exactly the same band height, and that
   height matches the rest of the site to the pixel. */
/* The article head uses the plain shell, exactly like an industry page head.
   It used to be boxed to the narrower reading width, which put the title 106px
   right of where the title sits on every other page on the site. */
.pagehead--article .pagehead__inner { max-width: var(--content-wide); }
/* The title still keeps a reading measure of its own so a long sentence does
   not run the whole 1400px band, but the block starts at the site's edge. */
.pagehead--article .artmast__title { max-width: 20ch; }
.pagehead--article .artmast__title,
.artmast__title {
  white-space: normal;
  max-width: none;
  /* Same size as an industry page title. Both are --text-2xl, so an insight
     head and an industry head set their headline at identical scale. */
  font-size: var(--text-2xl);
  line-height: 1.06;
  /* Pure white, not the 72% white the base inverse display uses. An industry
     page reaches full white by wrapping its title in .accent; an insight
     title is a sentence and cannot be wrapped, so it is set here instead. */
  color: #ffffff;
  /* Three lines are always reserved whether the title needs them or not, so a
     three-word title and a twelve-word title make the same band. Three, not
     two: at this size the longest titles in the set run to a third line, and
     a two-line reservation cut them off. */
  min-height: 3.18em;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

/* The band is given room for the photograph rather than being squeezed to the
   height of the type. Every insight uses the same figure, so the whole set is
   one height at any given viewport width. */
.pagehead--article {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(400px, 33vw, 560px);
}

/* On a phone the column is too narrow for two lines of a sentence, so the
   reservation grows to four. Every insight head still matches every other
   insight head; only the constant changes. */
@media (max-width: 700px) {
  .pagehead--article .artmast__title,
  .artmast__title {
    -webkit-line-clamp: 6;
    min-height: 6.36em;
  }
  .pagehead--article { min-height: 420px; }
}

/* The summary, now sitting under the meta bar instead of in the hero. */
.artstand { padding-block: 0 clamp(var(--space-7), 2.6vw, var(--space-9)); }
.artstand__p {
  margin: 0;
  max-width: 68ch;
  font-size: clamp(var(--text-lg), 1.5vw, 1.4375rem);
  font-weight: 300;
  line-height: 1.5;
  letter-spacing: -0.008em;
  color: var(--color-text-muted);
  text-wrap: pretty;
}


/* --- the meta ledger, on white directly under the plate ---------------- */
.artmetabar { padding-block: 0 clamp(var(--space-6), 2.2vw, var(--space-8)); }

.artmetabar .crumbs { border-bottom: 0; }

.artmeta {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}
.artmeta__row {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--space-5) var(--space-6) var(--space-5) 0;
  border-right: 1px solid var(--color-divider);
}
.artmeta__row:last-child { border-right: 0; }
.artmeta__row + .artmeta__row { padding-left: var(--space-6); }
.artmeta dt {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.artmeta dd {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  line-height: 1.4;
  color: var(--color-text);
}

/* --- the reading column ------------------------------------------------ */
/* Bands inside an article are tight. The grid below supplies the hairline
   that separates one from the next, so the padding does not also have to. */
.artsection { padding-block: 0 clamp(var(--space-7), 2.6vw, var(--space-9)); }
.sectionhead--tight { margin-bottom: var(--space-5); }

/* --- the article grid ---------------------------------------------------
   One grid for every band on every insight page. A rail on the left holds
   the section name, the portrait, or a contents list; the reading column
   sits beside it. The hairline is on the grid, not on the heading, so it
   spans the page's full content width and both edges line up with every
   other page on the site.

   Setting the heading beside the prose instead of above it is also what
   takes the height out: three sections no longer spend three heading blocks
   plus three margins of vertical space.
   ---------------------------------------------------------------------- */
.artgrid {
  display: grid;
  grid-template-columns: minmax(150px, 232px) minmax(0, 1fr);
  gap: clamp(var(--space-6), 3.2vw, var(--space-11));
  padding-top: clamp(var(--space-7), 2.6vw, var(--space-9));
  border-top: 1px solid var(--color-divider);
  align-items: start;
}
/* The rail follows the reader down the section, so on a long case study the
   heading is still on screen at the end of the section it names. */
.artgrid__rail { position: sticky; top: 104px; }
.artgrid__main { min-width: 0; }

.artrail__label {
  margin: 0 0 var(--space-4);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.artrail__toc { margin: 0; padding: 0; list-style: none; counter-reset: toc; }
.artrail__toc li { counter-increment: toc; margin-bottom: var(--space-3); }
.artrail__toc a {
  display: block;
  font-size: var(--text-sm);
  line-height: 1.4;
  color: var(--color-text-muted);
  text-decoration: none;
  border-left: 1px solid var(--color-divider);
  padding-left: var(--space-4);
}
.artrail__toc a:hover { color: var(--color-primary); border-left-color: var(--color-primary); }

@media (max-width: 900px) {
  .artgrid { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); }
  .artgrid__rail { position: static; }
  .artrail__toc { display: none; }
}

/* The reading measure. Wide enough to use the column the grid gives it,
   short enough to stay readable. */
.artprose { max-width: 74ch; }
.artprose > p {
  margin: 0 0 var(--space-5);
  font-size: clamp(var(--text-base), 1.05vw, 1.0625rem);
  /* 1.72 was set when the column was 840px wide. The column is wider now, so
     the lines are longer and the leading can come in without the eye losing
     its place returning to the left edge. This alone takes roughly a tenth of
     the height out of a long perspective. */
  line-height: 1.62;
  color: var(--color-text);
}
.artprose > p:last-child { margin-bottom: 0; }
.artprose > *:first-child { margin-top: 0; }

/* --- heading rules, shared by every article type ------------------------
   Three steps, told apart by size and weight rather than by colour, case or
   a label above them:

     h2  section     display 300, --text-xl, opened by a hairline rule
     h3  subsection  display 500, ~1.3rem, no rule
     p   body        body face, ~1.09rem

   The h2 no longer carries an eyebrow. A rust label reading THE CHALLENGE
   above a heading reading "The challenge" was the same words twice. The
   hairline does the work the label was doing, which is to say a new section
   has started. */
.arth2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  /* A step down from the old size: it now sits in a 232px rail rather than
     across the whole column, and it does not need to shout from there. */
  font-size: clamp(var(--text-lg), 1.7vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: var(--track-tight);
  /* Black. The section head is the darkest type on the page. */
  color: var(--color-text);
  text-wrap: balance;
}

/* A subsection is a step below the section head in both size and weight, and
   it is rust rather than black. Colour is doing the separating here, which
   lets the type stay small enough that it never competes with the h2. */
.artbody__h3 {
  margin: clamp(var(--space-6), 2.2vw, var(--space-8)) 0 var(--space-3);
  scroll-margin-top: 110px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.0625rem, 0.97rem + 0.34vw, 1.1875rem);
  line-height: 1.35;
  letter-spacing: -0.002em;
  color: var(--color-primary);
}
.artbody__h3:first-child { margin-top: 0; }

.artlist { margin: 0 0 var(--space-5); padding-left: var(--space-5); }
.artlist li {
  margin-bottom: var(--space-3);
  font-size: clamp(var(--text-base), 1.15vw, var(--text-lg));
  line-height: 1.65;
  color: var(--color-text);
}
.artlist li::marker { color: var(--color-primary); }

.artquote {
  margin: clamp(var(--space-7), 3vw, var(--space-9)) 0;
  padding-left: clamp(var(--space-5), 2vw, var(--space-7));
  border-left: 2px solid var(--color-primary);
}
.artquote p {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(var(--text-lg), 2vw, var(--text-2xl));
  line-height: 1.32;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.artbyline {
  margin: 0 0 var(--space-6);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-divider);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* --- the result --------------------------------------------------------
   No plate and no tint. The metric row directly under the heading is what
   sets this section apart; a shaded box on top of it was one device too many. */
.artbody--result .artprose { max-width: 70ch; }

/* --- spotlight: headshot beside the copy ------------------------------- */

/* --- tags -------------------------------------------------------------- */
.arttags {
  padding-block: clamp(var(--space-8), 3.2vw, var(--space-10))
                 clamp(var(--space-8), 3.2vw, var(--space-10));
  background: var(--color-surface-2);
  border-top: 1px solid var(--color-divider);
}

.arttags .chip-row { margin-top: var(--space-4); }
a.chip { text-decoration: none; }
a.chip:hover,
a.chip:focus-visible { border-color: var(--color-primary); color: var(--color-primary); }

@media (max-width: 860px) {
  .artmeta__row {
    flex: 1 1 100%;
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
    padding-left: 0 !important;
  }
  .artmeta__row:last-child { border-bottom: 0; }
}

/* --- the three metrics, at the top of the result ------------------------
   No boxes and no fill. Three numerals sitting on open page between two
   hairlines, which is how the rest of the site handles a register of facts.
   The size of the numeral is what gives it prominence, not a container. */
.metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-6), 3vw, var(--space-10));
  margin: 0 0 clamp(var(--space-8), 3.5vw, var(--space-10));
  padding-block: clamp(var(--space-6), 2.6vw, var(--space-8));
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
}
.metric__v {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.5rem, 4.2vw, 4rem);
  line-height: 0.94;
  letter-spacing: -0.03em;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
  text-wrap: nowrap;
}
.metric__l {
  margin: var(--space-4) 0 0;
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  line-height: 1.45;
  color: var(--color-text-muted);
}

/* --- spotlight: the fact ledger under the headshot --------------------- */
/* --- employee spotlight -------------------------------------------------
   The portrait and the introduction share the top of the page. Below that
   the questions run at the full width of the content column: hairline,
   number, question in rust, answer directly underneath. Nothing sits beside
   an answer, so the reading line is the column's own line.
   --------------------------------------------------------------------- */
.spotshot { margin: 0; }
.spotshot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius-md);
}
/* The introduction is set a step up from body copy. It is the one paragraph
   that carries the whole person, so it reads as a lede rather than as text. */
.spotintro__p { max-width: 68ch; }
.spotintro__p > p {
  font-size: clamp(var(--text-lg), 1.35vw, 1.375rem);
  font-weight: 300;
  line-height: 1.6;
}

.qalist { display: grid; gap: 0; }
.qa {
  display: block;
  padding-block: clamp(var(--space-6), 2.4vw, var(--space-8));
  border-top: 1px solid var(--color-divider);
}
.qa:first-child { border-top: 0; padding-top: 0; }
.qa__n {
  margin: 0 0 var(--space-3);
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  color: var(--color-text-faint);
  font-variant-numeric: tabular-nums;
}
/* Rust, like every other subsection heading on an insight page. */
.qa__q {
  margin: 0 0 var(--space-5);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(var(--text-lg), 1.5vw, 1.5rem);
  line-height: 1.28;
  letter-spacing: -0.008em;
  color: var(--color-primary);
  text-wrap: pretty;
}
/* Full width of the content container, not a short measure inside it. */
.qa__a { max-width: 76ch; }
.qa__a > p { font-size: clamp(var(--text-base), 1.15vw, var(--text-lg)); }

@media (max-width: 900px) {
  .metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-5); }
  .spotshot { max-width: 200px; }
}
@media (max-width: 600px) {
  .metrics { grid-template-columns: minmax(0, 1fr); }
}

/* An employee spotlight hero holds its focal point on the face, because the
   hero band is far shorter than the 16:9 card the photograph was made for. */
.pagehead--portrait .pagehead__img { object-position: 80% 26%; }
@media (max-width: 860px) {
  .pagehead--portrait .pagehead__img { object-position: 86% 20%; }
}



/* --- an article's footer row -------------------------------------------
   Three equal cards under the same rail heading every other band uses, so
   the row lines up with the article above it and reads as a footer.
   ---------------------------------------------------------------------- */
.artmore {
  padding-block: 0 clamp(var(--space-10), 4vw, var(--space-12));
  background: var(--color-surface-2);
}
.moregrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-5), 2vw, var(--space-7));
}
.morecard { display: block; text-decoration: none; }
.morecard__th {
  display: block;
  overflow: hidden;
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}
.morecard__th img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transform: scale(1.001);
  transition: transform var(--dur-md) var(--ease-out);
}
.morecard:hover .morecard__th img { transform: scale(1.04); }
.morecard__k {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-eyebrow);
  font-size: var(--text-2xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-primary);
}
.morecard__t {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-base);
  line-height: 1.35;
  color: var(--color-text);
  transition: color var(--dur-sm) var(--ease-out);
}
.morecard:hover .morecard__t { color: var(--color-primary); }
@media (max-width: 700px) {
  .moregrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .moregrid > :nth-child(3) { display: none; }
}

/* === HOME SCROLL HERO — generated by build_home_hero_live.py === */
.sh {
  --sh-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --sh-dur: 220ms;
  --bg-deep: #3a1119;
  --bg-mid: #6e2833;
  --bg-lift: #9a3f4c;
  --bg-glow: #c07180;
  --bg-eb: #e6b9c1;
}


/* ==========================================================================
   SCROLL STAGE — shared by every option
   A tall container holds a sticky viewport-height frame. Scrolling through
   the container advances the story; the page continues normally after it.
   ========================================================================== */
.sh { position: relative; }
.sh__pin {
  position: sticky; top: 0; height: 100svh; min-height: 560px;
  overflow: hidden; isolation: isolate;
  background: var(--bg-deep); color: #fff;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.sh__in {
  position: relative; z-index: 6; width: 100%;
  max-width: var(--content-wide); margin-inline: auto;
  padding: clamp(var(--space-8), 4vw, var(--space-12)) var(--gutter);
}
.sh__eb {
  margin: 0 0 var(--space-5); height: 1.2em;
  font-family: var(--font-eyebrow); font-size: var(--text-xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--bg-eb);
}
/* The headline is the site's own hero type. Everything visual comes from
   .display .display--hero .display--inverse in site.css, so the stage cannot
   drift away from the live home page. Only the measure is set here. */
.sh__h { margin: 0; max-width: none; }
/* Every headline reads on exactly two lines: the grey lead, then the white
   phrase. Breaking the phrase itself is what pushed "change at scale" onto a
   third line, so the accent is a block and is not allowed to wrap. */
.sh__h .accent { display: block; text-wrap: nowrap; }
.sh__lede {
  margin: clamp(var(--space-5), 2.5vw, var(--space-8)) 0 0;
  /* 42ch is the measured floor: one character narrower and the paragraph
     spills to a fifth line at 1512 and 1024. 43ch keeps four lines with a
     character of slack against font-metric rounding. */
  max-width: 43ch; font-size: var(--text-lg);
  font-weight: var(--weight-light); line-height: var(--lh-relaxed);
  color: rgb(255 255 255 / 0.9);
}
/* sized so the longest phrase still clears the gutter at 360px */
.sh__h { font-size: min(var(--text-3xl), 9vw); }
.sh__acts { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: clamp(var(--space-7), 3vw, var(--space-10)); }
.sh__btn {
  display: inline-flex; align-items: center; padding: 0.72em 1.5em;
  border: 1px solid rgb(255 255 255 / 0.4); border-radius: var(--radius-sm);
  font-family: var(--font-eyebrow); font-size: var(--text-xs);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: #fff; text-decoration: none;
  transition: background var(--sh-dur) var(--sh-ease), border-color var(--sh-dur) var(--sh-ease);
}
.sh__btn:hover { background: rgb(255 255 255 / 0.12); border-color: #fff; }

/* the photographs */
.sh__ph { position: absolute; inset: 0; z-index: 1; }
.sh__sl { position: absolute; inset: 0; opacity: 0; will-change: opacity, transform; }
.sh__sl img { width: 100%; height: 100%; object-fit: cover; }
.sh__sl.on { opacity: 1; }

/* the burgundy grade that sits over every photograph */
.sh__veil { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.sh__veil--btm {
  background:
    radial-gradient(92% 82% at 0% 106%, color-mix(in srgb, var(--bg-mid) 92%, transparent) 0%,
      color-mix(in srgb, var(--bg-mid) 44%, transparent) 36%, transparent 70%),
    linear-gradient(180deg, color-mix(in srgb, var(--bg-deep) 52%, transparent) 0%,
      transparent 32%, color-mix(in srgb, var(--bg-deep) 92%, transparent) 100%);
}
/* every photograph is graded toward the burgundy so the set holds together */
/* The photographs are desaturated but never hue-shifted. Staining the
   highlights turns a building into a pink smear; the burgundy belongs in the
   gradient underneath the type, not in the sky. */
.sh__sl img { filter: saturate(0.18) contrast(1.06); }

/* copy blocks swap with the pictures */
.sh__copy { position: relative; }
.sh__cs { opacity: 0; transition: opacity 420ms var(--sh-ease), transform 620ms var(--sh-ease);
  transform: translate3d(0, 22px, 0); }
.sh__cs.on { opacity: 1; transform: none; }
.sh__cs:not(:first-child) { position: absolute; inset: 0; pointer-events: none; }
.sh__cs.on { pointer-events: auto; }

/* numbered progress rail */
.sh__rail::after { content: none; }
.sh__rail { position: absolute; z-index: 7; right: clamp(var(--space-5), 3vw, var(--space-10));
  top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; gap: var(--space-5); }
.sh__rail button { position: relative; border: 0; background: none; cursor: pointer;
  padding: var(--space-2) 0 var(--space-2) var(--space-4);
  font-family: var(--font-eyebrow); font-size: var(--text-2xs);
  letter-spacing: var(--track-caps); color: rgb(255 255 255 / 0.42); }
.sh__rail button::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: rgb(255 255 255 / 0.2); }
.sh__rail button i { position: absolute; left: 0; top: 0; width: 2px; height: 0; background: var(--bg-glow);
  transition: height 380ms var(--sh-ease); }
.sh__rail button.on { color: #fff; }
.sh__rail button.on i { height: 100%; }

/* a scroll hint that fades once you start */
.sh__hint { position: absolute; z-index: 7; left: 50%; transform: translateX(-50%);
  bottom: clamp(var(--space-6), 3vw, var(--space-9));
  font-family: var(--font-eyebrow); font-size: var(--text-2xs); letter-spacing: var(--track-caps);
  text-transform: uppercase; color: rgb(255 255 255 / 0.5); transition: opacity 400ms var(--sh-ease); }
.sh.moved .sh__hint { opacity: 0; }

@media (max-width: 760px) {
  .sh__rail { display: none; }
  .sh__h { max-width: none; }
}

/* ---------- SC1 cross-fade ------------------------------------------- */
.sc1 .sh__sl { transition: opacity 760ms var(--sh-ease), transform 1600ms var(--sh-ease); transform: scale(1.06); }
.sc1 .sh__sl.on { transform: scale(1); }



/* one short scroll per slide, then the stage releases */
.sh { height: calc(84svh + 120svh); }


/* generated background: colour bed + linework, no scrim on the type */
.sh--gen { background: var(--color-bg); }
.sh--gen .sh__pin { background: #000; }
.sh--gen .sh__cv { position: absolute; inset: 0; z-index: 1;
  display: block; width: 100%; height: 100%; }
.sh--gen .sh__in { position: relative; z-index: 6; }
.sh--gen .sh__cs { position: absolute; top: 0; left: 0;
  right: 0; bottom: auto; pointer-events: none; }
.sh--gen .sh__cs:nth-child(2) { position: relative; }
.sh--gen .sh__cs.on { pointer-events: auto; }
.sh--gen .sh__copy { position: relative; }
.sh--gen .sh__rail, .sh--gen .sh__hint { z-index: 8; }

/* a shorter frame so the copy is not stranded under empty sky */
.sh--gen .sh__pin { height: 84svh; min-height: 560px;
  justify-content: center; }
.sh--gen .sh__rail button i { background: #fff; }

/* the headline steps down a little for balance against the frame */
.sh--gen .sh__h { font-size: min(calc(var(--text-3xl) * 0.84), 8vw); }
@media (max-width: 900px) {
  .sh--gen .sh__pin { height: 84svh; min-height: 640px;
    justify-content: flex-end; }
  .sh--gen .sh__in { padding-bottom: 22svh; }
}
@media (max-width: 400px) {
  .sh--gen .sh__lede { font-size: 0.95rem; line-height: 1.55; }
}

/* === END HOME SCROLL HERO === */

/* --- case study: numbers, summary, two-column body -------------------------
   A case study fills the whole content container. The three metrics sit
   directly under the page head, divided by a hairline and each on a soft
   circular tint. The summary is centred under them. Every section below is a
   heading with its body stacked underneath in two columns, so the page runs
   edge to edge while a line of prose stays near 85 characters. */
.casemetrics {
  padding-block: clamp(var(--space-8), 4vw, var(--space-12))
                 clamp(var(--space-7), 3vw, var(--space-10));
}
.cmetrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.cmetric {
  padding-block: clamp(var(--space-4), 1.6vw, var(--space-6));
  padding-inline: clamp(var(--space-3), 1.4vw, var(--space-5));
  border-left: 1px solid var(--color-divider);
  /* The number and its label are centred on the cell rather than hung off its
     left edge, so the three read as one row of three rather than as three
     stacked left-aligned blocks. */
  text-align: center;
}
.cmetric:first-child { border-left: 0; }
.cmetric__v {
  margin: 0;
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: clamp(3rem, 6vw, 6rem);
  line-height: 0.9;
  letter-spacing: -0.038em;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
  text-wrap: nowrap;
  /* The value sits in a box the height of a full-size line and is centred in
     it, so a stepped-down word value does not lift its label above the labels
     either side of it. The three cells stay on one line whatever size the
     values inside them are set at. */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(clamp(3rem, 6vw, 6rem) * 0.9);
  /* Set in caps so a word-based metric -- ONE, ALL, REPEATABLE -- carries the
     same weight in the row as a figure does, and so a unit suffix reads the
     same from one case to the next ($125M, not $125m). */
  text-transform: uppercase;
}

/* A metric can be a word rather than a figure, and a long word set at the
   figure size runs straight through the cell divider. The builder measures
   the value and steps the size down, so a long word still fills its cell
   without spilling out of it. */
.cmetric__v--mid  { font-size: clamp(2.25rem, 4.2vw, 3.75rem); }
.cmetric__v--long { font-size: clamp(1.5rem, 2.9vw, 2.5rem); }
.cmetric__l {
  /* The label is broken onto two lines by the builder, so it needs a measure
     wide enough that neither of those lines wraps again. */
  margin-inline: auto;
  margin-block: clamp(var(--space-4), 1.6vw, var(--space-6)) 0;
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  line-height: 1.45;
  color: var(--color-text-muted);
}
/* The summary runs the full width of the content container rather than sitting
   in a narrower centred column. It is a short paragraph, so at full width it
   is two or three lines -- a block, not a column -- and it lines up with the
   metric row above it and the section rules below it. */
.artstand .artstand__p--case {
  max-width: none;
  margin-inline: 0;
  text-align: center;
  text-wrap: pretty;
}

.casesec { padding-block: 0 clamp(var(--space-8), 3.4vw, var(--space-10)); }
.caseh2 {
  margin: 0 0 clamp(var(--space-5), 2vw, var(--space-7));
  padding-top: clamp(var(--space-5), 2vw, var(--space-7));
  border-top: 1px solid var(--color-divider);
  font-family: var(--font-display);
  font-weight: var(--weight-light);
  font-size: clamp(var(--text-xl), 2.4vw, 2.25rem);
  line-height: 1.12;
  letter-spacing: var(--track-tight);
  color: var(--color-text);
}
/* One column, the full width of the content container. */
.artprose.casecols { max-width: none; }
.artprose.casecols > *:first-child { margin-top: 0; }

/* A case section now runs narrative, bullets, narrative. The two paragraphs
   set the argument and the bullets carry the detail between them, so all
   three have to be the same face at the same size -- a list set larger than
   the prose around it reads as the important part, which it is not.

   The bullets sit in two columns because six of them stacked one to a line
   pushes the closing paragraph most of a screen below the opening one. */
.casesec .artlist {
  margin-bottom: clamp(var(--space-6), 2.4vw, var(--space-8));
  columns: 2;
  column-gap: clamp(var(--space-8), 4vw, var(--space-12));
}
.casesec .artlist li {
  break-inside: avoid;
  font-size: clamp(var(--text-base), 1.05vw, 1.0625rem);
  line-height: 1.62;
}
@media (max-width: 760px) {
  .casesec .artlist { columns: 1; }
}

@media (max-width: 900px) {
  .cmetrics { grid-template-columns: minmax(0, 1fr); }
  .cmetric {
    border-left: 0;
    border-top: 1px solid var(--color-divider);
    padding-inline: 0;
    padding-block: var(--space-6);
  }
  .cmetric:first-child { border-top: 0; padding-top: 0; }
}

/* The three insights that close a case study are the same tile the library
   uses, held to three across at every width the library shows three. */
.artmore--cards { padding-block: clamp(var(--space-8), 3.4vw, var(--space-10)); }
.artmore--cards .igrid { margin-top: 0; }

/* A perspective uses the case shape with nothing above its subheads and a
   little more air where the section rule would have been. */
.casesec--plain { padding-top: clamp(var(--space-8), 4vw, var(--space-12)); }

/* A spotlight keeps its portrait, set beside the introduction across the
   whole container. Everything under it is one full-width column. */
.spotlead { display: flex; gap: clamp(var(--space-5), 3vw, var(--space-8)); align-items: flex-start; }
.spotlead .spotshot { flex: 0 0 clamp(220px, 22vw, 320px); margin: 0; }
.spotlead .spotshot img { width: 100%; height: auto; display: block; }
.spotlead .artprose { flex: 1 1 auto; min-width: 0; }
.caseh2--plain { border-top: 0; padding-top: 0; }
.casesec--qa { padding-top: clamp(var(--space-6), 3vw, var(--space-10)); }
@media (max-width: 760px) {
  .spotlead { display: block; }
  .spotlead .spotshot { max-width: 220px; margin: 0 0 var(--space-5); }
}

/* In the case shape the answers run the full container and nothing rules
   between them. */
.casesec--qa .qa { border-top: 0; }
.casesec--qa .artprose.qa__a { max-width: none; }

/* ---- spotlight head: portrait beside the name, equal heights ---- */
.spothead {
  padding: calc(var(--header-height) + clamp(var(--space-10), 6vw, var(--space-16))) 0 0;
}
.spothead__grid {
  display: grid;
  grid-template-columns: clamp(220px, 22vw, 320px) 1fr;
  gap: clamp(var(--space-8), 3.5vw, var(--space-16));
  align-items: start;
}
.spothead__shot {
  overflow: hidden;
  background: var(--color-surface-2);
  border-radius: var(--radius-md);
}
.spothead__shot img {
  width: 100%;
  aspect-ratio: 1 / 1;
  height: auto;
  object-fit: cover;
  object-position: 50% 22%;
  display: block;
}
.spothead__text { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); }
.spothead__text .artmast__title {
  margin: 0;
  /* The article title rule is written for white type on a photograph and
     reserves three clamped lines. On this head it is dark type on paper and
     takes exactly the room it needs. */
  color: var(--color-text);
  min-height: 0;
  display: block;
  -webkit-line-clamp: none;
  overflow: visible;
}
.spothead + .casesec--qa { padding-top: clamp(var(--space-10), 4.4vw, var(--space-16)); }
.spothead__sum { max-width: none; }
.spothead__sum > p:last-child { margin-bottom: 0; }
/* The introduction is the one paragraph that carries the whole person, so it
   is set a step up from body copy and reads as a lede. */
.spothead__sum > p {
  font-size: clamp(var(--text-lg), 1.3vw, 1.3125rem);
  font-weight: 300;
  line-height: 1.6;
}

@media (max-width: 760px) {
  .spothead__grid { grid-template-columns: 1fr; min-height: 0; }
  .spothead__shot { max-width: 220px; aspect-ratio: 1 / 1; }
}


/* ---------------------------------------------------------------------------
   Page head -- photograph variant. The canvas paints the same colour field as
   the home banner and punches its own keep-out under the copy, so the type
   never needs a scrim. The vehicle is a cut-out laid over the field.
   --------------------------------------------------------------------------- */
/* Every page head on the site runs the approved rust ramp. The Twin Wave field
   is retired here — a gradient and a moving field cannot both be the
   background. The canvas element stays in the markup so reverting is deleting
   the background line and the display:none below. The home page has its own
   hero and is untouched by this rule. */
.pagehead--car {
  position: relative;
  background: var(--gradient-hero);
  padding-block: 116px 44px;
  min-height: 556px;
  overflow: hidden;
  display: flex;
  align-items: center;
}
.pagehead--car .ph__cv {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: none; z-index: 0;
}

/* ---------------------------------------------------------------------------
   Grain Plate -- the shared surface treatment for the rust ramp.

   A single flat gradient reads as a fill. Two layers fix that without adding
   any motion: fine fractal noise gives the ramp a surface, and a soft corner
   fall-off gives it a lit side (top right) and a shadow side (bottom left).

   Applied to both the page heads and the CTA band so the two always match.
   Both layers sit at z-index 0, which puts them under the hero cut-out
   (z-index 1) and under the copy (page head z-index 2, CTA z-index 1), so a
   cut-out subject is never veiled and text contrast is untouched.

   The home page hero is a different band entirely and is not in this list.
   --------------------------------------------------------------------------- */
.pagehead--car::before,
.pagehead--car::after,
.cta::before,
.cta::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
/* The noise is an inline SVG turbulence tile rather than a raster file, so it
   costs no request and stays sharp at any device pixel ratio. Overlay blending
   keeps it neutral -- it lightens the light end of the ramp and darkens the
   dark end instead of greying the whole band. */
.pagehead--car::before,
.cta::before {
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
}
.pagehead--car::after,
.cta::after {
  background:
    radial-gradient(120% 90% at 88% 12%, rgb(255 255 255 / 0.10), transparent 62%),
    radial-gradient(90% 80% at 4% 96%, rgb(0 0 0 / 0.26), transparent 66%);
}

/* The lower-left falloff reads as an isolated dark spot on the shorter
   Industries CTA bands. Keep their rust ramp, grain, and light-side lift,
   but remove that shadow pool. */
[data-nav="industries"] .cta::after {
  background:
    radial-gradient(120% 90% at 88% 12%, rgb(255 255 255 / 0.10), transparent 62%);
}

.pagehead--car .ph__car {
  position: absolute; z-index: 1; pointer-events: none;
  right: calc(max(0px, (100% - var(--content-wide)) / 2) + var(--gutter));
  bottom: var(--phb, 18%); width: var(--phw, 46%); max-width: var(--phmax, 760px);
}
.pagehead--car .ph__car img {
  display: block; width: 100%; height: auto;
  /* Lift the subject toward white without blowing it out: contrast first so
     the panel lines and shadow detail survive, then brightness, then most of
     the colour cast pulled out so it reads neutral rather than grey-blue. */
  filter: var(--phgrade, none);
}
/* A cutout with no shadow floats. A soft elliptical contact patch under the
   wheels sets it down without inventing a floor for it to stand on. */
.pagehead--car .ph__car::after {
  content: ""; position: absolute;
  left: 6%; right: 6%; bottom: -2%; height: 14%;
  background: radial-gradient(closest-side, rgb(0 0 0 / .55), transparent 76%);
  filter: blur(6px);
  opacity: var(--phsh, 1);
}
.pagehead--car .ph__inner { position: relative; z-index: 2; width: 100%; }
.pagehead--car .ph__say { max-width: 40%; }
.pagehead--car .display { margin: 0; }
.pagehead--car .ph__say .eyebrow { display: block; margin-bottom: var(--space-4); }
.pagehead--car .pagehead__lede {
  margin: var(--space-4) 0 0;
  max-width: 34em;
  font-size: var(--text-lg);
  font-weight: var(--weight-light);
  color: rgb(255 255 255 / 0.9);
  line-height: var(--lh-relaxed);
}

/* One-line heads. Above the nav breakpoint the title and the lede each hold
   a single line. Pages with no cut-out get the full shell to do it in; the
   aerospace head keeps its subject, so the title alone is scaled to the room
   left of the cut-out. Below 900px both wrap normally -- a phone has no room
   for a single line and forcing one would shrink the type past reading size. */
@media (min-width: 901px) {
  .pagehead--car.pagehead--noart .ph__say { max-width: min(100%, 1200px); }
  .pagehead--car.pagehead--noart #page-title,
  .pagehead--car.pagehead--noart .pagehead__lede { white-space: nowrap; }
  .pagehead--car.pagehead--noart .pagehead__lede { max-width: none; }
  .pagehead--car.pagehead--fitline #page-title {
    white-space: nowrap;
    font-size: min(3.66vw, 57px);
  }
}

/* Between 900 and 1400 the copy column and the vehicle start to close on
   each other. Give the copy the room and let the vehicle shrink. */
@media (max-width: 1400px) {
  .pagehead--car .ph__car { width: calc(var(--phw, 46%) * .94); bottom: calc(var(--phb, 18%) + 2%); }
  .pagehead--car .ph__say { max-width: 46%; }
}

/* Below the nav breakpoint the cut-out is dropped altogether. Stacked above
   the copy it cost most of the first screen and read small, so on a phone the
   band carries the type alone: it closes up and the type centres rather than
   sitting on the floor of an empty field. */
@media (max-width: 900px) {
  .pagehead--car {
    min-height: 400px;
    padding-block: 128px 44px;
    align-items: center;
  }
  .pagehead--car .ph__car { display: none; }
  .pagehead--car .ph__say { max-width: 100%; }
}

/* --- 41. Coming Soon placeholders ---------------------------------------- */
/* Insight slots outside the library. Until an insight is written for that
   industry or service line, the slot holds its footprint and says so, using
   the same dashed-plate-and-ghost-mark treatment as an open seat on About.
   Nothing is invented to fill it, and nothing here is clickable. */

/* Typed as `img.insoon__mark` so it outranks the `.inrail__th img` and
   `.storyrow__visual img` cover sizing meant for a real thumbnail. */
img.insoon__mark {
  display: block;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: grayscale(1);
  opacity: 0.2;
}

.insoon__label {
  display: block;
  font-family: var(--font-eyebrow);
  letter-spacing: var(--track-caps-sm);
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* feature slot ------------------------------------------------------------ */
.infeat--soon {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-5);
  padding: var(--space-10);
  border: 1px dashed var(--color-border);
  background: var(--color-surface-2);
  cursor: default;
}

.infeat--soon img.insoon__mark { width: 21%; min-width: 74px; }
.infeat--soon .insoon__label { font-size: var(--text-xs); }

/* rail slot --------------------------------------------------------------- */
.inrail__i--soon { cursor: default; }

.inrail__th--soon {
  display: grid;
  place-items: center;
  border: 1px dashed var(--color-border);
  background: var(--color-surface-2);
}

.inrail__th--soon img.insoon__mark { width: 52%; }

.inrail__i--soon .insoon__label { font-size: var(--text-2xs); }

/* story row --------------------------------------------------------------- */
.storyrow--soon { cursor: default; }

.storyrow__visual--soon {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 10;
  border: 1px dashed var(--color-border);
  background: var(--color-surface-2);
}

.storyrow__visual--soon::after { content: none; }
.storyrow__visual--soon img.insoon__mark { width: 26%; min-width: 56px; }
.storyrow--soon .insoon__label { font-size: var(--text-xs); }

/* The mark is drawn in the rust ink, so on a dark plate it needs lifting
   rather than the flat grey wash that reads correctly in light mode. */
[data-theme='dark'] .insoon__mark {
  filter: grayscale(1) invert(1);
  opacity: 0.24;
}

/* About page: the same treatment on the Latest at Canadian Breaks rows. */
.lrow--soon { cursor: default; }

.lrow__th--soon {
  display: grid;
  place-items: center;
  border: 1px dashed var(--color-border);
  background: var(--color-surface-2);
}

.lrow__th--soon img.insoon__mark { width: 50%; }
.lrow--soon .insoon__label { font-size: var(--text-2xs); }

/* Careers: the people panel no longer opens an article, so it loses the
   pointer, the arrow column and the hover lift, and keeps everything else. */
.spotr--flat, .spotf--flat { cursor: default; }
.spotr--flat .spotr__go { display: none; }


/* --- perspective, set as an article ------------------------------------- */
/* The deck, the byline, the prose, the subheads and the lists all run the
   full width of the content container and share one left and one right
   edge, so the article lines up with every other page on the site. */
.povcol { max-width: none; margin: 0; }
.artprose.povprose { max-width: none; }

.povlede { padding-block: var(--space-8) 0; }
.povlede__deck {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  line-height: 1.4;
  font-weight: 400;
  color: var(--color-text);
  margin: 0;
  text-wrap: pretty;
}

.povby {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-divider);
}
/* A roster headshot is framed for a large card, so at 56px the face is a
   thumbnail inside a thumbnail. The portrait is scaled up inside a round
   clip and pulled to the face rather than to the centre of the frame. */
.povby__shot {
  width: 56px; height: 56px;
  border-radius: 50%;
  overflow: hidden;
  flex: none;
  background: var(--color-surface-2);
  display: block;
}
/* The roster portraits are framed for a large card, so at 56px the face is a
   speck unless the image is pushed in. How far to push depends on how tightly
   the source is cropped, so both numbers are variables the record can set. */
.povby__shot img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--shot-x, 47%) var(--shot-y, 30%);
  transform: scale(var(--shot-zoom, 1.75));
  transform-origin: var(--shot-x, 47%) var(--shot-y, 30%);
  display: block;
}
.povby__who { min-width: 0; }
.povby__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-text);
}
.povby__role,
.povby__date {
  margin: 2px 0 0;
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.povby__date { margin-left: auto; text-align: right; flex: none; }

.povbody { padding-block: var(--space-8) var(--space-10); }

/* Section headings and subsection headings are two visibly different
   sizes. A section opens with a hairline above it so the reader can see
   where one part of the argument ends and the next begins. */
.povprose > .artbody__h3 {
  font-size: var(--text-xl);
  line-height: 1.2;
  margin-top: var(--space-10);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-divider);
}
.povprose > .artbody__h3:first-child { margin-top: 0; border-top: 0; padding-top: 0; }
.povprose > .artbody__h4 {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1.3;
  font-weight: 600;
  color: var(--color-text);
  margin: var(--space-7) 0 var(--space-2);
}
.povprose > p { margin: 0 0 var(--space-4); }

/* Lists stay in one full-width column, left aligned to the prose. The
   two-column bullet grid a case study uses is explicitly off here. */
.povprose .artlist {
  columns: 1 !important;
  column-count: 1 !important;
  width: 100%;
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
}
/* A bullet is prose, so it is set at exactly the size and leading of a
   paragraph. Left to the shared list rule the bullets came out a step
   larger than the sentences around them. */
.povprose .artlist li {
  position: relative;
  padding-left: var(--space-5);
  margin: 0 0 var(--space-3);
  break-inside: avoid;
  font-size: clamp(var(--text-base), 1.05vw, 1.0625rem);
  line-height: 1.62;
}
.povprose .artlist li::before {
  content: "";
  position: absolute;
  left: 0; top: .78em;
  width: 10px; height: 1px;
  background: var(--color-primary);
}
.povprose .artquote { margin: var(--space-6) 0; }

@media (max-width: 700px) {
  .povby__date { display: none; }
  .povlede__deck { font-size: var(--text-lg); }
}

/* ==========================================================================
   CBC NEWS -- the editorial article head
   Title in the banner, subtitle under it, dateline and published date on a
   hairline. Same reading column as a perspective.
   ========================================================================== */
.newslede .povlede__deck { max-width: 46ch; }

.povby--news { gap: var(--space-4); }

.newsby__place {
  margin: 0;
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-primary);
}

/* The date is the point of a news page, so it stays on at every width. */
.povby--news .povby__date { display: block; }

/* --------------------------------------------------------------------------
   The painted field banner on an article. Same canvas as an industry page,
   with a rounded portrait plate on the right instead of a product cut-out.
   -------------------------------------------------------------------------- */
.pagehead--field {
  min-height: 486px;
  padding-block: 140px 56px;
}

.pagehead--field .ph__say { max-width: 54%; }

.pagehead--field #page-title {
  font-size: clamp(1.875rem, 3vw, 2.875rem);
  line-height: 1.14;
}

.pagehead--car .ph__port {
  display: block;
  position: absolute;
  z-index: 1;
  pointer-events: none;
  right: calc(max(0px, (100% - var(--content-wide)) / 2) + var(--gutter));
  /* Nudged below centre so the plate clears the overlaid site header. */
  top: calc(50% + 26px);
  transform: translateY(-50%);
  width: var(--phw, 22%);
  max-width: var(--phmax, 312px);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 26px 64px rgb(0 0 0 / .5);
}

.pagehead--car .ph__port img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: inherit;
}

@media (max-width: 1180px) {
  .pagehead--field .ph__say { max-width: 58%; }
  .pagehead--car .ph__port { max-width: 254px; }
}

@media (max-width: 900px) {
  /* The portrait stops floating and stacks above the words. */
  .pagehead--field {
    display: block;
    min-height: 0;
    padding-block: 116px 40px;
    align-items: initial;
  }
  .pagehead--field .ph__say { max-width: 100%; }
  .pagehead--car .ph__port {
    /* relative, not static -- z-index only applies to positioned elements,
       and the painted-field canvas would otherwise cover the plate. */
    position: relative;
    inset: auto;
    transform: none;
    width: 140px;
    max-width: 140px;
    margin: 0 0 var(--space-6) var(--gutter);
    box-shadow: 0 14px 34px rgb(0 0 0 / .45);
  }
}

/* ===================== ACCORDION TYPE SCALE ===================== */
/* Option B — size + measure. Row heights unchanged. */
.solpanel__body { font-size: 1rem; line-height: 1.66; max-width: 51ch; }
.solrow--phase .solpanel__body { font-size: 1rem; max-width: 34ch; }
.solpanel__detail { font-size: 1rem; line-height: 1.66; max-width: 64ch; }
.solrow--ent .solpanel__q { font-size: 1.0625rem; max-width: 51ch; }
.solpanel__get { font-size: 0.92rem; line-height: 1.5; }
.solpanel__tier,
.solpanel__tag { font-size: 0.6875rem; }
.solpanel__num { font-size: 0.75rem; }
.solpanel__title { font-size: 1.25rem; }
.solpanel:hover .solpanel__tier,
.solpanel:focus-visible .solpanel__tier { color: rgba(255,255,255,0.82); }

@media (hover: none), (max-width: 980px) {
  .solpanel__body,
  .solrow--phase .solpanel__body,
  .solpanel__detail,
  .solrow--ent .solpanel__q { max-width: 60ch; }
  .solpanel__title { font-size: 1.15rem; }
  .solrow--phase .solpanel__title { font-size: var(--text-lg); }
}
/* =================== END ACCORDION TYPE SCALE =================== */

/* ===================== ACCORDION HOVER — C1 (LEFT RULE + LIFT) ===================== */
/* Replaces the rust fill on hover with a white cell, a rust left rule and a
   soft lift. Scoped to hover-capable desktop so the mobile fallbacks at
   (hover: none), (max-width: 980px) keep winning below that width.        */

.solrow {
  --hoveracc: var(--color-primary);
  --hoveredge: rgba(166, 74, 64, 0.34);
  --a3-face: var(--color-bg);
  --a3-wash: #f1f1f4;
  --a3-ring: rgba(0, 0, 0, 0.05);
  --solq: #9a9a9a;
}
[data-theme='dark'] .solrow {
  --hoveracc: var(--color-primary);
  --hoveredge: rgba(208, 121, 107, 0.42);
  --a3-face: #2a2a2e;
  --a3-wash: #232326;
  --a3-ring: rgba(255, 255, 255, 0.07);
  --solq: #96969b;
}
@media (prefers-color-scheme: no-preference-forced-off) {
  :root:not([data-theme]) .solrow {
    --hoveracc: var(--color-primary);
    --hoveredge: rgba(208, 121, 107, 0.42);
    --a3-face: #2a2a2e;
    --a3-wash: #232326;
    --a3-ring: rgba(255, 255, 255, 0.07);
    --solq: #96969b;
  }
}

@media (hover: hover) and (min-width: 981px) {

  .solrow .solpanel:hover,
  .solrow .solpanel:focus-visible {
    background: var(--color-bg);
    box-shadow: inset 4px 0 0 0 var(--hoveracc),
                0 14px 32px -14px rgba(0, 0, 0, 0.26),
                0 3px 10px -6px rgba(0, 0, 0, 0.14);
    z-index: 3;
  }

  .solrow .solpanel:hover .solpanel__title,
  .solrow .solpanel:focus-visible .solpanel__title,
  .solrow--ent .solpanel:hover .solpanel__title,
  .solrow--ent .solpanel:focus-visible .solpanel__title,
  .solrow--phase .solpanel:hover .solpanel__title,
  .solrow--phase .solpanel:focus-visible .solpanel__title { color: var(--hoveracc); }

  .solrow .solpanel:hover .solpanel__num,
  .solrow .solpanel:focus-visible .solpanel__num { color: var(--hoveracc); }

  .solrow .solpanel:hover .solpanel__tier,
  .solrow .solpanel:focus-visible .solpanel__tier { color: var(--color-text-faint); }

  .solrow .solpanel:hover .solpanel__body,
  .solrow .solpanel:focus-visible .solpanel__body,
  .solrow .solpanel:hover .solpanel__detail,
  .solrow .solpanel:focus-visible .solpanel__detail,
  .solrow .solpanel:hover .solpanel__get,
  .solrow .solpanel:focus-visible .solpanel__get { color: var(--color-text-muted); }

  .solrow--ent .solpanel:hover .solpanel__q,
  .solrow--ent .solpanel:focus-visible .solpanel__q { color: var(--solq); }

  .solrow .solpanel:hover .solpanel__arrow,
  .solrow .solpanel:focus-visible .solpanel__arrow { color: var(--hoveracc); }

  .solrow .solpanel:hover .solpanel__tag,
  .solrow .solpanel:focus-visible .solpanel__tag {
    color: var(--hoveracc);
    border-color: var(--hoveredge);
    background: transparent;
  }

  .solrow .solpanel:hover .solpanel__get::before,
  .solrow .solpanel:focus-visible .solpanel__get::before { background: var(--hoveracc); }

  .solrow--phase .solpanel:hover .solpanel__gets,
  .solrow--phase .solpanel:focus-visible .solpanel__gets {
    border-top-color: var(--color-border);
  }

}


/* ===================== ACCORDION HOVER — A3 + S5 =====================
   A3 (LAYERED): the open cell becomes a rounded white card with a faint
   grey wash falling down it, a hairline ring and one large diffuse shadow.
   Type, tags and arrow keep the C1 token treatment above — unchanged.

   S5 (DENSITY): closed cells hold at 168px instead of collapsing to 74px,
   so their titles and tier labels stay readable and the open cell narrows
   to the width its text actually needs. Rows also lose ~20px of height and
   the arrow sits beside the tags instead of hugging the far edge.
   Revert: delete from this header to the end of the file.          */

@media (hover: hover) and (min-width: 981px) {

  /* --- A3: the card ------------------------------------------------ */

  /* The row clips to its rounded corners at rest, exactly as before. It
     only opens up while a cell is hovered, so the card's shadow can
     escape. First and last panels carry the row's own corner radius so
     nothing square pokes out of a rounded corner mid-animation. */
  .solrow:hover,
  .solrow:focus-within { overflow: visible; }

  .solrow .solpanel {
    background: linear-gradient(180deg,
      var(--color-bg) 0%, var(--color-bg) 42%, var(--color-bg) 100%);
    box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0),
                0 6px 18px -12px rgba(0, 0, 0, 0),
                inset 0 0 0 1px rgba(0, 0, 0, 0);
    border-radius: 0;
    will-change: flex-basis;
    transition:
      flex 0.6s cubic-bezier(0.4, 0.02, 0.2, 1),
      padding 0.6s cubic-bezier(0.4, 0.02, 0.2, 1),
      border-radius 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      background-image 0.5s ease,
      box-shadow 0.5s ease,
      border-color 0.35s ease;
  }

  .solrow .solpanel:first-child {
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  }
  .solrow .solpanel:last-child {
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  }

  /* Everything that moves gets an easing curve, so nothing snaps. */
  .solpanel__title,
  .solpanel__tier,
  .solpanel__body,
  .solpanel__q,
  .solpanel__tags,
  .solpanel__arrow,
  .solpanel__detail,
  .solpanel__gets {
    transition:
      opacity 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      font-size 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      margin 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      padding 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      color 0.35s ease,
      border-color 0.35s ease;
  }

  .solrow .solpanel:hover,
  .solrow .solpanel:focus-visible {
    background: linear-gradient(180deg,
      var(--a3-face) 0%, var(--a3-face) 42%, var(--a3-wash) 100%);
    border-radius: 0;
    border-right-color: transparent;
    box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.20), 0 6px 18px -12px rgba(0, 0, 0, 0.12), inset 0 0 0 1px var(--color-divider);
    z-index: 3;
    flex: 1 1 0;
  }

  /* The open cell is square, but the row it sits in is not. A first or
     last cell still has to carry the row's own corner radius, otherwise
     a square edge pokes out of the rounded row while the row is open. */
  .solrow .solpanel:first-child:hover,
  .solrow .solpanel:first-child:focus-visible {
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  }
  .solrow .solpanel:last-child:hover,
  .solrow .solpanel:last-child:focus-visible {
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  }

  /* --- S5: tighter rows --------------------------------------------- */

  .solrow .solpanel {
    padding-top: var(--space-4);
    padding-bottom: var(--space-4);
  }

  .solrow .solpanel:hover,
  .solrow .solpanel:focus-visible {
    padding-left: var(--space-6);
    padding-right: var(--space-6);
  }

  .solrow .solpanel:hover .solpanel__title,
  .solrow .solpanel:focus-visible .solpanel__title { margin-top: 0; }

  .solrow .solpanel:hover .solpanel__body,
  .solrow .solpanel:focus-visible .solpanel__body {
    margin-top: var(--space-2);
    max-width: 62ch;
  }

  .solrow .solpanel:hover .solpanel__detail,
  .solrow .solpanel:focus-visible .solpanel__detail { max-width: 62ch; }

  /* --- S5: the arrow comes home ------------------------------------- */

  .solrow .solpanel:hover .solpanel__arrow,
  .solrow .solpanel:focus-visible .solpanel__arrow {
    margin-left: var(--space-4);
  }

  .solrow--phase .solpanel:hover .solpanel__gets,
  .solrow--phase .solpanel:focus-visible .solpanel__gets {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
  }

}

/* The held width scales with the viewport so the open cell is never
   squeezed. Below 1360px the rows keep their original height, because the
   copy wraps onto more lines at those widths.                        */

@media (hover: hover) and (min-width: 1180px) {

  .solrow { --s5-hold: 132px; }

  .solrow:hover .solpanel:not(:hover),
  .solrow:focus-within .solpanel:not(:focus-visible):not(:hover) {
    flex: 0 0 var(--s5-hold);
    padding-left: var(--space-4);
    padding-right: var(--space-4);
  }

  .solrow .solpanel:hover,
  .solrow .solpanel:focus-visible { flex: 1 1 0; }

  /* Neighbour titles and tiers stay legible now the cell is light. */
  .solrow:hover .solpanel:not(:hover) .solpanel__title,
  .solrow:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title {
    opacity: 1;
    font-size: 0.85rem;
  }
  .solrow:hover .solpanel:not(:hover) .solpanel__tier,
  .solrow:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__tier {
    opacity: 1;
  }

}

@media (hover: hover) and (min-width: 1360px) {
  .solrow { --s5-hold: 168px; height: 11.75rem; }
  .solrow--ent { height: 12.25rem; }
  .solrow--phase { height: 17rem; }

  .solrow:hover .solpanel:not(:hover) .solpanel__title,
  .solrow:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title {
    font-size: 0.92rem;
  }

  .solrow .solpanel:hover .solpanel__tags,
  .solrow .solpanel:focus-visible .solpanel__tags { flex-wrap: nowrap; }
}

@media (hover: hover) and (min-width: 1600px) {
  .solrow { --s5-hold: 180px; }
}

/* ===================== ACCORDION HOVER — REVEAL =====================
   Fixes three things about the lateral accordion:

   1. Text used to run across the screen. The revealed copy was laid out
      inside the cell while the cell was still narrow, so every word
      reflowed as the cell grew. Now the open cell's content is laid out
      at its FINAL width from the first frame and the cell clips it, so
      the copy never moves — the cell's right edge sweeps across and
      uncovers it.

   2. The tag row wrapped onto two or three lines while the cell was
      narrow, which pushed the foot out of the bottom of the cell. The
      foot is now fixed-width and never wraps, and the panel clips as a
      backstop.

   3. Closing was abrupt. The wide layout is now held for the length of
      the close, so the cell wipes shut over the same copy it opened on.

   Revert: delete from this header to the end of the file.           */

@media (hover: hover) and (min-width: 981px) {

  /* The row becomes an inline-size container so each cell can work out
     how wide it will be once open, before it gets there. */
  .solrow {
    container-type: inline-size;
    --s5-cells: 5;
  }
  .solrow--phase { --s5-cells: 4; }

  /* Open width = row width, less the held neighbours, their dividers and
     the open cell's own padding. --s5-hold is only declared at 1180px and
     up; below that the neighbours hold at the original 74px. */
  .solrow .solpanel {
    --s5-openw: calc(
      100cqw
      - (var(--s5-cells) - 1) * var(--s5-hold, 74px)
      - (var(--s5-cells) - 1) * 1px
      - 2 * var(--space-6)
    );
    overflow: hidden;
  }

  /* --- 1 + 2: lay the copy out at its final width from frame one ---- */

  /* An explicit resting width matters: `auto` cannot be interpolated, so
     a transition never gets created and the hold on close below would
     never fire. 100% is what auto already resolves to here. */
  .solpanel__mid,
  .solpanel__foot { width: 100%; }

  .solrow .solpanel:hover .solpanel__mid,
  .solrow .solpanel:focus-visible .solpanel__mid,
  .solrow .solpanel:hover .solpanel__foot,
  .solrow .solpanel:focus-visible .solpanel__foot {
    width: var(--s5-openw);
    flex-shrink: 0;
  }

  /* Where a cell carries the italic question, the copy is pinned to the
     bottom of its block so the title can grow downward into the gap
     without shunting the paragraph up the cell. The only movement during
     the reveal is then the cell's own edge.

     Rows without the question have nothing to fill that gap, so pinning
     left a void of about 48px between the title and the paragraph and the
     copy sat far too low in the cell. Those rows stack from the top
     instead, exactly as the phase rows already do, and the slack collects
     above the foot where the tier label already sits.               */
  .solrow--ent .solpanel:hover .solpanel__mid,
  .solrow--ent .solpanel:focus-visible .solpanel__mid {
    justify-content: space-between;
  }

  .solrow:not(.solrow--phase):not(.solrow--ent) .solpanel:hover .solpanel__mid,
  .solrow:not(.solrow--phase):not(.solrow--ent) .solpanel:focus-visible .solpanel__mid {
    justify-content: flex-start;
  }

  .solrow .solpanel:hover .solpanel__foot,
  .solrow .solpanel:focus-visible .solpanel__foot {
    flex-wrap: nowrap;
  }

  .solrow .solpanel:hover .solpanel__tags,
  .solrow .solpanel:focus-visible .solpanel__tags {
    flex-wrap: nowrap;
    flex-shrink: 0;
  }

  /* --- 3: hold the open layout for the length of the close ---------- */

  .solpanel__mid,
  .solpanel__foot {
    transition: width 0s linear 0.55s;
  }

  .solrow .solpanel:hover .solpanel__mid,
  .solrow .solpanel:focus-visible .solpanel__mid,
  .solrow .solpanel:hover .solpanel__foot,
  .solrow .solpanel:focus-visible .solpanel__foot {
    transition-delay: 0s;
  }

  /* Copy that is switched on for the open cell keeps its box until the
     cell has finished shutting, so it wipes away rather than vanishing.
     Browsers without allow-discrete simply behave as they did before. */
  .solpanel__body,
  .solpanel__q,
  .solpanel__tags,
  .solpanel__arrow,
  .solpanel__detail,
  .solpanel__gets {
    transition:
      display 0.55s allow-discrete,
      opacity 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      font-size 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      margin 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      padding 0.5s cubic-bezier(0.4, 0.02, 0.2, 1),
      color 0.35s ease,
      border-color 0.35s ease;
  }

  /* The title goes from stacked to a single line. That switch is discrete
     — a browser would run it at the halfway point, which puts a visible
     jump in the middle of the reveal. It happens on the first frame
     instead, while the cell is still narrow and only the first word is
     showing, so the second word arrives as part of the wipe. */
  .solpanel__title {
    transition:
      color 0.35s ease,
      font-size 0.55s cubic-bezier(0.4, 0.02, 0.2, 1),
      margin 0.55s cubic-bezier(0.4, 0.02, 0.2, 1),
      opacity 0.22s ease;
  }

}

/* Three tags do not fit beside the tier label and the arrow once the open
   cell drops below about 660px, so the last one steps out rather than
   wrapping onto a second line.                                        */
@media (hover: hover) and (min-width: 981px) and (max-width: 1359px) {
  .solpanel__tag:nth-child(n + 3) { display: none; }
}

/* ================= INTERVIEW TIPS -- PUSH TRANSITION =================
   Two frames per cell. The resting frame is the number, the title and the
   tier, laid out exactly as they were before this block existed. The
   arriving frame is .solpanel__push, parked one cell-height below the
   bottom edge.

   On hover both frames translate up by exactly one cell height. The
   resting frame clears the top edge as the arriving frame lands, and the
   cell clips both, so the effect is a slide advancing -- not a fade, not a
   grow, not a reflow.

   Everything the lateral accordion normally does is switched off here:
   no width change, no neighbour collapse, no dimming, no shadow, no
   corner-radius animation. Every selector doubles .solrow--tips because
   the accordion rules further up this file are three and four levels deep
   and would otherwise win on specificity.

   Revert: delete from this header to the end of the file, restore
   careers/index.html and build_careers.py from /tmp/*.pre-push.*
   ==================================================================== */

@media (hover: hover) and (min-width: 981px) {

  /* One number drives both frames, so they always travel together. */
  .solrow--tips.solrow--tips {
    /* Taller than the shared row. The arriving frame carries a full
       paragraph at reading size, which the 13rem row could only fit by
       shrinking the type. Height and travel are the same number so the
       two frames stay in step. */
    height: 15rem;
    --tip-h: 15rem;
    --tip-ease: cubic-bezier(0.4, 0.02, 0.2, 1);
    --tip-dur: 0.44s;
    --tip-fill: #18191E;
    overflow: hidden;
    container-type: normal;
  }

  /* The row must keep clipping while a cell is hovered. The accordion
     opens it up so a card shadow can escape; here that would let both
     frames spill over the neighbours. */
  .solrow--tips.solrow--tips:hover,
  .solrow--tips.solrow--tips:focus-within { overflow: hidden; }

  /* --- widths frozen ------------------------------------------------ */

  .solrow--tips.solrow--tips .solpanel,
  .solrow--tips.solrow--tips:hover .solpanel,
  .solrow--tips.solrow--tips:focus-within .solpanel,
  .solrow--tips.solrow--tips:hover .solpanel:not(:hover),
  .solrow--tips.solrow--tips:focus-within .solpanel:not(:focus-visible):not(:hover),
  .solrow--tips.solrow--tips .solpanel:hover,
  .solrow--tips.solrow--tips .solpanel:focus-visible {
    flex: 1 1 0;
    padding-left: var(--space-5);
    padding-right: var(--space-5);
    border-radius: 0;
    box-shadow: none;
    background-image: none;
    overflow: hidden;
    will-change: auto;
    transition: background-color var(--tip-dur) var(--tip-ease);
  }

  .solrow--tips.solrow--tips .solpanel { background-color: var(--color-bg); }

  .solrow--tips.solrow--tips .solpanel:hover,
  .solrow--tips.solrow--tips .solpanel:focus-visible {
    background-color: var(--tip-fill);
    outline: none;
  }

  /* --- neighbours untouched ----------------------------------------- */

  .solrow--tips.solrow--tips:hover .solpanel:not(:hover) .solpanel__title,
  .solrow--tips.solrow--tips:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title,
  .solrow--tips.solrow--tips:hover .solpanel:not(:hover) .solpanel__tier,
  .solrow--tips.solrow--tips:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__tier {
    /* Size is deliberately NOT reset here -- the tier has its own scale
       and inheriting would blow it up. Only the title is pinned back. */
    opacity: 1;
  }

  /* Neighbour titles keep the resting size. The accordion shrinks them
     to make room for an opening cell; nothing opens here. */
  .solrow--tips.solrow--tips:hover .solpanel:not(:hover) .solpanel__title,
  .solrow--tips.solrow--tips:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title {
    font-size: 1.25rem;
  }

  /* --- the resting frame -------------------------------------------- */

  /* Laid out exactly as the static cell always was: number at the top,
     title beneath it, tier on the floor. Nothing about the resting look
     changes -- the three elements only ever move as one rigid block. */
  .solrow--tips.solrow--tips .solpanel__num,
  .solrow--tips.solrow--tips .solpanel__mid,
  .solrow--tips.solrow--tips .solpanel__foot {
    transform: translateY(0);
    transition: transform var(--tip-dur) var(--tip-ease);
  }

  .solrow--tips.solrow--tips .solpanel:hover .solpanel__num,
  .solrow--tips.solrow--tips .solpanel:hover .solpanel__mid,
  .solrow--tips.solrow--tips .solpanel:hover .solpanel__foot,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__num,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__mid,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__foot {
    transform: translateY(calc(-1 * var(--tip-h)));
  }

  /* The accordion restyles the title and number on hover -- bigger type,
     horizontal, recoloured. None of that here: the frame leaves looking
     precisely as it looked at rest. */
  .solrow--tips.solrow--tips .solpanel:hover .solpanel__title,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__title {
    flex-direction: column;
    gap: 0;
    white-space: normal;
    font-size: 1.25rem;
    margin-top: var(--space-3);
    color: var(--color-text);
    opacity: 1;
  }

  .solrow--tips.solrow--tips .solpanel:hover .solpanel__num,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__num {
    color: var(--color-primary);
  }

  .solrow--tips.solrow--tips .solpanel:hover .solpanel__tier,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__tier {
    color: var(--color-text-faint);
  }

  /* --- the arriving frame ------------------------------------------- */

  .solrow--tips.solrow--tips .solpanel__push {
    position: absolute;
    inset: 0;
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    transform: translateY(100%);
    transition: transform var(--tip-dur) var(--tip-ease);
    pointer-events: none;
  }

  .solrow--tips.solrow--tips .solpanel:hover .solpanel__push,
  .solrow--tips.solrow--tips .solpanel:focus-visible .solpanel__push {
    transform: translateY(0);
  }

  .solrow--tips.solrow--tips .solpanel__pushnum {
    font-family: var(--font-eyebrow);
    font-size: var(--text-2xs);
    letter-spacing: var(--track-caps);
    color: rgba(255, 255, 255, 0.55);
    margin-bottom: var(--space-3);
  }

  .solrow--tips.solrow--tips .solpanel__pushtitle {
    display: flex;
    flex-direction: column;
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: var(--weight-light);
    line-height: 1.3;
    color: #fff;
    margin-bottom: var(--space-3);
  }

  .solrow--tips.solrow--tips .solpanel__push .solpanel__body {
    display: block;
    margin-top: 0;
    font-size: 0.92rem;
    line-height: 1.62;
    color: #fff;
    max-width: none;
  }

  .solrow--tips.solrow--tips .solpanel__pushnum { display: none; }

  @media (prefers-reduced-motion: reduce) {
    .solrow--tips.solrow--tips .solpanel__num,
    .solrow--tips.solrow--tips .solpanel__mid,
    .solrow--tips.solrow--tips .solpanel__foot,
    .solrow--tips.solrow--tips .solpanel__push { transition-duration: 0.01ms; }
  }
}

/* Dark mode. #18191E sits two points off the dark surface (#1a1a1a), so
   the arriving frame would be invisible. Lifted just enough to read as a
   deliberate fill rather than a hole. */
@media (hover: hover) and (min-width: 981px) {
  [data-theme='dark'] .solrow--tips.solrow--tips { --tip-fill: #2A2B31; }
}

@media (hover: hover) and (min-width: 981px) and (prefers-color-scheme: no-preference-forced-off) {
  :root:not([data-theme]) .solrow--tips.solrow--tips { --tip-fill: #2A2B31; }
}

/* The shared row shortens above 1360px, so the travel has to follow it.
   Both are expressed in rem, so they stay in step as the root size
   scales up on wide viewports. */
@media (hover: hover) and (min-width: 1360px) {
  .solrow--tips.solrow--tips { height: 14.3rem; --tip-h: 14.3rem; }
}

/* Under 1180px the cells are only ~190px wide, so the same paragraph
   runs to seven or eight lines. The row grows rather than the type
   shrinking. */
@media (hover: hover) and (min-width: 981px) and (max-width: 1179px) {
  .solrow--tips.solrow--tips { height: 17rem; --tip-h: 17rem; }
}

/* ==========================================================================
   INDCELL -- INK REVEAL
   Four rows swap the rust reveal for a near-black fill: Our Values (about),
   Why Work Here (careers), and the construction and enterprise rows on the
   industries index. Applied through a modifier rather than to `.indcell`
   itself so the ten "How We Help" rows on the industry sub-pages keep the
   rust ground they have today.

   The fill is #18191E in light mode. Dark mode lifts it to #2A2B31: the dark
   surface token is #1a1a1a, two points off #18191E, so the reveal would be
   invisible against it. #2A2B31 is the same neutral, raised far enough to
   separate from both #1a1a1a and the #262626 offset surface.
   ========================================================================== */
.indrow--ink { --ink-fill: #18191E; }

.indrow--ink .indcell__reveal {
  background-image: none;
  background-color: var(--ink-fill);
}

/* Doubled class so these beat the `.indcell__reveal .indcell__x` rules that
   colour the foreground for the rust ground (0,2,0 -> 0,3,0). */
.indrow--ink.indrow--ink .indcell__reveal .indcell__num { color: rgba(255, 255, 255, 0.6); }
.indrow--ink.indrow--ink .indcell__reveal .indcell__title { color: #fff; }
.indrow--ink.indrow--ink .indcell__reveal .indcell__body { color: #fff; }
.indrow--ink.indrow--ink .indcell__reveal .indcell__attr { color: rgba(255, 255, 255, 0.7); }
.indrow--ink.indrow--ink .indcell__reveal .indcell__arrow { color: #fff; }

[data-theme='dark'] .indrow--ink { --ink-fill: #2A2B31; }

@media (prefers-color-scheme: no-preference-forced-off) {
  :root:not([data-theme='light']) .indrow--ink { --ink-fill: #2A2B31; }
}

/* ==========================================================================
   CELL GRID -- F3 OUTLINE HOVER
   Replaces the 7% rounded rust wash with a square 1px rust outline. The cell
   no longer tints its text wholesale: the name takes the deeper rust and the
   index takes the standard rust, so the note stays quiet and readable.

   Applied to `.cell` itself rather than a modifier, so every place the grid
   renders picks it up -- "Where This Fits" on the ten solution sub-pages,
   the client-segment grids on the ten industry pages, and both rows on the
   home page.

   Pointer only. Touch has no hover state and the wash never fired there.
   ========================================================================== */
@media (hover: hover) and (min-width: 981px) {
  /* The ::before pseudo drew the wash; it now draws the outline. */
  .cell::before {
    border-radius: 0;
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--row-accent);
  }

  /* .cell--now is the stage you are already on. It is a div, not a link, and
     it is excluded from every hover rule below -- these are appended after
     its own rules and would otherwise win on source order. */
  .cell:not(.cell--now):hover { color: var(--color-text); }

  .cell:not(.cell--now):hover .cell__name,
  .cell:focus-visible .cell__name { color: var(--row-accent-strong); }

  .cell:not(.cell--now):hover .cell__idx,
  .cell:focus-visible .cell__idx { color: var(--row-accent); }

  /* The divider hairline belongs to the cell on its right and paints above
     the outline, so the hovered cell's left edge would stay grey without
     this. */
  .cell:not(.cell--now):hover::after,
  .cell:focus-visible::after { background: var(--row-accent); }
}

/* ==========================================================================
   SOLROW -- PUSH-UP INK REVEAL (solutions page, both rows)
   The same hover the careers Interview Tips row uses. On hover the cell
   fills with ink, the resting frame (number, title, band label) travels
   up by exactly one cell height and clears the top edge, and an arriving
   frame carrying the detail lands in its place. The row clips both, so it
   reads as a slide advancing -- not a fade, not a widening accordion.

   Everything the lateral accordion normally does is switched off here:
   no width change, no neighbour collapse, no dimming, no rust gradient,
   no padding change. Every selector doubles .solrow--push because the
   accordion rules in section 19 are several levels deep and would
   otherwise win on specificity.

   The resting frame keeps its own copies of body, tags and arrow in the
   markup so the stacked layout below 981px is untouched. They stay
   hidden on desktop; the arriving frame carries the visible copies and
   is aria-hidden, so nothing is announced twice.

   Revert: delete from this header to the end of the file, and restore
   solutions/index.html from /tmp/solutions.pre-push.html
   ========================================================================== */

@media (hover: hover) and (min-width: 981px) {

  .solrow--push.solrow--push {
    --push-h: 18.65rem;
    --push-ease: cubic-bezier(0.4, 0.02, 0.2, 1);
    --push-dur: 0.44s;
    --push-fill: #18191E;
    height: var(--push-h);
    overflow: hidden;
  }

  /* The accordion opens the row up so a card shadow can escape. Here that
     would let both frames spill over the neighbours. */
  .solrow--push.solrow--push:hover,
  .solrow--push.solrow--push:focus-within { overflow: hidden; }

  /* ---- widths frozen ---------------------------------------------------- */

  .solrow--push.solrow--push .solpanel,
  .solrow--push.solrow--push:hover .solpanel,
  .solrow--push.solrow--push:focus-within .solpanel,
  .solrow--push.solrow--push:hover .solpanel:not(:hover),
  .solrow--push.solrow--push:focus-within .solpanel:not(:focus-visible):not(:hover),
  .solrow--push.solrow--push .solpanel:hover,
  .solrow--push.solrow--push .solpanel:focus-visible {
    flex: 1 1 0;
    padding-left: var(--space-5);
    padding-right: var(--space-5);
    border-radius: 0;
    box-shadow: none;
    background-image: none;
    overflow: hidden;
    will-change: auto;
    transition: background-color var(--push-dur) var(--push-ease);
  }

  .solrow--push.solrow--push .solpanel { background-color: var(--color-bg); }

  .solrow--push.solrow--push .solpanel:hover,
  .solrow--push.solrow--push .solpanel:focus-visible {
    background-color: var(--push-fill);
    outline: none;
  }

  /* ---- neighbours untouched --------------------------------------------- */

  .solrow--push.solrow--push:hover .solpanel:not(:hover) .solpanel__title,
  .solrow--push.solrow--push:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title,
  .solrow--push.solrow--push:hover .solpanel:not(:hover) .solpanel__tier,
  .solrow--push.solrow--push:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__tier {
    opacity: 1;
  }

  /* Neighbour titles keep the resting size. The accordion shrinks them to
     0.85rem / 0.92rem to make room for the cell that is opening; nothing
     opens here, the widths are frozen, so the shrink is unwanted. Size is
     deliberately NOT reset on the tier -- it has its own scale. */
  .solrow--push.solrow--push:hover .solpanel:not(:hover) .solpanel__title,
  .solrow--push.solrow--push:focus-within .solpanel:not(:focus-visible):not(:hover) .solpanel__title {
    font-size: 1.25rem;
  }

  /* ---- the resting frame ------------------------------------------------ */

  /* Number, title and band label move as one rigid block and leave looking
     exactly as they looked at rest. The accordion recolours and enlarges
     them on hover; none of that happens here. */
  .solrow--push.solrow--push .solpanel__num,
  .solrow--push.solrow--push .solpanel__mid,
  .solrow--push.solrow--push .solpanel__foot {
    transform: translateY(0);
    transition: transform var(--push-dur) var(--push-ease);
  }

  .solrow--push.solrow--push .solpanel:hover .solpanel__num,
  .solrow--push.solrow--push .solpanel:hover .solpanel__mid,
  .solrow--push.solrow--push .solpanel:hover .solpanel__foot,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__num,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__mid,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__foot {
    transform: translateY(calc(-1 * var(--push-h)));
  }

  .solrow--push.solrow--push .solpanel:hover .solpanel__title,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__title {
    flex-direction: column;
    gap: 0;
    white-space: normal;
    font-size: 1.25rem;
    margin-top: var(--space-3);
    color: var(--color-text);
    opacity: 1;
  }

  .solrow--push.solrow--push.solrow--ent .solpanel:hover .solpanel__title,
  .solrow--push.solrow--push.solrow--ent .solpanel:focus-visible .solpanel__title {
    display: block;
    white-space: normal;
    font-size: 1.25rem;
  }

  .solrow--push.solrow--push .solpanel:hover .solpanel__num,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__num {
    color: var(--color-primary);
  }

  .solrow--push.solrow--push .solpanel:hover .solpanel__tier,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__tier {
    color: var(--color-text-faint);
  }

  /* The accordion reveals these inside the resting frame on hover. The
     arriving frame carries them instead, so the originals stay down. */
  .solrow--push.solrow--push .solpanel:hover .solpanel__mid > .solpanel__body,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__mid > .solpanel__body,
  .solrow--push.solrow--push .solpanel:hover .solpanel__mid > .solpanel__q,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__mid > .solpanel__q,
  .solrow--push.solrow--push .solpanel:hover .solpanel__foot > .solpanel__tags,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__foot > .solpanel__tags,
  .solrow--push.solrow--push .solpanel:hover .solpanel__foot > .solpanel__arrow,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__foot > .solpanel__arrow {
    display: none;
  }

  /* ---- the arriving frame ----------------------------------------------- */

  .solrow--push.solrow--push .solpanel__push {
    position: absolute;
    inset: 0;
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    transform: translateY(100%);
    transition: transform var(--push-dur) var(--push-ease);
    pointer-events: none;
  }

  .solrow--push.solrow--push .solpanel:hover .solpanel__push,
  .solrow--push.solrow--push .solpanel:focus-visible .solpanel__push {
    transform: translateY(0);
  }

  .solrow--push.solrow--push .solpanel__pushtitle {
    display: flex;
    flex-direction: column;
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: var(--weight-light);
    line-height: 1.3;
    color: #fff;
    margin-bottom: var(--space-3);
  }

  .solrow--push.solrow--push.solrow--ent .solpanel__pushtitle { display: block; }

  .solrow--push.solrow--push .solpanel__push .solpanel__body {
    display: block;
    margin-top: 0;
    margin-bottom: 0;
    font-size: 0.92rem;
    line-height: 1.62;
    color: #fff;
    max-width: none;
  }

  .solrow--push.solrow--push .solpanel__pushfoot {
    display: flex;
    align-items: flex-end;
    gap: var(--space-3);
    margin-top: auto;
    padding-top: var(--space-3);
  }

  .solrow--push.solrow--push .solpanel__push .solpanel__arrow {
    display: block;
    margin-left: auto;
    flex: none;
    color: #fff;
  }

  @media (prefers-reduced-motion: reduce) {
    .solrow--push.solrow--push .solpanel__num,
    .solrow--push.solrow--push .solpanel__mid,
    .solrow--push.solrow--push .solpanel__foot,
    .solrow--push.solrow--push .solpanel__push { transition-duration: 0.01ms; }
  }
}

/* Below 981px the arriving frame is switched off entirely and the stacked
   layout uses the original copies, so the duplicate never renders. */
@media (hover: none), (max-width: 980px) {
  .solpanel__push { display: none; }
}

/* Dark mode. #18191E sits two points off the dark surface, so the arriving
   frame would read as a hole rather than a fill. Lifted to match careers. */
@media (hover: hover) and (min-width: 981px) {
  [data-theme='dark'] .solrow--push.solrow--push { --push-fill: #2A2B31; }
}

@media (hover: hover) and (min-width: 981px) and (prefers-color-scheme: no-preference-forced-off) {
  :root:not([data-theme]) .solrow--push.solrow--push { --push-fill: #2A2B31; }
}

/* Row height is the tallest arriving frame in each band plus a small margin,
   measured rather than guessed. Both rows share one height, which lands
   within five pixels of the careers Interview Tips row. */
@media (hover: hover) and (min-width: 1180px) {
  .solrow--push.solrow--push { --push-h: 15.65rem; }
}

@media (hover: hover) and (min-width: 1360px) {
  .solrow--push.solrow--push { --push-h: 14rem; }
}

/* ==========================================================================
   SOLROW -- IMPACT REVEAL (Strategic Portfolio Management, "How We Help")

   Rides on .solrow--tips, so the push-up mechanic is inherited from the
   careers Interview Tips row rather than reimplemented: same easing, same
   duration, same fill, and the same load-bearing rule that travel distance
   equals row height. Nothing in this block redefines any of those.

   The delta is what each frame carries:
     resting  -- number, title, description, footer label
     arriving -- the outcome for the client, then the substance behind it

   The description is height-locked to four lines rather than left to the
   copy, so the resting cell is the same height whatever the wrap does and
   the row cannot shift when the viewport changes.

   Revert: delete from this header to the end of the file, and restore
   solutions/enterprise/strategy-portfolio-management/index.html from
   /tmp/spm.pre-impact.html.
   ========================================================================== */

/* Four lines of description at the resting size, reserved whether the copy
   fills them or not. Shared by every viewport so nothing reflows. */
.solrow--impact {
  --impact-desc-fs: 0.88rem;
  --impact-desc-lh: 1.6;
  --impact-desc-lines: 4;
}

/* Reserve two lines for the title. A single-word title such as
   Preconstruction would otherwise lift its description a line above the
   other three cells in the row. */
.solrow--impact .solpanel__title {
  min-height: 2lh; /* exactly two lines of this element's own leading */
}

.solrow--impact .solpanel__desc {
  display: block;
  margin-top: var(--space-3);
  font-size: var(--impact-desc-fs);
  line-height: var(--impact-desc-lh);
  color: var(--color-text-muted);
  text-wrap: pretty;
  min-height: calc(var(--impact-desc-fs) * var(--impact-desc-lh) * var(--impact-desc-lines));
}

@media (hover: hover) and (min-width: 981px) {

  /* Taller than the careers row: the resting cell carries a description as
     well as a title. Height and travel are one number, exactly as the
     careers row does it, so the two frames stay in step. */
  .solrow--impact.solrow--impact.solrow--impact {
    height: 17rem;
    --tip-h: 17rem;
  }

  .solrow--impact.solrow--impact .solpanel__mid { justify-content: flex-start; }

  /* The description rides up with the resting frame, but it would ghost
     over the arriving copy for the length of the travel. Faded out on the
     way, not moved -- moving it would break the rigid-block rule. */
  .solrow--impact.solrow--impact .solpanel__desc { transition: opacity 0.18s linear; }

  .solrow--impact.solrow--impact .solpanel:hover .solpanel__desc,
  .solrow--impact.solrow--impact .solpanel:focus-visible .solpanel__desc { opacity: 0; }

  /* --- the arriving frame ------------------------------------------- */

  /* Trebled because the careers rules are .solrow--tips.solrow--tips and
     would otherwise win the justification and the padding. */
  .solrow--impact.solrow--impact.solrow--impact .solpanel__push {
    justify-content: center;
    padding: var(--space-6) var(--space-5);
  }

  .solrow--impact.solrow--impact .solpanel__stmt {
    display: block;
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: 1.42rem;
    line-height: 1.22;
    letter-spacing: -0.012em;
    color: #fff;
    text-wrap: balance;
  }

  .solrow--impact.solrow--impact .solpanel__sup {
    display: block;
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--color-primary);
    font-size: 0.88rem;
    line-height: 1.62;
    color: rgba(255, 255, 255, 0.74);
    text-wrap: pretty;
  }
}

/* The root size is fluid above roughly 1280px, so from 1360 up the cell
   and the type shrink together and the copy holds its four lines. Below
   that the type stops scaling while the cells keep narrowing, so the same
   sentence runs longer. Rather than shrink the description to an unreadable
   size to force four lines at 1024, the reservation follows the wrap and
   the row grows with it -- the block is always exactly full, so there is
   no dead space at any width and nothing moves. */
/* Boundaries sit at the measured wrap thresholds, not at the site's usual
   breakpoints. The four sentences are cut to within 1% of each other in
   rendered length so they cross together, and each band reserves the
   longest wrap in that band -- which keeps the footer label on the same
   line in all four cells at every width. */
@media (hover: hover) and (min-width: 1160px) and (max-width: 1379px) {
  .solrow--impact { --impact-desc-lines: 5; }
  .solrow--impact.solrow--impact.solrow--impact { height: 18.5rem; --tip-h: 18.5rem; }
}

@media (hover: hover) and (min-width: 1010px) and (max-width: 1159px) {
  .solrow--impact { --impact-desc-lines: 6; }
  .solrow--impact.solrow--impact.solrow--impact { height: 19.8rem; --tip-h: 19.8rem; }
}

/* The last 30px before the row stacks. */
@media (hover: hover) and (min-width: 981px) and (max-width: 1009px) {
  .solrow--impact { --impact-desc-lines: 7; }
  .solrow--impact.solrow--impact.solrow--impact { height: 21.2rem; --tip-h: 21.2rem; }
}

/* --------------------------------------------------------------------------
   Touch and narrow. There is no hover, so the arriving frame can never be
   reached -- both frames are shown stacked inside the one cell, separated
   by a rule so the outcome reads as its own block rather than as a second
   paragraph of the description.
   -------------------------------------------------------------------------- */
@media (max-width: 980px), (hover: none) {

  /* Reading order, top to bottom: number, title, what we do, what you get,
     then the label. Source order puts the label above the reveal because
     that is what the desktop cell needs, so it is moved here rather than
     duplicated in the markup. */
  .solrow--impact .solpanel {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }

  .solrow--impact .solpanel__num { order: 1; }
  .solrow--impact .solpanel__mid { order: 2; display: block; }
  .solrow--impact .solpanel__push { order: 3; }
  .solrow--impact .solpanel__foot { order: 4; margin-top: var(--space-5); }

  .solrow--impact .solpanel__push {
    display: block;
    position: static;
    transform: none;
    inset: auto;
    padding: 0;
    margin-top: var(--space-5);
    padding-top: var(--space-5);
    border-top: 1px solid var(--color-divider);
    pointer-events: auto;
  }

  .solrow--impact .solpanel__stmt {
    display: block;
    font-family: var(--font-display);
    font-weight: var(--weight-light);
    font-size: 1.18rem;
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: var(--color-primary-hover);
    text-wrap: pretty;
  }

  .solrow--impact .solpanel__sup {
    display: block;
    margin-top: var(--space-3);
    font-size: 0.88rem;
    line-height: 1.62;
    color: var(--color-text-muted);
    text-wrap: pretty;
  }

  /* The four-line reservation is a desktop device. On a narrow cell the
     copy sets its own height and an empty reserved block would just be a
     gap above the rule. */
  .solrow--impact .solpanel__desc { min-height: 0; }
}

/* ===========================================================================
   === ARTICLE TYPE SCALE ====================================================

   One ladder, shared by all four insight templates. The templates keep their
   own layouts -- a case study opens on numbers, a perspective on a byline, a
   spotlight on a portrait -- but every piece of type on all four is one of
   the seven roles below, at one size, in one face, in one colour.

   Measured at 1512px the ladder is:

     title        53.8   Switzer 300   uppercase   ink or white   ls  0.004em
     deck         33.1   Switzer 300               grey           ls -0.020em
     section      33.1   Switzer 300               ink            ls -0.030em
     subsection   18.0   Switzer 500               rust           ls -0.004em
     lede para    21.7   Satoshi 300               grey           ls -0.006em
     body         17.6   Satoshi 400               ink            ls -0.002em
     meta caps    13.4   Questrial 400 uppercase   faint          ls  0.140em

   Two things carry the sleeker feel. Display type is set light and tracked
   tight rather than medium and tracked open, so a heading reads by scale
   instead of by weight. And rust comes out of the section heading -- it is
   now punctuation on the page (metrics, subsections, tags, links) rather
   than the loudest thing on it.

   A summary is grey. That covers the case study summary, the spotlight
   introduction, and the perspective and announcement decks: all of them set
   the piece up rather than being part of it, and grey is what says so.

   Nothing in an article should sit between two of these steps. If a new
   element needs type, give it one of these roles rather than a new size.
   --------------------------------------------------------------------------- */

:root {
  --art-deck: var(--text-xl);
  --art-h2: var(--text-xl);
  --art-h3: clamp(1.0625rem, 1rem + 0.2vw, 1.125rem);
  --art-lede: var(--text-lg);
  --art-body: clamp(var(--text-base), 1.15vw, var(--text-lg));
}

/* --- title ---------------------------------------------------------------
   The announcement banner used to set its headline smaller than every other
   article, because the copy shares the band with a portrait. The column is
   widened instead, so the title is the same size as the rest of the set. */
.pagehead--field .ph__say { max-width: 62%; }
.pagehead--field #page-title {
  font-size: var(--text-2xl);
  line-height: 1.01;
}
/* Uppercase display was tracked at 0.055em, which is a print setting. On a
   screen at 53px it reads loose and dated; near zero reads current. */
.display.artmast__title,
.artmast__title,
.pagehead--field #page-title { letter-spacing: 0.004em; line-height: 1.02; }

/* --- deck ----------------------------------------------------------------
   The one sentence that says what the piece is. A case study set this in
   Satoshi 300 grey and a perspective set it in Switzer 400 black; both are
   doing the same job, so both are now the second line of the ladder. */
.artstand__p,
.povlede__deck {
  font-family: var(--font-display);
  font-size: var(--art-deck);
  font-weight: 300;
  line-height: 1.24;
  letter-spacing: -0.02em;
  color: var(--color-text);
  text-wrap: pretty;
}
/* A perspective and an announcement open on a headline -- a claim, in the
   writer's voice. It is black. A case study opens on a summary of the job,
   which is description rather than claim, so it takes the same grey as the
   caption under a metric. */
.artstand__p { color: var(--color-text-faint); }
/* The case summary is the one place on the site set lighter than Light 300.
   It runs on the variable cut of Switzer at Extralight 200, which reads as
   quieter and more open than the rest of the ladder without changing its
   size or its colour. */
.artstand__p {
  font-family: 'SwitzerVF', var(--font-display);
  font-weight: 200;
  font-variation-settings: 'wght' 200;
}
/* Extralight at 17px on a phone is too faint to read comfortably, so the
   summary returns to Light where the type is small. */
@media (max-width: 760px) {
  .artstand__p { font-weight: 300; font-variation-settings: 'wght' 300; }
}
/* The deck runs the full width of the content container on every template,
   the same as body copy does. A case summary stays centred under the metric
   row -- that is a layout decision, not a type one. */
.artstand__p,
.povlede__deck,
.newslede .povlede__deck { max-width: none; }
.artstand .artstand__p--case { margin-inline: auto; }

/* --- section heading -----------------------------------------------------
   "The Challenge", a perspective's section heads, and a spotlight question
   are all the same thing: the top of a part of the page. Set large and light
   in black, at the deck's size, so it carries by scale. */
.caseh2,
.povprose > .artbody__h3,
.qa__q {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--art-h2);
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--color-primary);
  text-wrap: pretty;
}

/* --- subsection ----------------------------------------------------------
   Well below a section heading and rust rather than black, so the two are
   never mistaken for the same level. This is where rust does its work now. */
.artbody__h3,
.povprose > .artbody__h4 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--art-h3);
  line-height: 1.34;
  letter-spacing: -0.004em;
  color: var(--color-primary);
}
/* The rule above is written for the general case; the perspective section
   head is more specific and keeps its rust. */

/* --- lede paragraph ------------------------------------------------------
   A paragraph set a step above body copy. A spotlight introduction is the
   only one today. */
.artprose.spothead__sum > p {
  font-family: var(--font-body);
  font-size: 21.7px;
  font-weight: 300;
  line-height: 1.55;
  letter-spacing: -0.006em;
  color: var(--color-text-faint);
}

/* --- spotlight head ------------------------------------------------------
   The portrait sets the height of the row. The name sits at the top of the
   column beside it and the introduction sits at the bottom, so the open
   space between the two is whatever the portrait leaves over. */
.spothead__grid { align-items: stretch; }
.spothead__shot { align-self: start; }
.spothead__text { justify-content: flex-start; }
.spothead__text .artprose.spothead__sum { margin-top: var(--space-5); }
.spothead__text .artprose.spothead__sum > p { max-width: 860px; }
@media (max-width: 760px) {
  .spothead__text .artprose.spothead__sum { margin-top: var(--space-4); }
}

/* --- body ----------------------------------------------------------------
   Paragraphs and bullets are the same size and leading on every template. A
   perspective's bullets were set a half step smaller than its paragraphs. */
.artprose > p,
.qa__a > p,
.artlist li,
.povprose .artlist li,
.casesec .artlist li {
  font-size: var(--art-body);
  line-height: 1.6;
  letter-spacing: -0.002em;
}

/* --- meta caps -----------------------------------------------------------
   Every small uppercase label on an article -- the metric caption, the
   byline role, the published date, a question number -- is one style. The
   metric caption was tracked at 0.18em in grey and the byline at 0.06em in
   faint; they are now both the ladder's bottom step. */
.cmetric__l,
.povby__role,
.povby__date,
.newsby__place,
.qa__n {
  font-family: var(--font-eyebrow);
  font-size: var(--text-xs);
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.45;
  color: var(--color-text-faint);
}

@media (max-width: 700px) {
  .artstand__p,
  .povlede__deck { font-size: var(--text-lg); }
}

/* === END ARTICLE TYPE SCALE === */

/* ==========================================================================
   ABOUT PAGE — ENTERPRISE ALIGNMENT
   Keeps the About page within the approved enterprise/industry visual system
   without changing any shared component outside this page.
   ========================================================================== */

.enthero--about .enthero__grid {
  grid-template-columns: minmax(0, 2.6fr) minmax(170px, 0.7fr);
  column-gap: clamp(var(--space-8), 4vw, var(--space-16));
}

.enthero--about .enthero__lede {
  max-width: none;
  white-space: nowrap;
  font-size: clamp(1rem, 0.6rem + 0.65vw, 1.25rem);
}

.enthero--about .about-hero__figure {
  box-sizing: border-box;
  width: 100%;
  max-width: 360px;
  height: auto;
  aspect-ratio: 520 / 300;
  margin: 0;
  padding: 0;
  overflow: visible;
  contain: none;
  clip-path: none;
}

.enthero--about .about-hero__figure svg {
  position: static;
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  contain: none;
}

.about-hero__datum {
  stroke: #66787C;
  stroke-width: 1;
  opacity: 0.42;
}

.about-hero__profile {
  stroke: #A64A40;
  stroke-width: 4;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

.about-hero__markers {
  stroke: #4F5E61;
  stroke-width: 1.5;
  opacity: 0.72;
}

.about-hero__points {
  fill: #F8F8F8;
  stroke: #A64A40;
  stroke-width: 3;
}

.about-values .indcell__reveal {
  background-image: none;
  background-color: #A64A40;
}

@media (max-width: 900px) {
  .enthero--about .enthero__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .enthero--about .enthero__lede {
    max-width: 38em;
    white-space: normal;
  }
}

/* SPOTLIGHT-CARD-OVERRIDES-START */
/* Spotlight cards use a short 'Meet [Name]' title and a longer 3-line
   description. Collapse the reserved 2-line title height and expand the
   description slot to fit the standardized copy without clipping. */
.icard[data-type="spotlight"] .icard__t {
  min-height: calc(1.28em * 1);
  max-height: calc(1.28em * 1);
}
.icard[data-type="spotlight"] .icard__d {
  height: auto;
  max-height: calc(1.42em * 3);
}
/* SPOTLIGHT-CARD-OVERRIDES-END */
