/* ===========================================================================
   ABOUT DIGITAL EMPATHY — /about-us/  (built 9/18)
   ---------------------------------------------------------------------------
   Built by scripts/build-about.py from Alie's locked copy. Body classes
   "page-launch page-about": the hero, the indigo quote and the closing panel
   are launching.css's; this sheet holds the rest. Tokens only; no gradients
   (verify.js reads every sheet).

   CORNER CHAIN (alternating back from the CTA, each section pulled up by the
   3x corner over the one before and painted above it):
     hero (white) · story TL (INDIGO) · note TR (SKY-SOFT) · team TL
     (white) · glance TR (oat) · CTA TL (.lp-cta)   [9/21: the indigo climbed one
     section for the photo-led opening, so Robert's note took a light ground -
     two dark bands must never sit adjacent.]
   Contrast: ink on white 13.3 · ink on sky-soft 12.3 · petal-muted on sky-soft
   5.5 · oat on indigo 7.01 · oat-75 on indigo 4.77 · lime on indigo 5.44.
   =========================================================================== */

/* --------------------------------------------------------------- 1. hero */
.ab-hero {
  position: relative;
  /* NO z-index and NO isolation here: both would trap .ab-hero__discs below
     .ab-story (z-index 2) and the circles could not cross the seam. The hero's
     white still paints under section 2 because .ab-story is the positioned one. */
  overflow-x: clip;
  overflow-y: visible;
  padding-block: calc(var(--section-pad) * 0.75) calc(var(--s-5) + var(--corner-3x));
  background-color: var(--white);
}
.ab-hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  /* 🔴 INTRINSIC, NOT A BREAKPOINT. A fixed `minmax(0,1fr) 520px` starves the
     text column before it stacks - measured 226px of text beside a 520px photo
     at 924px wide, which broke the H1 onto three lines. auto-fit stacks the two
     tracks instead of crushing one, at every width, with no media query. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: var(--s-6) clamp(var(--s-4), 5vw, 72px);
  align-items: end;
}
.ab-hero__copy { padding-bottom: var(--s-3); }
.ab-hero__h1 { max-width: 11ch; margin: 0 0 var(--s-4); }
/* Altivo, not the display face: it is a paragraph. 500 is the weight .faq__q
   and .t-h3 already use, so it is the house precedent rather than a new step. */
.ab-hero__lead {
  max-width: 28ch;
  margin: 0;
  font-size: clamp(1.5rem, 2.1vw, 1.875rem);
  font-weight: 500;
  line-height: 1.24;
  text-wrap: pretty;
}
.ab-hero__q {
  max-width: 40ch;
  margin: var(--s-3) 0 0;
  color: var(--ink-muted);
  font-size: clamp(1.125rem, 1.4vw, 1.25rem);
  line-height: 1.55;
}

/* The pattern disc moves up-right, BEHIND the arch, so it reads as a ground for
   the photo rather than as the hero's only object. */
.ab-hero__pattern {
  z-index: 0;
  top: -120px;
  right: -8%;
  width: min(520px, 38vw);
  aspect-ratio: 1;
}

/* THE ARCH. A tall panel with a fully rounded top and square feet — the icon's
   body shape, which is where the layout system's radius comes from. Drawn with
   border-radius, not a mask: it stays crisp at any size and needs no SVG. */
.ab-hero__figure { position: relative; isolation: isolate; }
.ab-hero__photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 520 / 620;
  max-height: 620px;
  border-radius: 260px 260px 0 0;
  object-fit: cover;
}
/* 🔴 THE DISCS CROSS THE SEAM (Brees 9/21: "circles in sec1 should overlap
   sec2"), which is launching.css's .lp-hero__discs device, not the photo-anchored
   one this page shipped with. Two things it gets right and a hand-rolled version
   does not: the pair sits in ONE isolated layer, so they still multiply where
   they overlap EACH OTHER but paint true colour over the indigo (multiplying
   petal and lime straight onto indigo turns both to mud - recorded at
   launching.css:48); and the offsets are multiples of each disc's OWN width, so
   the crossing looks the same at every size instead of drifting with the copy. */
.ab-hero__discs {
  position: absolute;
  z-index: 3;            /* over .ab-story (2). The hero itself must stay unpositioned for this to escape. */
  inset: 0;
  isolation: isolate;
  pointer-events: none;
}
.ab-hero__disc {
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  mix-blend-mode: multiply;
}
/* 🔴 THE OFFSET IS FROM THE SEAM, NOT THE HERO'S BOX. .ab-story pulls up over
   the hero by --corner-3x, so the PAINTED seam sits that far above the hero's
   padded bottom edge. Anchored to the box alone (launching.css's raw numbers,
   where no section pulls up) both discs landed wholly inside section 2, on top
   of candid 2's arch - measured 46px of clear indigo above the petal. Paying
   back --corner-3x puts them back astride the seam. */
/* 🔴 CLEAR OF THE PHOTO, ACROSS THE SEAM (Brees 9/21: "shapes shouldn't overlap
   the img, just the section"). The hero's bottom padding IS the gap between the
   photo's foot and the hero's edge (the grid is align-items:end), so deriving
   the top from --corner-3x + --s-5 keeps the discs under the photo at EVERY
   width - a picked px value only clears it at the width it was picked at. The
   photo's foot measured 64px ABOVE the seam, which is why a disc crossing the
   seam from above ran through it. */
/* 🔴 THE DISCS LIVE IN THE GAP BETWEEN THE TWO PHOTOS. Both arches sit in the
   SAME right-hand column, 206px apart with the seam running through that gap
   (measured 9/21), so a disc that crosses the seam has only that band to occupy.
   The sizes below are capped to fit it and still overlap each other; they are
   not free design numbers. Re-measure the gap before enlarging either, or the
   disc lands on candid 1 above or candid 2 below. */
.ab-hero__disc--petal { --d: clamp(88px, 8vw, 150px);  --clear: 14px; width: var(--d); right: 20%; bottom: calc(var(--corner-3x) + var(--s-5) - var(--clear) - var(--d)); background-color: var(--petal); }
.ab-hero__disc--lime  { --d: clamp(104px, 9vw, 164px); --clear: 30px; width: var(--d); right: 13%; bottom: calc(var(--corner-3x) + var(--s-5) - var(--clear) - var(--d)); background-color: var(--lime); }

@media (max-width: 899px) {
  .ab-hero { padding-block: calc(var(--section-pad) * 0.5 + 43px) calc(var(--s-5) + var(--corner-3x)); }
  .ab-hero__pattern { width: 240px; top: -60px; right: -90px; }
  /* Stacked, the photo is full-width and the discs have no gutter to sit in. */
  .ab-hero__discs { display: none; }
  .ab-hero__photo { border-radius: 180px 180px 0 0; }
}
@media (max-width: 599px) {
  .ab-hero__pattern { width: 200px; top: -96px; right: -118px; }
}

/* ------------------------------------------------------------ 2. story */
.ab-story {
  position: relative;
  z-index: 2;
  overflow: hidden;   /* the petal tint bleeds past the box */
  margin-top: calc(-1 * var(--corner-3x));
  /* 🔴 THE BOTTOM PADDING PAYS BACK THE PULL-UP EXACTLY. Anything smaller and
     Robert's note climbs over the closing line - measured 10px of overlap when
     this was authored as its own clamp. Pull-up and pad-out move together. */
  padding-block: calc(var(--section-pad) + 54px) calc(var(--section-pad) + var(--corner-3x));
  border-top-left-radius: var(--corner-3x);
  background-color: var(--indigo);
  color: var(--oat);
}
/* The Google Ads / homepage quote-section device: a large petal circle at 16%,
   bottom-right, well clear of the text column. */
.ab-story::before {
  content: "";
  position: absolute;
  z-index: 0;
  right: -140px;
  bottom: -220px;
  width: min(540px, 38vw);
  aspect-ratio: 1;
  border-radius: var(--r-pill);
  background-color: var(--petal);
  opacity: 0.16;
  pointer-events: none;
}
.ab-story__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
  /* 🔴 THE ROW GAP IS WHAT SETS THE CLOSING LINE DOWN, not its margin: the close
     spans 1/-1 on row 2, so it clears the TALLER of photo/text by this gap.
     Brees 9/21 wanted it tucked under the paragraph - the margin was already 0
     and moving it did nothing until this came down. */
  gap: var(--s-5) clamp(var(--s-4), 5vw, 72px);
  align-items: start;
}
/* Brees 9/21: "in sec2 put the img on the left and text on the right". Done by
   DOCUMENT ORDER, not grid-column numbers: the grid is auto-fit, so at narrow
   widths it collapses to one column and an explicit `grid-column: 2` would
   invent a second track and leave the text in a phantom column. Source order
   gives the swap at wide widths and a sane photo-then-text stack at narrow. */
.ab-story__text { min-width: 0; }
/* THE ARCH AGAIN (Brees 9/21: "the photo in sec2 should still be in a arch"),
   with its feet rounded to the card radius: on a coloured ground a square-footed
   panel reads as a crop, not a shape.
   🔴 Candid 2 is a 12-up call grid at 1.36 landscape and the arch is portrait,
   so the source is cropped to 53% of its width - Brees chose the shape over the
   edge tiles 9/21, knowing four people fall outside it. Re-crop the SOURCE if
   who is in frame ever needs to change; do not stretch the arch to fit. */
.ab-story__photo {
  align-self: start;
  width: 100%;
  height: auto;
  /* 🔴 THE ARCH FITS THE PHOTO, THE PHOTO IS NOT CROPPED TO THE ARCH. Brees
     reflowed the call grid to 2-up portrait (0.593) on 9/21 precisely so nobody
     falls outside it; holding the old 460/640 would have cover-cropped 17% of
     the height - a whole row of four people - for no reason. */
  aspect-ratio: 944 / 1600;
  max-height: 900px;
  border-radius: 230px 230px var(--r-card) var(--r-card);
  object-fit: cover;
}
/* Her section-2 opening line, in Altivo 500 — the same step as the hero's
   standfirst so the two read as one voice across the seam. */
.ab-story__open {
  max-width: 34ch;
  margin: 0;
  color: var(--oat);
  font-size: clamp(1.5rem, 2vw, 1.75rem);
  font-weight: 500;
  line-height: 1.28;
  text-wrap: pretty;
}
.ab-story__p { max-width: 56ch; margin: var(--s-3) 0 0; color: var(--oat); font-size: 1.1875rem; line-height: 1.62; }
.ab-story__p--quiet { margin-top: var(--s-2); color: var(--oat-75); }
/* A short lime rule, not a coloured left border (house style, .sh__quote). */
.ab-story__rule { display: block; width: 40px; height: 3px; margin: var(--s-4) 0 var(--s-3); border-radius: 2px; background-color: var(--lime); }
/* Brees 9/21: no green on "Digital does the labor." The turn there now reads as
   body copy; the lime is spent once, on the closing line, so it lands. */
.ab-story__p .ab-story__turn { color: inherit; }
.ab-story__close .ab-story__turn { color: var(--lime); }
/* Brees 9/21: "under the paragraph on the right" - it now lives INSIDE
   .ab-story__text, so it simply follows the last paragraph in the right column
   and stacks with it. No grid-column: spanning 1/-1 is what put it back on the
   left under the photo. */
.ab-story__close {
  max-width: 30ch;
  /* Brees 9/21: band removed, line pulled up under the paragraph and stepped
     down a size. It still carries the display face and the lime turn, so it
     reads as the close without needing a rule to separate it. */
  margin: var(--s-4) 0 0;
  color: var(--oat);
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 2.4vw, 2.125rem);
  font-weight: 500;
  line-height: 1.18;
  text-wrap: balance;
}

@media (max-width: 899px) {
  .ab-story__photo { border-radius: 160px 160px var(--r-card) var(--r-card); }
}

/* ------------------------------------------------------- 3. Robert's note */
/* .lp-proof supplies the pull-up, the top-right corner and the pad-out; only
   the ground and the quote's colours are overridden here. The petal circle
   .lp-proof::before draws is KEPT — it reads at 16% on sky-soft — but the
   quote's own colours have to come off white/lime. */
.ab-note {
  z-index: 3;
  background-color: var(--sky-soft);
}
.ab-note__h {
  margin: 0;
  color: var(--ink);
  /* Brees 9/21: "make sure roberts section is altivo to match the site". This
     heading is an eyebrow - small, uppercase, tracked - and the rest of the site
     sets that in Altivo. The display face at --fs-small reads as a different
     label, not as the h2 it is. (Reverts the handoff's 9/10-rule change.) */
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.page-about .ab-quote { margin-top: var(--s-4); }
/* Brees 9/21: "center a note from robert section". Centring the text needs the
   quote's own grid centred too, or the block stays left in a centred section. */
.ab-note { text-align: center; }
.ab-note .lp-quote { margin-inline: auto; justify-items: center; }
.ab-note .lp-quote__block, .ab-note .lp-quote__by { justify-self: center; }
/* 9/21 (combined build): launching.css sets the quote text WHITE for the indigo quotes; on sky-soft it has to be ink
   (12.3:1), or the note is unreadable. */
.ab-note .lp-quote__text { margin-inline: auto; color: var(--ink); }
/* Brees 9/21: "have the quote from robert be the same color. Instead add the
   green underline to where the pink was." The turn now reads as the quote
   (--ink, 11.54:1) and the emphasis is carried by a rule under it.
   🔴 NOT --lime. Measured on --sky-soft: --lime #d2db75 = 1.29:1, which is not
   a faint underline, it is an invisible one. --lime-deep = 3.02:1, clearing the
   1.4.11 non-text bar for a graphical object while still reading green.
   (--lime-ink would be 5.60:1 if this wants to be louder.) */
.ab-note .lp-quote__turn {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--lime-deep);
  text-decoration-thickness: 3px;
  text-underline-offset: 6px;
  text-decoration-skip-ink: none;
}
.ab-note .lp-quote__name { color: var(--ink); }
/* The signature sits UNDER the typeset name (Brees 9/21). Capped by width, not
   height, so it scales with the measure; --ink ink on --sky-soft, no recolour. */
.ab-quote__sig {
  display: block;
  width: min(232px, 62%);
  height: auto;
  margin: var(--s-2) auto 0;
}
.ab-note .lp-quote__role { color: var(--ink-muted); }
/* One column: the caption sits under the quote at every width. The 297px logo
   column exists for the client quotes that carry a mark; this one has none, and
   holding the two-track grid left the quote in a third of the measure. */
.ab-note .lp-quote {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: none;
  max-width: 62rem;
}
.ab-note .lp-quote__block,
.ab-note .lp-quote__by { grid-column: 1; grid-row: auto; }
.ab-note .lp-quote__by { margin-top: var(--s-3); }

/* ------------------------------------------------------------- 4. team */
.tm {
  position: relative;
  z-index: 4;
  margin-top: calc(-1 * var(--corner-3x));
  padding-block: calc(var(--section-pad) + 24px) calc(var(--section-pad) + var(--corner-3x));
  border-top-left-radius: var(--corner-3x);
  background-color: var(--white);
}
/* heading + subtext CENTRED over the roster (Brees 9/18: "center the title and subtext instead of having it in two
   columns") */
.tm__head { display: flex; flex-direction: column; align-items: center; gap: var(--s-2); margin: 0 auto var(--s-5); max-width: 40rem; text-align: center; }
.tm__h { margin: 0; }
.tm__intro { margin: 0; color: var(--ink-muted); }

/* A · THE ROSTER. Each row is its heading's button: dot, big name, title, arrow. The portrait (.tm-row__peek) rises
   beside a hovered or focused row on screens wide enough to hold it; the bio opens beneath the row on click/tap. */
.tm-rows { margin: 0; padding: 0; list-style: none; border-bottom: 1px solid rgb(47 47 53 / 0.14); }
.tm-row { position: relative; border-top: 1px solid rgb(47 47 53 / 0.14); }
.tm-row--petal    { --tm-dot: var(--petal); }
.tm-row--lime     { --tm-dot: var(--lime); }
.tm-row--sky      { --tm-dot: var(--sky); }
.tm-row--marigold { --tm-dot: var(--marigold); }
.tm-row__h { margin: 0; font: inherit; }
.tm-row__btn {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto 32px;
  align-items: center;
  column-gap: var(--s-2);
  width: 100%;
  min-height: 44px;
  padding: clamp(20px, 2.6vw, 36px) 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.tm-row__dot { width: 14px; height: 14px; border-radius: 50%; background-color: var(--tm-dot); }
.tm-row__name {
  justify-self: start;   /* as wide as the name, not the column - team.js measures where the name ENDS */
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 4rem);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
  transition: color 0.25s ease;
}
.tm-row__role {
  justify-self: start;
  min-width: 18rem;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.tm-row__arrow { justify-self: end; font-size: 1.625rem; line-height: 1; transition: transform 0.25s ease; }
.tm-row__btn[aria-expanded="true"] .tm-row__arrow { transform: rotate(90deg); }
.tm-row__btn:focus-visible { outline: 3px solid var(--ink); outline-offset: 4px; border-radius: 6px; }
/* while one row is hovered or focused, the others step back (never below 4.5:1 for the titles: ink-muted).
   Pointer devices only: on a phone a tap leaves a sticky :hover and the other names would stay faded. */
@media (hover: hover) {
  .tm-rows:has(.tm-row__btn:hover, .tm-row__btn:focus-visible) .tm-row__btn:not(:hover):not(:focus-visible) .tm-row__name { color: rgb(47 47 53 / 0.38); }
  .tm-rows:has(.tm-row__btn:hover, .tm-row__btn:focus-visible) .tm-row__btn:not(:hover):not(:focus-visible) .tm-row__role { color: var(--ink-muted); }
}

/* the portrait that rises beside the active row (decorative: the name is the button's text). team.js places it in the
   gap between the END OF THAT ROW'S NAME and the start of its title (--tm-peek-x / --tm-peek-w, measured per row), so
   it never covers the name it belongs to; a row without room for it (under ~160px) gets no peek (.tm-row--nopeek).
   Wide screens only - below 1200 the names fill the row, and the photo is in the opened bio anyway. */
.tm-row__peek {
  position: absolute;
  top: 50%;
  left: var(--tm-peek-x, 50%);
  z-index: 3;
  width: var(--tm-peek-w, 220px);
  aspect-ratio: 250 / 310;
  height: auto;
  border-radius: 28px;
  object-fit: cover;
  box-shadow: 0 40px 70px -28px rgb(20 20 30 / 0.55);
  opacity: 0;
  pointer-events: none;
  transform: translate(0, -50%) rotate(-4deg) scale(0.92);
  transition: opacity 0.25s ease, transform 0.35s ease;
}
.tm-row:has(.tm-row__btn:hover, .tm-row__btn:focus-visible) .tm-row__peek { opacity: 1; transform: translate(0, -50%) rotate(-4deg) scale(1); }
.tm-row:has(.tm-row__btn[aria-expanded="true"]) .tm-row__peek,
.tm-row--nopeek .tm-row__peek { opacity: 0; }
@media (max-width: 1199px) { .tm-row__peek { display: none; } }
@media (max-width: 899px) {
  .tm-row__btn { grid-template-columns: 28px minmax(0, 1fr) 28px; row-gap: 6px; }
  .tm-row__role { grid-column: 2; grid-row: 2; min-width: 0; }
  .tm-row__arrow { grid-column: 3; grid-row: 1 / span 2; }
}

/* the bio, opened under its row: the photo (in colour, with its alt) and her three paragraphs */
.tm-bio {
  display: grid;
  gap: var(--s-4);
  padding: 0 0 var(--s-5) 56px;
}
.tm-bio[hidden] { display: none; }
.tm-bio__photo { width: 100%; max-width: 280px; height: auto; aspect-ratio: 4 / 5; border-radius: 24px; object-fit: cover; }
.tm-bio__text { display: flex; flex-direction: column; gap: var(--s-2); max-width: 44rem; }
.tm-bio__text p { margin: 0; color: var(--ink); font-size: 1.0625rem; line-height: 1.65; }
@media (min-width: 900px) { .tm-bio { grid-template-columns: 280px minmax(0, 1fr); align-items: start; } }
@media (max-width: 599px) { .tm-bio { padding-left: 0; } }

/* the band under the roster (9/21): two candids side by side - the roster is the polished half, this is the other
   half. Captions in the roster's small-caps role style, so they read as labels, not copy. */
.tm-band { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); margin: var(--s-5) 0 0; }
.tm-band__ph { margin: 0; }
.tm-band__ph img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 28px; }
@media (max-width: 699px) { .tm-band { grid-template-columns: minmax(0, 1fr); } }
.ab-cap { margin: 12px 0 0; color: var(--ink-muted); font-size: 0.875rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }

/* B · THE PORTRAIT STRIP (local preview only - scripts/build-about.py --b). Name plate BELOW the photo. */
.tmb-cards { display: grid; gap: var(--s-3); margin: 0; padding: 0; list-style: none; }
@media (min-width: 600px)  { .tmb-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .tmb-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.tmb-card { display: flex; flex-direction: column; overflow: hidden; border-radius: 32px; background-color: var(--white); box-shadow: 0 0 0 1px rgb(47 47 53 / 0.1), 0 18px 40px -26px rgb(20 20 30 / 0.4); }
.tmb-card--petal { --tm-dot: var(--petal); } .tmb-card--lime { --tm-dot: var(--lime); }
.tmb-card--sky { --tm-dot: var(--sky); } .tmb-card--marigold { --tm-dot: var(--marigold); }
.tmb-card__photo { display: block; width: 100%; height: auto; aspect-ratio: 300 / 336; object-fit: cover; filter: grayscale(1); transition: filter 0.3s ease; }
.tmb-card:hover .tmb-card__photo { filter: none; }
.tmb-card__plate { display: grid; grid-template-columns: 12px minmax(0, 1fr); column-gap: 12px; margin: 0; padding: 18px 20px 22px; }
.tmb-card__dot { grid-row: 1 / span 2; align-self: center; width: 12px; height: 12px; border-radius: 50%; background-color: var(--tm-dot); }
.tmb-card__name { font-family: var(--font-display); font-size: 1.375rem; font-weight: 500; line-height: 1.15; }
.tmb-card__role { color: var(--ink-muted); font-size: var(--fs-small); }

/* ----------------------------------------------------------- 5. glance */
.ab-glance {
  position: relative;
  z-index: 5;
  margin-top: calc(-1 * var(--corner-3x));
  padding-block: calc(var(--section-pad) + 24px) calc(var(--section-pad) + var(--corner-3x));
  border-top-right-radius: var(--corner-3x);
  background-color: var(--oat);
}
/* 9/21: six fact tiles (was one white card with bullets). The figure or the phrase big, the label small; the roster's
   colour dots; the site's card radius. Same facts, her words. */
.ab-glance__card { max-width: none; }
.ab-glance__h { margin: 0 0 var(--s-4); font-family: var(--font-display); font-size: clamp(1.5rem, 2.6vw, 2.25rem); font-weight: 500; line-height: 1.15; text-align: center; }
.ab-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3); margin: 0; }
.ab-fact { display: flex; flex-direction: column; gap: 10px; min-height: 190px; padding: 26px 28px 28px; border-radius: 24px; background-color: var(--white); box-shadow: 0 0 0 1px rgb(47 47 53 / 0.08), 0 18px 40px -30px rgb(20 20 30 / 0.35); }
.ab-fact::before { content: ""; display: block; width: 14px; height: 14px; margin-bottom: 8px; border-radius: 50%; background-color: var(--dot); }
.ab-fact__big { margin: 0; color: var(--ink); font-family: var(--font-display); font-size: clamp(2.5rem, 3.6vw, 3.5rem); font-weight: 500; line-height: 1; letter-spacing: -0.02em; }
.ab-fact__big--words { font-size: clamp(1.5rem, 2vw, 1.875rem); line-height: 1.15; letter-spacing: -0.01em; }
.ab-fact__label { margin: auto 0 0; color: var(--ink-muted); font-size: 0.9375rem; line-height: 1.45; }
@media (max-width: 999px) { .ab-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 599px) { .ab-facts { grid-template-columns: minmax(0, 1fr); } .ab-fact { min-height: 0; } }

/* ------------------------------------------------------------- 6. CTA */
.page-about .lp-cta { z-index: 6; }

@media (prefers-reduced-motion: reduce) {
  .tm-row__name, .tm-row__arrow, .tm-row__peek, .tmb-card__photo { transition: none; }
}
