/* BAII Landing Page Styles */

html, body {
  margin: 0;
  padding: 0;
  background: var(--baii-white);
  color: var(--fg1);
  font-family: var(--font-mono);
}

* { box-sizing: border-box; }

a { color: inherit; cursor: pointer; }
button { font-family: inherit; cursor: pointer; }

/* ---------- Form elements ---------- */

/* Every field on the site is placeholder-only by design. A placeholder is not
   an accessible name — Chrome falls back to it, but the fallback disappears the
   instant the user types. Each field therefore carries a real <label>, hidden
   from sight with this class so the visual design is unchanged. position:absolute
   keeps it out of the flex/grid flow of the forms it sits in. */
.vh-label {
  position: absolute !important;
  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;
}

/* ---------- Visible field labels (2026-08-11) ----------
   The four multi-field forms now show their labels instead of hiding them.
   A placeholder is not a label: it disappears the instant someone types, so a
   half-filled form stopped saying which box was which — and on the contact page
   it made the subject <select> look identical to a text input.

   The two newsletter forms KEEP .vh-label. They are a single email box inside a
   pill, sitting under a heading that says The BAII Brief, next to a button that
   says Subscribe. A visible label there would have to live inside the pill's
   flex row, and it would be labelling something already unambiguous.

   Values are not invented: this is the same treatment the "Areas of interest"
   group label already used on the Join form, promoted to every field. */
.field-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg3);
  margin-bottom: 7px;
}

/* "(optional)" rides along in lowercase so it reads as an aside rather than
   part of the field name. Optional is marked rather than required: on the Join
   form seven of eight fields are optional, and saying so makes a long form feel
   like the small ask it actually is. */
.field-label .opt {
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.75;
}

.surface--blue .field-label,
.form-on-blue .field-label {
  color: rgba(255, 255, 255, 0.55);
}

/* A label and its control travel together. Spacing BETWEEN fields is the
   parent form's flex `gap` — do not add margin here: the Join form lays two
   .field-rows side by side in a grid, where an adjacent-sibling margin lands
   on the right-hand column only and drops it 2px below the left. */
.field-row { display: block; }

/* Focus indicator. Every input in app.jsx sets `outline: none` as an inline
   style, which a stylesheet can only beat with !important. 2px of --baii-blue
   on paper (4.9:1 against #fff) and 2px of white on the blue grounds
   (4.9:1 against --baii-blue) — both clear of the 3:1 non-text minimum.
   :focus-visible, so a mouse click does not draw a ring. */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--baii-blue) !important;
  outline-offset: 2px;
}

.surface--blue input:focus-visible,
.surface--blue textarea:focus-visible,
.surface--blue select:focus-visible,
.form-on-blue input:focus-visible,
.form-on-blue textarea:focus-visible,
.form-on-blue select:focus-visible {
  outline: 2px solid #fff !important;
  outline-offset: 2px;
}

/* ---------- Keyboard operability ----------
   Controls that used to be <a role="button" tabIndex={0}> are now real
   <button>s: focus, Enter and Space all come for free instead of being
   hand-rolled. A <button> does not inherit the page font and ships a UA
   background/border/padding, so each converted control resets exactly those
   properties and nothing else — the rendered result is identical to the
   anchor it replaced. */
.btn-reset {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  text-align: inherit;
  text-decoration: none;
  cursor: pointer;
}

/* The site header. A plain flex box so the nav pill keeps its exact box:
   a block wrapper would add an inline line box under the inline-flex pill. */
.site-header {
  display: flex;
  align-items: center;
}

/* Portalled to <body> and placed by useStickyHeader. It is fixed rather than
   sticky because .route-content carries an identity transform (routeIn has
   fill: both) and would otherwise become its containing block, and because
   .surface / .about-hero-stick / .about-hero-scroll are overflow hidden|clip,
   which defeats sticky. See the comment on useStickyHeader in app.jsx.
   z-index sits above the page (.route-content's own stacking context paints at
   0) and below .mobile-nav-overlay (1000), so the mobile menu still covers the
   header. The person panel used to sit between them at 200; it is now an inline
   disclosure with no overlay, so nothing else competes here. */
.site-header--fixed {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 150;
}

/* Reserves the header's exact box in the flow it was lifted out of, so
   .hero-top-bar and .subpage-nav-wrap keep their space-between layout.
   Width/height are written by useStickyHeader. */
.site-header-slot {
  flex-shrink: 0;
  pointer-events: none;
}

/* The pill and the hamburger are already opaque white with a graphite border,
   so they stay legible the moment they cross onto text — the only thing added
   once the header leaves its resting place is the site's existing lift. */
.site-header--fixed[data-stuck="true"] .nav-pill,
.site-header--fixed[data-stuck="true"] .hamburger-btn {
  box-shadow: var(--shadow-2);
}
.site-header--fixed .nav-pill,
.site-header--fixed .hamburger-btn {
  transition: box-shadow var(--dur-base) var(--ease-standard);
}
@media (prefers-reduced-motion: reduce) {
  .site-header--fixed .nav-pill,
  .site-header--fixed .hamburger-btn { transition: none; }
}

/* Holds the portalled header. Zero-size: its only child is position:fixed. */
.site-header-host {
  display: contents;
}

/* In-page jump targets. Without this every scrollIntoView on #publications,
   #services-section, #courses and #sign-section lands its heading underneath
   the header, measured 6px under it. --site-header-clear is written by
   useStickyHeader and is the header's stuck bottom edge plus 24px.

   None of these ids may match a route name in PUBLIC_ROUTES: id="services"
   used to, and the route hash then fired a native fragment jump that opened
   the Services page at scrollY 1469. */
#publications,
#areas,
#contact,
#services-section,
#courses,
#adoption,
#sign-section,
[id^="letter-"] {
  scroll-margin-top: var(--site-header-clear, 96px);
}

/* Skip to content. Off-screen until it takes focus, then it lands in the
   top-left corner in the site's own mono type. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  z-index: 2000;
}
.skip-link:focus {
  position: fixed;
  left: 16px;
  top: 16px;
  width: auto;
  height: auto;
  overflow: visible;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 12px 22px;
  border-radius: 999px;
  background: var(--baii-blue);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  outline: 2px solid #fff;
  outline-offset: -4px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

/* Footer links sit on --baii-blue, where the UA focus ring is close to
   invisible. */
.footer-link:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
  border-radius: 2px;
}

/* Both footer rows set their resting colour inline, at two different alphas, so
   the hover has to be a colour the inline style cannot already be — plain white
   reads as "lit" from either tier. */
.footer-link {
  transition: color 160ms ease;
}
.footer-link:hover {
  color: #fff !important;
}

input::placeholder,
textarea::placeholder {
  color: var(--fg3);
  opacity: 1;
}

.surface--blue input::placeholder,
.surface--blue textarea::placeholder,
.surface--blue select,
.form-on-blue input::placeholder,
.form-on-blue textarea::placeholder {
  color: rgba(255,255,255,0.45);
  opacity: 1;
}

.form-on-blue select {
  color: rgba(255,255,255,0.85);
}

select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23666' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 40px !important;
}

.form-on-blue select {
  background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23ffffff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' opacity='0.6'/%3E%3C/svg%3E");
}

select option {
  background: #fff;
  color: var(--fg1);
}

/* ---------- Layout ---------- */
.page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 24px 24px 64px;
}

.page-bg {
  background-color: #F0F2F7;
  min-height: 100vh;
}

/* ---------- Surface cards ---------- */
.surface {
  background: var(--baii-white);
  border: 1px solid var(--baii-bone);
  border-radius: 8px;
  margin: 0 0 24px;
  position: relative;
  box-shadow: var(--shadow-1);
}
.surface--emphasis {
  border-color: var(--baii-graphite);
}
.surface--blue {
  background: var(--baii-hero-gradient);
  color: #fff;
  border-color: var(--baii-blue-deep);
}
.surface__inner {
  padding: 56px 56px;
}

/* ---------- Nav pill ---------- */
.nav-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  background: var(--baii-white);
  border: 1px solid var(--baii-graphite);
  border-radius: 999px;
}
.nav-pill__item {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 400;
  color: var(--fg1);
  padding: 8px 18px;
  border-radius: 999px;
  text-decoration: none;
  transition: background var(--dur-base) var(--ease-standard), color var(--dur-base) var(--ease-standard);
  /* These six lines exist because every nav item is now a real <button>. */
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  margin: 0;
  line-height: normal;
  text-align: inherit;
  cursor: pointer;
}
.nav-pill__item:hover { background: var(--baii-paper); }
.nav-pill__item.is-active {
  background: var(--baii-paper);
  color: var(--fg1);
}
.nav-pill__item.is-active:hover { background: var(--baii-bone); }
.nav-pill__cta {
  background: var(--baii-blue);
  color: #fff;
}
.nav-pill__cta:hover { background: var(--baii-blue-deep); color: #fff; }

/* ---------- Nav dropdown ----------
   Same values the panel used as inline styles before; only the trigger and the
   items changed element, from href-less <a>s to real <button>s. */
.nav-dropdown {
  position: relative;
}
.nav-dropdown__trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  user-select: none;
}
.nav-dropdown__panel {
  position: absolute;
  top: calc(100% + 5px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  animation: navDropdownIn 180ms var(--ease-out) both;
}
@keyframes navDropdownIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .nav-dropdown__panel { animation: none; }
}
.nav-dropdown__bridge {
  position: absolute;
  top: -6px;
  left: 50%;
  transform: translateX(-50%);
  width: calc(100% - 16px);
  height: 8px;
  background: var(--baii-white);
  z-index: 1;
}
.nav-dropdown__menu {
  background: var(--baii-white);
  border: 1px solid var(--baii-graphite);
  border-top: none;
  border-radius: 0 0 16px 16px;
  padding: 4px 6px 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-dropdown__item {
  display: block;
  width: 100%;
  margin: 0;
  padding: 8px 18px;
  border: 0;
  border-radius: 10px;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 400;
  line-height: normal;
  color: var(--fg1);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-standard), color var(--dur-base) var(--ease-standard);
}
.nav-dropdown__item:hover { background: var(--baii-paper); }
.nav-dropdown__item.is-active {
  color: var(--baii-blue);
  background: var(--baii-paper);
}
/* same ring the mobile menu items use */
.nav-dropdown__item:focus-visible {
  outline: 2px solid var(--baii-blue);
  outline-offset: -2px;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 500;
  padding: 13px 22px;
  border-radius: 20px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all var(--dur-base) var(--ease-standard);
  text-decoration: none;
  line-height: 1;
  /* .btn is applied to both <a> and <button>; the modifiers below set the
     real background, so this only clears the UA button chrome. */
  appearance: none;
  -webkit-appearance: none;
  background: none;
  margin: 0;
}
.btn--primary {
  background: var(--baii-blue);
  color: #fff;
  border-color: var(--baii-blue);
}
.btn--primary:hover { background: var(--baii-blue-deep); border-color: var(--baii-blue-deep); }
.btn--hollow {
  background: #fff;
  color: var(--fg1);
  border-color: var(--baii-graphite);
}
.btn--hollow:hover { background: var(--baii-blue); color: #fff; border-color: var(--baii-blue); }
.btn--on-blue {
  background: rgba(255,255,255,0.1);
  color: #fff;
  border-color: rgba(255,255,255,0.4);
}
.btn--on-blue:hover { background: rgba(255,255,255,0.18); }
.btn--sm { padding: 9px 16px; font-size: 13px; }

/* ---------- Typography helpers ---------- */
.display-xl {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(48px, 6.5vw, 88px);
  line-height: 0.96;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}
.display-lg {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 4vw, 56px);
  line-height: 1.04;
  letter-spacing: -0.018em;
  margin: 0;
  text-wrap: balance;
}
.display-md {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 2.6vw, 40px);
  line-height: 1.08;
  letter-spacing: -0.012em;
  margin: 0;
  text-wrap: balance;
}
.body-mono {
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1.65;
  color: var(--fg1);
  margin: 0;
}
.section-index {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg3);
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.section-index__num {
  color: var(--baii-blue);
}
.section-index__rule {
  display: inline-block;
  width: 18px;
  height: 1px;
  background: var(--baii-ash);
}
.caption {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg3);
}

/* ---------- Scroll Reveal Animations ---------- */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 800ms cubic-bezier(0.25, 0.1, 0.25, 1), transform 800ms cubic-bezier(0.25, 0.1, 0.25, 1);
}
.reveal--left {
  transform: translateX(-14px);
}
.reveal--right {
  transform: translateX(14px);
}
.reveal--visible {
  opacity: 1;
  transform: translateY(0) translateX(0);
}

/* ---------- Hero Load Animation ---------- */
.hero-title {
  opacity: 0;
  transform: translateY(10px);
  animation: heroFadeUp 450ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
}
.hero-subtitle {
  opacity: 0;
  transform: translateY(8px);
  animation: heroFadeUp 400ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
}
.hero-ctas {
  opacity: 0;
  transform: translateY(8px);
  animation: heroFadeUp 400ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
}
@keyframes heroFadeUp {
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Brain entrance (smooth fade in) ----------
   Driven by .is-in, which HeroCard adds once that side's image has DECODED —
   not by an animation-delay. A timer here cannot know when a hero illustration
   has arrived, so it used to fade an empty box to full opacity and let the
   picture snap in afterwards.

   Only the two STATES live here. The transition itself is declared inline in
   HeroCard alongside the parallax transform, because that inline `transition`
   shorthand would otherwise override anything set here — see the note there.
   Under reduced motion the element simply starts at opacity 1, so there is no
   change for a transition to animate and none needs suppressing. */
.hero-brain-left,
.hero-brain-right { opacity: 0; }
.hero-brain-left.is-in,
.hero-brain-right.is-in { opacity: 1; }

/* ---------- Float Bob (brain illustrations) ---------- */
.hero-float {
  animation: floatBob 7s ease-in-out infinite;
}
.hero-float--delay {
  animation-delay: -3.5s;
}
@keyframes floatBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(6px); }
}

/* ---------- Scroll indicator pulse ---------- */
.scroll-indicator {
  animation: scrollPulse 2s ease-in-out infinite;
}
@keyframes scrollPulse {
  0%, 100% { opacity: 0.6; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(4px); }
}

/* ---------- Section index rule draw ---------- */
.section-index__rule {
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 400ms ease-out;
}
.reveal--visible .section-index__rule,
.hero-loaded .section-index__rule {
  transform: scaleX(1);
}

/* ---------- Typewriter cursor blink ---------- */
@keyframes blink {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 0; }
}

/* ---------- Route transition ---------- */
.route-content {
  animation: routeIn 360ms cubic-bezier(0.25, 0.1, 0.25, 1) both;
}
@keyframes routeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Footer entrance ---------- */
.footer-logo {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 700ms cubic-bezier(0.25, 0.1, 0.25, 1), transform 700ms cubic-bezier(0.25, 0.1, 0.25, 1);
}
.footer-logo--visible {
  opacity: 1;
  transform: translateY(0);
}
.footer-tagline {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 700ms cubic-bezier(0.25, 0.1, 0.25, 1) 150ms, transform 700ms cubic-bezier(0.25, 0.1, 0.25, 1) 150ms;
}
.footer-tagline--visible {
  opacity: 1;
  transform: translateY(0);
}

/* ============================================================
   Audience closing line  ("Who we work with", under the three cards)
   ============================================================
   The three cards segment by SITUATION — before deploying, after deploying,
   building it. This closes on ROLE, because a reader who recognised their
   situation may still assume the engagement is somebody else's to start.

   It was a bordered box with a heading and the roles set as separate mono
   chips, which made it read as a fourth card arguing with the three above.
   The roles now live inside the sentence, so there is nothing here but one
   line of type and the button. */
.audience-close {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  flex-wrap: wrap;
  padding-top: 30px;
}
.audience-close__line {
  font-family: var(--font-mono);
  font-size: 15px;
  line-height: 1.65;
  color: var(--fg1);
  margin: 0;
  max-width: 64ch;
  text-wrap: pretty;
}

@media (max-width: 768px) {
  .audience-close { padding-top: 26px; flex-direction: column; align-items: stretch; gap: 20px; }
  .audience-close__cta { width: 100%; justify-content: center; }
}

/* ============================================================
   Hamburger button
   ============================================================ */
.hamburger-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--baii-graphite);
  border-radius: 999px;
  background: var(--baii-white);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  position: relative;
  z-index: 1001;
}
.hamburger-btn span {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--fg1);
  border-radius: 1px;
  transition: transform 250ms ease, opacity 250ms ease;
  position: absolute;
}
.hamburger-btn span:nth-child(1) { transform: translateY(-5px); }
.hamburger-btn span:nth-child(2) { transform: translateY(0); }
.hamburger-btn span:nth-child(3) { transform: translateY(5px); }
.hamburger-btn.is-open span:nth-child(1) { transform: rotate(45deg); }
.hamburger-btn.is-open span:nth-child(2) { opacity: 0; }
.hamburger-btn.is-open span:nth-child(3) { transform: rotate(-45deg); }

/* ============================================================
   Mobile nav overlay
   ============================================================ */
.mobile-nav-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--baii-white);
  z-index: 1000;
  flex-direction: column;
  padding: 80px 32px 32px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  animation: mobileNavFadeIn 250ms ease forwards;
}
/* Deliberately opacity-only. `forwards` leaves the end state applied forever, so
   a translateY(0) here would give the overlay a permanent identity transform —
   which makes it the containing block for its own position:fixed children (the
   close X) and re-creates the exact trap that broke this overlay in the first
   place. The 12px entrance slide is not worth another one. */
@keyframes mobileNavFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
/* The items are real <button>s (href-less <a>s were unfocusable). These
   declarations only undo the UA button styling — the resting look is unchanged. */
.mobile-nav-overlay .mobile-nav-item {
  display: block;
  width: 100%;
  margin: 0;
  text-align: left;
  background: none;
  border: 0;
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--fg1);
  text-decoration: none;
  padding: 16px 0;
  border-bottom: 1px solid var(--baii-bone);
  cursor: pointer;
  transition: color 150ms ease;
}
.mobile-nav-overlay .mobile-nav-item:last-child {
  border-bottom: none;
}
.mobile-nav-overlay .mobile-nav-item:focus-visible,
.mobile-nav-overlay .mobile-nav-cta:focus-visible,
.mobile-nav-overlay .mobile-nav-close:focus-visible {
  outline: 2px solid var(--baii-blue);
  outline-offset: 3px;
}
/* Sits exactly over the in-nav hamburger, which is inside .route-content's
   stacking context and therefore paints under the portalled overlay. Placed by
   measurement in JS; these are only the fallbacks. */
.mobile-nav-overlay .mobile-nav-close {
  position: fixed;
  top: 25px;
  right: 25px;
  z-index: 1002;
}
.mobile-nav-overlay .mobile-nav-item.is-active {
  color: var(--baii-blue);
}
.mobile-nav-overlay .mobile-nav-section {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg3);
  padding: 24px 0 8px;
}
.mobile-nav-overlay .mobile-nav-sub-item {
  display: block;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 400;
  color: var(--fg2);
  text-decoration: none;
  padding: 12px 0 12px 16px;
  border-bottom: 1px solid var(--baii-bone);
  cursor: pointer;
  transition: color 150ms ease;
}
.mobile-nav-overlay .mobile-nav-sub-item.is-active {
  color: var(--baii-blue);
}
.mobile-nav-overlay .mobile-nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  margin: 24px 0 0;
  padding: 14px 28px;
  background: var(--baii-blue);
  color: #fff;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}


/* ============================================================
   RESPONSIVE - Tablet (max-width: 768px)
   ============================================================ */
/* Mid-width band: brains are fixed 620px wide, so between 769px and 1199px
   they crowd the hero text channel — pull them further offscreen. */
@media (min-width: 769px) and (max-width: 1199px) {
  .hero-brain-left { left: -400px !important; }
  .hero-brain-right { right: -400px !important; }
}

@media (max-width: 768px) {
  .page { padding: 12px 12px 40px; }
  .surface__inner { padding: 32px 24px; }

  .display-xl { font-size: clamp(38px, 9vw, 52px); line-height: 1.0; }
  .display-hero { font-size: clamp(52px, 14vw, 72px) !important; line-height: 0.95 !important; }
  .display-lg { font-size: clamp(30px, 7vw, 42px); line-height: 1.06; }
  .display-md { font-size: clamp(24px, 5vw, 34px); }
  .body-mono { font-size: 14px; }
  /* .section-index keeps its 11px base on mobile — it used to shrink to 10px,
     which made the eyebrow labels smaller on phones than on desktop. */

  /* Remove maxWidth on headings — let them breathe on mobile */
  .display-xl, .display-lg, .display-md { max-width: none !important; }
  .body-mono { max-width: none !important; }

  /* Mission: show mobile image under title, hide desktop illustrations column */
  .mission-illustrations { display: none !important; }
  .mission-mobile-img { display: block !important; }

  /* Network/People: show mobile globe under title, hide desktop globe column */
  .network-globe-col { display: none !important; }
  .network-mobile-img { display: block !important; }

  /* Research: stack to single column, hide paper column, show inline image */
  .research-grid-mobile { display: flex !important; flex-direction: column !important; gap: 32px !important; }
  .research-paper-visual { display: none !important; }
  .research-mobile-img { display: block !important; }

  /* Institutions: wrap into 2 rows */
  .institutions-row {
    display: grid !important;
    grid-template-columns: repeat(5, 1fr) !important;
    gap: 16px 12px !important;
    justify-items: center !important;
  }
  .institutions-row img { height: 20px !important; }

  /* Four Ways: full card clickable */
  .fourways-card { cursor: pointer; }

  /* Research hero: collapse constellation column, reduce min-height */
  .research-hero-grid { min-height: auto !important; }
  .research-constellation-wrap { display: none !important; }

  /* Research publications: hide desktop paper column, show inline mobile image */
  .publications-paper-col { display: none !important; }
  .publications-mobile-img { display: block !important; }

  /* Research + landing publication cards: remove tall aspect ratio */
  .publication-grid article { aspect-ratio: auto !important; min-height: 200px; }

  /* About principle cards: constrain height on mobile but keep flip mechanism working */
  .principle-card { min-height: 420px !important; aspect-ratio: 1 / 1.3 !important; }

  /* About mission quote: reduce nested padding and text size on mobile */
  .mission-quote-card { padding: 28px 20px !important; }
  .mission-quote-card p { font-size: 20px !important; line-height: 1.4 !important; }

  /* Mobile-only images: show on mobile, hidden by default */
  .research-hero-mobile-img { display: block !important; }

  /* Newsletter subscribe form: stack vertically on mobile */
  .brief-subscribe-form { flex-direction: column !important; border-radius: 12px !important; }
  .brief-subscribe-form .btn { border-radius: 999px !important; width: 100% !important; justify-content: center; }

  /* Desktop nav hidden, hamburger shown */
  .nav-pill { display: none; }
  .hamburger-btn { display: flex !important; }
  .mobile-nav-overlay.is-open { display: flex !important; }

  /* Hero */
  .hero-brain-left, .hero-brain-right { display: none !important; }
  .hero-inner { padding: 24px 24px 36px !important; }
  .hero-top-bar { margin-bottom: 24px !important; }
  .hero-center { padding-top: 48px !important; }
  .scroll-indicator-wrap { padding-top: 36px !important; padding-bottom: 12px !important; }

  /* About hero tension split → stacked on mobile */
  .about-hero-split { flex-direction: column !important; min-height: auto !important; gap: 40px !important; align-items: center !important; }
  .about-hero-half { padding: 0 !important; transform: none !important; text-align: center !important; }
  .about-hero-half .about-hero-bigtype { font-size: clamp(36px, 10vw, 56px) !important; }
  .about-hero-bust { display: none !important; }
  .about-hero-preamble { font-size: clamp(24px, 5vw, 36px) !important; margin-bottom: 48px !important; }
  .about-hero-inner { padding: 24px 24px 48px !important; }
  .about-hero-content { padding-top: 48px !important; padding-bottom: 32px !important; }

  /* Four Ways cards - less min height on mobile */
  .grid-4col article { min-height: auto !important; }

  /* Sub-page hero inner padding */
  .subpage-hero-pad { padding: 24px 24px 48px !important; }

  /* SubPageNav */
  .subpage-nav-wrap { padding: 24px 24px 0 !important; }

  /* Grid overrides */
  .grid-2col { grid-template-columns: 1fr !important; gap: 32px !important; }
  .grid-3col { grid-template-columns: 1fr !important; gap: 16px !important; }
  .grid-4col { grid-template-columns: repeat(2, 1fr) !important; gap: 0 !important; }
  .grid-4col > * { border-left: none !important; }
  .grid-4col > *:nth-child(odd) { border-right: 1px solid var(--baii-bone) !important; }
  .grid-4col > *:nth-child(even) { border-right: none !important; }

  /* Work areas bottom: stack to single column on mobile */
  .grid-work-areas-bottom .grid-2col-areas { grid-template-columns: 1fr !important; }

  /* Mission / Research illustrations */
  .mission-illustrations { display: none !important; }
  .research-constellation-wrap { display: none !important; }

  /* Footer */
  .footer-main { flex-direction: column !important; align-items: flex-start !important; gap: 24px !important; }
  .footer-main .footer-tagline-text { text-align: left !important; }
  /* .footer-main stacks here, so its main axis is vertical — the equal-column
     flex:1 that centres the tagline on desktop would stretch these two
     vertically instead. Neutralised. */
  .footer-brand,
  .footer-cta { flex: 0 0 auto !important; justify-content: flex-start !important; }
  .footer-nav,
  .footer-bottom { flex-direction: column !important; gap: 16px !important; align-items: flex-start !important; }
  /* The engagement row is centred on DESKTOP only. Centring it here too was
     tried and reverted: the five links wrap to two lines on a phone, and a
     centred second line leaves "Contact" stranded mid-air looking like a
     mistake. Left-aligned, the same wrap reads as an ordinary list.
     `!important` is required — the centring is an inline style on the element,
     which a plain stylesheet rule cannot beat. */
  .footer-nav { margin-bottom: 24px !important; }
  .footer-nav .footer-links { justify-content: flex-start !important; }
  /* .footer-main stacks, so the CTA group is on its own line and can keep
     LinkedIn beside the button; it only needs to wrap on the narrowest phones. */
  .footer-cta { flex-wrap: wrap !important; gap: 20px !important; }
  .footer-links { flex-wrap: wrap !important; gap: 0 16px !important; font-size: 11px !important; }
  .footer-pad { padding: 32px 24px 24px !important; }

  /* Blog */
  .blog-featured-grid { grid-template-columns: 1fr !important; }
  .blog-featured-image { min-height: 200px !important; }
  .blog-filter-bar { flex-direction: column !important; align-items: flex-start !important; gap: 16px !important; }
  .blog-filter-buttons { flex-wrap: wrap !important; }

  /* Events */
  .event-row-grid { grid-template-columns: 1fr !important; gap: 16px !important; }
  .event-date-block { display: flex !important; gap: 12px !important; align-items: center !important; text-align: left !important; }
  .event-cta-cell { justify-self: start !important; }
  .grid-past-events { grid-template-columns: repeat(2, 1fr) !important; gap: 16px !important; }
  /* .event-highlight / .next-event-banner are handled in the mobile-pass
     block below — .event-highlight is a grid, not a flex row. */

  /* Podcast */
  .podcast-row { grid-template-columns: 48px 1fr auto !important; gap: 12px !important; padding: 14px 16px !important; }
  .podcast-play-col { display: none !important; }

  /* Signatory grid */
  .signatory-grid { grid-template-columns: repeat(2, 1fr) !important; }

  /* Newsletter */
  .grid-newsletter-sections { grid-template-columns: repeat(2, 1fr) !important; gap: 24px !important; }
  .newsletter-archive-row { grid-template-columns: 40px 1fr auto !important; gap: 12px !important; }
  .newsletter-archive-date { display: none !important; }

  /* Contact */
  .contact-blue-grid { grid-template-columns: 1fr !important; }
  /* Six intent cards two-up is already tight at 1440; on a phone the hint
     line wraps to three and the pair stops scanning as a pair. */
  .contact-intent-grid { grid-template-columns: 1fr !important; }

  /* Credentials */
  .credentials-grid { grid-template-columns: 1fr !important; }
  .credentials-grid > * { padding: 16px 0 !important; border-left: none !important; border-bottom: 1px solid var(--baii-bone); }
  .credentials-grid > *:last-child { border-bottom: none; }

  /* Training */
  .training-course-grid { grid-template-columns: 1fr !important; }
  .training-creds-grid { grid-template-columns: 1fr !important; }
  .adoption-grid { grid-template-columns: 1fr !important; }
  .adoption-grid > article { border-left: none !important; border-right: none !important; border-bottom: 1px solid var(--baii-bone); }

  /* Fellowship / Join */
  .fellowship-grid { grid-template-columns: 1fr !important; gap: 24px !important; }
  .fellowship-grid > * { border-left: none !important; padding: 0 !important; padding-bottom: 24px !important; border-bottom: 1px solid var(--baii-bone); }
  .fellowship-grid > *:last-child { border-bottom: none; padding-bottom: 0 !important; }
  .profiles-grid { grid-template-columns: 1fr !important; }
  .join-form-row { grid-template-columns: 1fr !important; }

  /* Open letter */
  .open-letter-actions { flex-direction: column !important; gap: 12px !important; }

  /* Institutions */
  .institutions-row { flex-wrap: wrap !important; gap: 16px !important; justify-content: flex-start !important; }

  /* Community links */
  .community-links-grid { grid-template-columns: 1fr !important; gap: 24px !important; }
  .community-links-grid > * { border-left: none !important; padding: 0 !important; padding-bottom: 24px !important; border-bottom: 1px solid var(--baii-bone); }
  .community-links-grid > *:last-child { border-bottom: none; padding-bottom: 0 !important; }

  /* Publication / Service */
  .publication-grid { grid-template-columns: 1fr !important; gap: 16px !important; }
  .publication-grid article { aspect-ratio: auto !important; min-height: 200px; }
  .service-grid { grid-template-columns: 1fr !important; }
  .service-grid article { aspect-ratio: auto !important; min-height: auto !important; padding-bottom: 24px !important; }

  /* Audience cards */
  .audience-grid { grid-template-columns: 1fr !important; border-top: none !important; border-bottom: none !important; }
  .audience-grid > article { border-left: none !important; border-right: none !important; border-bottom: 1px solid var(--baii-bone) !important; min-height: auto !important; }

  /* Glossary */
  /* .glossary-alphabet is laid out in the mobile-pass block below. */
  .glossary-search-filter { flex-direction: column !important; gap: 12px !important; }
  .glossary-search-filter input { max-width: 100% !important; flex: 1 1 100% !important; }

  /* Buttons: stack vertically, equal width on mobile */
  .btn-group-mobile {
    flex-direction: column !important;
    gap: 10px !important;
  }
  .btn-group-mobile .btn {
    width: 100% !important;
    justify-content: center !important;
    text-align: center !important;
  }

  /* Buttons - touch targets */
  .btn { min-height: 44px; }
  .btn--sm { min-height: 44px; }

  /* Work areas: flatten into single column with clean borders on every cell */
  .grid-work-areas-top,
  .grid-work-areas-bottom {
    border: none !important;
    max-width: 100% !important;
  }
  .grid-work-areas-top .grid-3col,
  .grid-work-areas-bottom .grid-2col-areas {
    gap: 0 !important;
  }
  .work-area-cell {
    border: 1px solid var(--baii-bone) !important;
    border-top: none !important;
  }
  .grid-work-areas-top .grid-3col > .work-area-cell:first-child {
    border-top: 1px solid var(--baii-bone) !important;
  }

  /* About hero: left-align text, full-bleed right-centered background image */
  .about-hero-bridge-img {
    display: block !important;
  }
  .about-hero-content {
    align-items: flex-start !important;
  }
  .about-hero-preamble {
    text-align: left !important;
  }
  .about-hero-split {
    align-items: stretch !important;
    gap: 16px !important;
  }
  .about-hero-half {
    text-align: left !important;
    background: rgba(255, 255, 255, 0.7) !important;
    backdrop-filter: blur(8px) !important;
    -webkit-backdrop-filter: blur(8px) !important;
    border: 1px solid var(--baii-bone) !important;
    border-radius: 8px !important;
    padding: 28px 24px !important;
  }

  /* ============================================================
     Mobile pass — PRD baii-launch-6 (2026-07-30)
     Measured at 390 / 430 / 768. Each rule below fixes a defect
     that was reproduced and measured, not a stylistic preference.
     ============================================================ */

  /* Glossary A–Z was one 26-button flex row that could not shrink below
     ~489px, so #glossary was the one route with horizontal overflow
     (scrollWidth 489 vs clientWidth 390). Wrap it into a keypad; the
     44px cells also fix the 16–24px wide tap targets. */
  .glossary-alphabet {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(44px, 1fr)) !important;
    gap: 2px !important;
  }
  .glossary-alphabet button {
    width: 100% !important;
    height: 44px !important;
  }

  /* ScrollReveal wraps every grid cell in <div class="reveal">, so the
     `.audience-grid > article` / `.grid-4col > *` resets further up never
     matched their target: cards kept their desktop side borders (stray
     vertical hairlines in a one-column layout) and their 360px min-height
     (~110px of dead space per card). Reset the article itself and hang the
     row separator off the wrapper. */
  .grid-4col article,
  .audience-grid article,
  .adoption-grid article {
    border-left: none !important;
    border-right: none !important;
    min-height: auto !important;
  }
  .audience-grid > *,
  .adoption-grid > * { border-bottom: 1px solid var(--baii-bone); }
  .audience-grid > *:last-child,
  .adoption-grid > *:last-child { border-bottom: none; }

  /* .event-highlight is display:grid, so the flex-direction rule above was
     inert and the copy column stayed at 147px (18 characters per line). */
  .event-highlight { grid-template-columns: 1fr !important; }
  .event-highlight > div:last-child { padding: 28px 24px !important; }
  .next-event-banner { min-height: 200px !important; }

  /* Pill labels were wrapping to two lines inside the button ("Sign the /
     letter", "Registration coming / soon"). */
  .btn { white-space: nowrap; }

  /* Filter pills measured 24px (glossary) and 28px (insights) tall. */
  .glossary-search-filter button,
  .blog-filter-buttons button { min-height: 44px !important; }
  .blog-filter-buttons { flex-wrap: wrap !important; }

  /* Footer links measured 13px tall. (The six route links are now <button>,
     so the selector has to name buttons or they drop back to 14px.) */
  .footer-links a,
  .footer-links button,
  .footer-links [role="button"] {
    display: inline-flex !important;
    align-items: center;
    min-height: 44px;
  }

  /* Join "areas of interest" checkbox pills measured 36px tall. */
  .form-on-blue label { min-height: 44px !important; }

  /* Standalone (non-prose) links that were 14–17px tall. */
  .tap-link {
    display: inline-flex !important;
    align-items: center;
    min-height: 44px;
  }

  /* Text fields and selects measured 38–43px tall. */
  input:not([type="checkbox"]):not([type="radio"]),
  select,
  textarea { min-height: 44px; }

  /* Newsletter hero: the email input keeps min-width:auto, so the flex row
     could not shrink and the Subscribe button rendered 91px outside the
     pill (right edge 416 against a 390px viewport) where the section's
     overflow:hidden clipped it. */
  .hero-ctas input { min-width: 0 !important; padding-left: 10px !important; padding-right: 10px !important; }
}


/* ============================================================
   RESPONSIVE - Phone (max-width: 480px)
   ============================================================ */
@media (max-width: 480px) {
  .page { padding: 8px 8px 32px; }
  .surface__inner { padding: 24px 16px; }
  .surface { border-radius: 6px; margin-bottom: 16px; }

  .hero-inner { padding: 16px 16px 28px !important; }
  .hero-center { padding-top: 36px !important; }
  .subpage-nav-wrap { padding: 16px 16px 0 !important; }

  .display-xl { font-size: clamp(34px, 9vw, 44px); line-height: 1.02; letter-spacing: -0.02em; }
  .display-hero { font-size: clamp(46px, 13vw, 60px) !important; line-height: 0.95 !important; }
  .display-lg { font-size: clamp(28px, 7vw, 36px); line-height: 1.08; }
  .display-md { font-size: clamp(22px, 5.5vw, 30px); }
  .body-mono { font-size: 13px; }
  .section-index { letter-spacing: 0.14em; }

  .institutions-row { grid-template-columns: repeat(5, 1fr) !important; }
  .institutions-row img { height: 16px !important; }

  .about-hero-half .about-hero-bigtype { font-size: clamp(30px, 9vw, 44px) !important; }
  .about-hero-preamble { font-size: clamp(22px, 5vw, 30px) !important; margin-bottom: 36px !important; }
  .about-hero-content { padding-top: 32px !important; }
  .subpage-hero-pad { padding: 16px 16px 36px !important; }

  .grid-4col { grid-template-columns: 1fr !important; }
  .grid-4col > * { border-right: none !important; border-bottom: 1px solid var(--baii-bone) !important; }
  .grid-4col > *:last-child { border-bottom: none !important; }

  .grid-past-events { grid-template-columns: 1fr !important; }
  .signatory-grid { grid-template-columns: 1fr !important; }
  .grid-newsletter-sections { grid-template-columns: 1fr !important; }
  .newsletter-preview { padding: 20px 20px !important; }
  .footer-pad { padding: 24px 16px 20px !important; }
  .blog-featured-content { padding: 24px 20px !important; }
  .open-letter-banner { flex-direction: column !important; gap: 8px !important; padding: 16px 20px !important; }
  .join-form-container { padding: 24px 20px !important; }

  /* Mission quote: even tighter on phones */
  .mission-quote-card { padding: 20px 16px !important; }
  .mission-quote-card p { font-size: 18px !important; line-height: 1.4 !important; }

  /* Principle cards: slightly shorter on small phones */
  .principle-card { min-height: 380px !important; }
}


/* ---------- Reduced Motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .hero-title, .hero-subtitle, .hero-ctas {
    opacity: 1;
    transform: none;
    animation: none;
  }
  .hero-float {
    animation: none;
  }
  .hero-brain-left, .hero-brain-right {
    opacity: 1;
    animation: none;
  }
  .scroll-indicator {
    animation: none;
    opacity: 0.6;
  }
  .section-index__rule {
    transform: scaleX(1);
    transition: none;
  }
  .footer-logo, .footer-tagline {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .route-content {
    animation: none;
  }
}

/* ============================================================
   About hero — parallax
   The section is tall; a 100vh child pins inside it and one scroll
   progress value drives the figure, the text block, and the per-line
   reveal. Progress comes from the section's absolute position, so it
   is correct at any scroll offset — unlike an intersection trigger,
   a fast flick cannot strand it part-drawn.
   NOTE: do not put overflow:hidden/auto on .about-hero-scroll. That
   makes it a scroll container and the sticky child would pin to it
   instead of to the page. overflow:clip is safe — it clips to the
   card's radius without creating a scrollport.
   ============================================================ */
.about-hero-scroll {
  height: 235vh;
  position: relative;
  /* White ground, matching every other section. RULED by Samuel 2026-08-01
     after seeing it live; was var(--baii-paper) #F4F2EC.
     This and the .about-hero-stick rule below must ALWAYS carry the same
     value: sticky creates a stacking context, so the Thinker's
     mix-blend-mode:multiply composites against the stick, not this section.
     Change one without the other and the statue renders wrong. */
  background: var(--baii-white);
  overflow: clip;
  border-radius: 8px;
}
.about-hero-stick {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  /* sticky creates a stacking context, so the figure's multiply blends against
     THIS element's backdrop, not the section's. Without a ground painted here
     the blend has nothing to multiply into and the statue renders plain white. */
  background: var(--baii-white);
}
.about-hero-nav {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 2;
  padding: 32px 56px 0;
}
.about-hero-figure {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 47%;
  z-index: 0;
  overflow: hidden;
  mix-blend-mode: multiply;
  /* right-hand fade keeps the figure off the text; the bottom fade stops the
     travelling image being guillotined at the end of the scroll */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, #000 30%),
    linear-gradient(to bottom, #000 90%, transparent 100%);
  mask-image:
    linear-gradient(to right, transparent 0%, #000 30%),
    linear-gradient(to bottom, #000 90%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* taller than its window, so moving it carries the whole figure through —
   nothing is ever masked away, it is simply not in frame yet */
.about-hero-track {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 142%;
  will-change: transform;
}
.about-hero-track img {
  display: block;
  width: 100%; height: 100%;
  object-fit: contain;
  object-position: 50% 50%;
  /* the source's "white" is 253,253,253 — clip it to a true 255 so the
     multiply blend leaves no rectangle on the paper */
  filter: brightness(1.04) contrast(1.03);
}
.about-hero-body {
  position: relative;
  height: 100%;
  padding: 0 56px;
  display: flex;
  align-items: center;
}
.about-hero-text {
  position: relative;
  z-index: 1;
  will-change: transform;
}
.about-hero-mission {
  font-family: var(--font-display);
  font-size: clamp(34px, 4.4vw, 62px);
  line-height: 1.11;
  letter-spacing: -0.03em;
  margin: 34px 0 0;
  color: var(--fg1);
}
/* every line always occupies its space, so the block never reflows —
   only opacity and offset are driven */
.about-hero-line { display: block; }
.about-hero-line + .about-hero-line { opacity: 0; will-change: opacity, transform; }
/* T4 — five authored words carry a hairline rule. Drawn with ::after rather
   than text-decoration so the weight stays exactly 1px at every hero size
   (the mission scales 34→62px, and an underline would scale with it).
   `nowrap` keeps a marked word from breaking across lines, which would split
   the rule. Inline + a pseudo-element only: the span's box is untouched, so
   the scroll parallax measures exactly what it measured before. */
.hero-mark {
  font-style: normal;
  position: relative;
  white-space: nowrap;
}
.hero-mark::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0.04em;
  height: 1px;
  background: var(--baii-blue);
}
@media (prefers-contrast: more) {
  .hero-mark::after { height: 2px; }
}

@media (max-width: 768px) {
  .about-hero-scroll { height: 200vh; }
  .about-hero-nav { padding: 24px 22px 0; }
  /* top padding has to clear the nav bar, which is absolutely positioned inside
     the pinned area and so contributes no flow height */
  .about-hero-body { padding: 152px 22px 0; align-items: flex-start; }
  .about-hero-figure {
    width: 80%;
    right: -22px; left: auto; top: auto; bottom: 0;
    height: 46%;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 20%);
    mask-image: linear-gradient(to right, transparent 0%, #000 20%);
  }
  .about-hero-track { height: 138%; }
  /* the two-speed drift is a desktop nicety; at phone width its 26px of upward
     travel walks the eyebrow into the logo, and there is no room to absorb it */
  .about-hero-text { transform: none !important; }
  .about-hero-mission { font-size: 31px; margin-top: 24px; }
  /* five authored breaks collapse into flowing text at phone width; the
     spans are adjacent in the markup, so the word space has to be put back */
  .about-hero-line,
  .about-hero-line + .about-hero-line { display: inline; }
  .about-hero-line + .about-hero-line::before { content: " "; }
}

@media (prefers-reduced-motion: reduce) {
  .about-hero-track,
  .about-hero-text { transform: none !important; }
  .about-hero-line { opacity: 1 !important; transform: none !important; }
}

/* ============================================================
   The people section — grid, and the reading spread it becomes
   ============================================================ */
/* Both views share this box. The grid is in flow and sets the resting height;
   the spread is absolute on top of it. Neither is ever in the other's layout,
   so the section simply eases between two heights and nothing below About is
   pushed around by a disclosure. */
.people-stage {
  position: relative;
  overflow: hidden;
}
.people-grouplabel {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg3);
  margin-bottom: 20px;
}

/* The grid does not fade as a block. --cell-delay is written per card by JS
   from its distance to the one that was clicked, so the dissolve radiates out
   from the face under the cursor, and reverses on the way back. */
.people-flow {
  transition: opacity 240ms var(--ease-standard);
}
.people-stage.is-open .people-flow {
  pointer-events: none;
}
.people-stage.is-open .people-cell {
  animation: cellDissolve 380ms var(--ease-out) var(--cell-delay, 0ms) both;
}
.people-stage:not(.is-open) .people-cell {
  animation: cellReturn 420ms var(--ease-out) var(--cell-delay, 0ms) both;
}
@keyframes cellDissolve {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(16px) scale(0.965); }
}
@keyframes cellReturn {
  from { opacity: 0; transform: translateY(16px) scale(0.965); }
  to   { opacity: 1; transform: none; }
}
/* The heading and the two group labels leave first and come back last — they
   frame the grid, so they should not still be sitting there once the thing
   they label has gone.

   `.reveal` ONLY — these are the ScrollReveal wrappers around the heading and
   the two labels. This selector also carried `> div[style]`, which matched the
   two grids and the divider purely because they happen to have inline styles,
   and translated the whole grid -8px. That was redundant motion on top of the
   per-card dissolve, and it moved every card out from under any measurement
   taken while the spread was open — which is exactly what a closing flight has
   to measure. */
.people-stage.is-open .people-flow > .reveal {
  transition: opacity 220ms var(--ease-standard), transform 300ms var(--ease-out);
  opacity: 0;
  transform: translateY(-8px);
}

/* ---------- The spread ---------- */
.pspread {
  position: absolute;
  inset: 0 0 auto 0;
  display: grid;
  grid-template-rows: auto auto;
  gap: 34px;
  background: var(--baii-white);
  animation: spreadIn 460ms var(--ease-out) both;
}
.pspread:focus { outline: none; }
@keyframes spreadIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* When the portrait did NOT fly in — because the section had too far to travel
   for a flight to be visible — it gets its own arrival instead of being fully
   formed the instant the spread appears. */
.pspread--arrive .pspread__photo {
  animation: spreadPhoto 620ms var(--ease-out) both;
}
@keyframes spreadPhoto {
  from { opacity: 0; transform: translateY(20px) scale(1.03); }
  to   { opacity: 1; transform: none; }
}

/* Stepping between people: the text leaves before its replacement arrives. A
   straight swap at this size reads as a glitch rather than as a change. */
.pspread--leaving .pspread__text {
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 120ms ease-in, transform 120ms ease-in;
}

.pspread__main {
  display: grid;
  grid-template-columns: minmax(260px, 36%) 1fr;
  gap: 56px;
  /* START, not center. The row's height is set by whichever column is taller,
     which is always the bio — and the bios differ by a factor of two. Centring
     therefore parked the portrait at a different height for every person, so
     stepping through the index made the face slide up and down according to how
     much someone had written about themselves. Pinning both columns to the top
     gives the portrait one fixed position for all twelve, and starts every name
     on the same line as the top of the photograph. */
  align-items: start;
  min-height: 0;
  /* Sized to ONE SCREEN, not to the grid it replaced. The section is ~1700px
     tall; a spread that inherited that height would put the index strip — the
     only way to reach the other eleven — 800px below the fold. The row is now
     driven by the portrait and the bio rather than a fixed height, because the
     portrait's shape is no longer free (see below). */
  max-height: 62vh;
}

/* SQUARE, and that is not a style choice. Every source portrait is 800×800.
   This slot was 369×487, so `cover` scaled the image to 487 wide and threw
   away 118px of it — 12% off each side of every face on the site. Antoine's
   was visibly clipped. A square slot crops nothing at all: the photograph is
   shown exactly as it was prepared, for all twelve, permanently.

   If these are ever re-shot or re-cropped taller, this can go back to a tall
   column — but the slot must never be a shape the source cannot fill. */
.pspread__photo {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--baii-paper);
  min-height: 0;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.10);
}
/* One crop rule, matching the card's. These were 50% 18% here, 50% 22% on the
   flying clone and 50% 50% on the card — three different framings of the same
   face in one transition, which is what made the portrait appear to shift as it
   opened and again as it closed. */
.pspread__photo-img,
.pspread__photo-ghost {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  filter: grayscale(1) contrast(1.05);
  display: block;
}
.pspread__photo-ghost { z-index: 2; }
.pspread__city {
  position: absolute;
  left: 16px; bottom: 16px;
  z-index: 3;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  padding: 4px 10px;
}

/* Centred against the portrait, whichever of the two runs taller, so a 63-word
   bio reads as composition rather than as a block that ran out. */
.pspread__text {
  min-width: 0;
  min-height: 0;
  max-width: 62ch;
  overflow-y: auto;
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out);
}
/* The bio sets itself line by line behind the portrait's flight. Delays start
   around 200ms so the eye is still following the photograph when the name
   appears beside it. */
.pspread__text > * { animation: spreadLine 480ms var(--ease-out) both; }
.pspread__text > *:nth-child(1) { animation-delay: 200ms; }
.pspread__text > *:nth-child(2) { animation-delay: 248ms; }
.pspread__text > *:nth-child(3) { animation-delay: 292ms; }
.pspread__text > *:nth-child(4) { animation-delay: 332ms; }
.pspread__text > *:nth-child(5) { animation-delay: 372ms; }
.pspread__text > *:nth-child(n+6) { animation-delay: 408ms; }
@keyframes spreadLine {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
/* Stepping: the portrait cross-dissolve is 420ms and there is no flight to
   hide behind, so the words follow the face almost immediately. */
.pspread__text--step > *,
.pspread__text--step > *:nth-child(n) { animation-duration: 380ms; }
.pspread__text--step > *:nth-child(1) { animation-delay: 30ms; }
.pspread__text--step > *:nth-child(2) { animation-delay: 64ms; }
.pspread__text--step > *:nth-child(3) { animation-delay: 96ms; }
.pspread__text--step > *:nth-child(4) { animation-delay: 126ms; }
.pspread__text--step > *:nth-child(5) { animation-delay: 154ms; }
.pspread__text--step > *:nth-child(n+6) { animation-delay: 180ms; }
.pspread__text--step .pspread__rule { animation-delay: 96ms; }

.pspread__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(34px, 3.6vw, 52px);
  line-height: 1.02;
  letter-spacing: -0.025em;
  margin: 0 0 10px;
  color: var(--fg1);
}
.pspread__role {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--baii-blue);
  line-height: 1.5;
}
/* Drawn, not faded — a 28px rule appearing at full width is invisible as
   motion, whereas one that draws reads as the page settling. */
.pspread__rule {
  width: 28px;
  height: 1px;
  background: var(--baii-bone);
  margin: 24px 0;
  transform-origin: left center;
  animation: spreadRule 460ms var(--ease-out) 300ms both;
}
@keyframes spreadRule {
  from { transform: scaleX(0); opacity: 0; }
  to   { transform: scaleX(1); opacity: 1; }
}
.pspread__bio {
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.8;
  color: var(--fg2);
  margin: 0 0 16px;
}
.pspread__links {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--baii-bone);
}
.pspread__links a:hover { text-decoration: underline; }
.pspread__links a:focus-visible { outline: 2px solid var(--baii-blue); outline-offset: 3px; }

/* ---------- The index ---------- */
.pspread__index {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 28px;
  align-items: center;
  border-top: 1px solid var(--baii-bone);
  padding-top: 18px;
  animation: spreadLine 520ms var(--ease-out) 380ms both;
}
.pspread__back {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  white-space: nowrap;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg2);
  background: var(--baii-white);
  border: 1px solid var(--baii-bone);
  border-radius: 999px;
  padding: 9px 15px 9px 12px;
  transition: color var(--dur-base) var(--ease-standard), border-color var(--dur-base) var(--ease-standard);
}
/* Deliberately at the BOTTOM. At the top of the spread it sat exactly where
   the fixed nav pill floats, and a hit test caught it unclickable — which is
   the same fault this rework exists to remove. */
.pspread__back:hover { color: var(--baii-blue); border-color: var(--baii-blue); }
.pspread__back:focus-visible { outline: 2px solid var(--baii-blue); outline-offset: 2px; }

.pspread__strip {
  position: relative;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 3px;
}
.pspread__strip::-webkit-scrollbar { display: none; }

/* One ring that travels, rather than a class that blinks from one thumbnail to
   the next — the eye follows a moving object and loses a blinking one. */
.pspread__marker {
  position: absolute;
  top: 3px; left: 0;
  border: 1.5px solid var(--baii-blue);
  border-radius: 8px;
  box-shadow: 0 0 0 3px var(--baii-blue-95);
  pointer-events: none;
  z-index: 2;
  transition: transform 460ms var(--ease-out), width 460ms var(--ease-out), height 460ms var(--ease-out);
}

.pspread__thumb {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--baii-bone);
  background: none;
  padding: 0;
  cursor: pointer;
  position: relative;
  animation: thumbIn 420ms var(--ease-out) both;
  transition: transform var(--dur-base) var(--ease-out);
}
.pspread__thumb:nth-child(2)  { animation-delay: 400ms; }
.pspread__thumb:nth-child(3)  { animation-delay: 424ms; }
.pspread__thumb:nth-child(4)  { animation-delay: 448ms; }
.pspread__thumb:nth-child(5)  { animation-delay: 472ms; }
.pspread__thumb:nth-child(6)  { animation-delay: 496ms; }
.pspread__thumb:nth-child(7)  { animation-delay: 520ms; }
.pspread__thumb:nth-child(8)  { animation-delay: 544ms; }
.pspread__thumb:nth-child(9)  { animation-delay: 568ms; }
.pspread__thumb:nth-child(10) { animation-delay: 592ms; }
.pspread__thumb:nth-child(11) { animation-delay: 616ms; }
.pspread__thumb:nth-child(12) { animation-delay: 640ms; }
.pspread__thumb:nth-child(n+13) { animation-delay: 664ms; }
@keyframes thumbIn {
  from { opacity: 0; transform: translateY(10px) scale(0.9); }
  to   { opacity: 1; transform: none; }
}
.pspread__thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  filter: grayscale(1) contrast(1.05) brightness(1.08);
  display: block;
  transition: filter var(--dur-base) var(--ease-standard);
}
.pspread__thumb:hover { transform: translateY(-3px); }
.pspread__thumb:hover img,
.pspread__thumb.is-on img { filter: grayscale(1) contrast(1.05); }
.pspread__thumb:focus-visible { outline: 2px solid var(--baii-blue); outline-offset: 3px; }

.pspread__nav { display: flex; align-items: center; gap: 8px; }
.pspread__count {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  color: var(--fg3);
  font-variant-numeric: tabular-nums;
  margin-right: 4px;
}
.pspread__count i { font-style: normal; opacity: 0.5; }
.pspread__step {
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--baii-bone);
  border-radius: 999px;
  background: var(--baii-white);
  color: var(--fg2);
  cursor: pointer;
  transition: color var(--dur-base) var(--ease-standard), border-color var(--dur-base) var(--ease-standard);
}
.pspread__step:hover { color: var(--baii-blue); border-color: var(--baii-blue); }
.pspread__step:focus-visible { outline: 2px solid var(--baii-blue); outline-offset: 2px; }

@media (max-width: 900px) {
  .pspread__main { grid-template-columns: 1fr; gap: 24px; max-height: none; }
  .pspread__photo { max-width: 240px; }
  .pspread__text { align-self: start; overflow: visible; }
  .pspread__index { grid-template-columns: 1fr; gap: 16px; }
  .pspread__strip { justify-content: flex-start; }
  .pspread__nav { justify-content: space-between; }
  .pspread__name { font-size: 32px; }
  .pspread__bio { font-size: 13.5px; }
}

@media (prefers-reduced-motion: reduce) {
  /* No arrival choreography and no portrait flight — flyPortrait and
     crossPortrait both bail out on this query in JS. Everything simply is
     where it belongs. */
  .pspread,
  .pspread--arrive .pspread__photo,
  .pspread__text,
  .pspread__text > *,
  .pspread__rule,
  .pspread__index,
  .pspread__thumb,
  .people-cell {
    animation: none;
    opacity: 1;
    transform: none;
    transition: none;
  }
  .people-stage.is-open .people-cell { display: none; }
  .pspread__marker { transition: none; }
}

/* ---------- Open letter · signatories ----------
   The count block, the featured board and the running list of everyone else.
   .signatory-board is a GRID, not column-count: column-count flows
   column-major, which would place display_order 31 top-right where it reads
   as the second most prominent position. Grid flows across, so the order set
   in the admin is the order a reader actually gets. */
.signatory-count-n {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(76px, 11vw, 150px);
  line-height: 0.86;
  letter-spacing: -0.035em;
  color: var(--baii-blue);
  font-variant-numeric: tabular-nums;
  margin-bottom: 16px;
}
.signatory-count-meta { display: flex; gap: 30px; flex-wrap: wrap; align-items: baseline; }
.signatory-count-sec {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--fg3); letter-spacing: 0.02em;
}
.signatory-count-sec b { font-weight: 400; color: var(--fg2); font-variant-numeric: tabular-nums; }

.signatory-tier {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg3);
  display: flex; align-items: center; gap: 10px; margin: 0 0 18px;
}
.signatory-tier::after { content: ""; flex: 1; height: 1px; background: var(--baii-bone); }

.signatory-board {
  display: grid; grid-template-columns: repeat(2, 1fr);
  column-gap: 52px; margin-bottom: 44px;
}
.signatory-person {
  padding: 11px 0; border-bottom: 1px solid var(--baii-bone);
  display: flex; flex-direction: column;
}
.signatory-name {
  font-family: var(--font-display); font-size: 20px; line-height: 1.2; letter-spacing: -0.01em;
  color: var(--fg1);
}
.signatory-meta {
  font-family: var(--font-mono); font-size: 11px; color: var(--fg2);
  line-height: 1.5; margin-top: 3px;
}
.signatory-prose {
  font-family: var(--font-mono); font-size: 12.5px; line-height: 2.05;
  color: var(--fg2); margin: 0;
}
.signatory-prose b { font-weight: 400; color: var(--fg1); }
.signatory-prose span { color: var(--fg3); }
.signatory-prose .signatory-sep { color: var(--baii-ash); }

@media (max-width: 860px) {
  .signatory-board { grid-template-columns: 1fr; column-gap: 0; }
  .signatory-count-meta { gap: 8px 20px; }
}


/* ============================================================
   CONTACT — three ways, forms open in place
   Added 2026-08-20. Left column states, right column chooses, the blue panel
   below is where the work happens.
   ============================================================ */
.contact-surface { position: relative; overflow: hidden; }

/* The hand. Slide, hover-nudge and float each want `transform`, and the last
   one declared wins — so each gets its own layer. The hotspot rides inside the
   bobbing layer or the hand drifts away from its own fingertip. */
.contact-h1 { max-width: 18ch; margin: 0 0 48px; }

/* One column at every width: the question, the three answers, the form the
   answer opens, then the direct routes.

   It was cards-left / form-right until 2026-08-22. That worked on a desktop
   and had no way to survive stacking: on a phone the form landed 1.2 screens
   below the chooser, and tapping a choice changed nothing you could see. One
   column has no second state to get wrong. */
.contact-grid {
  display: flex; flex-direction: column; gap: 26px; align-items: stretch;
}

/* .contact-left is gone from the markup — the two-column split it existed for
   was replaced on 2026-08-22 by a single column: prompt, three choices, form,
   direct routes. */

.contact-direct {
  border-top: 1px solid var(--baii-bone); margin-top: 28px; padding-top: 22px;
  display: flex; flex-direction: column; gap: 13px;
}
.contact-direct a, .contact-direct span {
  font-family: var(--font-mono); font-size: 13.5px; line-height: 1.5;
  color: var(--fg2); text-decoration: none;
}
.contact-direct a:hover { color: var(--baii-blue); }

.chand {
  /* Sits in the band between the nav pill and the grid, bleeding off the
     right. Its lower third is transparent, so the box may overlap the panel's
     top edge — nothing visible does. */
  /* Above .surface__inner (z-index 2), which is transparent but still covers
     this corner and was swallowing every event aimed at the fingertip. Safe to
     raise: the whole layer is pointer-events:none except the 76px hotspot, and
     the ink clears the panel by 53px so nothing paints over anything. */
  position: absolute; right: -118px; top: 22px; width: 520px; z-index: 3;
  pointer-events: none; user-select: none;
  opacity: 0; transform: translateX(150px);
  transition: opacity 1.7s cubic-bezier(.25,.1,.25,1),
              transform 2.1s cubic-bezier(.19,.63,.26,1);
}
.chand.is-in { opacity: .95; transform: translateX(0); }
.chand__nudge { transition: transform .5s cubic-bezier(.19,.63,.26,1); }
.chand__nudge.nudged { transform: translateX(-9px); }
.chand__bob { position: relative; animation: floatBob 7s ease-in-out infinite; }
/* Mirrored so the finger points into the page rather than off the edge. */
.chand__img { display: block; width: 100%; filter: grayscale(1) contrast(1.08); transform: scaleX(-1); }

/* Reactive zone is the fingertip alone — measured at 87% across, 34.5% down.
   Nothing signals it; the glow on hover is the only tell. */
.chand__tip {
  position: absolute; left: 13%; top: 34.5%;
  width: 76px; height: 76px; margin: -38px 0 0 -38px;
  border: 0; background: none; padding: 0; border-radius: 50%;
  pointer-events: auto; cursor: pointer; -webkit-appearance: none; appearance: none;
}
.chand__tip::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, rgba(2,99,255,.34) 0%, rgba(2,99,255,0) 68%);
  opacity: 0; transition: opacity .4s ease; pointer-events: none;
}
.chand__tip:hover::after, .chand__tip:focus-visible::after { opacity: 1; }
.chand__tip:focus { outline: none; }
.chand__tip:focus-visible { outline: 2px solid var(--baii-blue); outline-offset: 4px; }

/* Dots, not a ring — the illustration is made of dots. */
.cspark { position: absolute; left: 13%; top: 34.5%; pointer-events: none; }
.cspark i {
  position: absolute; width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px;
  border-radius: 50%; background: var(--baii-blue);
  animation: cSparkOut .78s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes cSparkOut {
  0%   { transform: translate(0,0) scale(1); opacity: .9; }
  100% { transform: translate(var(--dx), var(--dy)) scale(.4); opacity: 0; }
}

/* ---- the three ---- */
/* Three across where there is room, stacking below ~700px. auto-fit rather
   than a counted repeat(3,...) so removing or adding a route cannot leave a
   ragged row. 200px is the width at which "Everything else" stops wrapping. */
.cways { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.contact-prompt {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--fg3); margin: 0 0 14px;
}
/* One line, no description. The hint text was dropped from the markup on
   2026-08-22 — three compact boxes keep the form high on the page, which was
   the whole problem with the old cards. */
.cway {
  position: relative; display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; font-family: inherit; cursor: pointer;
  background: var(--baii-white); border: 1px solid var(--baii-bone);
  border-radius: 10px; padding: 15px 34px 15px 16px;
  transition: border-color .22s, background .22s, transform .22s, box-shadow .22s;
}
.cway:hover { border-color: var(--baii-ash); transform: translateY(-2px); box-shadow: 0 6px 22px rgba(0,0,0,.05); }
.cway.is-on {
  border-color: var(--baii-blue); background: var(--baii-blue-95);
  transform: none; box-shadow: none;
}
.cway__n {
  font-family: var(--font-display); font-size: 15px;
  line-height: 1; color: var(--baii-ash); transition: color .22s;
}
.cway__title {
  font-family: var(--font-display); font-weight: 400;
  font-size: 18px; line-height: 1.15; letter-spacing: -.01em;
  margin: 0; color: var(--fg1); transition: color .22s;
}
/* .cway__hint has no element left to style. */
.cway.is-on .cway__n, .cway.is-on .cway__title { color: var(--baii-blue); }
.cway__mark {
  position: absolute; top: 50%; margin-top: -4.5px; right: 14px; width: 9px; height: 9px;
  border-radius: 50%; background: transparent;
  border: 1px solid var(--baii-ash); transition: all .22s;
}
.cway.is-on .cway__mark { background: var(--baii-blue); border-color: var(--baii-blue); }

/* Attract relay on ::after, the fingertip pulse on ::before, so the two can
   never collide — the relay is suppressed exactly when the pulse fires. */
.cway::after {
  content: ''; position: absolute; inset: -1px; border-radius: 11px;
  border: 1px solid var(--baii-blue); opacity: 0; pointer-events: none;
  animation: cAttract 7.2s ease-in-out infinite;
}
.cway:nth-child(2)::after { animation-delay: 2.4s; }
.cway:nth-child(3)::after { animation-delay: 4.8s; }
@keyframes cAttract {
  0% { opacity: 0; } 3% { opacity: .5; } 29% { opacity: .5; }
  33.3% { opacity: 0; } 100% { opacity: 0; }
}
.cways:hover .cway::after, .cways.engaged .cway::after { animation: none; opacity: 0; }
.cway::before {
  content: ''; position: absolute; inset: -1px; border-radius: 11px;
  border: 1px solid var(--baii-blue); opacity: 0; pointer-events: none;
}
.cway.ping::before { animation: cPing .6s ease-out; }
@keyframes cPing { 0% { opacity: 0; } 22% { opacity: .8; } 100% { opacity: 0; } }

/* ---- the drawer ---- */
/* White, not the blue gradient it carried until 2026-08-22. A full-bleed blue
   panel is a strong object; at the top of a single column, directly under the
   three choices, it read as a separate screen rather than as the answer to the
   one just picked. Everything below that used rgba(255,255,255,x) for its ink
   moved with it — labels, rules, placeholders, chips, the note and the sent
   state. If this ever goes back to blue, all of them go back together. */
.cpanel {
  background: var(--baii-white); color: var(--fg1);
  border: 1px solid var(--baii-bone);
  border-radius: 12px; padding: 34px 36px 36px;
}
.cpanel__title {
  font-family: var(--font-display); font-weight: 400; font-size: 28px;
  line-height: 1.1; letter-spacing: -.01em; margin: 0 0 26px; color: var(--fg1);
}
.cpanel__form { display: flex; flex-direction: column; gap: 30px; }
.cpanel__send { display: flex; align-items: center; gap: 20px; margin-top: 16px; flex-wrap: wrap; }
.cpanel__note { font-family: var(--font-mono); font-size: 11.5px; color: var(--fg3); }

/* Ruled fields, not boxes — a rule and a label do the same job without making
   the panel read as an admin screen. */
.cf { position: relative; padding-top: 24px; }
.cf__label {
  position: absolute; top: 0; left: 0;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--fg3);
}
/* Same look as .cf__label but in flow — a group heading has no field to sit
   above, and borrowing the absolutely-positioned one tore it out of the panel. */
.cf__grouplabel {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--fg3); margin-bottom: 12px;
}
.cf__input {
  width: 100%; border: 0; border-bottom: 1px solid var(--baii-ash);
  background: transparent; padding: 7px 0 11px; border-radius: 0;
  font-family: var(--font-mono); font-weight: 300; font-size: 15px; color: var(--fg1);
  outline: none; transition: border-color .18s; resize: none;
  -webkit-appearance: none; appearance: none;
}
.cf__input:focus { border-bottom-color: var(--baii-blue); }
.cf__input::placeholder { color: var(--baii-ash); }
select.cf__input { cursor: pointer; }
select.cf__input option { color: var(--fg1); }
.cf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }

.cchips { display: flex; flex-wrap: wrap; gap: 7px; }
.cchip {
  font-family: var(--font-mono); font-size: 12px; color: var(--fg2);
  border: 1px solid var(--baii-bone); background: var(--baii-white);
  border-radius: 999px; padding: 7px 13px; cursor: pointer; transition: all .16s;
}
.cchip:hover { border-color: var(--baii-ash); }
.cchip[aria-pressed="true"] {
  background: var(--baii-blue-95); border-color: var(--baii-blue); color: var(--baii-blue);
}

.contact-dot {
  width: 32px; height: 32px; border-radius: 50%; background: var(--baii-bone);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}

@media (max-width: 1200px) {
  .chand { right: -170px; width: 460px; }
}
@media (max-width: 980px) {
  .chand { display: none; }
  .contact-h1 { margin-bottom: 34px; }
  /* 48px a side on a phone leaves the fields about 250px wide. */
  .cpanel { padding: 32px 22px 34px; border-radius: 10px; }
  .cf-row { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .chand { transition: none; opacity: .95; transform: none; }
  .chand__nudge { transition: none; }
  .chand__bob { animation: none; }
  .cway::after, .cway.ping::before, .cspark i { animation: none; }
}

/* ---------- The open-role document (#head-of-partnerships) ----------

   This page is deliberately plain — one column, no cards, no imagery. That
   decision is recorded in app.jsx above HeadOfPartnershipsPage and it stands.
   What lives here is the layer underneath: typographic craft that a reader
   feels without noticing, and that inline styles cannot express because it is
   all pseudo-elements and wrapping algorithms.

   Nothing in this block is decoration. If a rule here starts drawing
   attention to itself rather than to the sentence it is setting, it is wrong.
   Everything is scoped to .role-doc so no other page inherits it.            */

/* Dragging over text is the most common thing a candidate does on a job
   description — they copy the email, or a line to send to someone. A tinted
   selection is the cheapest possible sign that the page is not a screenshot. */
.role-doc ::selection {
  background: var(--baii-blue-70);
  color: var(--baii-graphite);
}

/* Headings set their own breaks. balance keeps "Senior Fellow, Head of
   Partnerships" from dropping one orphaned word onto line two — which is
   exactly what it does at several common widths without this. The site
   already does the same on .display-xl / .display-lg; these headings use
   inline sizes rather than those classes, so they need it stated here. */
.role-doc h1,
.role-doc h2 { text-wrap: balance; }

/* pretty costs the last two lines of each paragraph a little re-flow and
   buys no single-word final lines anywhere in a page of solid prose. */
.role-doc p,
.role-doc li { text-wrap: pretty; }


/* The default disc is a browser artefact. An en dash in the accent, set in
   the mono the body is already using, reads as something someone chose. */
.role-doc li::marker {
  content: '–  ';
  color: var(--baii-blue);
  font-family: var(--font-mono);
}

/* A rule that is one flat hairline all the way across says nothing. The
   first 44px in the accent gives the page a starting point for the eye,
   and costs one pseudo-element. */
.role-doc .doc-rule { position: relative; }
.role-doc .doc-rule::after {
  content: '';
  position: absolute;
  top: -1px; left: 0;
  width: 44px;
  border-top: 1px solid var(--baii-blue);
}

/* The email is the single action on the page, so it is the one thing that
   earns a transition. The underline sits off the baseline and thickens on
   approach; it does not move the text, so the line never re-flows. */
.role-doc .doc-mail {
  color: var(--baii-blue);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-thickness 140ms var(--ease-standard),
              text-underline-offset 140ms var(--ease-standard);
}
.role-doc .doc-mail:hover {
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.role-doc a:focus-visible {
  outline: 2px solid var(--baii-blue);
  outline-offset: 3px;
  border-radius: 2px;
}

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

/* ---------- Emphasis ----------

   ONE level: weight. There was briefly a second — a tinted marker pen on two
   sentences — and Samuel removed it on 2026-08-21. Do not reintroduce a
   highlight, a colour or a size change as a way of making something stand out
   here. On a page set in mono, weight is the whole vocabulary, and a second
   level stops reading as emphasis and starts reading as a rash.

   strong — SemiBold 600, not the global 500. At 15px mono, 500 against 400 is
   close to invisible, which is how you end up bolding more and more of a
   paragraph trying to make the bold work. 600 is legible at a glance, so five
   or six across the page is enough.                                          */
.role-doc strong {
  font-weight: 600;
  color: var(--baii-graphite);
}

/* ---------- The apply block ----------

   The one place on this page that is allowed to look like a control. Everything
   above it is a document; this is the thing the document is asking for. It gets
   a ground, a border and a real button so that a reader who has scrolled to the
   bottom does not have to hunt for the address in a sentence.                 */
.role-doc .doc-apply {
  background: var(--baii-blue-95);
  border: 1px solid var(--baii-blue-85);
  border-radius: 12px;
  padding: 32px 36px;
  margin-top: 4px;
}

@media (max-width: 768px) {
  .role-doc .doc-apply { padding: 26px 22px; }
  /* Full width is a better tap target than a pill floating in a box. The
     label is short enough that this can never set the page's scroll width. */
  .role-doc .doc-apply .btn {
    width: 100%;
    justify-content: center;
  }
}

/* The webinar hero band (#thinkslop). The blue panel needs less padding on a
   phone than the 52px it carries on a desktop, and the face tiles want to be
   larger than a third of the width once the column is only 340px wide. */
@media (max-width: 768px) {
  .event-hero-panel { padding: 30px 22px !important; border-radius: 12px; }
}

/* ---------- Webinar hero: the title, at scale ----------

   Not .display-xl. That class caps at 88px and is shared by every page on the
   site; this title is one nine-letter word with a whole band to itself, so it
   gets its own ceiling. Changing .display-xl to suit it would have resized
   every h1 on the site.

   The ceiling is set by the column, not by taste: the title sits centre-left in
   a 1.15fr column, which is ~626px at a 1440 viewport. "Thinkslop" is nine
   letters of Instrument Serif at roughly 0.44em each, so 140px lands near
   558px and fits with room. It was briefly 180px and full-width, spanning the
   whole panel above both columns — that ran about 750px, which is why it could
   not live in a column at that size. If this number goes up again, the title
   has to leave the column again. */
.event-hero-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(56px, 9vw, 140px);
  line-height: 0.86;
  letter-spacing: -0.035em;
  color: #fff;
  margin: 0 0 18px;
}
.event-hero-sub {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(20px, 2.3vw, 32px);
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.84);
  margin: 0;
  max-width: 26ch;
  text-wrap: balance;
}

/* ---------- Webinar hero: the faces ----------

   Sizes and tilts vary per tile so the group reads as a handful of prints
   dropped on a desk rather than a contact sheet. The angles are small (2-3
   degrees) on purpose: past about 5 the group stops looking arranged and
   starts looking broken, and the corners begin to clip the panel.

   Straighten and lift on hover, so the scatter is clearly deliberate. */
.face-tile {
  transition: transform 320ms var(--ease-out);
  transform-origin: center center;
}
.face-tile:hover {
  transform: rotate(0deg) scale(1.04) !important;
  z-index: 2;
}
@media (prefers-reduced-motion: reduce) {
  .face-tile { transition: none; }
}
@media (max-width: 768px) {
  /* Tilt survives on a phone; the staggered vertical offsets do not — they
     were sized against a two-column desktop block and leave gaps here. */
  .face-tile { margin-top: 0 !important; }
  .event-hero-sub { font-size: clamp(19px, 5.6vw, 26px); }
}

/* ---------- Webinar body copy (#thinkslop) ----------

   Speaker names carry weight in the running prose. 600, not the global 500:
   at 15px mono, 500 against 400 is close to invisible — the same reason the
   open-role document sets its own weight. */
.event-doc strong {
  font-weight: 600;
  color: var(--baii-graphite);
}

@media (max-width: 768px) {
  /* Once grid-2col collapses, the sidebar is the last thing on the page and
     has nothing left to stick to. Sticky there just pins it to the bottom of
     a scroll it has already reached. */
  .event-aside { position: static !important; }
}

