/* ==========================================================================
   bto-about.css — about.html ONLY. Linked immediately after bto-static.css so
   palette.css still lands after it, exactly as on every other static page.

   WHY THIS FILE EXISTS AT ALL
   Round 2 runs three designers concurrently on founder / about / contact.
   bto-static.css, reveals.js and static-panels.js are SHARED and are therefore
   read-only for this job. Everything about.html needs that the shared sheet
   does not already provide lives here, and nothing here is reachable from any
   other page: every selector is scoped `.bto-static` AND keyed to a class or a
   structure that only about.html ships.

   THE THREE CONTRACTS bto-static.css states about itself are held here too:
     · ZERO new colour values — palette tokens only, no hex literal anywhere
     · ZERO !important
     · everything scoped under .bto-static

   Two curves only (design-system §4b): cubic-bezier(.2,.7,.2,1) and ease.
   -3deg is the only rotation, and it is not re-declared here — the slab in
   bto-static.css owns it.
   ========================================================================== */


/* --- 1 · HERO HEADER CLEARANCE, preserved through the panel opt-in --------
   A1 declares itself GROUND A (`.bto-panel.bto-panel--canvas`) so the ground
   rhythm is legible in the markup rather than relying on the body background
   happening to be the same colour.

   That opt-in has one side effect worth undoing precisely. `.bto-panel` sets
   `padding-block: clamp(88px,9.6vh,116px) …` at bto-static.css:224 — LATER in
   the cascade than `.bto-static .page-header-content { padding-top: 104px }`
   at line 31, and at equal specificity, so it wins and the hero loses 16px of
   top clearance at a 900px-tall viewport (9.6vh = 86.4 → clamps to 88).

   That 104px is not a taste value: bto-static.css:25-30 records it as MEASURED
   against the sticky header bar, whose bottom edge is y=80 desktop / y=66 at
   ≤575. These pages put an eyebrow ABOVE the h1, so losing clearance puts the
   smallest line on the page under the bar. Restored at 0-2-1 so it beats
   `.bto-panel` without touching the shared sheet. */
.bto-static .page-header-content.bto-panel { padding-top: 104px; }

@media (max-width: 575px) {
  .bto-static .page-header-content.bto-panel { padding-top: 88px; }
}


/* --- 2 · NO CANVAS STRIP UNDER THE LAST PANEL -----------------------------
   `.bto-static__body { padding: 0 0 8vh }` (bto-static.css:22) was correct
   when every section sat on one continuous canvas. With ground blocking, A10
   is a polar panel and that 8vh becomes a cream band between the last panel
   and the footer — a visible seam that reads as a layout bug.

   Gated on :has(.bto-panel) for the same reason the shared sheet gates its
   overflow guard: the rule must not fire on a page that has not opted into
   grounds. If :has() were unsupported the page simply keeps its old bottom
   padding — the failure direction is a cosmetic gap, never lost content. */
.bto-static .bto-static__body:has(.bto-panel) { padding-bottom: 0; }


/* --- 3 · BIG-STATEMENT TYPE — A9 only ------------------------------------
   design-system §2 "Big statement": 3rem → md 6rem → 2xl 8.5rem, LH 9vw,
   LS -.35vw. A9 is the section that replaces MPH's client-logo wall, so it has
   to carry the same structural weight a wall of logos would have. Type is the
   only thing doing that job — the section ships no imagery by design.

   🔴 LINE-HEIGHT IS APPLIED AT ONE BREAKPOINT ONLY, DELIBERATELY.
   `9vw` is a viewport unit and the font sizes are rem, so the ratio between
   them is not constant — it only resolves sanely where the system pairs them:
     1536px: 8.5rem = 136px vs 9vw = 138.2px  → ratio 1.02  ✓
      768px: 6rem   =  96px vs 9vw =  69.1px  → ratio 0.72  ✗ lines overlap
      390px: 3rem   =  48px vs 9vw =  35.1px  → ratio 0.73  ✗ lines overlap
   Carrying `9vw` down the scale would collide the two lines of this heading
   into each other on every phone. Below 2xl the heading uses the display law's
   own .95 (design-system §2: "line-height .95–1"), which is what the measured
   ratio at 2xl works out to anyway. Same intent, arithmetic that survives.

   Specificity 0-4-0 to clear `.bto-static .bto-panel .content__title`
   (0-3-0) from bto-static.css:346. No !important. */
.bto-static .bto-panel .content__title.bto-bigstate {
  margin: 0;
  max-width: none;
  font-family: Antonio, Archivo, sans-serif;
  font-weight: 700;
  font-size: 3rem;
  line-height: .95;
  letter-spacing: -.02em;
  text-transform: uppercase;
}

@media (min-width: 768px) {
  .bto-static .bto-panel .content__title.bto-bigstate {
    font-size: 6rem;
    line-height: .95;
    letter-spacing: -.03em;
  }
}

@media (min-width: 1536px) {
  .bto-static .bto-panel .content__title.bto-bigstate {
    font-size: 8.5rem;
    line-height: 9vw;
    letter-spacing: -.35vw;
  }
}


/* --- 4 · GHOST BUTTON ON GROUND B ----------------------------------------
   `.p2-cta--ghost` takes `border: 1px solid var(--bg-hairline)` — and the
   hairline token IS polar at .55 alpha (`rgba(204,213,218,.55)`,
   palette.css:24). On `--bg-panel2`, which is polar, that is polar on polar:
   the outline of the secondary button disappears and the CTA pair reads as one
   amber pill and one floating label.

   A10 is the page's close, so the second route ("See what we make") has to be
   visibly a button. `--fg-ink` is a token, it is the same ink the panel's own
   type uses, and a 1px ink hairline on polar is the lightest thing that
   actually draws. Keyed to `.bto-panel--panel` so ghost buttons on canvas and
   on dark are untouched. */
.bto-static .bto-panel--panel .p2-cta--ghost { border-color: var(--fg-ink); }


/* --- 4b · SECTION HEADS ON LIGHT GROUNDS USE THE INK TOKEN ----------------
   MEASURED on the built page, not assumed: every `.content__title` sitting on
   GROUND A or B computes to `rgb(0, 0, 0)` — pure black, the CSS initial
   value, because nothing in the chain declares a colour for it. Only the dark
   panels get one, from `.bto-panel--dark .content__title` (bto-static.css:267).

   Pure black is not in MP071. The palette's ink is #13181B, and the difference
   is small enough to be invisible and large enough to be wrong: it is a colour
   the design system never sanctioned, arriving by omission rather than by
   choice, and it would drift further the moment the theme flips — `--fg-heading`
   follows the theme, `black` does not.

   This is a PRE-EXISTING condition, not something the round-2 rebuild
   introduced; the backup file has the same markup and the same gap. Corrected
   here because this page now declares its grounds, so the pairing is finally
   explicit. Keyed to the two light grounds only, so the dark rule is untouched. */
.bto-static .bto-panel--canvas .content__title,
.bto-static .bto-panel--panel .content__title { color: var(--fg-heading); }


/* --- 5 · TWO-COLUMN PROSE — A3 only --------------------------------------
   design-system §3: "Prose column-count 2 ≥901". `.bto-prose` is capped at
   62ch for single-column measure; split in two that would give ~31ch columns,
   which is too narrow to read. The modifier widens the block so each column
   lands near the 46-64ch the type scale is set for, and only above 901 where
   there is width to spend.

   `break-inside: avoid` on the paragraphs stops a 4-paragraph story splitting
   mid-thought across the gutter. */
@media (min-width: 901px) {
  .bto-static .bto-prose--cols {
    max-width: 108ch;
    column-count: 2;
    column-gap: clamp(28px, 4vw, 64px);
  }
  .bto-static .bto-prose--cols p { break-inside: avoid; }
}


/* --- 6 · REDUCED MOTION ---------------------------------------------------
   Nothing in this file animates: every rule above is type, spacing or a border
   colour. The branch is here because the design system says every motion needs
   one and the honest way to satisfy that is to state that there is no motion
   to branch, not to leave the reader guessing. The shared sheet's reduced
   branch (bto-static.css:553-576) covers every effect about.html actually
   uses. */
@media (prefers-reduced-motion: reduce) {
  /* intentionally empty — see the note above */
}


/* --- 7 · THE JOURNEY RAIL — A3b only -------------------------------------
   Ported from Master Production House's /about "Our Journey" section
   (captured verbatim to _ref/mph-about/, 2026-08-06). Founder: take the
   mechanic, the copy is placeholder.

   WHAT THE EFFECT ACTUALLY IS — there is no JavaScript in it.
   MPH's timeline reads like a scroll animation and is not one. The whole
   thing is `position: sticky` on the year column INSIDE each card: the year
   pins at the top of the viewport while its own card scrolls past, then
   releases when the card ends and the next year takes over. The only data
   attribute in their entire section is `data-nimg`, which is Next.js's image
   tag. No GSAP, no ScrollTrigger, no IntersectionObserver.

   That matters here for one reason: sticky is the single thing ScrollSmoother
   breaks — it transforms #smooth-content, which becomes the containing block
   and kills every descendant sticky. bto-js/no-smoother.js already bans it on
   static pages, so this section is safe BY AN EXISTING RULE, not by luck. If
   that ban is ever lifted, this section dies silently and first.

   THEIR NUMBERS, TRANSLATED OUT OF TAILWIND
     lg:grid-cols-[11rem_1fr] → --tl-year-col
     lg:top-36                → 9rem sticky offset
     left-5 / w-px            → the rail, 1px, gradient-faded at both ends
     shadow-[0_0_0_8px_…12%]  → the dot's ring

   ONE THING DELIBERATELY IMPROVED, not copied. MPH's rail sits at a flat 20px
   while their dot lands at card-padding + 6px, so the two never line up; the
   rail only reads in the 32px gutters between cards and ghosts through the
   78%-opaque card bodies. Here both are driven off --tl-pad, so the dot sits
   ON the rail at every width. Same look, aligned.

   COLOUR: no hex literal, per the file contract. Borders and fills are
   `color-mix` off `currentColor`, so the section re-inks itself from whatever
   ground it is dropped on — it is on GROUND C (dark) today and would still be
   correct on canvas. (Chrome reports color-mix() back as `color(srgb …)` with
   0-1 components; a contrast checker that scrapes digits will misread that as
   near-black and invent failures. The rendering is fine.)

   MOTION: none. `position: sticky` is scroll-linked layout, not animation, so
   §6's reduced-motion branch stays empty and correct. The heading uses the
   shared `.bto-wipe` (M2), which reveals.js already resolves with
   querySelectorAll — safe to add an eighth one. NOT `.bto-scrub`: that class
   is resolved with querySelector and is spent on A9. */

.bto-static .bto-tl {
  --tl-pad: clamp(20px, 2.4vw, 28px);
  --tl-dot: 12px;
  --tl-year-col: 11rem;
  position: relative;
  margin-top: clamp(28px, 4vw, 48px);
}

/* The rail. Fades to nothing at both ends so it reads as a thread rather than
   a border that got loose. Hidden below the desktop switch, where the cards
   collapse to one column and there is nothing to thread. */
.bto-static .bto-tl__rail {
  position: absolute;
  top: 0;
  left: calc(var(--tl-pad) + (var(--tl-dot) / 2));
  width: 1px;
  height: 100%;
  display: none;
  background: linear-gradient(
    to bottom,
    transparent,
    color-mix(in srgb, currentColor 42%, transparent) 12%,
    color-mix(in srgb, currentColor 42%, transparent) 88%,
    transparent
  );
}

.bto-static .bto-tl__list {
  display: grid;
  gap: clamp(18px, 2.2vw, 32px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* position:relative is load-bearing, not habit — it lifts each card into the
   paint order above the absolutely-positioned rail, which is what makes the
   rail read as running BEHIND the cards. */
.bto-static .bto-tl__item {
  position: relative;
  display: grid;
  gap: clamp(14px, 1.6vw, 20px);
  padding: var(--tl-pad);
  border: 1px solid color-mix(in srgb, currentColor 16%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, currentColor 5%, transparent);
}

.bto-static .bto-tl__head { display: grid; }

.bto-static .bto-tl__mark {
  display: flex;
  align-items: center;
  gap: 12px;
}

.bto-static .bto-tl__dot {
  display: none;
  flex: 0 0 auto;
  width: var(--tl-dot);
  height: var(--tl-dot);
  border-radius: 50%;
  border: 1px solid var(--fill-accent);
  background: var(--bg-inset-dark);
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--fill-accent) 12%, transparent);
}

/* THE EXTRA `.bto-tl` IN THIS SELECTOR IS NOT DECORATION — measured, 2026-08-06.
   `.bto-tl__year` and `.bto-tl__kicker` are both <p>, and bto-static.css:269-271
   sets `.bto-static .bto-panel--dark p { color: var(--fg-on-dark-mute) }`. That
   is 0,2,1 against this rule's 0,2,0, so the accent lost and the year rendered
   at #B7B6B5 — probe read `rgb(183,182,181)` where #FFBF65 was intended. Adding
   the parent class makes it 0,3,0, which wins on class count without touching
   the shared sheet, without !important, and without keying to a ground — so it
   still holds if this section is ever moved off dark. The lead paragraph is
   deliberately NOT given the same treatment: muted is what it should be. */
.bto-static .bto-tl .bto-tl__year {
  margin: 0;
  font-family: var(--font-display, inherit);
  font-size: clamp(2rem, 3.4vw, 3rem);
  font-weight: 600;
  line-height: 1;
  color: var(--fill-accent);
}

/* Pills — the year's own tags. Wrap inline on phones, stack under the year
   once the column exists to stack them in. */
.bto-static .bto-tl__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.bto-static .bto-tl__pill {
  border: 1px solid color-mix(in srgb, var(--fill-accent) 25%, transparent);
  background: color-mix(in srgb, var(--fill-accent) 9%, transparent);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fill-accent);
}

.bto-static .bto-tl__body { min-width: 0; }

/* Same 0,3,0 reason as the year above — this is a <p> too. */
.bto-static .bto-tl .bto-tl__kicker {
  margin: 0;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--fill-accent);
}

/* 🔴 `color: inherit` IS THE BUG FIX, NOT A TIDY-UP. Measured 2026-08-06:
   these five <h3> rendered PURE BLACK on the #13181B dark ground — 1.05:1,
   effectively invisible — and the DOM said so while the page still looked
   plausible in a scaled screenshot.

   Mokko's reset carries `h1, h2, h3, h4, h5, h6 { color: var(--color-contrast-higher) }`
   and on these pages that variable resolves to `hsl(0, 0%, 0%)`. It is a real
   declaration, not an undefined-var fallback, so it BEATS inheritance: the
   parent `.bto-tl__body` computes rgb(240,238,235) and the h3 threw it away.
   Every other text node in this section was fine precisely because
   bto-static.css:269-271 names `p` explicitly — nothing named h3.

   `inherit` rather than a token, so the heading follows whatever ground the
   section is dropped on. 0,3,0 against the reset's 0,0,3, so it wins without
   !important and without this file having to know it is on dark today. */
.bto-static .bto-tl .bto-tl__title { color: inherit; }

.bto-static .bto-tl__title { margin: 12px 0 0; }
.bto-static .bto-tl__lead  { margin: 16px 0 0; }

/* Capability chips. */
.bto-static .bto-tl__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}

.bto-static .bto-tl__chip {
  border: 1px solid color-mix(in srgb, currentColor 16%, transparent);
  background: color-mix(in srgb, currentColor 7%, transparent);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: .9rem;
  font-weight: 600;
}

/* Bullets. Two columns only where there is width for two readable measures. */
.bto-static .bto-tl__notes {
  display: grid;
  gap: 12px;
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
  font-size: .95rem;
  line-height: 1.6;
}

.bto-static .bto-tl__notes > li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
}

.bto-static .bto-tl__notes > li::before {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: .55em;
  border-radius: 50%;
  background: var(--fill-accent);
}

/* "Also that year" — the volume line under the milestone roll. Added
   2026-08-09 on founder instruction: the `.bto-tl__notes` list above is the
   year's NAMED wins, and this single line admits everything else that ran
   that year without listing it. That is the whole point of the pairing — the
   card has to read as milestones-plus-volume, not as a portfolio dump.
   Deliberately quieter than a note: no bullet, dimmed, rule-separated, so it
   never competes with a brand name. The hairline is mixed off currentColor
   rather than --fill-accent so it survives all three grounds (canvas, panel,
   dark) without a per-ground override. */
.bto-static .bto-tl__also {
  margin: 22px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid color-mix(in srgb, currentColor 16%, transparent);
  font-size: .88rem;
  line-height: 1.65;
  /* 0.78, not lower. At .66 this measured 4.53:1 on the dark ground (GROUND C,
     rgb(19,24,27)) — technically AA at 14px but visually it read as broken
     rather than deliberately quiet. .78 lands ~5.6:1 and still sits far below
     the notes list beside it, which runs 15:1. Re-measure if this element is
     ever reused on the canvas or panel ground. */
  opacity: .78;
}

/* --- the desktop switch --------------------------------------------------
   992px, matching the header's inline-nav breakpoint rather than this file's
   own 901px prose switch (§5). The year column needs 11rem plus a readable
   body measure beside it; 901 is not enough for both and the body drops under
   ~40ch. Below this line the rail is hidden, the card is one column, and
   nothing sticks. */
@media (min-width: 992px) {
  .bto-static .bto-tl__rail { display: block; }
  .bto-static .bto-tl__dot  { display: block; }

  .bto-static .bto-tl__item {
    grid-template-columns: var(--tl-year-col) 1fr;
    column-gap: clamp(24px, 3vw, 40px);
    padding: clamp(24px, 2.6vw, 28px);
  }

  /* THE EFFECT. align-self:start is not optional — a grid item defaults to
     stretch, which makes the column full-height and leaves sticky nothing to
     travel inside. */
  .bto-static .bto-tl__head {
    position: sticky;
    top: 9rem;
    align-self: start;
  }

  .bto-static .bto-tl__pills { display: grid; justify-items: start; }
}


/* --- 8 · JOURNEY RAIL MODE — one year pinned for the whole section --------
   Founder decision 2026-08-06: §7's per-card sticky holds each year for only
   143-191px (measured), which is too short to read as a hold. This block
   replaces it with a single year column that pins for the ENTIRE section and
   swaps its label as each card passes.

   🔴 EVERY SELECTOR HERE IS GATED ON `.bto-tl--rail`, AND THAT CLASS IS ADDED
   BY SCRIPT (bto-js/journey.js), LAST, AFTER the replacement column is built
   and populated. Delete the script, block it, let it 404 — the class never
   lands, none of these rules match, and the section falls back to §7's
   per-card years, which are already in the markup and already work. There is
   no failure mode where the years are hidden and nothing replaces them. This
   is the reveals.css §0 contract, held.

   The per-card heads are CLIPPED, not `display:none`. Five years are five real
   pieces of content; removing them from the accessibility tree to win a visual
   effect is not a trade this page makes. The clip idiom is the one already in
   sections.css:215-222. The sticky aside carries `aria-hidden` instead — it is
   a duplicate of whichever card is on screen. */

@media (min-width: 992px) {

  .bto-static .bto-tl--rail {
    display: grid;
    grid-template-columns: var(--tl-year-col) 1fr;
    column-gap: clamp(24px, 3vw, 40px);
    align-items: start;
  }

  /* THE EFFECT. One pinned element for the whole section instead of five.
     WAS `position: sticky` — 2026-08-10, ScrollSmoother came on for this page
     (see bto-js/bto-smoother.js) and a transformed #smooth-content kills native
     sticky outright. journey.js now pins this element with ScrollTrigger
     instead (same 9rem offset as this rule used to carry, and as §7's no-JS
     fallback below still does), which is the one pin mechanism that
     coexists with ScrollSmoother. `position: static`
     here is deliberate: ScrollTrigger applies its own `position: fixed`
     inline only for the pinned duration, and the element must be in normal
     flow the rest of the time. */
  .bto-static .bto-tl--rail .bto-tl__aside {
    position: static;
    align-self: start;
  }

  /* The cards give up their own year column and run full width of column 2. */
  .bto-static .bto-tl--rail .bto-tl__item { grid-template-columns: 1fr; }

  /* Clipped, not removed — see the note above.
     🔴 THE `.bto-tl__item` IN THIS SELECTOR IS LOAD-BEARING. journey.js builds
     the sticky column by CLONING a card's `.bto-tl__head`, so the clone carries
     that class too. Without `.bto-tl__item` scoping the clip, this rule matches
     the clone as well and hides the one year the whole mechanic exists to show
     — an empty left column, on every card. Cost a screenshot to find, because a
     clipped element still reports its text and its position: the probe read
     `year: "2024", asideTop: 144` and looked perfectly healthy. Only the
     rendered pixels showed it. Clip the heads INSIDE CARDS, never the clone. */
  .bto-static .bto-tl--rail .bto-tl__item .bto-tl__head {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* The rail now belongs to the year column, not the cards. It is absolutely
     positioned against `.bto-tl` (which §7 already made `relative`), so it
     spans the full section height and the sticky dot rides it like a playhead.
     Same --tl-pad/--tl-dot arithmetic as §7, minus the card padding the aside
     does not have. */
  .bto-static .bto-tl--rail .bto-tl__rail { left: calc(var(--tl-dot) / 2); }

  /* Pills stack under the year in the aside exactly as they did in the card. */
  .bto-static .bto-tl--rail .bto-tl__aside .bto-tl__pills {
    display: grid;
    justify-items: start;
  }

  /* The label swap is instant by design — no crossfade. A fade would have to
     run on every boundary crossing including fast scrolls, where it reads as
     lag rather than polish, and it would need a timer this file does not
     otherwise need. Nothing here animates, so §6's empty reduced-motion branch
     stays correct for this block too. */
}


/* --- 8 · WORK & COLLABORATION SIGNALS — inline timeline logo clusters -----
   ADDED 2026-08-09. Structural pattern borrowed from masterproductionhouse.com
   /about (see _notes/21_mph-services-reference.md — STRUCTURE only, never
   their copy or scope). Small clusters of real collaborator marks sit inside
   the ONE timeline era whose prose already names them — nothing here invents
   a client relationship; every logo placed corresponds to a name already
   written into that entry's `.bto-tl__lead` / `.bto-tl__notes` copy.

   THE LIGHT PLATE IS A DELIBERATE DEPARTURE FROM MPH'S "BARE PNG ON THE PAGE
   BACKGROUND" TREATMENT, AND HERE IS WHY. MPH's reference sits on one flat
   page background throughout. This page alternates FOUR real grounds
   (bto-about-grounds.css), and the sourced logo set is a genuine mix of
   dark-ink marks (e.g. The RBI Museum's black serif wordmark) and light-ink
   marks drawn for dark surfaces (several DJ/event marks ship as white
   artwork, each with a dark-ink "-inverted" twin in
   img/sourced-logos/inverted/ for exactly this situation — that folder is
   THE OTHER HALF of this decision, not an accident of sourcing). Rather than
   hand-picking which of the four grounds each logo can tolerate, every mark
   here sits on the SAME small canvas-token plate: legible on any ground this
   page can put behind it. `--bg-canvas` only — no hex literal, per this
   file's own §0 contract. */
.bto-static .bto-tl__logos { margin: 22px 0 0; }

.bto-static .bto-tl__logos-label {
  margin: 0 0 10px;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: color-mix(in srgb, currentColor 62%, transparent);
}

.bto-static .bto-tl__logos-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bto-static .bto-tl__logos-row li { display: flex; }

/* Shared by both the inline clusters (§8) and the closing wall (§9) — one
   component, one contrast fix, applied everywhere a sourced logo lands. */
.bto-static .bto-logo-plate {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-canvas);
  border-radius: 8px;
  padding: 8px 14px;
  line-height: 0;
}

.bto-static .bto-logo-plate img {
  display: block;
  height: clamp(16px, 1.7vw, 24px);
  width: auto;
  max-width: 108px;
  object-fit: contain;
}


/* --- 9 · CLOSING LOGO WALL — "Client brands and collaborations" -----------
   ADDED 2026-08-09, section A9b. Fills the GROUND D (dark) slot the removed
   A9 panel used to occupy — about-audiences (canvas) on one side, about-close
   (navy) on the other, so the no-adjacent-repeat rhythm bto-about-grounds.css
   describes is unbroken by the insertion. One flowing wall of every sourced
   logo judged a real, confirmed collaborator; no captions, same
   `.bto-logo-plate` component as §8, just a looser wrap. */
.bto-static .bto-logowall__grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 1.6vw, 18px);
  margin: clamp(28px, 3.2vw, 40px) 0 0;
  padding: 0;
  list-style: none;
}

.bto-static .bto-logowall__grid li { display: flex; }

.bto-static .bto-logowall__grid .bto-logo-plate img {
  height: clamp(18px, 2vw, 28px);
  max-width: 128px;
}
