/* Built Logic visual system — website handoff v2, File 3.
   Scoped components only. Nothing here restyles a bare element selector, and
   nothing here is required for the page to read completely: every component
   degrades to static, readable HTML with CSS or JavaScript unavailable.

   Palette and type are the locked design.md set. Layout tokens follow File 2:
   64–96px desktop section spacing, 20–32px card padding, 55–75ch prose. */

:root {
  --bl-shadow-1: 0 1px 2px rgba(35,42,49,.06), 0 8px 24px rgba(35,42,49,.08);
  --bl-shadow-2: 0 2px 4px rgba(35,42,49,.08), 0 16px 40px rgba(35,42,49,.12);
  --bl-grid: repeating-linear-gradient(0deg, rgba(35,42,49,.055) 0 1px, transparent 1px 24px),
             repeating-linear-gradient(90deg, rgba(35,42,49,.055) 0 1px, transparent 1px 24px);
  --bl-radius: 6px;
  --bl-t: 160ms var(--ease, cubic-bezier(.2,.6,.2,1));
}

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

.bl-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 16px;
  margin-top: 30px;
}

/* ------------------------------------------------- homepage hero fallback */
/* No recording is supplied yet, so the film block is hidden and the hero
   collapses to one readable column rather than leaving an empty half. */

.hp-hero__inner:has(.hp-hero__visual .bl-film[hidden]) {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "copy";
}
.hp-hero__inner:has(.hp-hero__visual .bl-film[hidden]) .hp-hero__copy { max-width: 46em; }
.hp-hero__inner:has(.hp-hero__visual .bl-film[hidden]) .hp-hero__visual { display: none; }

.hp-hero__support { max-width: 40em; }
.hp-hero__terms { max-width: 42em; }

/* ------------------------------------------------ commercial outcome rows */

.hp8-lost__ch {
  margin: 0 0 10px;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: clamp(21px, 2vw, 25px);
  line-height: 1.2;
  letter-spacing: -.012em;
  color: #232A31;
}
.hp8-lost__col .hp8-lost__body { max-width: 34em; }

/* ------------------------------------------------------- service cards (C) */

.bl-svc-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin-top: 40px;
}
/* One faint line links the three cards on desktop, behind them. */
.bl-svc-grid::before {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  top: 46px;
  height: 1px;
  background: rgba(35,42,49,.14);
  z-index: 0;
}

.bl-svc {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 28px;
  border: 1px solid rgba(35,42,49,.14);
  border-radius: var(--bl-radius);
  background: #FAFAF8;
  transition: border-color var(--bl-t), box-shadow var(--bl-t);
}
.bl-svc:hover,
.bl-svc:focus-within { border-color: #1B3A5B; }

.bl-svc__icon { display: block; color: #1B3A5B; }
.bl-svc__title {
  margin: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: 24px;
  line-height: 1.2;
  letter-spacing: -.012em;
  color: #232A31;
}
.bl-svc__body { margin: 0; font-size: 16.5px; line-height: 1.62; color: #586069; }
.bl-svc__terms { margin: 0; font-size: 14px; line-height: 1.55; color: #586069; }
.bl-svc__link {
  margin-top: auto;
  padding-top: 6px;
  font-weight: 600;
  font-size: 16px;
  color: #1B3A5B;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: rgba(27,58,91,.35);
  transition: text-decoration-color var(--bl-t), color var(--bl-t);
}
.bl-svc__link:hover { color: #17314D; text-decoration-color: #1B3A5B; }

.hp8-journey__lead { max-width: 62ch; font-size: 17.5px; line-height: 1.62; color: #586069; }

/* --------------------------------------------------------------- bridge */

.hp8-bridge__h2 { font-size: clamp(26px, 3vw, 38px); }
.hp8-bridge__body { margin: 16px 0 0; max-width: 62ch; font-size: 17px; line-height: 1.62; color: #586069; }
.hp8-bridge__link {
  display: inline-block;
  margin-top: 18px;
  font-weight: 600;
  color: #1B3A5B;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* --------------------------------------------------------- Map teaser */

.hp8-map-teaser__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: 48px;
  align-items: center;
}
.hp8-map-teaser__body { margin: 16px 0 0; max-width: 58ch; font-size: 17.5px; line-height: 1.62; color: #586069; }
.hp8-map-teaser__points { margin-top: 28px; }
.hp8-map-teaser__sample {
  font-weight: 600;
  color: #1B3A5B;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.hp8-map-teaser__visual { justify-self: center; }

/* ---------------------------------------------------------- final action */

.hp8-final__body { margin: 16px 0 0; max-width: 58ch; font-size: 17.5px; line-height: 1.62; color: #586069; }
.hp8-final__cta { margin-top: 26px; }

@media (max-width: 899px) {
  .bl-svc-grid { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  .bl-svc-grid::before { display: none; }
  .bl-svc { padding: 22px; }
  .hp8-map-teaser__inner { grid-template-columns: minmax(0, 1fr); gap: 30px; }
  .bl-actions { gap: 12px; }
  .bl-actions > .hero-btn { width: 100%; justify-content: center; }
}

/* ------------------------------------------------- training page structure */

.tt-hero__media { align-self: start; }
.tt-hero:has(.tt-hero__media .bl-film[hidden]) { grid-template-columns: minmax(0, 1fr); }
.tt-hero:has(.tt-hero__media .bl-film[hidden]) .tt-hero__media { display: none; }

.tt-compare .tt-sel--panel { margin-top: 28px; }

/* --------------------------------------------------- project page structure */

.seo-hero__media { align-self: start; }
.seo-hero__grid:has(.seo-hero__media .bl-film[hidden]) { grid-template-columns: minmax(0, 1fr); }
.seo-hero__grid:has(.seo-hero__media .bl-film[hidden]) .seo-hero__media { display: none; }

.seo-panel--demoted { margin-top: 48px; }
.seo-panel__links { margin-top: 14px; font-size: 15.5px; color: #586069; }
.seo-panel__links a { font-weight: 600; color: #1B3A5B; text-decoration: underline; text-underline-offset: 4px; }
.seo-panel__links a:hover { color: #17314D; }
.seo-close__act { margin-top: 26px; }

/* --------------------------------------------------- stage sequences (C) */

.bl-steps__caption {
  margin: 40px 0 16px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #586069;
}
.seo-section--dark .bl-steps__caption { color: #AFC4DD; }

.bl-steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.bl-steps--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.bl-steps--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 18px; }
.bl-steps--6 .bl-steps__title { font-size: 18px; }
/* A step whose whole content is its label needs no separate body line. */
.bl-steps__title--plain { margin-bottom: 0; font-weight: 500; }
.bl-steps__step {
  position: relative;
  padding-top: 20px;
  border-top: 1px solid rgba(35,42,49,.14);
}
.seo-section--dark .bl-steps__step { border-top-color: rgba(250,250,248,.22); }
.bl-steps__num {
  margin: 0 0 10px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: .16em;
  color: #1B3A5B;
}
.seo-section--dark .bl-steps__num { color: #AFC4DD; }
.bl-steps__title {
  margin: 0 0 8px;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: 21px;
  line-height: 1.22;
  color: #232A31;
}
.seo-section--dark .bl-steps__title { color: #FAFAF8; }
.bl-steps__body { margin: 0; font-size: 16px; line-height: 1.6; color: #586069; }
.seo-section--dark .bl-steps__body { color: rgba(250,250,248,.72); }

/* --------------------------------------------------------- evidence (D) */

.bl-evidence-section__h { font-size: clamp(28px, 3.2vw, 44px); }
.bl-evidence-section__lead { margin: 14px 0 0; max-width: 62ch; font-size: 17px; line-height: 1.62; color: #586069; }

.bl-evidence-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  margin-top: 36px;
}
.bl-evidence {
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(35,42,49,.14);
  border-left: 3px solid #1B3A5B;
  border-radius: var(--bl-radius);
  background: #FAFAF8;
  box-shadow: var(--bl-shadow-1);
  overflow: hidden;
}
.bl-evidence__figure {
  margin: 0;
  padding: 18px;
  background: #E5E5E2;
  background-image: var(--bl-grid);
}
.bl-evidence__figure img {
  display: block;
  width: 100%;
  min-height: 280px;
  object-fit: contain;
  background: #FAFAF8;
  border: 1px solid rgba(35,42,49,.14);
}
.bl-evidence__meta { padding: 24px 28px 28px; }
.bl-evidence__tag {
  margin: 0 0 10px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #1B3A5B;
}
.bl-evidence__title {
  margin: 0 0 8px;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: 22px;
  line-height: 1.2;
  color: #232A31;
}
.bl-evidence__what { margin: 0; font-size: 16px; line-height: 1.6; color: #586069; }
.bl-evidence__action {
  display: inline-block;
  margin-top: 16px;
  font-weight: 600;
  color: #1B3A5B;
  text-decoration: underline;
  text-underline-offset: 4px;
}

@media (max-width: 899px) {
  .bl-steps { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .bl-steps__step { border-top: 0; border-left: 1px solid rgba(35,42,49,.14); padding: 0 0 26px 20px; }
  .seo-section--dark .bl-steps__step { border-left-color: rgba(250,250,248,.22); }
  .bl-steps__step:last-child { padding-bottom: 0; }
  .bl-evidence-grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .bl-evidence__figure { padding: 12px; background-image: none; }
  .bl-evidence__figure img { min-height: 0; }
  .bl-evidence__meta { padding: 20px; }
}

/* ================================================================ A. FILM */
/* The frame reserves its own geometry, so nothing shifts when a recording is
   finally supplied. With readiness: media_pending the whole block is hidden in
   the HTML and the hero falls back to one column. */

.bl-film {
  margin: 0;
  border: 1px solid rgba(35,42,49,.24);
  border-radius: var(--bl-radius);
  background: #E5E5E2;
  box-shadow: var(--bl-shadow-1);
  overflow: hidden;
  transition: border-color var(--bl-t), box-shadow var(--bl-t);
}
.bl-film:hover,
.bl-film:focus-within { border-color: #1B3A5B; }

.bl-film__strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: 32px;
  padding: 0 14px;
  border-bottom: 1px solid rgba(35,42,49,.14);
  background: #FAFAF8;
}
.bl-film__label,
.bl-film__duration {
  margin: 0;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #232A31;
}
.bl-film__duration { color: #586069; }

.bl-film__stage {
  position: relative;
  aspect-ratio: 16 / 9;
  /* v5: no graph paper on any film frame, primary or sectional. The grid was
     declared here, so removing it from the placeholder variant alone changed
     nothing: that variant only ever set a background colour over this. */
  background: #E5E5E2;
}
.bl-film__video {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 300ms var(--ease, cubic-bezier(.2,.6,.2,1));
}
.bl-film[data-playing] .bl-film__video { opacity: 1; }
.bl-film[data-instant] .bl-film__video { transition: none; }

/* Four 12px registration marks, one per corner. */
.bl-film__marks { position: absolute; inset: 10px; pointer-events: none; }
.bl-film__marks::before,
.bl-film__marks::after,
.bl-film__stage::before,
.bl-film__stage::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  border: 0 solid #1B3A5B;
}
.bl-film__marks::before { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.bl-film__marks::after { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; }
.bl-film__stage::before { bottom: 10px; left: 10px; border-bottom-width: 1px; border-left-width: 1px; }
.bl-film__stage::after { bottom: 10px; right: 10px; border-bottom-width: 1px; border-right-width: 1px; }

.bl-film__play {
  position: absolute;
  left: 16px;
  bottom: 16px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 22px 0 18px;
  border: 0;
  border-radius: 28px;
  background: #1B3A5B;
  color: #FAFAF8;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 15.5px;
  cursor: pointer;
  transition: background-color var(--bl-t);
}
.bl-film__play::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 11px solid #FAFAF8;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
}
/* bl-visual.js hides this with the hidden attribute once playback starts, and
   display: inline-flex above would otherwise keep it on screen over the film. */
.bl-film__play[hidden] { display: none; }
.bl-film__play:hover { background: #17314D; }
.bl-film__play:focus-visible { outline: 3px solid #1B3A5B; outline-offset: 2px; }

.bl-film__state {
  margin: 0;
  padding: 12px 16px;
  border-top: 1px solid rgba(35,42,49,.14);
  background: #FAFAF8;
  font-size: 15px;
  line-height: 1.5;
  color: #586069;
}

/* =============================================================== B. FLOW */

.bl-flow {
  margin-top: 36px;
  padding: 32px;
  border: 1px solid rgba(35,42,49,.14);
  border-radius: var(--bl-radius);
  background: #FAFAF8;
  background-image: var(--bl-grid);
  box-shadow: var(--bl-shadow-1);
}
.bl-flow__track + .bl-flow__track { margin-top: 40px; padding-top: 36px; border-top: 1px solid rgba(35,42,49,.14); }

.bl-flow__label {
  margin: 0 0 20px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #586069;
}

.bl-flow__rail { position: relative; }
.bl-flow__connector {
  position: absolute;
  left: 0;
  right: 0;
  top: 27px;
  width: 100%;
  height: 2px;
  overflow: visible;
}
.bl-flow__stages {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.bl-flow__item { display: flex; }

.bl-flow__stage {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  min-height: 56px;
  padding: 14px 16px;
  border: 1px solid rgba(35,42,49,.14);
  border-radius: var(--bl-radius);
  background: #FAFAF8;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--bl-t), box-shadow var(--bl-t);
}
.bl-flow__stage:hover { border-color: #1B3A5B; }
.bl-flow__stage:focus-visible { outline: 3px solid #1B3A5B; outline-offset: 2px; }
.bl-flow__stage[aria-pressed="true"] {
  border: 2px solid #1B3A5B;
  padding: 13px 15px;
  box-shadow: var(--bl-shadow-1);
}
.bl-flow__stage--review { border-style: double; border-width: 3px; padding: 12px 14px; }

.bl-flow__idx {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .16em;
  color: #586069;
}
.bl-flow__stage[aria-pressed="true"] .bl-flow__idx { color: #1B3A5B; }
.bl-flow__name { font-size: 15px; line-height: 1.4; color: #232A31; }
.bl-flow__tag {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #1B3A5B;
}

.bl-flow__note {
  margin: 18px 0 0;
  max-width: 68ch;
  font-size: 16.5px;
  line-height: 1.6;
  color: #586069;
}
.bl-flow__close {
  margin: 36px 0 0;
  padding-top: 24px;
  border-top: 1px solid rgba(35,42,49,.14);
  font-family: 'Fraunces', Georgia, serif;
  font-size: 20px;
  line-height: 1.35;
  color: #232A31;
}

@media (max-width: 767px) {
  .bl-flow { padding: 20px; }
  .bl-flow__connector { display: none; }
  .bl-flow__stages {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
    padding-left: 18px;
    border-left: 1px solid rgba(35,42,49,.14);
  }
}
@media (max-width: 639px) {
  .bl-film { box-shadow: none; }
  .bl-film__marks, .bl-film__stage::before, .bl-film__stage::after { display: none; }
}
@media (max-width: 479px) {
  .bl-flow { background-image: none; }
}

/* Reduced motion: remove the optional movement rather than speed it up. The
   components stay fully usable; only the decoration goes. */
@media (prefers-reduced-motion: reduce) {
  .bl-flow,
  .bl-flow *,
  .bl-film,
  .bl-film *,
  .bl-svc,
  .bl-svc *,
  .bl-evidence,
  .bl-evidence * {
    transition: none !important;
    animation: none !important;
  }
}

/* The About disciplines link is a retained internal route, not new copy. */
.hp8-journey__more { margin: 14px 0 0; font-size: 16px; }
.hp8-journey__more a { color: #1B3A5B; text-decoration: underline; text-underline-offset: 4px; }

/* Deliverable points read as a short vertical list in the Map section. */
.hp8-map-teaser__points li { border-top: 1px solid #E5E5E2; padding-top: 14px; }
.hp8-map-teaser__points li + li { margin-top: 14px; }

/* Section rhythm. .hp8 itself carries no vertical padding: each section
   supplies its own, so the three new sections take the same scale as the
   existing ones (56–92px desktop, 40–56px mobile). The footer band pulls up
   40px, so the last section reserves room for it. */
.hp8-journey--svc { padding: clamp(56px, 7vw, 92px) 0; }
.hp8-bridge { padding: clamp(40px, 5.5vw, 72px) 0; border-top: 1px solid #E5E5E2; }
.hp8-map-teaser { padding: clamp(56px, 7vw, 92px) 0; border-top: 1px solid #E5E5E2; }
.hp8-final { padding: clamp(56px, 7vw, 92px) 0 clamp(96px, 9vw, 132px); border-top: 1px solid #E5E5E2; }

/* Sample-document variant of the evidence card (File 3 D). The switcher, the
   enlarge buttons and every link keep their own behaviour; this only frames
   them and pins the C28 status where it cannot be detached from the excerpt. */
.bl-evidence--sample { margin-top: 28px; }
.bl-evidence--sample .bl-evidence__figure--pages { padding: 24px; }
.bl-evidence--sample .bl-evidence__figure--pages img { min-height: 0; border: 0; background: none; }
.bl-evidence__tagline { margin: 0; font-size: 16px; line-height: 1.6; color: #586069; }
.bl-evidence__tagline .bl-evidence__tag { display: block; margin-bottom: 8px; }
.bl-evidence--sample .bl-evidence__action { display: inline-block; margin-top: 16px; }

@media (max-width: 639px) {
  .bl-evidence--sample .bl-evidence__figure--pages { padding: 14px; }
}

/* ==================================================================== V3 */
/* Website handoff v3 (11 Sep 2026). design.md v3 allows gradients of the
   palette, translucent layers, restrained shadows, 12–24px media corners and
   purposeful motion in explanatory graphics. Palette and typefaces are
   unchanged: every value below is one of the six locked colours, the one hover
   blue, or a transparency of them. */

:root {
  --bl-radius-media: 16px;
  --bl-radius-card: 12px;
  /* v4: the three gradient tokens are removed. design.md v4 and the repo
     brand rules refuse gradients, so every surface below is a flat brand
     colour. Translucency and restrained shadow stay. */
  --bl-glass: rgba(250,250,248,.78);
  --bl-shadow-media: 0 24px 60px rgba(35,42,49,.14), 0 2px 6px rgba(35,42,49,.08);
  --bl-line: rgba(35,42,49,.14);
  --bl-line-strong: rgba(35,42,49,.24);
  --bl-ease: cubic-bezier(.2,.6,.2,1);
}

/* ---------------------------------------------------- media frame utility */
/* Video, document previews and diagram panels share one frame: 16px corners,
   a 1px border, restrained depth and a Soft Stone ground. */

.bl-media {
  position: relative;
  margin: 0;
  border: 1px solid var(--bl-line-strong);
  border-radius: var(--bl-radius-media);
  background: #E5E5E2;
  box-shadow: var(--bl-shadow-media);
  overflow: hidden;
}
.bl-media--paper { background: #FAFAF8; }
.bl-media--dark { background: #1B3A5B; border-color: rgba(175,196,221,.28); }
.bl-media--glass { background: var(--bl-glass); }
@supports (backdrop-filter: blur(8px)) {
  .bl-media--glass { backdrop-filter: blur(8px); }
}
.bl-media--flush { box-shadow: none; }
.bl-media__caption {
  margin: 14px 0 0;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  color: #586069;
}

/* -------------------------------------------------------------- card (v3) */

.bl-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding: 28px;
  border: 1px solid var(--bl-line);
  border-radius: var(--bl-radius-card);
  background: #FAFAF8;
  /* Top-aligned, natural height: a card never stretches to match a taller
     neighbour in the same grid or flex row. */
  align-self: start;
  transition: border-color 180ms var(--bl-ease), box-shadow 180ms var(--bl-ease);
}
.bl-card:hover,
.bl-card:focus-within { border-color: #1B3A5B; }
.bl-card--paper { background: #FAFAF8; }
.bl-card--dark { background: #1B3A5B; border-color: rgba(175,196,221,.28); }
.bl-card__eyebrow {
  margin: 0;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #1B3A5B;
}
.bl-card--dark .bl-card__eyebrow { color: #AFC4DD; }
.bl-card__title {
  margin: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: clamp(21px, 2vw, 25px);
  line-height: 1.2;
  letter-spacing: -.012em;
  color: #232A31;
}
.bl-card--dark .bl-card__title { color: #FAFAF8; }
.bl-card__figure { margin: 0 0 4px; width: 100%; }
.bl-card__body { margin: 0; font-size: 17px; line-height: 1.62; color: #586069; }
.bl-card--dark .bl-card__body { color: rgba(250,250,248,.76); }
.bl-card__meta {
  margin: 0;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 12.5px;
  letter-spacing: .04em;
  color: #586069;
}
.bl-card__action { margin-top: auto; padding-top: 8px; }

/* --------------------------------------------------------- capability strip */
/* Plex Mono, dot separators, one line on desktop and wrapping cleanly. */

.bl-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 0;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11.5px;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: #586069;
}
.bl-strip__item { display: inline-flex; align-items: center; }
.bl-strip__item + .bl-strip__item::before {
  content: "";
  width: 4px;
  height: 4px;
  margin: 0 18px;
  border-radius: 50%;
  background: #AFC4DD;
}
.bl-strip--dark { color: #AFC4DD; }
.bl-strip--dark .bl-strip__item + .bl-strip__item::before { background: rgba(175,196,221,.6); }

/* ------------------------------------------------------- reservation cards */
/* A real component, visible in staging only, that says plainly what is still
   to be supplied. Dashed border so it never reads as finished content. */

.bl-reserve {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 24px 28px;
  border: 1px dashed var(--bl-line-strong);
  border-radius: var(--bl-radius-card);
  background: #E5E5E2;
}
.bl-reserve__label {
  margin: 0;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #586069;
}
.bl-reserve__body { margin: 0; max-width: 56ch; font-size: 16.5px; line-height: 1.6; color: #586069; }
.bl-reserve--feedback { align-items: flex-start; }
.bl-reserve--profile {
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 0;
  overflow: hidden;
}
.bl-reserve--profile .bl-reserve__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  background-color: #E5E5E2;
  background-image: var(--bl-grid);
}
.bl-reserve--profile .bl-reserve__frame::after {
  content: "";
  position: absolute;
  inset: 22%;
  background-image: url('/assets/monogram.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  opacity: .1;
}
.bl-reserve--profile .bl-reserve__label { padding: 0 20px 20px; }

/* v4 (11 Sep 2026): the Replay control and its button class are removed from
   the visual system.
   An explanatory graphic animates once on first entry and settles; it is never
   re-armed and needs no control to watch it again. Nothing replaces it: no
   Start, Run or Animate button. Native video controls, the calculator reset and
   real navigation are unaffected. */

/* ------------------------------------------------------------ diagram panel */

.bl-diagram {
  position: relative;
  margin: 0;
  padding: 28px;
  border: 1px solid var(--bl-line-strong);
  border-radius: var(--bl-radius-media);
  background-color: #FAFAF8;
  /* Flat Off-White under the faint measuring grid: the light-blue corner wash
     went with the gradient tokens in v4. */
  background-image: var(--bl-grid);
  box-shadow: var(--bl-shadow-media);
}
.bl-diagram--dark {
  background-color: #1B3A5B;
  background-image: none;
  border-color: rgba(175,196,221,.28);
}
.bl-diagram__head {
  margin: 0 0 6px;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: clamp(19px, 1.8vw, 23px);
  line-height: 1.28;
  color: #232A31;
}
.bl-diagram--dark .bl-diagram__head { color: #FAFAF8; }
.bl-diagram__lead { margin: 0 0 22px; max-width: 66ch; font-size: 16.5px; line-height: 1.6; color: #586069; }
.bl-diagram--dark .bl-diagram__lead { color: rgba(250,250,248,.76); }
.bl-diagram svg { display: block; width: 100%; height: auto; overflow: visible; }
.bl-diagram__foot { margin: 18px 0 0; font-size: 15.5px; line-height: 1.55; color: #586069; }
.bl-diagram--dark .bl-diagram__foot { color: rgba(250,250,248,.72); }

/* Desktop SVG and a stacked mobile version of the same meaning. */
.bl-diagram [data-mobile] { display: none; }
@media (max-width: 699px) {
  .bl-diagram { padding: 20px; background-image: none; }
  .bl-diagram [data-desktop] { display: none; }
  .bl-diagram [data-mobile] { display: block; }
}
.bl-diagram__stack { margin: 0; padding: 0; list-style: none; }
.bl-diagram__stack > li {
  padding: 14px 0 14px 18px;
  border-left: 2px solid #AFC4DD;
  font-size: 16.5px;
  line-height: 1.55;
  color: #232A31;
}
.bl-diagram__stack > li + li { border-top: 1px solid var(--bl-line); }

/* ------------------------------------------------------------ panel motion */
/* The sequence is decoration on finished content. The hidden start state is
   applied only under .is-armed, which assets/bl-visual.js adds, so the complete
   diagram is what shows with JavaScript blocked or reduced motion set. */

@keyframes bl-step-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@keyframes bl-draw {
  from { stroke-dashoffset: var(--bl-draw-len, 1200); }
  to { stroke-dashoffset: 0; }
}
@keyframes bl-pulse-once {
  0%, 100% { stroke-width: 1; filter: none; }
  45% { stroke-width: 3; }
}
@keyframes bl-pulse-once-box {
  0%, 100% { border-color: var(--bl-line-strong); }
  45% { border-color: #1B3A5B; }
}

[data-bl-animate].is-armed [data-step] { opacity: 0; transform: translateY(8px); }
[data-bl-animate].is-armed .draw {
  stroke-dasharray: var(--bl-draw-len, 1200);
  stroke-dashoffset: var(--bl-draw-len, 1200);
}
[data-bl-animate].is-armed.is-live [data-step] {
  animation: bl-step-in 320ms var(--bl-ease) both;
  animation-delay: calc(var(--i, 0) * 120ms);
}
[data-bl-animate].is-armed.is-live .draw {
  animation: bl-draw 900ms var(--bl-ease) both;
  animation-delay: calc(var(--i, 0) * 120ms);
}
[data-bl-animate].is-armed.is-live .pulse-once {
  animation: bl-pulse-once 900ms var(--bl-ease) 1 both;
  animation-delay: calc(var(--i, 0) * 120ms + 320ms);
}
[data-bl-animate].is-armed.is-live div.pulse-once,
[data-bl-animate].is-armed.is-live li.pulse-once {
  animation-name: bl-pulse-once-box;
}
/* One element can be both a step and the pulse point. The shorthand above
   would replace the reveal and leave that node at opacity 0 for good, so the
   combined case runs both animations. */
[data-bl-animate].is-armed.is-live [data-step].pulse-once {
  animation: bl-step-in 320ms var(--bl-ease) both, bl-pulse-once 900ms var(--bl-ease) 1 both;
  animation-delay: calc(var(--i, 0) * 120ms), calc(var(--i, 0) * 120ms + 320ms);
}
[data-bl-animate].is-armed.is-live div[data-step].pulse-once,
[data-bl-animate].is-armed.is-live li[data-step].pulse-once {
  animation-name: bl-step-in, bl-pulse-once-box;
}
/* Settled is the finished state, full stop: nothing is hidden and nothing runs.
   The armed and live rules above reach 0,3,0 and 0,4,0, so plain specificity
   would lose to them on a panel that has already run. !important is what makes
   "full stop" true for every combination of classes. */
[data-bl-animate].is-settled [data-step],
[data-bl-animate].is-settled .draw,
[data-bl-animate].is-settled .pulse-once {
  opacity: 1 !important;
  transform: none !important;
  stroke-dashoffset: 0 !important;
  animation: none !important;
}

/* ------------------------------------------------------- film: placeholder */
/* A reserved video position, visible in staging only. The frame is the final
   geometry, the tag says plainly what it is, and the play shape is decoration
   with no control behind it. */

.bl-film--placeholder {
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  overflow: visible;
}
.bl-film--placeholder:hover,
.bl-film--placeholder:focus-within { border-color: transparent; box-shadow: none; }
.bl-film--placeholder .bl-film__stage {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--bl-line-strong);
  border-radius: var(--bl-radius-media);
  background-color: #E5E5E2;
  box-shadow: var(--bl-shadow-media);
  overflow: hidden;
}
.bl-film--placeholder .bl-film__stage::before,
.bl-film--placeholder .bl-film__stage::after { display: none; }
.bl-film--placeholder .bl-film__marks { position: absolute; inset: 14px; pointer-events: none; }
.bl-film--placeholder .bl-film__marks::before,
.bl-film--placeholder .bl-film__marks::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid rgba(27,58,91,.45);
}
.bl-film--placeholder .bl-film__marks::before { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; }
.bl-film--placeholder .bl-film__marks::after { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }

/* The neutral Built Logic monogram, low contrast, centred. */
.bl-film--placeholder .bl-film__mono {
  position: absolute;
  inset: 0;
  background-image: url('/assets/monogram.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: min(34%, 220px) auto;
  opacity: .08;
}

/* Decoration, not a control: a Consulting Blue disc with an Off-White triangle. */
.bl-film--placeholder .bl-film__playshape {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 64px;
  height: 64px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(27,58,91,.9);
  pointer-events: none;
}
.bl-film--placeholder .bl-film__playshape::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 54%;
  transform: translate(-50%, -50%);
  width: 0;
  height: 0;
  border-left: 16px solid #FAFAF8;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}

.bl-film--placeholder .bl-film__tag {
  position: absolute;
  left: 18px;
  bottom: 18px;
  padding: 6px 10px;
  border-radius: 4px;
  background: var(--bl-glass);
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #232A31;
}
.bl-film__title {
  margin: 16px 0 0;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 17.5px;
  line-height: 1.4;
  color: #232A31;
}
.bl-film--placeholder .bl-film__presenter { margin: 4px 0 0; font-size: 15.5px; line-height: 1.5; color: #586069; }

/* The real player keeps the v2 frame: only the placeholder variant is new. */
.bl-film:not(.bl-film--placeholder) .bl-film__stage { border-radius: 0; }

@media (max-width: 639px) {
  .bl-film--placeholder .bl-film__stage { box-shadow: none; }
  .bl-film--placeholder .bl-film__marks { display: none; }
  .bl-film--placeholder .bl-film__playshape { width: 52px; height: 52px; }
  .bl-reserve { padding: 20px; }
  .bl-card { padding: 22px; }
}

/* A hero whose media column is empty in production, because the reserved frame
   was removed at build time, becomes a single readable column rather than
   leaving a dead track. The [hidden] rules above cover the v2 state. */
.hp-hero__inner:has(.hp-hero__visual:empty) {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "copy";
}
.hp-hero__inner:has(.hp-hero__visual:empty) .hp-hero__copy { max-width: 46em; }
.hp-hero__inner:has(.hp-hero__visual:empty) .hp-hero__visual { display: none; }
.tt-hero:has(.tt-hero__media:empty) { grid-template-columns: minmax(0, 1fr); }
.tt-hero:has(.tt-hero__media:empty) .tt-hero__media { display: none; }
.seo-hero__grid:has(.seo-hero__media:empty) { grid-template-columns: minmax(0, 1fr); }
.seo-hero__grid:has(.seo-hero__media:empty) .seo-hero__media { display: none; }

@media (prefers-reduced-motion: reduce) {
  .bl-card,
  .bl-card *,
  .bl-diagram,
  .bl-diagram *,
  .bl-reserve,
  .bl-reserve * {
    transition: none !important;
    animation: none !important;
  }
}

/* ==================================================================== V4 */
/* Website pass v4 (11 Sep 2026). Five additions and one removal:
     - .bl-hero       the 45:55 copy/media hero grid
     - .bl-film--*    primary, standalone and sectional geometry for one film
     - .bl-diagram--slate + .bl-ribbon   flat slate surfaces, no gradient
     - .bl-team       manual team carousel
     - .bl-tabs       selectable details, every panel in the DOM
     - the Replay control and its handler are gone
   Every value is one of the six locked colours, the one hover blue, or a
   transparency of them. */

:root {
  /* The flat slate ground. Charcoal, used as a surface rather than as ink. */
  --bl-deep-slate: #232A31;
  --bl-slate-grid: repeating-linear-gradient(0deg, rgba(250,250,248,.05) 0 1px, transparent 1px 24px),
                   repeating-linear-gradient(90deg, rgba(250,250,248,.05) 0 1px, transparent 1px 24px);
  --bl-on-slate: rgba(250,250,248,.72);
}

/* ------------------------------------------------------- wide container */
/* File 2 section 2 sizes the primary film against a 1,240–1,320px content
   container. The long-standing .fs-wrap is capped at 1,120px with 32px
   gutters, which leaves the 55% media column at about 554px: the film's own
   680px max-width can never bind inside it. One shared container fixes that
   for every .bl-hero section instead of four page-local widenings. Use
   .bl-wide in place of .fs-wrap on a hero's inner container; 1,304px less the
   64px gutters gives a 1,240px content width, so the media column lands at
   about 655px. At 390px the 20px gutters give the film about 350px, which is
   the File 2 mobile figure. */

.bl-wide {
  /* The seo-* routes do not load tailwind.css and so have no global
     border-box reset: without this, width 100% plus the gutters overflow the
     viewport by 64px. */
  box-sizing: border-box;
  width: 100%;
  max-width: 1304px;
  margin-inline: auto;
  padding-inline: 32px;
}
@media (max-width: 767px) {
  .bl-wide { padding-inline: 20px; }
}

/* ------------------------------------------------------------- hero grid */
/* 45:55 copy/media with a 48px gap. At a 1,240px container that leaves the
   film about 650px, which is the File 2 target. One column under 1024px, and
   because the copy column holds the headline, the supporting paragraph and the
   CTA, the stacked order is already headline → copy → CTA → video. */

.bl-hero {
  display: grid;
  grid-template-columns: minmax(0, 45fr) minmax(0, 55fr);
  gap: 48px;
  align-items: center;
}
.bl-hero--top { align-items: start; }
.bl-hero__copy { min-width: 0; }
.bl-hero__media { min-width: 0; }
.bl-hero__copy > :last-child { margin-bottom: 0; }

@media (max-width: 1023px) {
  .bl-hero { grid-template-columns: minmax(0, 1fr); gap: 32px; }
}
@media (max-width: 639px) {
  .bl-hero { gap: 26px; }
}

/* --------------------------------------------------------- film geometry */
/* Placeholder, poster and player share the ratio box; the title sits outside
   it. A variant sets width only, so no nested max-width, fixed height or
   max-content track can shrink the frame. */

.bl-film--primary,
.bl-film--standalone,
.bl-film--sectional { width: 100%; }
.bl-film--primary { max-width: 680px; }
.bl-film--standalone { max-width: 960px; margin-inline: auto; }
/* Sectional frames fill the cell their two-column grid gives them, so a pair
   stays equal however wide the narrower column is. */
.bl-film--sectional { max-width: none; }

/* Portrait films. The footage was shot 4:5, so the frame is 4:5 rather than
   pillarboxing a tall picture inside a wide box. Capped narrower than the
   16:9 frames so a tall frame cannot outgrow the column beside it. */
.bl-film--portrait .bl-film__stage { aspect-ratio: 4 / 5; }
.bl-film--primary.bl-film--portrait { max-width: 360px; }
/* Flat on the paper like every other surface: a tall dark picture with a drop
   shadow reads louder than the headline beside it. */
.bl-film--portrait,
.bl-film--portrait:hover,
.bl-film--portrait:focus-within { box-shadow: none; }
/* Same 16px corner as the diagrams and document previews on every page. */
.bl-film--portrait { border-radius: 16px; }
.bl-film--standalone.bl-film--portrait { max-width: 460px; }

/* The still sits under the video, which fades in over it on play. */
.bl-film__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.bl-film__stage > .bl-film__video {
  position: absolute;
  inset: 0;
  object-fit: cover;
}

.bl-film__titles { margin: 0; }
.bl-film__titles .bl-film__title { margin-top: 16px; }
.bl-film--sectional .bl-film__title { font-size: 16.5px; }

/* ------------------------------------------------------- slate diagram */
/* Flat #232A31, a faint light grid, Off-White node cards, Light Blue
   connectors. The review node carries the Light Blue 2px border. */

.bl-diagram--slate {
  background-color: var(--bl-deep-slate);
  /* Flat charcoal. The grid comes from the .bl-diagram base, which the light
     Map and training panels keep, so the slate variant switches it off. */
  background-image: none;
  border-color: rgba(175,196,221,.28);
}
.bl-diagram--slate .bl-diagram__head { color: #FAFAF8; }
.bl-diagram--slate .bl-diagram__lead,
.bl-diagram--slate .bl-diagram__foot,
.bl-diagram--slate .bl-diagram__mono { color: var(--bl-on-slate); }
.bl-diagram__eyebrow {
  margin: 0 0 10px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #586069;
}
.bl-diagram--slate .bl-diagram__eyebrow { color: var(--bl-on-slate); }
.bl-diagram__mono {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  fill: var(--bl-on-slate);
  color: #586069;
}

/* Node cards and connectors work the same in SVG and in HTML. */
.bl-node__box {
  fill: #FAFAF8;
  stroke: rgba(35,42,49,.2);
  stroke-width: 1;
}
.bl-node__label { fill: #232A31; font-family: 'Source Sans 3', system-ui, sans-serif; font-weight: 500; font-size: 14px; }
.bl-node__sub { fill: #586069; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; }
.bl-node--review .bl-node__box { stroke: #AFC4DD; stroke-width: 2; }
.bl-conn { stroke: #AFC4DD; stroke-width: 1.5; fill: none; }
.bl-conn--soft { stroke: rgba(175,196,221,.55); }

/* The HTML twin of a node card, used by the stacked mobile view. */
li.bl-node,
div.bl-node {
  padding: 14px 16px;
  border: 1px solid rgba(35,42,49,.2);
  border-radius: 8px;
  background: #FAFAF8;
  font-size: 16px;
  line-height: 1.5;
  color: #232A31;
}
li.bl-node--review,
div.bl-node--review { border: 2px solid #AFC4DD; padding: 13px 15px; }
/* The stacked twin is the mobile view only. `.bl-diagram [data-mobile] {
   display: none }` above is 0,2,0, so an unqualified `display: grid` here
   would tie on specificity, win on order, and paint the stack over the SVG at
   desktop width. Scoping it to the same breakpoint keeps the desktop hide. */
@media (max-width: 699px) {
  .bl-diagram--slate .bl-diagram__stack { display: grid; gap: 12px; }
  .bl-diagram--slate .bl-diagram__stack > li { border-left: 0; border-top: 0; padding: 14px 16px; }
  .bl-diagram--slate .bl-diagram__stack > li + li { border-top: 1px solid rgba(35,42,49,.2); }
  .bl-diagram--slate .bl-diagram__stack > li.bl-node--review + li,
  .bl-diagram--slate .bl-diagram__stack > li + li.bl-node--review { border-top-width: 2px; }
}

/* ------------------------------------------------------- ribbon surface */
/* A full-width flat slate band. One accent moment: the action or the figure,
   not both. */

.bl-ribbon {
  background-color: var(--bl-deep-slate);
  color: #FAFAF8;
}
.bl-ribbon__inner { padding: clamp(40px, 5vw, 64px) 0; }
.bl-ribbon__head {
  margin: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600;
  font-size: clamp(26px, 3vw, 38px);
  line-height: 1.18;
  letter-spacing: -.012em;
  color: #FAFAF8;
}
.bl-ribbon__eyebrow {
  margin: 0 0 12px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bl-on-slate);
}
.bl-ribbon__body { margin: 16px 0 0; max-width: 62ch; font-size: 17px; line-height: 1.62; color: var(--bl-on-slate); }
.bl-ribbon__action { margin-top: 26px; }
.bl-ribbon__action a { color: #AFC4DD; }

/* ------------------------------------------------------- team carousel */
/* Grid areas rather than source order, so the markup can put the buttons
   either side of the track or after it. Nothing moves on its own. */

.bl-team {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "prev track next";
  align-items: center;
  gap: 0 14px;
}
.bl-team__nav--prev { grid-area: prev; }
.bl-team__nav--next { grid-area: next; }
.bl-team__track { grid-area: track; }

/* v6: the buttons used to centre on the whole grid row, which is as tall as the
   tallest card including its caption and description, so they sat below the
   picture row. They now sit in the media row's coordinate system: the offset is
   the measured distance from the track's top to the portrait frame's midpoint,
   published by bl-visual.js as --bl-team-nav-offset and re-measured on every
   track resize. Nothing is taken from a screenshot or from caption height. */
@media (min-width: 768px) {
  .bl-team__nav {
    align-self: start;
    margin-top: var(--bl-team-nav-offset, 0px);
  }
}

.bl-team__nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--bl-line-strong);
  border-radius: 50%;
  background: #FAFAF8;
  color: #1B3A5B;
  font-size: 16px;
  cursor: pointer;
  transition: border-color 180ms var(--bl-ease), background-color 180ms var(--bl-ease);
}
.bl-team__nav:hover:not(:disabled) { border-color: #1B3A5B; background: #E5E5E2; }
.bl-team__nav:focus-visible { outline: 3px solid #1B3A5B; outline-offset: 2px; }
.bl-team__nav:disabled { opacity: .4; cursor: default; }
/* v7: a track that does not scroll has no navigation. bl-visual.js measures the
   track and sets the class, so the controls return as soon as there is travel
   (a third profile, a narrower viewport, a longer caption). */
.bl-team--static .bl-team__nav { display: none; }

.bl-team__track {
  display: flex;
  gap: 20px;
  margin: 0;
  padding: 4px;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Match the padding so snapping rests at scrollLeft 0 instead of nudging 4px on load. */
  scroll-padding-inline: 4px;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}
.bl-team__track:focus-visible { outline: 3px solid #1B3A5B; outline-offset: 2px; }
.bl-team__card {
  /* (track content width - two 20px gaps) / 3: three whole cards at any
     container width, so nothing is half-cut at the right edge (v5). */
  flex: 0 0 calc((100% - 48px) / 3);
  scroll-snap-align: start;
  min-width: 0;
}
.bl-team__frame {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 5;
  border-radius: 12px;
  background: #E5E5E2;
  overflow: hidden;
}
.bl-team__photo { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 22%; }
.bl-team__card--reservation .bl-team__frame {
  border: 1px dashed var(--bl-line-strong);
  background-image: var(--bl-grid);
}
.bl-team__monogram { width: 44px; height: 44px; opacity: .1; }
.bl-team__name {
  margin: 16px 0 0;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 17.5px;
  line-height: 1.35;
  color: #232A31;
}
.bl-team__role {
  margin: 6px 0 0;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #586069;
}
.bl-team__status {
  margin: 10px 0 0;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #1B3A5B;
}

@media (max-width: 767px) {
  /* v6: one centred control row under the active card instead of a pair pushed
     to the right. Flex rather than grid because two items cannot be centred
     together inside fixed grid columns; the track takes the first line on its
     own and the row gap plus the track's 4px padding is the 24px below the
     caption. */
  .bl-team {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: 14px;
    row-gap: 20px;
  }
  /* The track is the height of the card in view, published by bl-visual.js, so
     a short profile does not carry a reservation's description height as blank
     space. No transition on it: it changes with the slide, not on its own. */
  .bl-team__track {
    order: -1;
    flex: 1 0 100%;
    height: var(--bl-team-view-h, auto);
    overflow-y: hidden;
  }
  /* One substantial card plus a peek of the next. */
  .bl-team__card { flex-basis: min(78vw, 300px); }
  .bl-team__track { gap: 14px; }
}

/* ---------------------------------------------------- selectable details */
/* Three controls over one panel. Without `is-enhanced` every panel is laid out
   normally, so a no-JS visitor and a crawler read all of them. */

.bl-tabs__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 22px;
}
.bl-tabs__btn {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--bl-line-strong);
  border-radius: 22px;
  background: #FAFAF8;
  color: #232A31;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 15.5px;
  cursor: pointer;
  transition: border-color 180ms var(--bl-ease), background-color 180ms var(--bl-ease), color 180ms var(--bl-ease);
}
.bl-tabs__btn:hover { border-color: #1B3A5B; }
.bl-tabs__btn:focus-visible { outline: 3px solid #1B3A5B; outline-offset: 2px; }
.bl-tabs__btn[aria-pressed="true"] { border-color: #1B3A5B; background: #1B3A5B; color: #FAFAF8; }

.bl-diagram--slate .bl-tabs__btn,
.bl-ribbon .bl-tabs__btn {
  border-color: rgba(175,196,221,.4);
  background: rgba(250,250,248,.08);
  color: #FAFAF8;
}
.bl-diagram--slate .bl-tabs__btn[aria-pressed="true"],
.bl-ribbon .bl-tabs__btn[aria-pressed="true"] { border-color: #AFC4DD; background: #AFC4DD; color: #232A31; }
.bl-diagram--slate .bl-tabs__btn:focus-visible,
.bl-ribbon .bl-tabs__btn:focus-visible { outline-color: #AFC4DD; }

.bl-tabs__panels { display: grid; gap: 20px; }
.bl-tabs__panel { min-width: 0; }

/* Enhanced: the panels share one cell and cross-fade in 200ms. visibility is
   what takes the inactive panel out of the reading order; it stays in the DOM
   and in the document source. */
.bl-tabs.is-enhanced .bl-tabs__panels { gap: 0; }
.bl-tabs.is-enhanced .bl-tabs__panel {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 200ms var(--bl-ease), visibility 200ms var(--bl-ease);
}
.bl-tabs.is-enhanced .bl-tabs__panel[data-current] {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .bl-team__track { scroll-behavior: auto; }
  .bl-team__nav,
  .bl-tabs__btn,
  .bl-tabs__panel,
  .bl-ribbon * {
    transition: none !important;
    animation: none !important;
  }
}

/* ==================================================================== V5 */
/* Website pass v5 (12 Sep 2026). Four additions, no new colours:
     1. .bl-film--quiet     a primary frame with no visible title block.
     2. .bl-ribbon          a padded, 16px-cornered flat slate container with
                            the action on the right and optional stage marks.
     3. .bl-track           one compact repeating progress track.
     4. .bl-node--doc/--lg  document and larger-stage node surfaces.
   The decorative grid images were removed in place from .bl-diagram--slate,
   .bl-ribbon and .bl-film--placeholder .bl-film__stage; --bl-grid itself stays
   for the light Map, training and evidence panels that still carry it. */

/* --------------------------------------------------------- quiet film */
/* File 1/2 v5: the primary hero frames carry no visible title or presenter
   block. The text stays in the DOM and in the accessibility tree: clipped, not
   display:none, so the figure keeps its name with JavaScript blocked.
   bl-visual.ts additionally mirrors [data-title] into aria-label. */

.bl-film--quiet .bl-film__titles {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------ ribbon (v5) */
/* A padded container rather than a full-bleed band: 32-40px of padding on
   desktop, 24px on mobile, heading left and one action right, content-driven
   height, 16px corners. */

.bl-ribbon { background-image: none; border-radius: var(--bl-radius-media); }
.bl-ribbon__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 28px 40px;
  padding: clamp(32px, 3vw, 40px);
}
.bl-ribbon__text > :first-child { margin-top: 0; }
.bl-ribbon__text > :last-child { margin-bottom: 0; }
.bl-ribbon__action { margin: 0; }
.bl-ribbon__action a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 16.5px;
  color: #AFC4DD;
}

/* Three small stage marks as an accent, not a second diagram. */
.bl-ribbon__marks {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 20px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}
.bl-ribbon__mark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bl-on-slate);
}
.bl-ribbon__mark::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #AFC4DD;
}
.bl-ribbon__mark + .bl-ribbon__mark::before { background: rgba(175,196,221,.55); }

@media (max-width: 767px) {
  .bl-ribbon__inner { grid-template-columns: minmax(0, 1fr); gap: 22px; padding: 24px; }
}

/* ------------------------------------------------- progress track (v5) */
/* Three stages, all of them readable at all times. The only thing that moves
   is which stage the rail and its marker highlight, switched by the
   data-stage attribute bl-visual.ts sets on the root. Nothing is hidden, so
   the static, paused and reduced-motion states are all complete. */

.bl-track { display: grid; gap: 20px; justify-items: start; }
.bl-track__stages {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 28px;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}
.bl-track__stage { position: relative; padding: 30px 0 0; }
/* The rail segment this stage owns, and its marker. */
.bl-track__stage::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 0;
  right: -28px;
  height: 2px;
  background: var(--bl-line);
  transition: background-color 420ms var(--bl-ease);
}
.bl-track__stage:last-child::before { right: 0; }
.bl-track__stage::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 0;
  width: 12px;
  height: 12px;
  border: 2px solid var(--bl-line-strong);
  border-radius: 50%;
  background: #FAFAF8;
  transition: background-color 420ms var(--bl-ease), border-color 420ms var(--bl-ease);
}
.bl-track__name {
  margin: 0;
  font-family: 'Source Sans 3', system-ui, sans-serif;
  font-weight: 600;
  font-size: 17.5px;
  line-height: 1.35;
  color: #232A31;
}
.bl-track__body { margin: 8px 0 0; max-width: 40ch; font-size: 16px; line-height: 1.6; color: #586069; }

/* The highlight. One selector per stage, driven by the root attribute. */
.bl-track[data-stage="0"] .bl-track__stage:nth-child(1)::before,
.bl-track[data-stage="1"] .bl-track__stage:nth-child(2)::before,
.bl-track[data-stage="2"] .bl-track__stage:nth-child(3)::before { background: #1B3A5B; }
.bl-track[data-stage="0"] .bl-track__stage:nth-child(1)::after,
.bl-track[data-stage="1"] .bl-track__stage:nth-child(2)::after,
.bl-track[data-stage="2"] .bl-track__stage:nth-child(3)::after { border-color: #1B3A5B; background: #1B3A5B; }

.bl-track__toggle {
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--bl-line-strong);
  border-radius: 22px;
  background: #FAFAF8;
  color: #586069;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 180ms var(--bl-ease), color 180ms var(--bl-ease);
}
.bl-track__toggle:hover { border-color: #1B3A5B; color: #232A31; }
.bl-track__toggle:focus-visible { outline: 3px solid #1B3A5B; outline-offset: 2px; }

/* On a slate surface the same component inverts. */
.bl-diagram--slate .bl-track__name,
.bl-ribbon .bl-track__name { color: #FAFAF8; }
.bl-diagram--slate .bl-track__body,
.bl-ribbon .bl-track__body { color: var(--bl-on-slate); }
.bl-diagram--slate .bl-track__stage::before,
.bl-ribbon .bl-track__stage::before { background: rgba(175,196,221,.28); }
.bl-diagram--slate .bl-track__stage::after,
.bl-ribbon .bl-track__stage::after { border-color: rgba(175,196,221,.45); background: var(--bl-deep-slate); }
.bl-diagram--slate .bl-track[data-stage="0"] .bl-track__stage:nth-child(1)::before,
.bl-diagram--slate .bl-track[data-stage="1"] .bl-track__stage:nth-child(2)::before,
.bl-diagram--slate .bl-track[data-stage="2"] .bl-track__stage:nth-child(3)::before,
.bl-ribbon .bl-track[data-stage="0"] .bl-track__stage:nth-child(1)::before,
.bl-ribbon .bl-track[data-stage="1"] .bl-track__stage:nth-child(2)::before,
.bl-ribbon .bl-track[data-stage="2"] .bl-track__stage:nth-child(3)::before { background: #AFC4DD; }
.bl-diagram--slate .bl-track[data-stage="0"] .bl-track__stage:nth-child(1)::after,
.bl-diagram--slate .bl-track[data-stage="1"] .bl-track__stage:nth-child(2)::after,
.bl-diagram--slate .bl-track[data-stage="2"] .bl-track__stage:nth-child(3)::after,
.bl-ribbon .bl-track[data-stage="0"] .bl-track__stage:nth-child(1)::after,
.bl-ribbon .bl-track[data-stage="1"] .bl-track__stage:nth-child(2)::after,
.bl-ribbon .bl-track[data-stage="2"] .bl-track__stage:nth-child(3)::after { border-color: #AFC4DD; background: #AFC4DD; }
.bl-diagram--slate .bl-track__toggle,
.bl-ribbon .bl-track__toggle {
  border-color: rgba(175,196,221,.4);
  background: rgba(250,250,248,.08);
  color: var(--bl-on-slate);
}
.bl-diagram--slate .bl-track__toggle:hover,
.bl-ribbon .bl-track__toggle:hover { border-color: #AFC4DD; color: #FAFAF8; }
.bl-diagram--slate .bl-track__toggle:focus-visible,
.bl-ribbon .bl-track__toggle:focus-visible { outline-color: #AFC4DD; }

/* Stacked: the rail runs down the left instead of across the top. */
@media (max-width: 767px) {
  .bl-track__stages { grid-template-columns: minmax(0, 1fr); gap: 24px 0; }
  .bl-track__stage { padding: 0 0 0 28px; }
  .bl-track__stage::before { top: 6px; bottom: -24px; left: 5px; right: auto; width: 2px; height: auto; }
  .bl-track__stage:last-child::before { bottom: auto; height: 12px; }
  .bl-track__stage::after { top: 3px; left: 0; }
}

/* ---------------------------------------------------- node surfaces (v5) */
/* Document-shaped inputs and a larger main stage. The page owns where a node
   sits; this owns what it looks like. */

.bl-node--doc .bl-node__box { stroke: rgba(35,42,49,.28); }
/* The offset sheet behind a document node, for the SVG form. */
.bl-node__page { fill: #FAFAF8; stroke: rgba(35,42,49,.16); stroke-width: 1; }
.bl-node--lg .bl-node__label { font-size: 16px; font-weight: 600; }

li.bl-node--doc,
div.bl-node--doc {
  border-color: rgba(35,42,49,.28);
  border-radius: 4px;
  /* Two flat offsets read as a short stack of sheets: no blur, no elevation. */
  box-shadow: 4px -4px 0 -1px #FAFAF8, 4px -4px 0 0 rgba(35,42,49,.16);
}
li.bl-node--lg,
div.bl-node--lg { padding: 18px 20px; font-size: 17px; font-weight: 600; }
/* The heavier weight names the stage; a detail list inside it is body text. */
li.bl-node--lg :where(ul, ol, p),
div.bl-node--lg :where(ul, ol, p) { font-size: 16px; font-weight: 400; }

@media (prefers-reduced-motion: reduce) {
  .bl-track__stage::before,
  .bl-track__stage::after,
  .bl-track__toggle { transition: none !important; animation: none !important; }
}

/* ==================================================================
   Service page refresh (24 Sep 2026): the shared pieces every
   refreshed service page uses, switched on by body.bl-refresh.
   Rules: 03_Marketing/Website/website-refresh-rules.md. Motion follows
   Emil Kowalski's standards: strong ease-out, transform and opacity
   only, under 300ms, hover motion only on real pointers, gentler
   under reduced motion.
   ================================================================== */

.bl-refresh { --bl-ease-out: cubic-bezier(0.23, 1, 0.32, 1); --bl-tint: rgba(175, 196, 221, 0.18); }
.bl-refresh main > .fs-section:first-of-type { padding-top: 132px; }
@media (max-width: 760px) { .bl-refresh main > .fs-section:first-of-type { padding-top: 108px; } }

/* Primary button: Charcoal, turns Consulting Blue, arrow, press feedback */
.bl-refresh .fs-cta { display: inline-flex; align-items: center; justify-content: center; gap: 10px; padding: 16px 26px; border-radius: 11px; background: #232A31; color: #FAFAF8; font: 600 16px "Source Sans 3", system-ui, sans-serif; text-decoration: none; box-shadow: 0 14px 30px -16px rgba(35, 42, 49, 0.55); transition: background-color 200ms ease, transform 160ms var(--bl-ease-out), box-shadow 200ms ease; }
.bl-refresh .fs-cta::after { content: '\2192'; transition: transform 200ms var(--bl-ease-out); }
.bl-refresh .fs-cta:hover, .bl-refresh .fs-cta:focus-visible { background: #1B3A5B; color: #FAFAF8; }
.bl-refresh .fs-cta:focus-visible { outline: 2px solid #1B3A5B; outline-offset: 3px; }
.bl-refresh .fs-cta:active { transform: scale(0.97); }

/* Outlined button */
.bl-ghost { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 11px 20px; border: 1.5px solid #232A31; border-radius: 11px; color: #232A31; font: 600 16px "Source Sans 3", system-ui, sans-serif; text-decoration: none; white-space: nowrap; transition: background-color 200ms ease, color 200ms ease, transform 160ms var(--bl-ease-out, ease-out); }
.bl-ghost::after { content: '\2192'; transition: transform 200ms var(--bl-ease-out, ease-out); }
.bl-ghost:hover, .bl-ghost:focus-visible { background: #232A31; color: #FAFAF8; }
.bl-ghost:focus-visible { outline: 2px solid #1B3A5B; outline-offset: 3px; }
.bl-ghost:active { transform: scale(0.97); }

/* The lighter next step, as a text link */
.bl-alt { margin: 16px 0 0; font-size: 16px; line-height: 1.6; color: #586069; }
.bl-alt a { color: #1B3A5B; font-weight: 600; text-decoration: underline; text-decoration-color: #AFC4DD; text-underline-offset: 4px; transition: text-decoration-color 200ms ease; }
.bl-alt a:hover { text-decoration-color: #1B3A5B; }
.bl-alt--centre { text-align: center; margin-top: 18px; }

/* Hero: Light Blue field and halftone dots, as on the homepage and Map page */
.bl-refresh main > .fs-section--hero { position: relative; overflow: hidden; }
.bl-refresh main > .fs-section--hero::before { content: ''; position: absolute; z-index: 0; right: -8vw; top: 4%; width: min(48vw, 660px); aspect-ratio: 1; border-radius: 50%; background: rgba(175, 196, 221, 0.28); pointer-events: none; }
.bl-refresh main > .fs-section--hero::after { content: ''; position: absolute; z-index: 0; right: 2vw; top: 18%; width: min(26vw, 380px); height: min(18vw, 260px); border-radius: 28px; background-image: radial-gradient(#1B3A5B 1.3px, transparent 1.6px); background-size: 16px 16px; opacity: .34; pointer-events: none; }
.bl-refresh main > .fs-section--hero > * { position: relative; z-index: 1; }

/* Icon tiles */
.bl-icon { display: grid; place-items: center; flex: none; width: 48px; height: 48px; border-radius: 14px; background: #1B3A5B; color: #FAFAF8; }
.bl-icon--soft { background: rgba(175, 196, 221, 0.45); color: #1B3A5B; }
.bl-icon--sm { width: 36px; height: 36px; border-radius: 11px; }
.bl-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.bl-icon--sm svg { width: 20px; height: 20px; }

/* A section that should stand apart: a tinted rounded sheet */
.bl-refresh .bl-sheet { background: var(--bl-tint); margin: 0 clamp(8px, 1.4vw, 20px); border-radius: clamp(20px, 3vw, 36px); }

/* Cards that lift with a Consulting Blue rail */
.bl-lift { position: relative; overflow: hidden; border: 1px solid rgba(35, 42, 49, 0.1); border-radius: 18px; background: #FAFAF8; transition: transform 250ms var(--bl-ease-out, ease-out), box-shadow 250ms ease, border-color 250ms ease; }
.bl-lift::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 4px; background: #1B3A5B; transform: scaleX(0); transform-origin: left; transition: transform 250ms var(--bl-ease-out, ease-out); }

/* Questions: soft bordered cards */
.bl-refresh .fs-acc { border-top: 0; }
.bl-refresh .fs-acc__item { border: 1px solid #E5E5E2; border-radius: 14px; background: #FAFAF8; padding: 0 16px; transition: border-color 200ms ease; }
.bl-refresh .fs-acc__item + .fs-acc__item { margin-top: 10px; }
.bl-refresh .fs-acc__item:hover { border-color: #232A31; }

@media (hover: hover) and (pointer: fine) {
  .bl-refresh .fs-cta:hover { transform: translateY(-2px); box-shadow: 0 18px 34px -16px rgba(27, 58, 91, 0.6); }
  .bl-refresh .fs-cta:hover::after, .bl-ghost:hover::after { transform: translateX(4px); }
  .bl-refresh .fs-cta:active { transform: scale(0.97); }
  .bl-lift:hover { transform: translateY(-6px); border-color: rgba(27, 58, 91, 0.2); }
  .bl-lift:hover::before { transform: scaleX(1); }
}
@media (max-width: 760px) {
  .bl-refresh main > .fs-section--hero::before { width: 90vw; right: -40vw; top: auto; bottom: -8%; }
  .bl-refresh main > .fs-section--hero::after { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .bl-refresh .fs-cta, .bl-ghost, .bl-lift, .bl-lift::before { transition: background-color 200ms ease, color 200ms ease, border-color 200ms ease; }
  .bl-refresh .fs-cta:hover, .bl-refresh .fs-cta:active, .bl-ghost:active, .bl-lift:hover { transform: none; }
}

/* Page flipper (25 Sep 2026): round arrows either side of the page count. */
.bl-pager { display: flex; align-items: center; justify-content: center; gap: 14px; }
.bl-pager__btn { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; border: 1.5px solid #232A31; background: #FAFAF8; color: #232A31; cursor: pointer; transition: background-color 200ms ease, color 200ms ease, transform 160ms cubic-bezier(0.23, 1, 0.32, 1); }
.bl-pager__btn svg { width: 16px; height: 16px; }
.bl-pager__btn:hover, .bl-pager__btn:focus-visible { background: #232A31; color: #FAFAF8; }
.bl-pager__btn:focus-visible { outline: 2px solid #1B3A5B; outline-offset: 3px; }
.bl-pager__btn:active { transform: scale(0.94); }
.bl-pager__btn[hidden] { display: none; }
.bl-pager [data-bl-pager-count] { min-width: 8ch; text-align: center; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .bl-pager__btn { transition: background-color 200ms ease, color 200ms ease; } .bl-pager__btn:active { transform: none; } }
