/* ==========================================================================
   ABOUT PAGE (V5, "designer on and off screen")
   Source of truth: Figma EQ5vs6l8ARkiiJ1YLCnUkV, section 223:45002
   ("NEW about page"): ON frame 205:98961, OFF frame 221:37953.
   Loaded by /about/ only, after site.css. Reads tokens.css only; shared
   nav, footer, grid, theme/grid controls and cursor pill are untouched.

   One page, two states. html[data-about] ("off" for /about/#off-screen,
   otherwise on) picks the state: an inline <head> script sets it before
   first paint, /js/about.js owns it after that. Every state-specific region
   is an .about-swap whose ON and OFF panels share ONE grid cell, so the
   page keeps the same height in both states and the panels can crossfade.

   Geometry at 1200px+ follows the 12-column site grid (x=120 ... 1320,
   102.67px column pitch), as in Figma 223:45002 (2026-10-06): the H1 spans
   columns 1-8, the intro sits one column in (2-7) and the photo stack is
   the right-hand counterweight (9-12); principle rows put the number in
   column 1, the title from column 2 and the description in columns 8-12;
   the fact cells are staggered 3-column cells (see Experience below).
   ========================================================================== */

/* ---- State swap --------------------------------------------------------------
   Both panels of a region sit in the same cell. The inactive one is hidden
   (visibility, so it keeps its size and leaves the accessibility tree and
   tab order; about.js also marks it inert). With motion allowed the outgoing
   panel fades and lifts 8px quickly (140ms, ease-in, no stagger); the
   incoming one fades in and settles down 8px (240ms, ease-out) after a short
   beat, staggered 40ms per region down the page (--stagger 0-5), so the
   whole change lands in ~500ms. Transitions retarget mid-flight, so rapid
   toggling always resolves to the latest state. Reduced motion: instant. */
.about-swap { display: grid; }
/* overflow-anchor: none keeps the browser's scroll anchoring from locking
   onto a panel mid-transition (it counts the 8px offset and would nudge the
   page). Nothing here changes layout, so no anchoring is needed. */
.about-swap > [data-about-panel] { grid-area: 1 / 1; min-width: 0; overflow-anchor: none; }
html:not([data-about="off"]) [data-about-panel="off"],
html[data-about="off"] [data-about-panel="on"] {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}
html.motion-ok [data-about-panel] {
  transition:
    opacity 240ms cubic-bezier(0.2, 0.7, 0.2, 1) calc(60ms + var(--stagger, 0) * 40ms),
    transform 240ms cubic-bezier(0.2, 0.7, 0.2, 1) calc(60ms + var(--stagger, 0) * 40ms),
    visibility 0s linear 0s;
}
html.motion-ok:not([data-about="off"]) [data-about-panel="off"],
html.motion-ok[data-about="off"] [data-about-panel="on"] {
  transform: translateY(-8px);
  transition:
    opacity 140ms cubic-bezier(0.4, 0, 1, 1),
    transform 140ms cubic-bezier(0.4, 0, 1, 1),
    visibility 0s linear 140ms;
}
/* Full-bleed coloured panels (the fact bands) only fade: moving
   them would open a sliver of page background at their edges. */
html.motion-ok .about-facts[data-about-panel] { transform: none; }

/* ---- Section rules ----------------------------------------------------------------
   Intentional rules use --color-rule (a clear step above the background
   grid, see tokens.css line hierarchy). */
.about-hero { border-top: var(--border-width) solid var(--color-rule); }
/* The band has no rules of its own: hero -> band colour -> principles. */

/* Section headings (How I Work / How I Live, Experience / Currently): the
   Figma H200 text style, the site's H2 (Pacaembu Regular 28px, 135%, no
   tracking), from the shared tokens. Phones take the same 24px step the
   homepage's H2 (.section-head__title) takes. */
.about-section-heading {
  font-family: var(--text-h200-font);
  font-size: var(--text-h200-size);
  font-weight: var(--text-h200-weight);
  line-height: var(--text-h200-leading);
  letter-spacing: 0;
  color: var(--color-ink);
}
@media (max-width: 839px) {
  .about-section-heading { font-size: 24px; }
}

/* ---- Hero: H1 + intro | photo stack --------------------------------------------
   A staggered composition on the grid: the H1 on the content edge (columns
   1-8), the intro one column in beneath it (2-7), the photo stack on the
   right across both rows (9-12). 840-1199: the H1 runs full width and the
   intro sits beside the stack. Phones: H1, then the stack (so a switch
   visibly changes something right under it), then the intro. The DOM order
   stays H1, intro, stack at every width; only the grid placement changes. */
.about-hero__grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  align-items: start;
}
.about-hero__grid > .about-title { grid-column: 1 / span 8; grid-row: 1; padding-top: var(--space-4xl); }
.about-hero__grid > .about-intro {
  grid-column: 2 / span 6;
  grid-row: 2;
  margin-top: var(--space-2xl);
  padding-bottom: var(--space-4xl);
}
.about-hero__stacks {
  grid-column: 9 / span 4;
  grid-row: 1 / span 2;
  padding-block: 48px;
}
/* 1200+: the taller stack spans both rows; row 1 keeps the H1's own height
   (the stack's extra height goes to row 2), so the intro sits a fixed 40px
   under the H1 instead of being pushed down by the stack (was 68px). */
@media (min-width: 1200px) {
  .about-hero__grid { grid-template-rows: auto 1fr; }
  .about-hero__grid > .about-intro { margin-top: var(--space-3xl); }
}

/* H1 with the ON / OFF switch. Figma: Neulis 48/1.15, Regular with
   "Megan Learn," in Semibold, words 10px apart (flex gap). Each pill is kept
   on a line with the word after it ("ON and", "OFF screen."), so at 1440 the
   sentence breaks after "designer" exactly as in Figma. Accessible: the h1
   is named by its sr-only sentence; visible words are aria-hidden; the two
   buttons stay in the heading as their own toggle buttons. */
.about-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 0.2083em; /* 10px at 48px */
  font-family: var(--font-body);
  font-size: clamp(32px, calc(2vw + 20px), 48px);
  font-weight: var(--weight-regular);
  line-height: 1.15;
  color: var(--color-ink);
}
.about-title__name { font-weight: var(--weight-regular); } /* Figma: the whole H1 is Regular */
.about-title__pair {
  display: inline-flex;
  align-items: center;
  column-gap: 0.2083em;
  white-space: nowrap;
}

/* Figma "About H1 Button": 77x38 (ON) / 92x38 (OFF) with a 2px stroke drawn
   INSIDE the box, 8px radius, 24px side padding, Nitti 24 uppercase. CSS
   borders sit outside the padding, so the border is subtracted from the
   padding and the text line (22px sides, 32px line) to land on the same
   38px box. Everything is in em of the pill's own 24px (0.5em of the 48px
   H1), so it scales with the fluid heading. The 1.1px/0.9px vertical split
   centres Nitti's cap ink in the box (measured). Selected: brand-blue fill +
   Bold; unselected: surface fill + Medium (never hue alone).
   Vertical placement: the flex row centres the pill on the H1's line box,
   but Neulis's tall ascent puts that line-box centre 0.40em above the
   baseline, higher than the letters' optical centre, so the pill rode up
   past the ascenders. The optical centre of this mostly-lowercase line is
   the average of the cap-height and x-height middles, 0.30em above the
   baseline (Neulis: cap 0.69em, x 0.51em). `top` drops the pill by the
   difference, 0.097em of the H1 = 0.194em of the pill. It is a font-metric
   constant, so it holds at every size, state and wrap (measured at 2x: the
   pill now runs from the ascender top to just below the baseline). */
.about-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.0458em 0.9167em 0.0375em;
  border: 2px solid var(--color-blue-text);
  border-radius: 8px;
  background: var(--color-surface);
  color: var(--color-blue-text);
  font-family: var(--font-detail);
  font-size: 0.5em;
  font-weight: 500;
  line-height: 1.3333;
  text-transform: uppercase;
  top: 0.194em;
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}
.about-switch[aria-pressed="true"] {
  background: var(--color-blue);
  color: var(--color-white);
  font-weight: 700;
}
.about-switch[aria-pressed="false"]:hover { background: var(--color-light-blue-50); }
.about-switch:focus-visible { border-radius: 8px; outline-offset: 4px; }
/* Invisible hit area: the tap target stays at least 44x44 at every size. */
.about-switch::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

.about-intro__panel { display: flex; flex-direction: column; gap: var(--space-md); }
.about-intro__lead {
  font-size: var(--text-body100-size);
  font-weight: var(--weight-semibold);
  line-height: var(--text-body100-medium-leading);
}
.about-intro__body {
  font-size: var(--text-body200-size);
  line-height: var(--text-body200-leading);
}

/* ---- Photo stack -------------------------------------------------------------------
   Five equal cards (Figma 328.5 x 346.7 inside a 379 x 420 stack box) in a
   FIXED DOM order. about.js only sets each card's data-depth (0 = front ...
   4 = back), from (index - frontIndex) mod 5; the depth picks the card's
   z-index and its slot transform below. Slots are Figma's composition:
   offsets are % of the card (so they scale with it) plus a small rotation.
   The ON/OFF state transition moves the outer .about-stack-panel; the shuffle
   moves the cards inside it, so the two never fight over one transform. */
.about-stack {
  position: relative;
  width: 100%;
  aspect-ratio: 379 / 420;
}
.about-stack__card {
  position: absolute;
  left: 4.87%;
  top: 5.57%;
  width: 86.67%;
  height: 82.55%;
  padding: 0;
  border: 0;
  border-radius: 16px;
  overflow: hidden;
  background: var(--color-surface);
  transform: translate(var(--tx, 0), var(--ty, 0)) rotate(var(--r, 0deg));
  -webkit-tap-highlight-color: transparent;
}
html.motion-ok .about-stack__card { transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.about-stack__card img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
}
/* The card's 1px edge, drawn over the image in the rule colour so it themes
   (Figma "Gray 3"). */
.about-stack__card::after {
  content: "";
  position: absolute;
  inset: 0;
  border: var(--border-width) solid var(--color-rule);
  border-radius: inherit;
  pointer-events: none;
}
.about-stack__card:focus-visible { outline-offset: 3px; border-radius: 16px; }
/* The drawing is the existing flattened Figma illustration on its white
   paper (not themed, like the case-study letterbox fills), slightly wider
   than the card as in Figma (347.97 / 328.5). */
.about-stack__card--drawing { background: var(--color-white); }
.about-stack__card--drawing img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 105.93%;
  height: auto;
  object-fit: fill;
  transform: translate(-50%, -50%);
}
.about-stack__card[data-depth="0"] { z-index: 5; }
.about-stack__card[data-depth="1"] { z-index: 4; --tx: -2.05%; --ty: 4.17%; --r: -4deg; }
.about-stack__card[data-depth="2"] { z-index: 3; --tx: 6.18%;  --ty: 6.94%; --r: 4deg; }
.about-stack__card[data-depth="3"] { z-index: 2; --tx: 2.62%;  --ty: -5.12%; --r: 2deg; }
.about-stack__card[data-depth="4"] { z-index: 1; --tx: 0.3%;   --ty: 9.73%; --r: 6deg; }
/* OFF stack (Figma 223:38648): the same composition, with the second card
   at -3deg instead of -4deg. */
[data-about-panel="off"] .about-stack__card[data-depth="1"] { --r: -3deg; }

/* ---- Icon / doodle band -------------------------------------------------------------
   Figma: a 64px band, 64px items on an 80px pitch. ON: white icons on brand
   blue (a filled brand surface, so the same in both themes). OFF: blue
   doodles on Light Blue 100.
   ONE carousel, two treatments. There is a single row with a single
   animation, and every item is one subject carrying both of its artworks
   (ON icon, OFF doodle) stacked in the same 64px box. Switching state only
   crossfades the artwork and the band colour: the row's position, speed and
   direction are never touched, so each subject changes in place. (Two
   separate rows, with the hidden one paused, drifted apart and made the
   subjects jump on every switch.) Do not split this back into two rows.
   The row repeats one <ul> group; about.js appends aria-hidden copies and
   every group translates by -100% of its own width, so the loop distance is
   exactly one gap-inclusive group and the seam can't drift.
   Reduced motion: a static row and an instant swap. */
.about-bands { position: relative; }
/* The band colour sits on the stationary .about-band, not on the moving
   strip, so the focus-window filter below touches the artwork only. One
   continuous colour edge to edge: the band never acknowledges the grid. */
.about-band { overflow: hidden; background: var(--color-blue); }
html[data-about="off"] .about-band { background: var(--color-light-blue-100); }
.about-marquee { height: 64px; overflow: hidden; }
.about-marquee__track { display: flex; width: max-content; }
.about-marquee__group {
  flex: none;
  display: flex;
  gap: var(--space-lg);
  padding-right: var(--space-lg); /* keeps copies exactly one gap apart */
}
@keyframes about-marquee-left { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-100%, 0, 0); } }
html.motion-ok .about-marquee.is-looping .about-marquee__group {
  animation: about-marquee-left var(--marquee-duration, 60s) linear var(--marquee-delay, 0s) infinite;
}
/* Must out-rank the animation shorthand above, which resets play-state. */
html.motion-ok .about-bands.is-paused .about-marquee.is-looping .about-marquee__group,
html.motion-ok .about-bands.is-offscreen .about-marquee.is-looping .about-marquee__group { animation-play-state: paused; }

/* The sprites are the Figma carousel frames (20 items, 80px on a 96px
   pitch), scaled to Figma's 64px band: 64px items, 76.8px sprite pitch.
   --i (the subject's index, on the item) picks the same cell from both
   sprites, which hold the same 20 subjects in the same order. */
.about-icon { position: relative; flex: none; width: 64px; height: 64px; }
.about-icon__art {
  position: absolute;
  inset: 0;
  background: currentColor;
  -webkit-mask: var(--sprite) no-repeat;
  mask: var(--sprite) no-repeat;
  -webkit-mask-size: 1523.2px 64px;
  mask-size: 1523.2px 64px;
  -webkit-mask-position: calc(var(--i) * -76.8px) 0;
  mask-position: calc(var(--i) * -76.8px) 0;
}
.about-icon__art--on { --sprite: url("/images/about/icons-on.svg"); color: var(--color-white); }
.about-icon__art--off { --sprite: url("/images/about/doodles-off.webp"); color: var(--color-blue-text); }
html:not([data-about="off"]) .about-icon__art--off,
html[data-about="off"] .about-icon__art--on { opacity: 0; }
/* The same timing as every other state swap on the page: the outgoing
   artwork fades fast, then the incoming artwork and the band colour fade in
   together after the region's stagger beat. Opacity and colour only. */
html.motion-ok .about-band {
  transition: background-color 240ms cubic-bezier(0.2, 0.7, 0.2, 1) calc(60ms + var(--stagger, 0) * 40ms);
}

/* Grid focus window. The band runs full bleed in one continuous colour; only
   its artwork acknowledges the content column: full strength inside it, 50%
   outside (OFF also greyscale), with a soft ~64px crossfade at each content
   edge. The SVG filters are in the markup, on the stationary strip; about.js
   sizes them to the content column on load and resize and then adds
   html.about-focus, so without JS the band renders as before. Motion,
   speed, spacing and the ON/OFF swap are untouched. */
.about-focus-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
html.about-focus .about-marquee { filter: url(#about-focus-on); }
html.about-focus[data-about="off"] .about-marquee { filter: url(#about-focus-off); }
html.motion-ok .about-icon__art {
  transition: opacity 240ms cubic-bezier(0.2, 0.7, 0.2, 1) calc(60ms + var(--stagger, 0) * 40ms);
}
html.motion-ok:not([data-about="off"]) .about-icon__art--off,
html.motion-ok[data-about="off"] .about-icon__art--on {
  transition: opacity 140ms cubic-bezier(0.4, 0, 1, 1);
}

/* Pause/resume (WCAG 2.2.2: the band moves continuously for more than 5s).
   Same control as the homepage's More Things toggle. Fine-pointer desktop:
   in the empty left page margin, centred on the band, revealed on hover,
   focus or while paused. Phones and touch devices: always visible, 32px
   circle with a 44px hit area, bottom-right just below the band on the
   content's right edge (in the next section's top padding, so it covers no
   icon). Absolute, attached to the band, never fixed. Hidden under reduced
   motion (nothing moves). */
.about-bands__toggle {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: max(8px, calc((100% - var(--container-max)) / 4 - 16px));
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transform: translateY(-50%);
  border-radius: var(--radius-pill);
  background: var(--color-control-bg);
  color: var(--color-control-fg);
  box-shadow: 0 0 0 var(--border-width) var(--color-rule);
  font-size: 11px;
  line-height: 1;
  transition: opacity var(--duration-slow) var(--ease-standard);
}
.about-bands__toggle[hidden] { display: none; }
.about-bands__toggle:focus-visible { border-radius: var(--radius-pill); }
.about-bands__toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
@media (max-width: 839px), (hover: none), (pointer: coarse) {
  .about-bands__toggle {
    top: calc(100% + var(--space-sm));
    left: auto;
    right: max(var(--page-margin), calc((100% - var(--container-max)) / 2));
    transform: none;
  }
}
@media (hover: hover) and (pointer: fine) {
  .about-bands__toggle { opacity: 0; }
  .about-bands:hover .about-bands__toggle,
  .about-bands.is-paused .about-bands__toggle,
  .about-bands__toggle:focus-visible { opacity: 1; }
}

/* ---- How I work / How I live: six principle rows -----------------------------------
   Figma: rule above each row, 24px above the row content, 24px between rows;
   number (Nitti 12) in column 1, title (24 Semibold, every second row in
   blue) from column 2, description (16, blue-gray) in columns 8-12. */
.about-principles { padding-block: var(--space-4xl); }
.about-principles .container { display: flex; flex-direction: column; gap: var(--space-xl); }
.about-principles__list { display: flex; flex-direction: column; gap: var(--space-xl); }
.about-principle {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  align-items: center;
  padding-top: var(--space-xl);
  border-top: var(--border-width) solid var(--color-rule);
}
.about-principle__num {
  grid-column: 1;
  font-family: var(--font-detail);
  font-size: 12px;
  line-height: 1.35;
  color: var(--color-gray-2); /* Figma #A0A0A0 -> approved accessible gray */
}
.about-principle__title {
  grid-column: 2 / span 6;
  font-size: var(--text-h300-size);
  font-weight: var(--weight-regular); /* Figma: Regular 20 */
  line-height: var(--text-h300-leading);
  color: var(--color-ink);
}
.about-principle--accent .about-principle__title { color: var(--color-blue-text); }
.about-principle__desc {
  grid-column: 8 / span 5;
  font-size: var(--text-body200-size);
  line-height: var(--text-body200-leading);
  color: var(--color-blue-gray);
}

/* ---- Experience / Currently: staggered fact cells ----------------------------------
   Figma 223:45002 (2026-10-06): 48px band; six 3-column cells in two
   staggered rows on the 12-column grid (row 1: columns 1-3, 4-6, 7-9;
   row 2: 4-6, 7-9, 10-12), 24px between rows; a rule above each cell, 8px
   to its content; label (Nitti 12), value (14 Semibold), note (Nitti 14).
   No rule above or below the band: the field meets the page directly.
   Both states share one translucent light-blue field (--color-band-blue),
   so the page's vertical grid shows through, and its rules use the
   light-blue rule colour (#BEDEFF) instead of grey: decorative rules inside
   a light-blue field are never grey. Labels use --color-gray (AA). */
.about-facts { padding-block: 48px; background: var(--color-band-blue); }
.about-facts .container { display: flex; flex-direction: column; gap: var(--space-xl); }
.about-facts__grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
  column-gap: var(--grid-gutter);
  row-gap: var(--space-xl);
}
.about-fact {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: var(--space-sm);
  border-top: var(--border-width) solid var(--color-things-rule);
}
.about-fact:nth-child(1) { grid-column: 1 / span 3; grid-row: 1; }
.about-fact:nth-child(2) { grid-column: 4 / span 3; grid-row: 1; }
.about-fact:nth-child(3) { grid-column: 7 / span 3; grid-row: 1; }
.about-fact:nth-child(4) { grid-column: 4 / span 3; grid-row: 2; }
.about-fact:nth-child(5) { grid-column: 7 / span 3; grid-row: 2; }
.about-fact:nth-child(6) { grid-column: 10 / span 3; grid-row: 2; }
.about-fact__label,
.about-fact__note {
  font-family: var(--font-detail);
  line-height: 1.35;
  text-transform: uppercase;
}
.about-fact__label { font-size: 12px; color: var(--color-gray); }
.about-fact__value { font-size: var(--text-body300-size); font-weight: var(--weight-semibold); line-height: 1.35; color: var(--color-ink); }
.about-fact__note { font-size: var(--text-details200-size); color: var(--color-gray); }

/* ---- CTA ---------------------------------------------------------------------------
   State-specific heading (34px Bold, About-only) and a shared, informational
   "Let's Connect" with a gently bobbing arrow toward the footer contacts
   directly below (not a link). ON: the clean vector arrow; OFF: the same
   arrow with its textured stroke (see below). Only the arrow moves. */
.about-cta { padding-block: var(--space-3xl); }
.about-cta__row { display: flex; align-items: center; gap: var(--space-2xl); }
.about-cta__heading {
  font-size: 34px;
  font-weight: var(--weight-semibold); /* Figma: Semibold 34 */
  line-height: 1.25;
}
.about-cta__connect {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-sm);
  font-size: var(--text-intro-size);
  line-height: 1.35; /* a one-line CTA label, not body copy */
}
.about-cta__arrows { display: inline-grid; }
.about-cta__arrow-slot {
  display: flex;
  align-items: flex-start;
  height: 1.25em;
  font-size: 32px;
}
.about-cta__arrow {
  display: inline-block;
  font-size: 32px;
  line-height: 1.25;
  color: var(--color-blue-text);
}
/* Both arrows are the same glyph (Figma 197:88476), as masks in the
   blue-text role: ON the clean vector outline, OFF the same outline with
   Figma's textured 1px stroke. Same 19x23 box (at 40px, scaled by em),
   placed where Figma draws it: top just above the "Let's Connect" cap
   height, bottom just below its baseline (measured against Figma). */
.about-cta__arrow--vector {
  width: 0.475em;
  height: 0.575em;
  margin-top: 0.35em;
  background: var(--color-blue-text);
  -webkit-mask: var(--arrow) center / contain no-repeat;
  mask: var(--arrow) center / contain no-repeat;
}
.about-cta__arrow--clean { --arrow: url("/images/about/arrow-on.svg"); }
.about-cta__arrow--drawn { --arrow: url("/images/about/arrow-off.svg"); }
@keyframes about-arrow-bob {
  0%, 100% { transform: translateY(-3px); }
  50% { transform: translateY(3px); }
}
html.motion-ok .about-cta__arrow { animation: about-arrow-bob 1.6s ease-in-out infinite; }

/* ---- Tablet (840-1199) ------------------------------------------------------------
   The H1 runs full width; below it the intro (columns 1-7) sits beside the
   stack (8-12), so the cards stay legible. Rows and fact cells keep their
   columns. */
@media (min-width: 840px) and (max-width: 1199px) {
  .about-hero__grid > .about-title { grid-column: 1 / -1; }
  .about-hero__grid > .about-intro { grid-column: 1 / span 7; }
  .about-hero__stacks { grid-column: 8 / span 5; grid-row: 2; padding-top: var(--space-2xl); }
}

/* ---- Mobile (<840) ------------------------------------------------------------------
   4-column grid: the H1, then the stack (left on the content edge, capped
   at 290px so the offset cards still read as a stack), then the intro.
   The fact cells drop the stagger for a plain 2-column grid. Principle rows
   keep the number in column 1 and stack the title over its description in
   columns 2-4. Fact grids go to two columns; the CTA stacks. */
@media (max-width: 839px) {
  .about-hero__grid > .about-title { grid-column: 1 / -1; padding-top: var(--space-2xl); }
  .about-hero__stacks {
    grid-column: 1 / -1;
    grid-row: 2;
    width: min(100%, 290px);
    justify-self: start;
    padding-block: var(--space-2xl) 0;
  }
  .about-hero__grid > .about-intro { grid-column: 1 / -1; grid-row: 3; padding-bottom: var(--space-2xl); }
  .about-principles { padding-block: var(--space-3xl); }
  .about-principle { row-gap: var(--space-xs); align-items: baseline; padding-top: var(--space-lg); }
  .about-principles__list { gap: var(--space-lg); }
  .about-principle__num { grid-column: 1; grid-row: 1; }
  .about-principle__title { grid-column: 2 / -1; font-size: 20px; }
  .about-principle__desc { grid-column: 2 / -1; }
  .about-facts { padding-block: var(--space-3xl); }
  .about-facts__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl) var(--space-lg); }
  .about-fact:nth-child(n) { grid-column: auto; grid-row: auto; padding-top: var(--space-lg); }
  .about-cta__row { flex-direction: column; align-items: flex-start; gap: var(--space-sm); }
  .about-cta__heading { font-size: var(--text-h100-size); white-space: normal; }
  .about-cta__connect { justify-content: flex-start; }
}
