/* =========================================================================
   guilhermesantribe.com
   Tokens and components. Values pulled from Figma
   (Site box — Guilhermesantribe, nodes 2028:1192 / 1335 / 1547 / 1689)
   and mapped onto the scales in specs/design.md.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Tokens
   ---------------------------------------------------------------------- */
/* =========================================================================
   LEVEL 1 — PRIMITIVES
   The raw palette, named after the Figma variables. These never change and
   the theme swap never touches them. Components must not reference this
   layer directly; they reference the semantic layer below.
   ========================================================================= */
:root {
  /* the few px an arrow travels on hover — links and buttons share it */
  --arrow-shift: 3px;

  /* ink */
  --ink-500: #161616;
  --ink-400: #383838;
  --ink-300: #6b6b6b;
  --ink-200: #a6a6a6;
  --ink-100: #d9d9d9;

  /* grounds */
  --ground-100: #fdfdfc;
  --ground-200: #fcfbf8;
  --sage-050:   #f1f1ef;
  --sage-100:   #eff0eb;
  --gray-100:   #f6f5f1;
  --cream-050:  #fafaf9;
  --charcoal-050: #f3f2f2;
  --charcoal-500: #292323;
  --base-white: #ffffff;

  /* teal */
  --teal-100: #e7efee;
  --teal-200: #bad4d1;
  --teal-300: #78a499;
  --teal-400: #1f3f38;
  --teal-500: #0c1e1c;

  /* olive / link family */
  --link-500: #1e270f;
  --link-300: #556b2f;
  --link-100: #d5ddc8;

  /* pink */
  --pink-500: #f59191;
  --pink-300: #edbfbf;
  --pink-200: #ecd0d0;

  /* blue */
  --blue-300: #d7e8f7;
  --blue-500: #c1e2ff;

  /* muted inks that exist only to clear AA on a specific ground */
  --ink-muted-on-dark: #bdb7b7;
  --ink-350: #5d5d5d;
  --ink-330: #676767;
  --ink-380: #3f3f3f;
  --ink-420: #242424;
  --stone-300: #aea7a7;
}

/* =========================================================================
   LEVEL 2 — SEMANTIC
   One palette: sage/100 page ground, near-white content surfaces. The
   colour-swap mechanism this layer was built for has been removed, so each
   token below resolves to a single value.

        page ground        content surface
        sage/100           ground/100  (near-white)

   Two ink sets remain, and they differ by WHERE a thing sits:
     - the surface set  (--text-*, --link, --border) is dark ink on a light
       surface — cards, sheets, anything with its own fill;
     - the on-ground set (--on-ground-*) is for the few things that sit
       straight on the page ground (footer, page title, hero card, case
       band, progress chip).
   The palette swap these were built for has been removed, so each token now
   has exactly one value; the split is kept because it still names the two
   contexts correctly and components reference one API.
   ========================================================================= */
:root {
  --bg-page:        var(--sage-100);
  --bg-surface:     var(--ground-100);
  --bg-surface-alt: var(--charcoal-050);
  --bg-inset:       var(--gray-100);

  /* ---- surface set: constant, because surfaces are light either way ---- */
  --text-primary:   var(--ink-500);
  --text-secondary: var(--ink-400);
  --text-muted:     var(--ink-300);
  --text-on-accent: var(--base-white);
  --link:           var(--link-300);
  --border:         var(--ink-100);
  --border-strong:  var(--ink-200);

  /* ---- things sitting directly on the page ground --------------------- */
  --on-ground-text:  var(--ink-500);
  --on-ground-muted: var(--ink-300);
  --on-ground-link:  var(--link-300);
  --on-ground-border: var(--ink-100);
  --on-ground-btn-border: var(--ink-500);

  /* ---- controls -------------------------------------------------------- */
  --btn-bg:         var(--ink-500);
  --btn-fg:         var(--base-white);
  --btn-bg-hover:   var(--teal-500);
  --btn-outline-border: var(--ink-500);
  --btn-disabled-bg:    var(--ink-100);
  --btn-disabled-fg:    var(--ink-200);
  --btn-disabled-border: var(--ink-200);

  /* #242424 rather than #3f3f3f: the darker label is what pays for the 50%
     plate. At #3f3f3f the plate cannot drop below 0.66 without failing AA
     over the darkest backdrop — and 0.66 is the opaque bar being replaced. */
  --nav-ink:        var(--ink-420);
  --nav-active-bg:  var(--ink-500);
  --nav-active-fg:  var(--teal-100);
  --nav-glass:      rgba(255, 255, 255, 0.50);

  /* Nav Pill component set (2052:89475), all four real states.
     These four were referenced in ~10 rules but never defined — an
     undefined var invalidates the whole declaration, so every pill hover
     silently did nothing. Values read from the component, not invented:
       inactive + hover  bg #1f3f38  ink #e7efee
       active   + hover  bg #e7efee  ink #161616  */
  --pill-hover:            var(--teal-400);
  --pill-hover-ink:        var(--teal-100);
  --pill-active-hover:     var(--teal-100);
  --pill-active-hover-ink: var(--ink-500);

  /* button set (2002:8864), type=secondary state=hover: fills #0c1e1c and
     the label goes white. Same missing-token bug as the pills. */
  --btn-outline-hover:        var(--teal-500);
  --btn-outline-hover-border: var(--teal-500);
  --btn-outline-hover-ink:    var(--base-white);
}

/* Anything that sits straight on the page ground takes the on-ground set by
   re-pinning the same token names, so components keep referencing one API. */
.site-footer,
.page-title-block,
.page--case .case-hero,
.stack-card--hero {
  --text-primary:   var(--on-ground-text);
  --text-secondary: var(--on-ground-text);
  --text-muted:     var(--on-ground-muted);
  --link:           var(--on-ground-link);
  --border:         var(--on-ground-border);
  --btn-outline-border: var(--on-ground-btn-border);
}

/* A control on a light SURFACE keeps a dark outline. */
.stack-card,
.shell,
.home2-case,
.stack-card--about { --btn-outline-border: var(--ink-500); }
.stack-card--hero { --btn-outline-border: var(--on-ground-btn-border); }
.stack-card--charcoal { --btn-outline-border: var(--pink-500); }

:root {
  /* ---- compatibility aliases ----------------------------------------- */
  --shell-bg: var(--bg-page);
  --page-bg: var(--bg-surface);
  --text: var(--text-primary);
  --ink-label: var(--text-muted);
  --ink-meta: var(--text-muted);
  --accent: var(--link);
  --rule: var(--border);
  /* Figma "Details" component toggle label. */
  --case-details-link: #006b4f;
  --link-color: var(--link);

  /* ---- Type ------------------------------------------------------------
     Two families, one job each. Source Serif Pro: hero, section sentences,
     card titles, emphasis. DM Sans: body, lead, label, meta, number,
     button, menu, tab. */
  --font-serif: "Source Serif Pro", Georgia, "Times New Roman", serif;
  --font-sans: "DM Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: var(--font-serif);
  --font-poster: var(--font-serif);
  --font-body-case: var(--font-sans);

  /* Role scale. Base html is 16px, so 1rem = 16px. */
  --text-display: clamp(2.5rem, 6vw, 3.5rem);
  --text-h1: 2.5rem;
  --text-h2: 1.75rem;
  --text-lead: 1.25rem;
  --text-body: 1rem;
  --text-label: 0.75rem;
  --text-meta: 0.8125rem;
  --text-ui: 0.9375rem;
  --text-stat: 3rem;

  --lh-display: 1.05;
  --lh-h1: 1.1;
  --lh-h2: 1.15;
  --lh-lead: 1.5;
  --lh-label: 1.2;
  --lh-meta: 1.4;
  --lh-ui: 1;
  --lh-stat: 1;
  --ls-label: 0.04em;

  /* Fixed ramp — specs/design.md */
  --size-12: 0.75rem;
  --size-14: 0.875rem;
  --size-15: 0.9375rem;
  --size-16: 1rem;
  --size-18: 1.125rem;
  --size-20: 1.25rem;
  --size-24: 1.5rem;
  --size-28: 1.75rem;
  --size-32: 2rem;
  --size-36: 2.25rem;
  --size-48: 3rem;
  --size-64: 4rem;

  --lh-tight: 1.15;
  --lh-heading: 1.3;
  --lh-body: 1.4;
  --lh-prose: 1.6;

  /* ---- Space — 4px base ----------------------------------------------- */
  --sp-4: 4px;
  --sp-8: 8px;
  --sp-12: 12px;
  --sp-16: 16px;
  --sp-24: 24px;
  --sp-32: 32px;
  --sp-48: 48px;
  --sp-60: 60px;
  --sp-64: 64px;
  --sp-80: 80px;
  --sp-96: 96px;
  --sp-120: 120px;
  --sp-150: 150px;

  /* ---- Layout ---------------------------------------------------------- */
  --column: 1280px;
  --content: 1040px;
  --gutter: 120px;
  --aside: 320px;
  --prose: 720px;

  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-card: 8px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  --ease: cubic-bezier(0.2, 0, 0.2, 1);
}

/* -------------------------------------------------------------------------
   2. Base
   ---------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { font-size: 16px; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lh-prose);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }

h1, h2, h3, h4 { margin: 0; font-weight: 400; }
p { margin: 0; }
ul { margin: 0; padding: 0; }

a { color: inherit; }

/* Emphasis: the two families share one line rather than one shouting.
   Use sparingly — a phrase, not a sentence. */
.emphasis-serif {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 600;
}

/* Visible focus everywhere — guidelines.md, non-negotiable */
:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}
.shell :where(a, button, [tabindex]):focus-visible { outline-color: var(--link-300); }
.site-header :where(a, button):focus-visible,
.site-footer :where(a, button):focus-visible { outline-color: var(--link-100); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute;
  left: var(--sp-16);
  top: -100px;
  z-index: 100;
  background: var(--link-100);
  color: var(--link-500);
  padding: var(--sp-12) var(--sp-16);
  border-radius: var(--radius-md);
  font-size: var(--size-14);
  font-weight: 500;
  text-decoration: none;
  transition: top 160ms var(--ease);
}
.skip-link:focus { top: var(--sp-16); }

/* -------------------------------------------------------------------------
   3. Layout shell
   ---------------------------------------------------------------------- */
.page {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
}

/* The white column the content sits on */
.shell {
  width: 100%;
  max-width: var(--column);
  background: var(--bg-surface);
  overflow: clip;
}

.shell--padded { padding: var(--gutter); }

.stack { display: flex; flex-direction: column; }
.stack--150 { gap: var(--sp-150); }
.stack--80 { gap: var(--sp-80); }

/* Two-column section: label left, content right */
.section {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-64);
  width: 100%;
}
.section--ruled {
  border-top: 1px solid var(--rule);
  padding-block: var(--gutter);
}
.section__label {
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-size: var(--size-32);
  line-height: var(--lh-heading);
  letter-spacing: -0.32px;
  color: var(--text-muted);
}
.section__body {
  flex: 0 1 546px;
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}

.prose { font-family: var(--font-sans); font-size: var(--text-body); line-height: var(--lh-prose); }
.prose > p + p { margin-top: 1em; }
.prose--muted { color: var(--text-muted); }

/* -------------------------------------------------------------------------
   4. Header + nav chips  (component: Header/Nav)
   ---------------------------------------------------------------------- */
.site-header {
  width: 100%;
  max-width: var(--column);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  padding: var(--sp-16) var(--sp-24);
}

.site-header__home {
  display: block;
  border-radius: 50%;
  flex: 0 0 auto;
}
.site-header__avatar {
  width: 45px; height: 45px;
  border-radius: 50%;
  object-fit: cover;
}

.nav-chips {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  flex-wrap: wrap;
  justify-content: flex-end;
}
.nav-chips ul {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  flex-wrap: wrap;
  justify-content: flex-end;
  list-style: none;
}

/* Choice Chip — PADS design system pill */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  height: 32px;
  padding: 7px var(--sp-12);
  border-radius: var(--radius-pill);
  background: var(--link-100);
  color: var(--link-500);
  font-size: var(--size-14);
  font-weight: 500;
  line-height: 16px;
  letter-spacing: -0.25px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 160ms var(--ease), color 160ms var(--ease);
}
.chip:hover { background: #e6ebdd; }
.chip[aria-current="page"] {
  background: transparent;
  color: var(--link);
  box-shadow: inset 0 0 0 1px var(--link-100);
}

/* -------------------------------------------------------------------------
   5. Buttons and links
   ---------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  padding: var(--sp-12) var(--sp-24);
  border-radius: var(--radius-md);
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  font-weight: 500;
  line-height: var(--lh-ui);
  letter-spacing: -0.25px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms var(--ease), color 160ms var(--ease);
}
.btn:hover { background: var(--accent); color: var(--text-primary); }

.btn--solid {
  background: var(--accent);
  color: var(--text-primary);
}
.btn--solid:hover { background: var(--link-500); border-color: var(--link-500); }

.btn__icon { width: 16px; height: 16px; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--accent);
  font-size: var(--size-14);
  line-height: 1.8;
  text-decoration: none;
  width: fit-content;
}
.link-arrow::after {
  content: "→";
  transition: transform 160ms var(--ease);
}
.link-arrow:hover::after { transform: translateX(3px); }

/* -------------------------------------------------------------------------
   6. Hero (Home)
   ---------------------------------------------------------------------- */
.hero {
  position: relative;
  border-top: 1px solid var(--rule);
  padding-block: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
.hero__headline {
  font-family: var(--font-display);
  font-size: var(--size-64);
  line-height: var(--lh-tight);
  letter-spacing: -0.64px;
  color: var(--text-secondary);
  max-width: 720px; /* clears the portrait, which starts at 74% */
}

/* Line breaks that exist in the Figma composition. They hold on desktop
   and get out of the way once the text has to reflow. */
.designed-break { display: inline; }
@media (max-width: 900px) {
  .designed-break { display: none; }
}
.hero__sub {
  font-size: var(--size-18);
  line-height: var(--lh-body);
  letter-spacing: 0.2px;
  color: var(--text-muted);
  max-width: 46ch;
}
.hero__portrait {
  position: absolute;
  top: calc(var(--gutter) * -1);
  left: 74%; /* Figma: runs to the right edge of the white column */
  width: 406px;
  height: 825px;
  object-fit: cover;
  pointer-events: none;
}

/* -------------------------------------------------------------------------
   7. Case card (component: Case-card)
   ---------------------------------------------------------------------- */
/* On the link/100 band, ink/300 falls to 3.8:1 and link/300 to 4.25:1 —
   both under AA. Inside a band, labels step to ink/400 (8.4:1) and the
   accent darkens to #46591f (5.5:1). */
.band,
.about-row--band {
  --ink-label: var(--ink-400);
  --text-muted: var(--ink-400);
  --accent: #46591f;
}

.band {
  background: var(--link-100);
  padding: var(--sp-80) var(--sp-64);
  display: flex;
  flex-direction: column;
  gap: var(--sp-64);
  width: 100%;
}
.band__label {
  font-family: var(--font-display);
  font-size: var(--size-32);
  line-height: var(--lh-heading);
  letter-spacing: -0.32px;
  color: var(--text-muted);
}

.case-card {
  /* The card carries its own light ground, so the accent goes back to
     the designed link/300 (5.8:1 here). */
  --accent: var(--link-300);
  --text-muted: var(--ink-300);
  background: var(--ground-200);
  padding: var(--sp-32);
  display: flex;
  flex-direction: column;
  gap: var(--sp-32);
  text-decoration: none;
  color: inherit;
}
.case-card__logo { width: 54px; height: auto; }
.case-card__title {
  font-family: var(--font-display);
  font-size: var(--size-24);
  line-height: 30px;
  letter-spacing: -0.12px;
  color: var(--text-primary);
}
.case-card__teaser {
  font-family: var(--font-display);
  font-size: 17px;
  line-height: 27.2px;
  /* Figma: rgba(22,22,22,.7) — 6.9:1 on ground/200, passes AA */
  color: rgba(22, 22, 22, 0.7);
  max-width: 70ch;
}
.case-card__foot {
  border-top: 1px solid rgba(22, 22, 22, 0.1);
  padding-top: var(--sp-24);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-24);
  flex-wrap: wrap;
}

/* Metric — evidence gets its own treatment (guidelines.md) */
.metric__value {
  font-size: var(--size-32);
  line-height: 32px;
  letter-spacing: -0.64px;
  color: var(--accent);
}
.metric__label {
  margin-top: var(--sp-4);
  font-size: var(--size-12);
  line-height: 18px;
  letter-spacing: 0.96px;
  text-transform: uppercase;
  /* Figma: rgba(22,22,22,.5) = 3.3:1, fails AA. Stepped to .72 → 5.1:1 */
  color: rgba(22, 22, 22, 0.72);
}

/* -------------------------------------------------------------------------
   8. Rails — horizontally scrolling strips that bleed past the column
   ---------------------------------------------------------------------- */
.rail {
  display: flex;
  gap: var(--sp-24);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: var(--sp-8);
  /* thin, unobtrusive scrollbar */
  scrollbar-width: thin;
  scrollbar-color: var(--ink-200) transparent;
}
.rail > * { scroll-snap-align: start; flex: 0 0 auto; }
/* In Figma these strips are wider than the content column and run off its
   right edge. Bleed to the edge of the white column, then scroll. */
.rail--bleed { margin-right: calc(var(--gutter) * -1); }
.rail::-webkit-scrollbar { height: 6px; }
.rail::-webkit-scrollbar-thumb { background: var(--ink-200); border-radius: 3px; }
.rail::-webkit-scrollbar-track { background: transparent; }

/* Story thumbnails (component: Story-thumbnail) */
.rail--stories { gap: var(--sp-16); }
.story-thumb {
  width: 306px;
  height: 341px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  display: block;
}
.story-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
  transition: filter 240ms var(--ease), transform 240ms var(--ease);
}
a.story-thumb:hover img { filter: grayscale(0); transform: scale(1.02); }

/* Article card (component: Article-card) */
.article-card {
  background: var(--gray-100);
  border-radius: var(--radius-sm);
  width: 500px;
  height: 300px;
  padding: var(--sp-24);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-16);
  overflow: hidden;
  text-decoration: none;
  color: var(--text-primary);
}
.article-card__text { display: flex; flex-direction: column; gap: var(--sp-8); }
.article-card__title {
  font-size: var(--size-20);
  font-weight: 500;
  line-height: var(--lh-body);
  letter-spacing: -0.2px;
  max-width: 20ch;
}
.article-card__title b { font-weight: 700; }
.article-card__source {
  font-family: var(--font-sans);
  font-size: var(--text-meta);
  line-height: var(--lh-meta);
  color: var(--text-muted);
}
.article-card__image {
  align-self: stretch;
  width: 250px;
  object-fit: cover;
  flex: 0 0 auto;
}
/* no underline on hover — the card lift and fill carry the state */

.article-card--cta {
  width: 205px;
  background: var(--ink-500);
  color: var(--text-primary);
  align-items: center;
  justify-content: center;
  text-align: center;
}
.article-card--cta span {
  font-family: var(--font-poster);
  font-size: var(--size-36);
  line-height: 1.1;
}

/* -------------------------------------------------------------------------
   9. Experience rows (component: Experience-row)
   ---------------------------------------------------------------------- */
.experience-list { list-style: none; width: 100%; max-width: 546px; }
.experience-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-24);
  padding: var(--sp-24);
  border-bottom: 1px solid var(--rule);
}
.experience-row__org {
  font-size: var(--size-24);
  font-weight: 500;
  line-height: var(--lh-heading);
  letter-spacing: -0.24px;
  color: var(--text-primary);
}
.experience-row__org a { text-decoration: underline; }
.experience-row__role {
  font-size: var(--size-18);
  line-height: var(--lh-body);
  letter-spacing: 0.2px;
  color: var(--text-primary);
}
.experience-row__period {
  font-size: var(--size-18);
  line-height: var(--lh-body);
  letter-spacing: 0.2px;
  color: var(--text-muted);
  text-align: right;
  white-space: nowrap;
}

/* -------------------------------------------------------------------------
   10. Footer (component: Footer/Contato)
   ---------------------------------------------------------------------- */
.site-footer {
  width: 100%;
  max-width: var(--column);
  background: var(--bg-page);
  color: var(--text-primary);
  padding: var(--sp-80) var(--gutter) var(--sp-48);
}
.site-footer__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-64);
  flex-wrap: wrap;
}
.site-footer__title {
  font-family: var(--font-serif);
  font-size: var(--text-display);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: -0.02em;
  color: var(--text-primary);
  max-width: 12ch;
}
.site-footer__cta { display: flex; flex-direction: column; gap: var(--sp-12); max-width: 546px; }
.site-footer__question {
  font-size: var(--size-20);
  line-height: 1.65;
  color: var(--text-primary);
}
.site-footer__email {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  font-size: var(--size-20);
  font-weight: 600;
  letter-spacing: -0.2px;
  color: var(--link);
  text-decoration: none;
  width: fit-content;
}
/* the email's arrow is the same glyph the links below it use */
.site-footer__email .ext-arrow { font-size: 0.8em; }

.site-footer__bottom {
  margin-top: var(--sp-64);
  padding-top: var(--sp-48);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-32);
  flex-wrap: wrap;
}
.site-footer__links,
.site-footer__nav ul {
  display: flex;
  align-items: center;
  gap: var(--sp-32);
  flex-wrap: wrap;
  list-style: none;
}
.site-footer a:not(.site-footer__email) {
  font-size: var(--size-15);
  line-height: 22.5px;
  color: var(--link);
  text-decoration: none;
}
.site-footer__links a { text-decoration: underline; }
.site-footer__nav a:hover { text-decoration: underline; }

/* Section 11 (the first About build) removed — its .about-hero/.about-row
   rules were dead and .about-card collided with the redesign below. */

/* -------------------------------------------------------------------------
   12. Short stories page
   ---------------------------------------------------------------------- */
/* Figma 2028:1335: no rules between cases — 120px of air does the work. */
.story {
  padding-block: var(--sp-60, 60px);
  display: flex;
  flex-direction: column;
  gap: var(--sp-60, 60px);
}
/* the rule between consecutive stories — it is the divider the page had,
   drawn on the separator rather than as an extra element */
.story + .story {
  padding-top: var(--sp-60, 60px);
  border-top: 1px solid var(--rule);
}
.story__head {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-24);
}
/* 320 ident + 24 gap + 696 body = the 1040 content column */
.story__ident {
  flex: 0 0 var(--aside);
  max-width: var(--aside);
  display: flex;
  flex-direction: column;
  gap: var(--sp-12);
}
/* subject and company sit tight together, the tension line breathes below */
.story__subject {
  font-family: var(--font-sans);
  font-size: var(--text-lead);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--text-muted);
}
.story__org {
  margin-top: calc(var(--sp-8) - var(--sp-12));
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: 400;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--text-muted);
}
.story__title {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--text-h2);
  font-weight: 400;
  line-height: var(--lh-h2);
  letter-spacing: -0.01em;
  color: var(--text-secondary);
}
.story__body { flex: 1 1 696px; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-24); }
.story__block { display: flex; flex-direction: column; gap: var(--sp-8); }
.story__block h3 {
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: 400;
  line-height: var(--lh-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-primary);
}
.story__block p {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lh-prose);
  color: var(--text-muted);
}
.story__media {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-24);
}
.story__media img {
  border-radius: var(--radius-sm);
  object-fit: cover;
  height: 480px;
  background: var(--gray-100);
}
/* The fixed 290 / flexible 720 pair lived here. Both images are now driven
   from a shared height with width:auto (section 32.6), so they keep their
   own proportions and their relative sizes at every width. These rules were
   more specific than that one and pinned the first image at 290px. */

/* -------------------------------------------------------------------------
   13. Resume page
   ---------------------------------------------------------------------- */
.resume-section {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-48);
  width: 100%;
}
.resume-section__aside { flex: 0 0 var(--aside); max-width: var(--aside); }
.resume-section__label {
  font-size: var(--size-24);
  font-weight: 500;
  line-height: var(--lh-heading);
  letter-spacing: -0.24px;
  color: var(--text-primary);
}
.resume-section__sub {
  font-size: var(--size-18);
  line-height: var(--lh-body);
  letter-spacing: 0.2px;
  color: var(--text-muted);
  max-width: 233px;
}
.resume-section__body {
  flex: 0 1 var(--prose);
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lh-prose);
  color: var(--text-muted);
}
.resume-section__body > p + p { margin-top: 0; }

.resume-job { display: flex; flex-direction: column; gap: var(--sp-24); }
.resume-job__head {
  border-bottom: 1px solid var(--rule);
  padding-bottom: var(--sp-24);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-24);
  flex-wrap: wrap;
}
.resume-job__org {
  font-size: var(--size-24);
  font-weight: 500;
  line-height: var(--lh-heading);
  letter-spacing: -0.24px;
  color: var(--text-primary);
}
.resume-job__role {
  font-size: var(--size-18);
  line-height: var(--lh-body);
  color: var(--text-muted);
}
.resume-job__period {
  font-size: var(--size-18);
  color: var(--text-muted);
  white-space: nowrap;
}
.resume-job h4 {
  font-size: var(--size-18);
  font-weight: 700;
  color: var(--text-primary);
  margin-top: var(--sp-8);
}
.resume-list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-12); }
.resume-list li { position: relative; padding-left: var(--sp-24); }
.resume-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.6em;
  width: 6px; height: 1px;
  background: var(--ink-200);
}

.education-item {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-bottom: var(--sp-24);
  border-bottom: 1px solid var(--rule);
}
.education-item__period { font-size: var(--size-14); color: var(--text-muted); }
.education-item__name { font-size: var(--size-18); font-weight: 500; color: var(--text-primary); }
.education-item__org { font-size: var(--size-14); color: var(--text-muted); }

/* -------------------------------------------------------------------------
   14. Motion — only to clarify sequence
   ---------------------------------------------------------------------- */
.reveal { opacity: 1; }
/* JS adds .js-reveal only when it can also remove it; content never depends on it */
.js .reveal.js-reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
}
.js .reveal.js-reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .js .reveal.js-reveal { opacity: 1; transform: none; }
}

/* -------------------------------------------------------------------------
   15. Responsive — mobile is designed, not derived (checked at 375px)
   ---------------------------------------------------------------------- */
@media (max-width: 1160px) {
  :root { --gutter: 64px; --sp-150: 96px; }
  .hero__portrait { position: static; width: 100%; height: 420px; margin-top: var(--sp-32); }
  .hero__headline { max-width: none; }
  .about-hero { flex-direction: column; }
  .about-hero__portrait { width: 100%; flex: 0 0 auto; }
}

@media (max-width: 900px) {
  :root { --gutter: 40px; --sp-150: 80px; --sp-120: 72px; }

  .section,
  .story__head,
  .resume-section {
    flex-direction: column;
    gap: var(--sp-24);
  }
  .section__body,
  .story__body,
  .resume-section__body,
  .story__ident,
  .resume-section__aside {
    flex: 1 1 auto;
    max-width: none;
    width: 100%;
  }
  .section--ruled { padding-block: var(--sp-64); }

  .about-row,
  .about-row--reverse { flex-direction: column; align-items: stretch; gap: var(--sp-32); }
  .about-row__media,
  .about-row__content { flex: 1 1 auto; }
  .about-row--band .about-row__media { flex: 0 0 auto; max-width: 197px; }

  /* They stay side by side and scroll sideways rather than stacking. */
  .story__media { flex-direction: row; }
  .story__media img { width: auto; flex: 0 0 auto; height: clamp(240px, 52vw, 380px); }
  .story__media--single img { width: 100%; height: auto; }

  .band { padding: var(--sp-48) var(--sp-32); }
  .experience-list { max-width: none; }
}

@media (max-width: 640px) {
  :root {
    --gutter: 20px;
    --size-64: 2.5rem;
    --size-48: 2rem;
    --size-32: 1.5rem;
  }
  body { font-size: var(--size-16); }

  .site-header { padding: var(--sp-12) var(--sp-16); flex-wrap: wrap; }
  .nav-chips ul { justify-content: flex-start; }

  .shell--padded { padding: var(--gutter); }
  .site-footer { padding: var(--sp-48) var(--gutter) var(--sp-32); }
  .site-footer__title { max-width: none; }
  .site-footer__bottom { margin-top: var(--sp-32); padding-top: var(--sp-24); }

  .experience-row { flex-direction: column; align-items: flex-start; gap: var(--sp-8); padding: var(--sp-16) 0; }
  .experience-row__period { text-align: left; }

  .article-card { width: 300px; height: auto; min-height: 240px; flex-direction: column; align-items: flex-start; }
  .article-card__image { width: 100%; height: 140px; align-self: auto; }
  .article-card--cta { width: 300px; min-height: 160px; align-items: center; }

  .story-thumb { width: 220px; height: 250px; }
  .about-card { width: 300px; padding: var(--sp-24); }
  .case-card { padding: var(--sp-24); }
  .band { padding: var(--sp-32) var(--sp-24); }
}

/* -------------------------------------------------------------------------
   16. Print — this is what "Download resume" produces
   ---------------------------------------------------------------------- */
@media print {
  @page { margin: 16mm; }
  body { background: #fff; color: var(--text-primary); font-size: 10.5pt; }
  .site-header,
  .site-footer,
  .skip-link,
  .no-print { display: none !important; }
  .shell { max-width: none; padding: 0; }
  .resume-section {
    break-inside: avoid;
    page-break-inside: avoid;
    gap: var(--sp-24);
  }
  .resume-section__body { color: var(--text-primary); }
  .resume-job__head { break-after: avoid; page-break-after: avoid; }
  a { text-decoration: none; color: var(--text-primary); }
  .stack--80 { gap: 32px; }
}

/* -------------------------------------------------------------------------
   17. Case page (Selected work)
   Figma node 2048:18410. Narrower reading column (676px) and its own
   type treatment: Inter for running text instead of DM Sans.
   ---------------------------------------------------------------------- */
:root { --case-column: 676px; }

/* Dark title band, above the white page column */
.case-hero {
  width: 100%;
  max-width: var(--column);
  background: var(--link-500);
  padding: var(--sp-64) var(--gutter) var(--sp-80);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  text-align: center;
}
/* Figma 2048:18410 sets this line in DM Sans with "first three months" in
   Source Serif Pro SemiBold Italic. That mix is the point — the base stays
   sans and only the emphasis span switches family. */
.case-hero__title {
  font-family: var(--font-sans);
  font-size: var(--text-h1);
  font-weight: 400;
  line-height: var(--lh-h1);
  letter-spacing: -0.01em;
  color: var(--text-primary);
  max-width: 1042px;
}
.case-hero__meta {
  font-family: var(--font-sans);
  font-size: var(--text-meta);
  line-height: var(--lh-meta);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
}

.case-body {
  width: 100%;
  max-width: var(--case-column);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-48);
}

/* Running text on this page is Inter.
   Figma sets it at 14px; guidelines.md floors body text at 16px, so it
   renders at 16 with the designed 1.8 rhythm kept. */
.case-block { display: flex; flex-direction: column; gap: var(--sp-8); }
.case-eyebrow {
  font-size: var(--size-12);
  line-height: 1.8;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--text-muted);
}
.case-text {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lh-prose);
  color: var(--text-secondary);
}
.case-text > p + p { margin-top: 1.2em; }
.case-text b, .case-text strong { font-weight: 700; color: var(--text-primary); }

/* Break between the two initiatives */
.case-breakpoint {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  text-align: center;
  padding-top: var(--sp-32);
}
.case-breakpoint__label {
  font-family: var(--font-body-case);
  font-size: 10px;
  line-height: 1.8;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
.case-breakpoint__title {
  font-family: var(--font-display);
  font-size: var(--size-32);
  line-height: var(--lh-body);
  color: var(--text-primary);
}
.case-breakpoint__sub {
  font-family: var(--font-body-case);
  font-size: var(--size-16);
  line-height: 1.8;
  color: var(--text-muted);
  max-width: 60ch;
}

.case-divider { border: 0; border-top: 1px solid var(--rule); width: 100%; margin: 0; }

/* Two-column fact list — Initiatives / What we move */
.case-facts {
  display: flex;
  gap: var(--sp-24);
  flex-wrap: wrap;
}
.case-facts > div { flex: 1 1 240px; display: flex; flex-direction: column; gap: var(--sp-8); }
.case-list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-8); }
.case-list li {
  position: relative;
  padding-left: var(--sp-16);
  font-family: var(--font-body-case);
  font-size: var(--size-16);
  line-height: 1.8;
  color: var(--text-primary);
}
.case-list li::before {
  content: "\2726";
  position: absolute;
  left: 0;
  font-size: 8px;
  line-height: 2.9;
  color: var(--text-secondary);
}

/* The hypothesis / value-props panel — real text, ruled top and bottom.
   Figma component "Details" (2048:18735): the toggle sits at the FOOT of the
   panel, under the content, so the summary is ordered last. Values read from
   the node — rules #ebebeb 1px, label #006b4f at 14px. */
.case-details {
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding-block: var(--sp-16);
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
.case-details__content {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
/* display:flex on the <details> itself (needed to order the summary last)
   stops the UA from hiding the closed content, so hide it explicitly. */
.case-details:not([open]) > .case-details__content { display: none; }
.case-details__toggle {
  order: 2;                     /* the toggle belongs under the content */
  list-style: none;             /* drop the native disclosure triangle */
  display: inline-flex;
  align-items: center;
  gap: 4px;
  align-self: flex-start;
  font-family: var(--font-sans);
  font-size: var(--size-14);
  line-height: 25px;
  color: var(--case-details-link);
  cursor: pointer;
  user-select: none;
}
.case-details__toggle::-webkit-details-marker { display: none; }
/* the sign is the affordance: minus when open, plus when closed */
.case-details__toggle::before {
  content: "+";
  display: inline-block;
  width: 7px;
  text-align: center;
}
.case-details[open] > .case-details__toggle::before { content: "-"; }
.case-details__toggle:hover { text-decoration: underline; }
.case-details__toggle:focus-visible {
  outline: 2px solid var(--case-details-link);
  outline-offset: 3px;
  border-radius: 2px;
}
.case-details__lede {
  font-family: var(--font-body-case);
  font-size: var(--size-16);
  line-height: 1.8;
  color: var(--text-secondary);
}
.case-details__question {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--size-20);
  line-height: 1.8;
  color: var(--text-secondary);
}

/* Evidence pulled out of the running text */
.case-quote {
  font-family: var(--font-display);
  font-size: var(--size-18);
  line-height: 1.8;
  color: var(--text-secondary);
  margin: 0;
}

/* Figures. Wide ones bleed past the reading column but stay in the page. */
.case-figure { margin: 0; display: flex; flex-direction: column; gap: var(--sp-12); }
.case-figure img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  background: var(--gray-100);
}
.case-figure figcaption {
  font-family: var(--font-body-case);
  font-size: var(--size-14);
  line-height: 1.7;
  color: var(--text-muted);
}
.case-figure--wide {
  width: min(1040px, calc(100vw - 2 * var(--gutter)));
  margin-inline: calc((var(--case-column) - min(1040px, 100vw - 2 * var(--gutter))) / 2);
}
.case-figure__label {
  font-family: var(--font-body-case);
  font-size: var(--size-12);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}

.case-close__title {
  font-family: var(--font-display);
  font-size: var(--size-32);
  line-height: var(--lh-body);
  color: var(--text-primary);
}

/* Back to the rest of the work — no dead ends (guidelines.md) */
.case-next {
  border-top: 1px solid var(--rule);
  padding-top: var(--sp-32);
  display: flex;
  gap: var(--sp-24);
  flex-wrap: wrap;
}

@media (max-width: 900px) {
  .case-hero { padding: var(--sp-48) var(--gutter) var(--sp-64); }
  .case-figure--wide { width: 100%; margin-inline: 0; }
  .case-facts { flex-direction: column; }
}

/* =========================================================================
   18. Home redesign — Figma node 2035:10155
   Scoped to .page--home2 so the other pages keep the current language until
   they are redesigned too.
   ========================================================================= */
body.home2 { background: var(--bg-page); }

/* <main> here has no width of its own, so as a shrink-to-fit flex item it
   was sizing to the max-content of the rails (~2000px) and dragging the
   hero to 1280px inside a 375px viewport. Pin it to the viewport. */
.page--home2 > main {
  width: 100%;
  max-width: var(--column);
  min-width: 0;
  margin-inline: auto;
}
.page--home2 .home2-sheet,
.page--home2 .home2-hero,
.page--home2 .home2-header { min-width: 0; }

.page--home2 {
  --black-500: var(--bg-page);  /* alias -> semantic ground */
  --teal-500: #0c1e1c;
  --teal-100: #e7efee;
  --blue-300: #d7e8f7;
  --cream-050: #fafaf9;
  --ground-cream-100: #f3f2ea;
  --ink-100: #d9d9d9;
  --brand: #90bcd9;
  --secondary: #b39eb5;
  --offwhite: var(--text-primary);  /* alias -> semantic ink */

  background: var(--bg-page);
}

/* ---- Header: pill group ---------------------------------------------- */
.home2-header {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: var(--column);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  padding: var(--sp-16) var(--sp-24);
}
.nav-pillgroup {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4);
  border-radius: var(--radius-card);
  background: rgba(255, 255, 255, 0.2);
  list-style: none;
  flex-wrap: wrap;
}
.nav-pill {
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: var(--sp-12) var(--sp-24);
  border-radius: var(--radius-md);
  color: var(--nav-ink);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  font-weight: 500;
  line-height: var(--lh-ui);
  letter-spacing: -0.25px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 160ms var(--ease);
}
.nav-pill:hover { background: rgba(0, 0, 0, 0.25); }
.nav-pill[aria-current="page"] {
  background: var(--ink-500);
  color: #e7efee;   /* Nav Pill 2052:89475, Active=Yes */
  font-weight: 700;
}

/* ---- Hero: stays put while the sheet rides up over it ----------------- */
.home2-hero {
  position: sticky;
  top: 0;
  z-index: 0;
  width: 100%;
  max-width: var(--column);
  margin-inline: auto;
  /* No right padding: the portrait runs to the edge of the 1280 column,
     which is how the composition is built. */
  padding: var(--sp-48) 0 var(--sp-96) 144px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-64);
}
.home2-hero__text {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
  /* A fixed basis, not a max-width: as a flex sibling of the portrait the
     column was being squeezed to 388px, and the longest headline line
     measures 502px at 48px. */
  flex: 0 0 530px;
  max-width: 100%;
}
.home2-hero__title {
  font-family: var(--font-serif);
  font-size: var(--text-h1);        /* 40px; was the 40–56px display clamp */
  font-weight: 600;
  line-height: var(--lh-display);
  color: var(--text-primary);
}
.home2-hero__sub {
  font-family: var(--font-sans);
  font-size: var(--text-lead);
  font-weight: 400;
  line-height: var(--lh-lead);
  color: var(--text-muted);
  max-width: 430px;
}
.home2-hero__portrait {
  flex: 0 1 540px;
  width: 540px;
  height: auto;
  /* the source frame is rotated; these are the corners as rendered */
  border-radius: 0 153px 0 157px;
  object-fit: cover;
}

/* ---- The white sheet -------------------------------------------------- */
.home2-sheet {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--column);
  margin-inline: auto;
  background: var(--ground-100);
  border-radius: var(--radius-lg);
  padding-inline: var(--gutter);
  overflow: clip;
}

/* ---- What I do + the two expanders ------------------------------------ */
.home2-about {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-64);
  padding-block: var(--sp-120);
}
.home2-about__label {
  font-family: var(--font-display);
  font-size: var(--size-32);
  line-height: var(--lh-heading);
  color: var(--text-muted);
  flex: 0 0 auto;
}
.home2-about__body { flex: 0 1 546px; display: flex; flex-direction: column; gap: var(--sp-24); }

/* <details> reversed so the toggle chip sits under its own content,
   which is where the design puts it. Works with no JS at all. */
.expander {
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-start;
  gap: var(--sp-16);
  width: 100%;
}
.expander__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  height: 32px;
  padding: 7px var(--sp-12);
  border-radius: var(--radius-pill);
  background: var(--teal-500);
  color: var(--text-primary);
  font-size: var(--size-14);
  font-weight: 500;
  line-height: 16px;
  letter-spacing: -0.25px;
  cursor: pointer;
  list-style: none;
  white-space: nowrap;
  transition: background-color 160ms var(--ease);
}
.expander__toggle::-webkit-details-marker { display: none; }
.expander__toggle::before { content: "+"; font-weight: 700; }
.expander[open] > .expander__toggle::before { content: "\2212"; }
.expander__toggle:hover { background: #16302d; }
.expander__panel { width: 100%; }
/* display:flex on <details> turns every child into a flex item, which
   overrides the browser's own hiding of closed content — so hide it here. */
.expander:not([open]) > .expander__panel { display: none; }

/* Numbers as evidence — guidelines.md gives them their own treatment */
.metric-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
.metric-big__value {
  font-family: var(--font-sans);
  font-size: var(--text-stat);
  font-weight: 600;
  line-height: var(--lh-stat);
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.metric-big__label {
  margin-top: var(--sp-8);
  font-size: var(--size-12);
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.home2-exp { list-style: none; width: 100%; }
.home2-exp li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  padding: var(--sp-12);
  border-bottom: 1px solid var(--ground-cream-100);
}
.home2-exp__org { font-size: var(--size-18); font-weight: 500; color: var(--text-primary); }
.home2-exp__org a { text-decoration: underline; }
.home2-exp__role { font-size: var(--size-12); color: var(--text-muted); }
.home2-exp__period { font-size: var(--size-12); color: var(--text-muted); white-space: nowrap; }

/* ---- Selected work band ---------------------------------------------- */
.home2-selected {
  background: var(--blue-300);
  margin-inline: calc(var(--gutter) * -1);
  padding: var(--sp-80) var(--gutter);
}
.home2-case {
  display: flex;
  align-items: stretch;
  gap: var(--sp-32);
  background: #fff;
  border-radius: 12px;
  padding: var(--sp-32);
  text-decoration: none;
  color: inherit;
  overflow: clip;
}
.home2-case__text { flex: 1 1 514px; display: flex; flex-direction: column; gap: var(--sp-24); align-items: flex-start; }
.home2-case__eyebrow {
  font-size: var(--size-12);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.home2-case__logo { width: 54px; height: auto; }
.home2-case__title {
  font-size: var(--size-40, 2.5rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.4px;
  color: var(--text-primary);
}
.home2-case__title em {
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
}
.home2-case__teaser {
  font-family: var(--font-display);
  font-size: 17px;
  line-height: 1.6;
  color: var(--text-secondary);
}
.home2-case__media { flex: 0 1 474px; border-radius: var(--radius-card); overflow: clip; }
.home2-case__media img { width: 100%; height: 100%; object-fit: cover; }

.btn--dark {
  background: var(--ink-500);
  border-color: var(--ink-500);
  color: var(--text-primary);
}
/* the Home's Selected work card needs a tighter one */
.btn--compact { padding: 6px var(--sp-12); }
.btn--dark:hover { background: var(--ink-500); border-color: var(--ink-500); }
.btn--outline-dark { border-color: var(--ink-500); color: var(--text-primary); }
.btn--outline-dark:hover { background: var(--ink-500); color: var(--text-primary); }

/* ---- Short stories ---------------------------------------------------- */
.home2-stories { padding-block: var(--sp-120) var(--sp-48); display: flex; flex-direction: column; gap: var(--sp-24); }
.home2-stories__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-32);
}
.home2-stories__label {
  font-family: var(--font-display);
  font-size: var(--size-32);
  line-height: var(--lh-heading);
  color: var(--text-muted);
}
.home2-stories__aside { display: flex; align-items: center; gap: var(--sp-24); flex: 0 1 546px; justify-content: space-between; }

/* Story card — title only at rest; the subtitle rises on hover or focus */
.story-card {
  position: relative;
  flex: 0 0 auto;
  width: 250px;
  height: 450px;
  border-radius: var(--radius-card);
  overflow: clip;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  text-decoration: none;
  background: var(--brand);
}
.story-card__image { flex: 1 1 auto; min-height: 0; }
.story-card__image img { width: 100%; height: 100%; object-fit: cover; }
.story-card__text {
  padding: var(--sp-12);
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  color: var(--text-primary);
}
.story-card__title {
  font-size: var(--size-18);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.18px;
}
.story-card__title em { font-family: var(--font-display); font-style: italic; }
.story-card__sub {
  font-size: var(--size-12);
  line-height: 1.5;
  letter-spacing: -0.12px;
  color: inherit;
  opacity: 0.85;
  /* collapsed by default, revealed by pointer or keyboard */
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 260ms var(--ease), opacity 260ms var(--ease);
}
.story-card__sub > span { overflow: hidden; }
.story-card:hover .story-card__sub,
.story-card:focus-visible .story-card__sub,
.story-card:focus-within .story-card__sub {
  grid-template-rows: 1fr;
  opacity: 0.85;
}
/* The company tag hides with the subtitle and the two arrive together —
   same collapse technique, same timing, so they read as one reveal. */
.story-card .story-card__org {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 260ms var(--ease), opacity 260ms var(--ease);
}
.story-card__org > span { overflow: hidden; }
.story-card:hover .story-card__org,
.story-card:focus-visible .story-card__org,
.story-card:focus-within .story-card__org {
  grid-template-rows: 1fr;
  opacity: 1;
}

.rail--stories2 { gap: var(--sp-24); }

.carousel-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  padding: 6px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--ink-100);
  cursor: pointer;
  transition: background-color 160ms var(--ease);
}
.carousel-btn img { width: 16px; height: 16px; }

/* ---- Articles --------------------------------------------------------- */
.home2-articles {
  border-top: 1px solid var(--rule);
  padding-block: var(--sp-120);
  display: flex;
  flex-direction: column;
  gap: var(--sp-80);
}
.home2-articles .article-card {
  background: transparent;
  border: 1px solid var(--ink-500);
  border-radius: var(--radius-card);
}

/* ---- Footer on the black shell ---------------------------------------- */
.page--home2 .site-footer { background: var(--bg-page); }

/* ---- Responsive ------------------------------------------------------- */
@media (max-width: 1160px) {
  .home2-hero { padding-left: var(--sp-64); }
  .home2-hero__text { flex: 0 1 530px; }
}
@media (max-width: 900px) {
  /* The overlap reads as a glitch once the hero is taller than the screen */
  .home2-hero { position: static; flex-direction: column; align-items: flex-start; padding: var(--sp-32) var(--gutter) var(--sp-64); }
  .home2-hero__text { flex: 1 1 auto; }
  .home2-hero__text { max-width: none; }
  .home2-hero__portrait { width: 100%; border-radius: 0 96px 0 96px; }
  .home2-about,
  .home2-stories__head { flex-direction: column; gap: var(--sp-24); }
  .home2-about__body { flex: 1 1 auto; }
  .home2-stories__aside { flex: 1 1 auto; width: 100%; }
  .home2-case { flex-direction: column; }
  .home2-case__media { flex: 1 1 auto; max-height: 320px; }
}
@media (max-width: 640px) {
  .home2-sheet { border-radius: 12px; }
  .metric-big__value { font-size: 40px; }
  .home2-case__title { font-size: var(--size-28); }
  .home2-exp li { flex-direction: column; align-items: flex-start; gap: var(--sp-4); }
  .nav-pill { padding: var(--sp-8) var(--sp-16); height: 38px; font-size: var(--size-14); }
  .nav-pillgroup { height: auto; }
}

/* Sticky hero is a scroll effect, not an animation — but if someone has
   asked for less motion, the overlap goes away too. */
@media (prefers-reduced-motion: reduce) {
  .home2-hero { position: static; }
  .story-card__sub { grid-template-rows: 1fr; opacity: 0.85; }
  .story-card .story-card__org { grid-template-rows: 1fr; opacity: 1; }
}
/* Touch screens have no hover, so a reveal behind it would hide the company
   and subtitle for good. Where hover does not exist, both simply show. */
@media (hover: none) {
  .story-card__sub { grid-template-rows: 1fr; opacity: 0.85; }
  .story-card .story-card__org { grid-template-rows: 1fr; opacity: 1; }
}

/* ---- 18b. Home redesign: bits the markup needs ------------------------- */
.metric-big,
.metric-big__value,
.metric-big__label { display: block; }
.metric-big + .metric-big {
  border-top: 1px solid var(--ground-cream-100);
  padding-top: var(--sp-24);
}

.rail-nav { display: flex; align-items: center; gap: var(--sp-12); }

/* The story rail scrolls, so the cards must not be squashed by flex */
.rail--stories2 > .story-card { flex: 0 0 250px; }

/* =========================================================================
   19. Fixed top menu — site-wide
   The nav is persistent, so it now stays put while the page scrolls. Each
   header carries its own solid background: content passes *under* it, and
   a transparent bar would put white text over the white sheet.
   ========================================================================= */
:root { --header-h: 77px; }
.page--home2,
.page--case { --header-h: 84px; }

.site-header,
.home2-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  margin-inline: auto;
}
.site-header { background: var(--bg-page); }
.page--home2 .home2-header { background: var(--bg-page); }
.page--case .site-header { background: var(--blue-300); }

/* The header no longer takes up space, so give it back on the page itself —
   the first element after it differs per page (main, or the title band). */
.page { padding-top: var(--header-h); }

/* The sticky hero parks just under the bar rather than sliding beneath it. */
.page--home2 .home2-hero { top: var(--header-h); }

/* Anchored sections must not land under the bar */
[id] { scroll-margin-top: calc(var(--header-h) + var(--sp-16)); }

/* =========================================================================
   20. Selected work — updated (Figma 2048:18410)
   Top band moved from dark green to blue/300, nav is the pill group, and
   the case opens on a full-width result image.
   ========================================================================= */
body.case { background: var(--bg-page); }

/* The case page no longer carries a ground of its own; the blue survives
   only as the Selected work band, which is a fixed content colour. */
.page--case {
  background: var(--bg-page);
}

/* Light pill group: dark labels on a translucent white container */
.page--case .nav-pillgroup {
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 0 0 1px rgba(22, 22, 22, 0.08);
}
.page--case .nav-pill { color: var(--text-primary); }
.page--case .nav-pill:hover { background: rgba(255, 255, 255, 0.85); }
.page--case .nav-pill[aria-current="page"] { background: #fff; font-weight: 700; }

/* Title band, now on blue */
.page--case .case-hero {
  background: transparent;
  padding: var(--sp-32) var(--gutter) var(--sp-48);
}
.page--case .case-hero__title { color: var(--text-primary); }
/* ink/300 is 4.26:1 on the blue band — under AA. #676767 is the lightest
   grey that clears 4.5:1 on #d7e8f7. */
.page--case .case-hero__meta { color: var(--text-muted); }

/* Result image — Figma 2048:18419 puts it INSIDE the container: a 1340px
   image in a 1280px frame with clipsContent, at y=0 with padding-top 0.
   So it escapes the container padding, sits flush at the top, and is 4.66%
   wider than the container so the container crops it. That crop is why
   there is no band or seam under the image. */
.page--case .shell > .case-result {
  margin: calc(-1 * var(--gutter)) calc(-1 * var(--gutter)) 0;
  width: calc(100% + 2 * var(--gutter));
  display: block;
  overflow: clip;          /* the crop, matching the Figma frame */
}
.page--case .shell > .case-result img {
  width: 100%;
  height: auto;
  display: block;
}
/* Figma crops the Mercado Pago hero (1340px artwork in a 1280 clipping
   frame, ~2.3% off each side). That overhang is NOT reproduced here: the
   global `img { max-width: 100% }` on line 282 caps it, so the rule that
   used to sit here never took effect. Both heroes therefore render at the
   container width. Enabling the real crop would need `max-width: none`
   alongside the percentage width — deliberately not done, because the
   difference is ~2.3% per side and the page is signed off as it renders. */

@media (max-width: 900px) {
  .page--case .case-hero { padding: var(--sp-24) var(--gutter) var(--sp-32); }
}

/* ---- 19b. Narrow screens: keep the fixed bar one row high ---------------
   Wrapping the nav made the header 173px tall on a 375px screen while the
   offset stayed at 84px, so content slid underneath. One scrollable row
   keeps the bar a predictable height (and stops it eating the viewport). */
@media (max-width: 900px) {
  .site-header,
  .home2-header { flex-wrap: nowrap; gap: var(--sp-12); }

  .nav-pillgroup,
  .nav-chips ul {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
    justify-content: flex-start;
    min-width: 0;
  }
  .nav-pillgroup::-webkit-scrollbar,
  .nav-chips ul::-webkit-scrollbar { display: none; }

  /* The <nav> wrapper needs to shrink too, or the ul inherits its
     max-content width and overflows instead of scrolling. */
  .site-header > nav,
  .home2-header > nav,
  .nav-chips { min-width: 0; }
  .nav-pill { flex: 0 0 auto; }
  .chip { flex: 0 0 auto; }
}

@media (max-width: 640px) {
  /* Both headers use the same padding here, so both bars are the same
     height: avatar 45 + 2x12 = 69. The JS sync is only a safety net. */
  .site-header,
  .home2-header { flex-wrap: nowrap; padding: var(--sp-12) var(--sp-16); }
  .page--home2,
  .page--case,
  .page--tinted { --header-h: 69px; }
  :root { --header-h: 69px; }
  .nav-pill { height: 36px; }
  .nav-pillgroup { padding: 3px; }
}

/* =========================================================================
   21. Tinted pages — Short stories / About / Resume
   Figma 2028:1335 / 2028:1689 / 2028:1547. Each page now sits on its own
   tint with a white rounded sheet and a light footer, and carries the
   pill nav instead of the chips.
   ========================================================================= */
/* The four per-page tints (#f7f9f2, #f5eef9, #eff0eb, #d7e8f7) collapsed
   into one semantic ground. Pages no longer carry their own colour. */
body.qs,      .page--qs      { --tint: var(--bg-page); }
body.about,   .page--about   { --tint: var(--bg-page); }
body.resume,  .page--resume  { --tint: var(--bg-page); }

body.qs, body.about, body.resume { background: var(--bg-page); }

.page--tinted {
  --header-h: 84px;
  --teal-500: #0c1e1c;
  --offwhite: var(--text-primary);  /* alias -> semantic ink */
  background: var(--bg-page);
}

/* Header sits on the tint and carries the light pill group */
.page--tinted .site-header { background: var(--bg-page); }

.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup {
  background: rgba(255, 255, 255, 0.2);
  box-shadow: inset 0 0 0 1px rgba(22, 22, 22, 0.06);
}
.page--case .nav-pill,
.page--tinted .nav-pill { color: var(--text-muted); }
.page--case .nav-pill:hover,
.page--tinted .nav-pill:hover { background: rgba(255, 255, 255, 0.7); color: var(--text-primary); }
.page--case .nav-pill[aria-current="page"],
.page--tinted .nav-pill[aria-current="page"] {
  background: var(--ink-500);
  color: var(--teal-100, #e7efee);
  font-weight: 700;
}

/* The white sheet the content sits on */
.page--tinted .shell {
  border-radius: var(--radius-lg);
  margin-block-end: var(--sp-48);
}

/* Centred page title, matching the case page's block */
.page-title-block {
  width: 100%;
  max-width: 727px;
  margin-inline: auto;
  padding: var(--sp-48) var(--gutter) 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  text-align: center;
}
.page-title-block h1 {
  font-family: var(--font-serif);
  font-size: var(--text-h1);
  font-weight: 600;
  line-height: var(--lh-h1);
  color: var(--text-primary);
}
.page-title-block p {
  font-family: var(--font-sans);
  font-size: var(--text-meta);
  font-weight: 400;
  line-height: var(--lh-meta);
  color: var(--text-muted);
}

/* Light footer: same tint as the page, olive links */
.site-footer--light {
  background: var(--bg-page);
  color: var(--text-primary);
}
.site-footer--light .site-footer__title { color: var(--text-primary); }
.site-footer--light .site-footer__question { color: var(--text-muted); }
.site-footer--light .site-footer__email { color: var(--link); }
.site-footer--light .site-footer__bottom { border-top-color: var(--ink-200); }
.site-footer--light a:not(.site-footer__email) { color: var(--link); }
.site-footer--light :where(a, button):focus-visible { outline-color: var(--link-300); }

@media (max-width: 900px) {
  .page-title-block { padding: var(--sp-32) var(--gutter) 0; }
  .page--tinted .shell { border-radius: 12px; }
}

/* ---- 21b. Cascade fix -------------------------------------------------
   Section 21 sets --header-h: 84px on .page--tinted with no media query,
   so it was overriding the narrow-screen value declared earlier (media
   queries add no specificity). Restate it last. */
@media (max-width: 640px) {
  .page--home2,
  .page--case,
  .page--tinted { --header-h: 69px; }
}

/* =========================================================================
   22. Sticky stacking cards + glass header (Home)
   Each section is a card that pins at the top while the next one rides up
   over it. Pure CSS: position: sticky does the stacking, later siblings
   paint above earlier ones, so no z-index ladder is needed. JS only adds
   the depth cue (scale + dim).
   ========================================================================= */
.page--stacked {
  --card-gap: 16px;
  --card-top: calc(var(--header-h) + 12px);
  --card-radius: var(--radius-lg);
}

/* No clipping anywhere above the cards, or sticky stops working. */
.page--stacked,
.page--stacked > main { overflow: visible; }

.stack-cards {
  width: 100%;
  max-width: var(--column);
  min-width: 0;
  margin-inline: auto;
  /* No padding-bottom here: a sticky child is constrained by its
     container's CONTENT box, so bottom padding shortens the pin range
     instead of extending it — every card popped loose at the page end. */
}

/* Trailing scroll room so the last card can travel up to the pin line.
   It has to live INSIDE the content box, hence a pseudo-element rather
   than padding on the container. */
.stack-cards::after {
  content: "";
  display: block;
  height: 55vh;
}

.stack-card {
  position: sticky;
  top: var(--card-top);
  border-radius: var(--card-radius);
  padding: clamp(24px, 4vw, var(--gutter));
  margin-bottom: var(--card-gap);
  /* clip on the card itself is safe — only *ancestors* break sticky */
  overflow: hidden;
  isolation: isolate;
  transform-origin: 50% 0;
  will-change: transform;
}

/* The dim that reads as depth while the next card covers this one. */
.stack-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--ink-500);
  opacity: calc(var(--cover, 0) * 0.5);
  pointer-events: none;
  z-index: 2;
}

.js .stack-card {
  /* The covered card is scaled from its TOP edge, so its top sits on the
     same pin line as the card covering it. At fractional scroll offsets and
     fractional card heights the two edges land half a pixel apart, and the
     covered card — dimmed to 50% black by ::after — shows through as a dark
     hairline along the top of the arriving card. Nudging the covered card
     down by up to 1px puts it definitively behind, and 1px is invisible
     against a movement of 28px. */
  transform: translateY(calc(var(--cover, 0) * 1px))
             scale(calc(1 - var(--cover, 0) * 0.04));
  transition: transform 120ms linear;
}

/* Card grounds — the dark theme is kept, cards alternate against it */
/* No ground of its own: it inherits --bg-page so it follows the theme.
   #1c1c1c only ever appeared here and is gone from the palette. */
.stack-card--hero {
  background: transparent;
  display: flex;
  align-items: center;
  padding: 0;
}
.stack-card--light { background: var(--ground-100); }
.stack-card--blue  { background: var(--blue-300); }
.stack-card--contact {
  background: var(--bg-page);
  padding: clamp(32px, 5vw, var(--sp-80)) clamp(24px, 4vw, var(--gutter)) clamp(24px, 3vw, var(--sp-48));
}

/* The hero keeps its own composition inside the card */
.page--stacked .home2-hero {
  position: static;
  width: 100%;
  max-width: none;
  padding: var(--sp-48) 0 var(--sp-48) clamp(24px, 8vw, 144px);
}

/* Sections lose the old sheet's padding — the card supplies it now */
.page--stacked .home2-about { padding-block: 0; }
.page--stacked .home2-stories { padding-block: 0; }
.page--stacked .home2-articles { border-top: 0; padding-block: 0; }
.page--stacked .home2-selected { margin-inline: 0; padding: 0; background: transparent; }
.page--stacked .site-footer { max-width: none; }

/* Rails punch through the card's padding and run edge to edge. The track
   keeps the padding as inset so the first item still lines up with the
   heading above it, and the card's own overflow:hidden + radius clips the
   corners. Nothing between the rail and the card edge. */
.page--stacked .rail--bleed {
  margin-inline: calc(var(--card-pad) * -1);
  padding-inline: var(--card-pad);
  /* without this the snap position for the first item is the container's
     own start edge, so the browser scrolls the inset away on load and the
     first card no longer lines up with the heading above it */
  scroll-padding-inline: var(--card-pad);
  width: auto;
  max-width: none;
  border: 0;
}


/* =========================================================================
   23. Glass header — no solid fill (WeTransfer-style)
   rgba(22,22,22,.72) over the blur keeps white nav text at 7.2:1 even when
   the white card is passing underneath, while staying 28% translucent.
   ========================================================================= */
.home2-header--glass {
  background: rgba(22, 22, 22, 0.72);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  /* inset shadow, not a border: a real border added 1px to the bar's height
     and pushed it past the --header-h offset, clipping the first card */
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.08),
              0 1px 20px rgba(0, 0, 0, 0.18);
  z-index: 60; /* above the cards */
}
/* The solid fill from section 19 must not win over the glass */
.page--home2 .home2-header--glass { background: rgba(22, 22, 22, 0.72); }

/* Browsers without backdrop-filter get a slightly denser fill instead */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .home2-header--glass,
  .page--home2 .home2-header--glass { background: rgba(22, 22, 22, 0.9); }
}

/* The pill group sits inside the glass bar, so it needs its own contrast */
.page--stacked .nav-pillgroup { background: rgba(255, 255, 255, 0.14); }

/* ---- Responsive: below 900px the overlap reads as a glitch ------------- */
@media (max-width: 900px) {
  .page--stacked { --card-gap: 24px; }
  .stack-card {
    position: relative;
    top: auto;
    transform: none !important;
    min-height: 0;
  }
  .stack-card::after { display: none; }
  .stack-cards::after { height: 0; }
  .stack-card--hero { min-height: 0; display: block; }
  .page--stacked .home2-hero { padding: var(--sp-32) var(--sp-24); }
}

/* ---- Reduced motion: normal flow, no overlap -------------------------- */
@media (prefers-reduced-motion: reduce) {
  .stack-card {
    position: relative;
    top: auto;
    transform: none !important;
  }
  .stack-card::after { display: none; }
  .stack-cards::after { height: 0; }
}

/* =========================================================================
   24. Home card design pass — Figma 2035:10155 (Dev Mode values)
   ========================================================================= */
.page--stacked {
  --sage-050: #f1f1ef;
  --charcoal-500: #292323;
  --charcoal-050: #f3f2f2;
  --pink-500: #f59191;
  /* ink/300 on charcoal is 2.9:1, so muted copy on the dark card lifts */
  --on-charcoal-muted: var(--text-muted);
}

/* ---- 4. Header: centred pill group, still glass ----------------------- */
.home2-header--centred {
  justify-content: center;
  padding: var(--sp-16) var(--sp-24);
}

/* ---- Card shells: px 120 / py 64 / radius 20 -------------------------- */
.page--stacked .stack-card {
  padding: clamp(24px, 4vw, 64px) clamp(24px, 8vw, var(--gutter));
  gap: var(--sp-24);
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.stack-card--white    { background: #fff; }
.stack-card--sage     { background: #fff; }   /* Short stories: white, like What I do */
.stack-card--charcoal { background: var(--charcoal-500); color: var(--text-primary); }
.page--stacked .stack-card--hero { padding: 0; gap: 0; }

/* ---- Section label: 12px eyebrow, not the old 32px serif -------------- */
.card-eyebrow {
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: 400;
  line-height: var(--lh-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-primary);
}
.card-eyebrow--pink { color: var(--pink-500); }

.card-body { display: flex; flex-direction: column; gap: var(--sp-24); }

.card-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
.card-head__aside {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-24);
  flex-wrap: wrap;
}
.card-intro { font-family: var(--font-sans); font-size: var(--text-lead); font-weight: 400; line-height: var(--lh-lead); }
.stack-card--charcoal .card-intro { color: var(--on-charcoal-muted); }

/* ---- 1. Tabs — _desktop/tab base -------------------------------------- */
.tabs { display: flex; flex-direction: column; gap: var(--sp-24); width: 100%; }

.tabs__list {
  display: flex;
  align-items: stretch;
  position: relative;
  border-bottom: 1px solid var(--ink-100, #d9d9d9);
}
.tab {
  flex: 1 0 0;
  min-width: 0;
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  font-weight: 500;
  line-height: var(--lh-ui);
  letter-spacing: -0.25px;
  text-align: center;
  color: var(--text-muted);
  padding: 14px 0 0;
  height: 48px;
  position: relative;
  transition: color 160ms var(--ease);
}
/* the 3px active bar sits on the divider */
.tab::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: transparent;
  transition: background-color 160ms var(--ease);
}
.tab[aria-selected="true"] { color: var(--teal-500, #0c1e1c); }
.tab[aria-selected="true"]::after { background: var(--teal-500, #0c1e1c); }
.tab:hover { color: var(--text-primary); }

/* Without JS both panels render, stacked and labelled. */
.tabs__panel { outline-offset: 4px; }
.tabs__panel + .tabs__panel { margin-top: var(--sp-24); }
.js .tabs__panel[hidden] { display: none; }
.js .tabs__panel + .tabs__panel { margin-top: 0; }

/* ---- 2. Card contents ------------------------------------------------- */
/* Figma 2077:103495 sets this card at 12, not the 8 the other cards use */
.page--stacked .home2-case { border-radius: 12px; padding: var(--sp-32); gap: var(--sp-32); }
.page--stacked .home2-case__title { font-family: var(--font-sans); font-size: 40px; font-weight: 400; line-height: 1.15; color: var(--text-primary); }
.page--stacked .home2-case__teaser { font-family: var(--font-sans); font-size: var(--size-14); line-height: 1.6; color: var(--text-muted); }

/* Article cards: light tiles on the charcoal card */
.stack-card--charcoal .article-card {
  background: var(--bg-surface-alt);
  border: 0;
  border-radius: var(--radius-card);
  padding: var(--sp-16);
  color: var(--text-primary);
}
.stack-card--charcoal .article-card__source { color: var(--text-muted); }

.btn--outline-light { border-color: var(--ground-100); color: var(--text-primary); }
.btn--outline-light:hover { background: var(--ground-100); color: var(--charcoal-500); }

/* Carousel: quiet prev, solid next (pink inside the Articles card) */
/* The old --solid pair and this .page--stacked fill were replaced by the
   Figma button/icon-only variants (--tertiary / --primary) in section 33.6.
   They were more specific than the new classes and kept winning. */

/* =========================================================================
   25. Footer reveal — it is no longer a card
   The footer is pinned to the bottom behind the stack; the cards scroll
   over it and it is uncovered as the last one clears.
   ========================================================================= */
.page--stacked { --footer-h: 340px; }

/* The footer is no longer revealed from behind the stack. Revealing it
   needed the stack painted in the page colour to cover a fixed footer, and
   that painted box is the "mask" that sliced through the footer as it
   scrolled in. The footer now simply follows the stack in the flow — the
   same thing narrow screens and reduced motion already did. */
.page--stacked .stack-cards {
  position: relative;
  z-index: 1;
  background: transparent;
  margin-bottom: 0;
}
/* Room for the last card to stay pinned before everything scrolls on and
   the footer comes up. It is content inside the container, not a margin on
   the card, so it extends the pin range of every card by the same amount
   and nobody releases early. */
.page--stacked .stack-cards::after { height: 70vh; }

.site-footer--reveal {
  position: static;        /* in the flow, after the stack — see above */
  width: 100%;
  max-width: none;
  margin-inline: auto;
  background: var(--ink-500);
  padding: clamp(32px, 5vw, var(--sp-80)) clamp(24px, 8vw, var(--gutter)) clamp(24px, 3vw, var(--sp-48));
}
.site-footer--reveal > * { max-width: var(--column); margin-inline: auto; }

@media (max-width: 900px) {
  /* No overlap on small screens, so the footer just sits at the end. */
  .site-footer--reveal { position: static; }
  .page--stacked .stack-cards { margin-bottom: 0; background: transparent; }
  .card-head__aside { flex-direction: column; align-items: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
  .site-footer--reveal { position: static; }
  .page--stacked .stack-cards { margin-bottom: 0; background: transparent; }
}

/* =========================================================================
   26. Home iteration — uppercase labels, card dwell, Selected work fixes
   ========================================================================= */

/* ---- 1. Section titles ------------------------------------------------
   The uppercase label role now lives on .card-eyebrow itself (section 1
   tokens), so the page-scoped duplicate is gone. Tabs are controls, so
   they take the --text-ui role like every other button and menu item. */

/* ---- 3. Card size and dwell ------------------------------------------
   Two different things that used to be confused with each other:

   --card-min-h is the card's VISUAL height. One value, one rule, every
   card — no per-card heights. It is capped by the viewport so a short
   screen never gets a card taller than it can show.

   --dwell is the SCROLL distance the card holds while pinned. It stays
   per-card, because the rail cards need longer to browse. Touching it
   would change navigation, not size. */
.page--stacked {
  --card-pad: clamp(24px, 3vw, 48px);
  /* set to the tallest card's natural content (the Short stories rail),
     so every card lands on exactly this number instead of the rail card
     sticking out. Raise it if a card ever grows past it. */
  --card-min-h: 730px;
  /* the one resolved height every card and its contents answer to.
     Deliberately NOT capped to the viewport: capping made short windows
     split the cards into different heights again, because the rail card
     cannot compress below its own content. Uniform wins. Below 900px wide
     the responsive rules drop min-height to 0 and the cards stack. */
  --card-h: var(--card-min-h);
}
.page--stacked .stack-card {
  min-height: var(--card-h);
  padding: var(--card-pad);
  margin-bottom: var(--dwell, 40vh);
}

/* The hero keeps padding:0 because its portrait is meant to touch the card
   edges; the composition inside supplies the same --card-pad instead. This
   has to be restated after the shared rule above, or the card gets both
   paddings and ends up 86px taller than every other card. */
.page--stacked .stack-card--hero { padding: 0; }
.page--stacked .stack-card--hero .home2-hero {
  padding: var(--card-pad) 0 var(--card-pad) clamp(24px, 8vw, 144px);
}
/* Desktop: the text and the portrait share one inset. The portrait used to
   run flush to the card's right edge while the text sat 8vw in from the
   left — the flush edge only showed once the card scrolled — so the pair
   read off-centre. Same inset both sides: the text moves closer to the left
   edge, the portrait comes off the right one. Mobile keeps its own layout. */
@media (min-width: 901px) {
  .page--stacked .stack-card--hero .home2-hero {
    --hero-inset: clamp(24px, 5vw, 80px);
    padding-inline: var(--hero-inset);
  }
}
.page--stacked .home2-hero__portrait {
  height: calc(var(--card-h) - var(--card-pad) * 2);
  max-height: none;
  object-fit: cover;
}
/* 64px between cards. --dwell is both the visible gap and the scroll a card
   holds before the next one arrives, so this also shortens each hold.
   ⚠️ Every card must carry the SAME margin, the last one included. A sticky
   element lets go when the bottom edge of its MARGIN box reaches the end of
   its container, so a card with a bigger margin-bottom releases earlier than
   the rest and slides up over the cards still pinned behind it. Giving
   Articles 70vh made it release 566px before Short stories. The hold the
   last card needs comes from the ::after spacer below, which extends the
   container for every card equally. */
.page--stacked .stack-card--hero      { --dwell: 64px; }
.page--stacked .stack-card--white     { --dwell: 64px; }
.page--stacked .stack-card--blue      { --dwell: 64px; }
.page--stacked .stack-card--sage      { --dwell: 64px; }
.page--stacked .stack-card--charcoal  { --dwell: 64px; }

/* ---- 4. Selected work card -------------------------------------------- */
.page--stacked .home2-case {
  position: relative;
  align-items: stretch;
  padding: var(--sp-32);
  gap: var(--sp-32);
  border-radius: 12px;
  overflow: hidden;      /* clips the bleeding image to the card */
}
/* 4.2 — text spans the full card height, distributed. It is capped to the
   room left beside the image (content box minus the image and a 32px gap):
   between ~960 and ~1150px the fixed 514px column ran under the image. */
.page--stacked .home2-case__text {
  flex: 0 1 514px;
  min-width: 0;
  max-width: calc(100% - min(474px, 46%) - var(--sp-32));
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--sp-24);
  min-height: 449px;
}
/* 4.1 — icon only: a 54x37 window onto the wordmark */
.page--stacked .home2-case__logo {
  display: block;
  width: 54px;
  height: 37px;
  overflow: hidden;
  flex: 0 0 auto;
}
/* The 54px box is a deliberate window onto the handshake mark — the
   wordmark stays outside it. The old percentages (269.48% wide, 99.6% tall
   with a 1.48% top nudge) shaved the top and bottom of the oval, which is
   the crop. Fitting by height instead lands the oval inside the window with
   room to spare, and the asset now carries a transparent bleed so the curve
   is never cut by the canvas edge either. */
.page--stacked .home2-case__logo img {
  width: auto;
  height: 100%;
  max-width: none;
  margin-top: 0;
  object-fit: contain;
  object-position: left center;
}
.home2-case__mid { display: flex; flex-direction: column; gap: var(--sp-24); }
/* 4.3 — divider above the button */
.home2-case__foot { display: flex; flex-direction: column; gap: var(--sp-12); align-items: flex-start; width: 100%; }
.home2-case__divider {
  display: block;
  width: 100%;
  max-width: 514px;
  height: 1px;
  background: var(--border);
}
/* 4.4 — the card's button is the secondary one (Figma 2237:22640); its
   hover, driven by hovering the whole card link, lives with the buttons
   in section 45. */

/* 4.5 — right-hand image: full-bleed, no border, no gap */
.page--stacked .home2-case__media {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  /* 46% of the CONTENT box, the same basis the text's cap uses (an absolute
     box resolves % against the padding box, hence the padding taken off) */
  width: min(474px, calc((100% - 2 * var(--sp-32)) * 0.46));
  border: 0;
  padding: 0;
  margin: 0;
  background: none;
  border-radius: 0 12px 12px 0;
  overflow: hidden;
  flex: none;
}
.page--stacked .home2-case__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* the artwork sits centred in its panel, as it does in Figma */
  object-position: 50% 50%;
  /* the mask lives on the image itself rather than only on the parent's
     overflow, so the card's corners are knocked out of the picture and
     there is no frame of any kind around it */
  border-radius: 0 12px 12px 0;
}

@media (max-width: 900px) {
  .page--stacked .stack-card { min-height: 0; margin-bottom: var(--card-gap); }
  .page--stacked .home2-case { flex-direction: column; }
  .page--stacked .home2-case__text { min-height: 0; flex: 1 1 auto; }
  .page--stacked .home2-case__media { position: static; width: 100%; max-height: 320px; }
}
@media (prefers-reduced-motion: reduce) {
  .page--stacked .stack-card { min-height: 0; margin-bottom: var(--card-gap); }
}

/* =========================================================================
   27. About redesign — Figma 2028:1689
   Shares the Home's stacking machinery (.page--stacked / .stack-cards /
   .stack-card and the same JS). Only the row layout and the colours are
   specific to this page.
   ========================================================================= */
body.about2 { background: var(--bg-page); }

.page--about2 {
  --accent-subtle: #eff6ff;   /* PagAmerican   */
  --orange-100:    #ebddd7;   /* Inter&Co      */
  --cream-200:     #eae6d3;   /* Mercado Livre */
  --pink-200:      #ecd0d0;   /* Hotmart       */
  /* ink/300 drops to 3.7:1 on the warmer cards; this is the lightest grey
     that still clears AA on all six grounds */
  --period-on-card: var(--text-muted);
  background: var(--bg-page);
}

/* ---- Row card: text on one side, photo full-bleed on the other -------- */
/* Scoped to .page--stacked so it beats `.page--stacked .stack-card`.
   No `position` here: the card is already sticky, and sticky is its own
   containing block for the absolutely-placed photo — setting relative
   silently dropped the stacking. */
.page--stacked .stack-card--about {
  display: block;
  padding: clamp(32px, 5vw, 72px) clamp(24px, 6vw, 88px);
}
.stack-card--a-hero  { background: var(--ground-100); }
.stack-card--a-pag   { background: var(--accent-subtle); }
.stack-card--a-inter { background: var(--orange-100); }
.stack-card--a-meli  { background: var(--cream-200); }
.stack-card--a-hot   { background: var(--pink-200); }
.stack-card--a-obs   { background: var(--link-100); }

/* Text column clears the photo instead of running under it */
.stack-card--about > .about-card__content,
.stack-card--about > .about-hero2__text {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-24);
  min-height: 100%;
  width: min(568px, 52%);
}
.stack-card--about.media-left > .about-card__content,
.stack-card--about.media-left > .about-hero2__text { margin-left: auto; }

/* B) The photo: full-bleed on its side, clipped by the card's own radius.
   Same treatment as the Selected work card on the Home. */
.stack-card--about > .about-card__media {
  position: absolute;
  top: 0;
  bottom: 0;
  width: min(568px, 46%);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  overflow: hidden;
  display: block;
}
.stack-card--about.media-left  > .about-card__media { left: 0; }
.stack-card--about.media-right > .about-card__media { right: 0; }

/* cover with no distortion; the box is driven by the card, never by the
   text length, so every photo crops on the same axis */
.stack-card--about > .about-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: cover;
  border-radius: 0;
}
/* keep faces and screens in frame rather than centre-cropping blindly */
/* the new hero photo (Figma 2130:127518) is almost the same ratio as its
   panel, so cover barely crops and the frame stays centred */
.stack-card--a-hero  > .about-card__media img { object-position: 50% 50%; }
.stack-card--a-pag   > .about-card__media img { object-position: 60% 50%; }
.stack-card--a-inter > .about-card__media img { object-position: 50% 40%; }
.stack-card--a-meli  > .about-card__media img { object-position: 50% 45%; }
.stack-card--a-hot   > .about-card__media img { object-position: 50% 35%; }
.stack-card--a-obs   > .about-card__media img { object-position: 50% 50%; }

/* ---- Hero typography --------------------------------------------------- */
.about-hero2__text { align-items: flex-start; }
.about-hero2__title { display: flex; flex-direction: column; gap: var(--sp-16); }
.about-hero2__line1 {
  font-family: var(--font-sans);
  font-size: var(--size-32);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.32px;
  color: var(--text-primary);
}
.about-hero2__line2 {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--size-32);
  line-height: 1.2;
  letter-spacing: -0.32px;
  color: var(--text-primary);
}
.about-hero2__line2 em { font-weight: 600; font-style: italic; }
.about-hero2__lede { display: flex; flex-direction: column; gap: 1em; }
.about-hero2__lede p {
  font-size: var(--size-18);
  line-height: var(--lh-body);
  letter-spacing: 0.2px;
  color: var(--text-muted);
}
.about-hero2__closing { color: var(--text-primary) !important; }
.about-hero2__closing em { font-family: var(--font-display); font-style: italic; font-weight: 600; }

/* ---- Row typography ---------------------------------------------------- */
.about-card__org {
  font-family: var(--font-serif);
  font-size: var(--text-h2);
  font-weight: 400;
  line-height: var(--lh-h2);
  letter-spacing: -0.01em;
  color: var(--text-secondary);
}
.about-card__period {
  font-size: var(--size-20);
  line-height: var(--lh-body);
  letter-spacing: -0.2px;
  color: var(--period-on-card);
}
.about-card__text { display: flex; flex-direction: column; gap: 1em; }
.about-card__text p {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  line-height: var(--lh-prose);
  color: var(--text-secondary);
}
.about-card__text--ink p { color: var(--text-primary); }

/* Dwell: same rhythm as the Home, longest on the text-heavy cards */
.page--stacked .stack-card--a-hero  { --dwell: 30vh; }
.page--stacked .stack-card--a-pag   { --dwell: 45vh; }
.page--stacked .stack-card--a-inter { --dwell: 50vh; }
.page--stacked .stack-card--a-meli  { --dwell: 50vh; }
.page--stacked .stack-card--a-hot   { --dwell: 70vh; }
.page--stacked .stack-card--a-obs   { --dwell: 40vh; }

/* ---- Dark footer ------------------------------------------------------- */
.site-footer--dark {
  background: var(--ink-500);
  color: var(--text-primary);
}
.site-footer--dark .site-footer__title { color: var(--text-primary); }
.site-footer--dark .site-footer__question { color: var(--text-primary); }
.site-footer--dark .site-footer__email,
.site-footer--dark a:not(.site-footer__email) { color: var(--link); }
.site-footer--dark .site-footer__bottom { border-top-color: rgba(252, 251, 248, 0.2); }

@media (max-width: 900px) {
  /* photo back into the flow, above the text */
  .page--stacked .stack-card--about { display: flex; flex-direction: column; gap: var(--sp-24); padding: var(--sp-32) var(--gutter); }
  .stack-card--about > .about-card__content,
  .stack-card--about > .about-hero2__text { width: 100%; min-height: 0; }
  .stack-card--about > .about-card__media {
    position: static;
    width: 100%;
    order: -1;
    aspect-ratio: 16 / 10;
    border-radius: 12px;
  }
  .stack-card--about > .about-card__media img { height: 100%; }
}

/* ---- 27b. Cascade fix: the centred header's padding was overriding the
   narrow-screen padding declared earlier, so the bar rendered 75px tall
   against a 69px offset and clipped the first card by 6px. --------------- */
@media (max-width: 640px) {
  .home2-header--centred { padding: var(--sp-12) var(--sp-16); }
  .page--home2,
  .page--case,
  .page--tinted { --header-h: 68px; }
}
/* The bar sizes from its own content: padding + the 52px pill group. It
   used to carry min-height: var(--header-h), but site.js syncs --header-h
   back to the measured height, so the two latched each other and the bar
   stayed 84px even where the narrow-screen rules ask for 68. The token is
   now the no-JS fallback only, and it is never smaller than the bar, so
   the first card is never clipped either way. */
.site-header,
.home2-header { box-sizing: border-box; }
.nav-pillgroup { height: 52px; box-sizing: border-box; }
@media (max-width: 640px) {
  .nav-pillgroup { height: 42px; }
}

/* =========================================================================
   28. One menu, one set of type roles — site-wide
   The glass bar is now the only header on the site, so the light pill
   treatment the tinted pages used (dark text on the tint) no longer
   applies: every page puts white pills on the same translucent dark bar.
   ========================================================================= */

/* One bar height everywhere. The bar is padding(16*2) + pillgroup(52) = 84. */
:root,
.page--home2,
.page--case,
.page--tinted { --header-h: 84px; }

/* No page paints a solid fill behind the nav any more — the blur is the
   whole point, and a fill would reproduce the background it sits over. */
.site-header,
.page--home2 .home2-header:not(.home2-header--glass),
.page--case .site-header,
.page--tinted .site-header { background: transparent; }

/* Pills read against the dark glass on every page */
.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup,
.page--stacked .nav-pillgroup {
  background: rgba(255, 255, 255, 0.14);
  box-shadow: none;
}
.page--case .nav-pill,
.page--tinted .nav-pill { color: #fff; }
.page--case .nav-pill:hover,
.page--tinted .nav-pill:hover { background: rgba(255, 255, 255, 0.16); color: #fff; }
.page--case .nav-pill[aria-current="page"],
.page--tinted .nav-pill[aria-current="page"] {
  background: var(--ink-500);
  color: #e7efee;
  font-weight: 700;
}

/* The bar is fixed and translucent, so nothing above it may clip or paint
   over it: ancestors keep overflow visible and the bar keeps the top layer. */
.page--tinted,
.page--case { overflow: visible; }
.home2-header--glass { z-index: 60; }

/* -------------------------------------------------------------------------
   28.1 Home story cards — Figma 2035:10155
   Ten cards, each carrying title + company at rest and lifting its subtitle
   on hover or keyboard focus. Colours are the Figma card fills.
   ---------------------------------------------------------------------- */
.story-card--ds         { background: #c1e2ff; }
.story-card--checkout   { background: #e8d0bb; }
.story-card--money      { background: #ebecfa; }
.story-card--spending   { background: #f7efe7; }
.story-card--pin        { background: #bda356; }
.story-card--settings   { background: #dcc3ea; }
.story-card--steps      { background: #f59191; }
.story-card--onboarding { background: #78a499; }
.story-card--messaging  { background: #e2a084; }
.story-card--signup     { background: #a5bc81; }

.story-card__text { color: var(--text-primary); }
.story-card__sub  { color: var(--story-sub, var(--ink-400)); }
/* #383838 on the sage card is 4.23:1 — under AA, so it steps down to ink/500 */
.story-card--onboarding { --story-sub: var(--ink-500); }

/* The company sits under the title and stays put; the subtitle is what moves. */
.story-card__org {
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: 400;
  line-height: var(--lh-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-primary);
}

/* The glass bar spans the viewport. At 1280 it left 80px of unblurred
   gutter on either side, so content slid past the blur at the edges. */
.home2-header--glass { max-width: none; }

/* -------------------------------------------------------------------------
   28.2 Short stories media — Figma 2028:1335
   Two-up rows keep the 290/720 split at a fixed 480 height and cover-crop.
   Single-image rows run the full column at their own aspect, so a 1042x587
   render is never squeezed into someone else's box.
   ---------------------------------------------------------------------- */
.story__media {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-32);
}
.story__media img {
  border-radius: var(--radius-md);
  object-fit: cover;
  object-position: center top;
  background: var(--gray-100);
  display: block;
}
/* The width/height attributes on the <img> already give the browser the
   intrinsic ratio, so width:100% + height:auto scales it without cropping
   or distorting — no aspect-ratio declaration needed. */
.story__media--single { display: block; }
.story__media--single img { width: 100%; height: auto; }

/* -------------------------------------------------------------------------
   28.3 About — more compact cards
   The cards were sized to fill the viewport, which made every one of them a
   full screen of mostly air. They now size to their content with a ceiling,
   and the text padding comes in. Images are untouched: the photo is still
   absolutely placed against the card's edges, so it follows the new height.
   ---------------------------------------------------------------------- */
.page--stacked .stack-card--about {
  min-height: 0;
  padding: clamp(24px, 3vw, 40px) clamp(20px, 3.5vw, 52px);
}
/* a ceiling so a long card (Hotmart) still fits on screen while pinned */
.page--stacked .stack-card--about > .about-card__content,
.page--stacked .stack-card--about > .about-hero2__text {
  min-height: 0;
  gap: var(--sp-16);
  padding-block: var(--sp-16);
}
/* the photo column keeps its share, the text column keeps its measure */
.page--stacked .stack-card--about > .about-card__content { width: min(520px, 52%); }

/* Shorter cards need less flow space after them, or the stack drifts apart */
.page--about2 .stack-card--a-hero  { --dwell: 22vh; }
.page--about2 .stack-card--a-pag   { --dwell: 30vh; }
.page--about2 .stack-card--a-inter { --dwell: 32vh; }
.page--about2 .stack-card--a-meli  { --dwell: 32vh; }
.page--about2 .stack-card--a-hot   { --dwell: 44vh; }
.page--about2 .stack-card--a-obs   { --dwell: 26vh; }

/* -------------------------------------------------------------------------
   28.4 Resume header — Figma 2028:1547
   Title, one line of description and the download button, stacked and
   centred over the white sheet, 24px between the text block and the button.
   ---------------------------------------------------------------------- */
.page-title-block--action {
  align-items: center;
  gap: var(--sp-4);
}
.page-title-block--action .resume-download {
  margin-top: calc(var(--sp-24) - var(--sp-4));
  display: inline-flex;
}

/* The card is a fixed 450px flex column. Pinning the text block so it never
   shrinks means the expanding subtitle is absorbed by the image instead of
   by the text itself — the card keeps its height and the reveal is the same
   distance on every card, whatever the title's line count. */
.story-card__text { flex: 0 0 auto; }
.story-card__image { flex: 1 1 auto; min-height: 0; }

/* =========================================================================
   29. Real component states — Figma component sets, not invented
   Sources: button/with-icon 2024:13523, button 2002:8864, Nav Pill 2052:89475.
   Every colour below is a variant that exists in the file.
   ========================================================================= */

/* ---- 1. Page titles in regular ----------------------------------------
   The Figma sets "How about we say hello" and "Ten years, itemised" in
   Source Serif Pro *Regular*. The 600 applied earlier was heavier than the
   design; the family stays, the weight comes back down. */
.home2-hero__title,
.about-hero2__title,
.page-title-block h1,
.case-hero__title,
.site-footer__title { font-weight: 400; }

/* ---- 2. Buttons -------------------------------------------------------- */
.btn {
  transition: background-color 160ms var(--ease), color 160ms var(--ease),
              border-color 160ms var(--ease);
}

/* secondary: outlined at rest, filled #0c1e1c with a white label on hover */
.btn:hover,
.btn:focus-visible {
  background: var(--btn-bg-hover);
  border-color: var(--btn-bg-hover);
  color: var(--btn-fg);
}
.btn--outline-dark:hover,
.btn--outline-dark:focus-visible {
  background: var(--btn-bg-hover);
  border-color: var(--btn-bg-hover);
  color: var(--btn-fg);
}
/* primary: #161616 at rest, #0c1e1c on hover, label stays white */
.btn--dark:hover,
.btn--dark:focus-visible {
  background: var(--btn-bg-hover);
  border-color: var(--btn-bg-hover);
  color: var(--btn-fg);
}
/* outline (light label on a dark card): fills #d9d9d9 with a dark label.
   That is the button set's type=link hover, so this variant re-pins the
   token rather than sharing the secondary one. */
.btn--outline-light { --btn-outline-hover: var(--ink-100); --btn-outline-hover-border: var(--ink-100); }
.btn--outline-light:hover,
.btn--outline-light:focus-visible {
  background: var(--btn-outline-hover);
  border-color: var(--btn-outline-hover-border);
  color: #161616;
}

/* ---- 3. Arrows travel on hover ----------------------------------------
   Right and diagonal arrows slide right; the download arrow points down,
   so it is left alone rather than given a direction it does not have. */
.btn__icon,
.ext-arrow {
  display: inline-block;
  transition: transform 160ms var(--ease), filter 160ms var(--ease);
}
.btn:hover .btn__icon:not(.btn__icon--down),
.btn:focus-visible .btn__icon:not(.btn__icon--down),
.home2-case:hover .btn__icon:not(.btn__icon--down),
.home2-case:focus-visible .btn__icon:not(.btn__icon--down) {
  transform: translateX(var(--arrow-shift));
}

/* icon colour follows the label: white on the filled hover states */

/* ---- 4. Footer links ---------------------------------------------------
   Figma defines no hover variant for these, so the only motion is the
   arrow travel asked for; the underline is the one the design already has. */
.site-footer__email,
.site-footer a:not(.site-footer__email) {
  transition: color 160ms var(--ease);
}
/* One arrow glyph for every external link in the footer, the email
   included — it used to carry a rotated SVG of its own. */
.site-footer__email:hover .ext-arrow,
.site-footer__email:focus-visible .ext-arrow,
.site-footer__links a:hover .ext-arrow,
.site-footer__links a:focus-visible .ext-arrow { transform: translateX(var(--arrow-shift)); }
/* links that carry an arrow move the arrow instead of gaining an underline;
   only the plain footer nav links underline on hover */
.site-footer__nav a:hover,
.site-footer__nav a:focus-visible { text-decoration: underline; }

/* ---- 5. Nav pills ------------------------------------------------------
   Nav Pill 2052:89475: inactive hover fills #1f3f38 with #e7efee, and the
   active pill inverts to #e7efee with #161616. */
.nav-pill { transition: background-color 160ms var(--ease), color 160ms var(--ease); }
.nav-pill:hover,
.nav-pill:focus-visible,
.page--case .nav-pill:hover,
.page--tinted .nav-pill:hover {
  background: var(--pill-hover);
  color: var(--pill-hover-ink);
}
.nav-pill[aria-current="page"]:hover,
.nav-pill[aria-current="page"]:focus-visible,
.page--case .nav-pill[aria-current="page"]:hover,
.page--tinted .nav-pill[aria-current="page"]:hover {
  background: var(--pill-active-hover);
  color: var(--pill-active-hover-ink);
}

/* ---- 6. Motion is a courtesy, not a requirement ------------------------ */
@media (prefers-reduced-motion: reduce) {
  .btn__icon,
  .ext-arrow { transition: none; transform: none !important; }
}

/* -------------------------------------------------------------------------
   29.1 Page title band — at least 48px of air on both sides
   The rule is written for the pages where a title sits above a white sheet:
   Short stories, Resume and Selected work. The Home and About put their h1
   inside the first stacking card, so there is no sheet edge to clear there.
   ---------------------------------------------------------------------- */
.page-title-block {
  padding-top: var(--sp-48);
  padding-bottom: var(--sp-48);
}
.page--case .case-hero {
  padding-top: var(--sp-48);
  padding-bottom: var(--sp-48);
}
/* the shells add their own gap on top of this, never less than it */
.page--tinted .shell,
.page--case .case-result { margin-top: 0; }

/* -------------------------------------------------------------------------
   29.2 About — overlay, tablet, and fill in the column layout
   ---------------------------------------------------------------------- */
/* A shorter card can't hide a taller one behind it at 50% black, so the
   About stack dims harder as the next card climbs over it. */
.page--about2 .stack-card::after { opacity: calc(var(--cover, 0) * 0.88); }

/* Tablet and below: photo on top, text filling the card.
   This has to sit after 28.3, or that block's `width: min(520px, 52%)`
   keeps the text at half width and leaves the gap on the right. */
@media (max-width: 900px) {
  .page--stacked .stack-card--about {
    display: flex;
    flex-direction: column;
    gap: var(--sp-24);
    padding: clamp(20px, 4vw, 32px);
    min-height: 0;
  }
  .page--stacked .stack-card--about > .about-card__content,
  .page--stacked .stack-card--about > .about-hero2__text {
    width: 100%;
    max-width: none;
    min-height: 0;
    margin-left: 0;
    padding-block: 0;
  }
  .page--stacked .stack-card--about > .about-card__media {
    position: static;
    width: 100%;
    order: -1;
    aspect-ratio: 16 / 10;
    border-radius: 12px;
    overflow: hidden;
  }
  .page--stacked .stack-card--about > .about-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

/* Tablet portrait: the 1280 column would otherwise run past the viewport */
@media (max-width: 1024px) {
  .page--stacked { --card-gap: 20px; }
  .stack-cards { padding-inline: clamp(16px, 3vw, 32px); }
}

/* =========================================================================
   30. Floating glass pill — the menu is no longer a bar
   The header used to be an edge-to-edge bar painting rgba(22,22,22,.72).
   Now the <header> is an invisible, click-through centring rail and the
   only thing that renders is the pill itself.

   The <header> is a DIRECT CHILD OF <body> in every page on purpose:
   backdrop-filter is cancelled by any ancestor carrying transform,
   will-change, filter, perspective, contain or overflow:hidden/clip, and
   .stack-card inside .page sets transform + will-change.
   ========================================================================= */

/* ---- the rail: no fill, no visible width, no click target -------------- */
.site-header,
.home2-header,
.home2-header--glass,
.home2-header--centred,
.page--home2 .home2-header,
.page--home2 .home2-header--glass,
.page--case .site-header,
.page--tinted .site-header {
  position: fixed;
  top: var(--nav-top, 24px);
  left: 0;
  right: 0;
  bottom: auto;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  width: auto;
  max-width: none;
  min-height: 0;
  margin: 0;
  padding: 0 var(--nav-side, 24px);
  background: none;
  background-color: transparent;
  box-shadow: none;
  border: 0;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  pointer-events: none;   /* the transparent gutters must not eat clicks */
}
.home2-header > nav,
.site-header > nav { min-width: 0; pointer-events: auto; }

/* ---- the pill: hugs its content and frosts what passes behind ---------- */
.nav-pillgroup,
.page--stacked .nav-pillgroup,
.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup {
  width: max-content;
  max-width: 100%;
  height: auto;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.18);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.45);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12),
              inset 0 1px 0 rgba(255, 255, 255, 0.55);
  pointer-events: auto;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.nav-pillgroup::-webkit-scrollbar { display: none; }

/* items follow the container's shape */
.nav-pill { border-radius: var(--radius-pill); height: 40px; }

/* ---- content clears the floating pill ---------------------------------- */
.page { padding-top: var(--header-h); }

/* Figma's pill group is 52px tall with 44px items; the 6px padding the
   floating pill uses puts it at 58. These are the no-JS fallbacks — site.js
   re-syncs --header-h to the pill's measured bottom edge plus the same
   top offset again, so the first card always clears it. */
.nav-pill { height: 44px; }
:root,
.page--home2,
.page--case,
.page--tinted { --nav-top: 24px; --nav-side: 24px; --header-h: 106px; }

@media (max-width: 640px) {
  :root,
  .page--home2,
  .page--case,
  .page--tinted { --nav-top: 12px; --nav-side: 12px; --header-h: 76px; }
  .nav-pill { height: 38px; padding: var(--sp-8) var(--sp-16); }
  .nav-pillgroup,
  .page--stacked .nav-pillgroup,
  .page--case .nav-pillgroup,
  .page--tinted .nav-pillgroup { padding: 5px; gap: 2px; }
}


/* ---- 30.1 Glass strength follows the shell behind it -------------------
   The pill floats over a near-black shell on the Home and About for most
   of the scroll, and over light ground on the other three. At a single
   0.18 fill it composites to #404040 on the dark pages, where a dark-grey
   label lands at 1.0:1 — invisible. The fill is raised only where the
   backdrop is dark, which is what a frosted pill over a dark hero does
   anyway: still translucent, still blurring, and the label ink can then be
   the same dark grey on all five pages.
   Measured: 4.86:1 on the dark shells, 8.8-10.4:1 on the light ones. */
/* Component 1 (2156:128141) fills the bar with #ffffff at 20% and carries
   NO stroke. Two deviations from the literal values, both forced, both
   measured:

   - 20% is not reachable. The bar floats over whatever scrolls beneath it,
     and that includes near-black content: the charcoal Articles card and
     the case hero's card renders. At 20% over #161616 the labels land at
     1.1:1. 50% is the most transparent plate that still clears AA there
     (4.57:1) — and buying that cost a darker label, see --nav-ink.
   - The blur is raised past the literal 5: Figma's GLASS also does
     refraction and dispersion, which CSS has no equivalent for, and 5px
     with neither reads as nothing.

   What made the old bar look flat was not the opacity — it was the grey
   1px border and the total absence of edge light. Both fixed below. */
:root { --nav-glass: rgba(255, 255, 255, 0.50); }

.nav-pillgroup,
.page--stacked .nav-pillgroup,
.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup { background: var(--nav-glass); }

/* ---- 30.2 Ink: dark grey labels, solid black active button ------------- */
.nav-pill,
.page--case .nav-pill,
.page--tinted .nav-pill { color: #3f3f3f; }

.nav-pill[aria-current="page"],
.page--case .nav-pill[aria-current="page"],
.page--tinted .nav-pill[aria-current="page"] {
  background: var(--ink-500);
  color: #e7efee;
  font-weight: 700;
}
/* hover keeps the Figma Nav Pill states */
.nav-pill:hover,
.nav-pill:focus-visible,
.page--case .nav-pill:hover,
.page--tinted .nav-pill:hover {
  background: var(--pill-hover);
  color: var(--pill-hover-ink);
}
.nav-pill[aria-current="page"]:hover,
.nav-pill[aria-current="page"]:focus-visible,
.page--case .nav-pill[aria-current="page"]:hover,
.page--tinted .nav-pill[aria-current="page"]:hover {
  background: var(--pill-active-hover);
  color: var(--pill-active-hover-ink);
}

/* No backdrop-filter support: lean on the fill rather than going solid */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root { --nav-glass: rgba(255, 255, 255, 0.82); }
}

/* -------------------------------------------------------------------------
   31. About — the Afya card and the rewritten headings (Figma 2028:1689)
   The Afya card carries no photo in the design, so its text runs the full
   width of the card instead of the 52% column the photo cards use.
   ---------------------------------------------------------------------- */
.stack-card--a-afya { background: var(--orange-100); }

.page--stacked .stack-card--about.media-none > .about-card__content {
  width: 100%;
  max-width: none;
  margin-left: 0;
}

/* The headings are now sentences, not company names, so they need room to
   breathe over two lines and the period sits right under them. */
.about-card__content > div:first-child {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

/* =========================================================================
   32. Real components, theme-aware links, and image proportions
   ========================================================================= */

/* ---- 32.1 The icon inherits the label colour ---------------------------
   arrow-right.svg is stroked white, so as an <img> it needed a filter per
   variant and still could not become the Articles pink. As a mask driven by
   currentColor it matches the label in every state, which is what the Figma
   component does. */
/* The icon is an inline <svg> whose path is stroke="currentColor", so it
   already follows the label. It used to be a <span> painted with
   background-color + a mask; that rule survived the switch and was filling
   the icon with the BUTTON's colour instead of the text's, which is why the
   download arrow disappeared against its own fill. */
.btn__icon {
  display: inline-block;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: inherit;
}
.btn__icon path { stroke: currentColor; }
/* the filters that used to recolour the <img> have nothing left to act on */

/* ---- 32.2 button/with-icon, type=outline, size=MD ----------------------
   Figma 2024:13523. Default: no fill, 1px #a6a6a6, label #161616, pad 8/16.
   Hover: #d9d9d9 fill, #bad4d1 border, label #161616. */
.btn--md { padding: var(--sp-8) var(--sp-16); }
.btn--outline {
  background: transparent;
  border-color: #a6a6a6;
  color: var(--text-primary);
}
.btn--outline:hover,
.btn--outline:focus-visible {
  background: var(--btn-outline-hover);
  border-color: var(--btn-outline-hover-border);
  color: var(--text-primary);
}
/* the same component sitting on the dark Articles card: Figma recolours the
   border to #ecd0d0 and the label to #f59191 */
.btn--outline.btn--on-dark {
  border-color: #ecd0d0;
  color: var(--pink-500);
}
.btn--outline.btn--on-dark:hover,
.btn--outline.btn--on-dark:focus-visible {
  background: var(--btn-outline-hover);
  border-color: var(--btn-outline-hover-border);
  color: var(--text-primary);
}

/* ---- 32.3 Section subtitles ------------------------------------------
   Figma sets both at DM Sans Regular 14: #161616 on the Short stories card,
   #edbfbf on the Articles card. */
.card-intro {
  font-family: var(--font-sans);
  font-size: var(--size-14);
  font-weight: 400;
  line-height: var(--lh-body);
  letter-spacing: 0;
}
.stack-card--sage .card-intro { color: var(--text-primary); }
.stack-card--charcoal .card-intro { color: #edbfbf; }

/* ---- 32.4 Link colour is a property of the theme, not of the page ------
   #556B2F on light ground, #BAD4D1 on dark. One token, flipped wherever
   the ground flips, so a link picks up the right colour from context
   instead of each page restating it.
   Measured AA: 4.75-5.84:1 on the light grounds, 9.9-11.6:1 on the dark. */
/* superseded: --link is the semantic token, defined with the theme */

/* The per-context link overrides are gone: --link is a semantic token now
   and the theme decides it (#556B2F on the light ground, #BAD4D1 on the
   dark one). The charcoal Articles card keeps its own, because it stays
   dark in both themes. */
.stack-card--charcoal { --link: var(--teal-200); }

/* Text links only — components (buttons, nav pills, whole-card links,
   carousel controls) carry their own colour from their own variant. */
.site-footer a:not(.btn),
.prose a,
.card-body a:not(.btn),
.about-card__text a,
.story__block a,
.case-text a,
.resume-section__body a,
.home2-exp__org a,
.home2-hero__sub a,
a.link-arrow { color: var(--link); }

.site-footer--dark .site-footer__email,
.site-footer--dark a:not(.site-footer__email):not(.btn) { color: var(--link); }
.site-footer--light .site-footer__email,
.site-footer--light a:not(.site-footer__email):not(.btn) { color: var(--link); }

/* ---- 32.5 Home hero image: squarer, so it takes less height -----------
   It was 540x614 (0.88). Driving it from aspect-ratio instead of a computed
   height brings it to 1:1 and lets cover crop the source without stretching
   anything. The card keeps its shared height; the image simply occupies
   less of it and centres. */
.page--stacked .home2-hero__portrait {
  width: min(540px, 46%);
  height: auto;
  aspect-ratio: 1 / 1;
  max-height: calc(var(--card-h) - var(--card-pad) * 2);
  object-fit: cover;
  object-position: 50% 30%;
}

/* ---- 32.6 Short stories: the two case images stay side by side --------
   They used to be a fixed 290 + a flexible 720, so as the column narrowed
   only the second one shrank — below roughly 500px of row the FIRST image
   became the larger of the two. Driving both from a shared height with
   width:auto keeps their natural proportions and their relative sizes
   locked at every width; if the pair stops fitting, the row scrolls
   sideways instead of one of them collapsing. */
.story__media {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-32);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-200) transparent;
  padding-bottom: var(--sp-8);
}
.story__media img {
  flex: 0 0 auto;
  width: auto;
  height: clamp(280px, 33vw, 480px);
  max-width: none;
  object-fit: contain;
  border-radius: var(--radius-md);
  background: var(--gray-100);
}
.story__media::-webkit-scrollbar { height: 6px; }
.story__media::-webkit-scrollbar-thumb { background: var(--ink-200); border-radius: 3px; }

/* a single wide render still spans the column */
.story__media--single { display: block; overflow: visible; padding-bottom: 0; }
.story__media--single img { width: 100%; height: auto; }

/* ---- 32.7 About: one height for every card ----------------------------
   Same approach as the Home: a single shared variable and a single rule,
   no per-card heights. 700px clears the tallest card's natural content
   (Hotmart at 685) so every card lands on exactly this number. */
.page--about2 { --about-card-h: 760px; --card-gap: 12px; }

.page--stacked .stack-card--about { min-height: var(--about-card-h); }

/* The dwell is uniform here too. The About has no carousel to browse, so
   the long per-card holds (22-44vh) only made the page feel slow. */
.page--about2 .stack-card--a-hero,
.page--about2 .stack-card--a-afya,
.page--about2 .stack-card--a-pag,
.page--about2 .stack-card--a-inter,
.page--about2 .stack-card--a-meli,
.page--about2 .stack-card--a-hot,
.page--about2 .stack-card--a-obs { --dwell: 26vh; }

/* Image to text: 64px, measured edge to edge.
   Computing the text WIDTH does not work here: the photo is absolutely
   placed and measured from the card's padding box, while a child's 100%
   resolves against the content box — the two disagree by the card padding
   and the gap drifted to 132px. Pushing the text away from the photo with
   a margin sidesteps the mismatch and holds at any card width. */
.page--about2 {
  --about-pad-x: clamp(20px, 3.5vw, 52px);
  --about-media-w: min(568px, 40vw);
  --about-col-gap: 64px;
  --about-text-offset: calc(var(--about-media-w) + var(--about-col-gap) - var(--about-pad-x));
}
.page--stacked .stack-card--about {
  padding: clamp(24px, 3vw, 40px) var(--about-pad-x);
}
.page--stacked .stack-card--about > .about-card__media { width: var(--about-media-w); }
.page--stacked .stack-card--about > .about-card__content,
.page--stacked .stack-card--about > .about-hero2__text {
  width: auto;
  max-width: none;
  margin-inline: 0;
}
.page--stacked .stack-card--about.media-left > .about-card__content,
.page--stacked .stack-card--about.media-left > .about-hero2__text {
  margin-left: var(--about-text-offset);
}
.page--stacked .stack-card--about.media-right > .about-card__content,
.page--stacked .stack-card--about.media-right > .about-hero2__text {
  margin-right: var(--about-text-offset);
}
.page--stacked .stack-card--about.media-none > .about-card__content {
  width: 100%;
  margin-inline: 0;
}

/* With one height for every card, the shorter cards left the text pinned to
   the top over a large void. The text column now fills the card's height so
   it centres against the photo, which spans the full card anyway. */
.page--stacked .stack-card--about > .about-card__content,
.page--stacked .stack-card--about > .about-hero2__text {
  min-height: calc(var(--about-card-h) - 2 * clamp(24px, 3vw, 40px));
  justify-content: center;
}

/* =========================================================================
   33. Label role, menu behaviour, carousels and card interaction
   ========================================================================= */

/* ---- 33.1 One rule for every DM Sans 12 label -------------------------
   DM Sans 12 / 4% tracking / uppercase / ink-300. Contexts where Figma
   names a different colour (the Short stories and Articles eyebrows) keep
   theirs — the class supplies the default, not an override. */
.text-label,
.card-eyebrow,
.story__block h3,
.story-card__org,
.story__org,
.case-hero__meta,
.metric-big__label,
.resume-section__label,
.article-card__source {
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: 400;
  line-height: var(--lh-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Figma sets these two explicitly */
.stack-card--sage .card-eyebrow { color: var(--text-primary); }
.card-eyebrow--pink { color: var(--pink-500); }

/* ---- 33.2 The pill shrinks on scroll, grows on hover ------------------ */
.nav-pillgroup {
  transform-origin: 50% 0;
  /* transform and paint only — animating padding (or width/height) relaid
     out the pill on every state change, which is what made it jump. */
  transition: transform 260ms cubic-bezier(.2,.7,.2,1),
              background-color 200ms var(--ease),
              box-shadow 200ms var(--ease);
  will-change: transform;
  /* the bar keeps its box no matter which state it is in */
  flex: 0 0 auto;
}
.is-scrolled .nav-pillgroup { transform: scale(0.88); }
.home2-header:hover .nav-pillgroup,
.home2-header:focus-within .nav-pillgroup { transform: scale(1.04); }
.is-scrolled .home2-header:hover .nav-pillgroup,
.is-scrolled .home2-header:focus-within .nav-pillgroup { transform: scale(0.98); }

/* ---- 33.3 The active pill glides instead of jumping ------------------- */
.nav-pill {
  position: relative;
  z-index: 1;
  background: transparent !important;   /* the moving indicator paints it */
  transition: color 220ms var(--ease);
}
.nav-pillgroup { position: relative; }
.nav-pill-indicator {
  position: absolute;
  /* zero origin: the script positions it entirely from the active item's
     measured box. A CSS top here was added on top of that y and pushed the
     black pill 7px below its label. */
  top: 0;
  left: 0;
  height: 44px;   /* replaced by the measured height on first paint */
  border-radius: var(--radius-pill);
  background: var(--ink-500);
  z-index: 0;
  pointer-events: none;
  transition: transform 380ms cubic-bezier(.2,.8,.2,1),
              width 380ms cubic-bezier(.2,.8,.2,1),
              opacity 200ms var(--ease);
  will-change: transform, width;
}
.nav-pill-indicator[hidden] { display: none; }
/* hover target for the indicator, so it follows the pointer too */
.nav-pillgroup:hover .nav-pill-indicator { background: var(--pill-hover); }
/* At rest the active pill is #e7efee on the #161616 indicator. Using
   --pill-active-hover-ink here painted the label #161616 on a #161616
   indicator and the word vanished. */
.nav-pill[aria-current="page"] { color: #e7efee; }
.nav-pillgroup:hover .nav-pill[aria-current="page"] { color: var(--pill-active-hover-ink); }

/* ---- 33.4 Page transition ---------------------------------------------
   Replaced by cross-document View Transitions in section 38. The old
   class-driven animation is gone: it had to intercept every click, and a
   transform on .page made it the containing block for the fixed footer. */

/* ---- 33.5 Hero image: square, full stop ------------------------------- */
.page--stacked .home2-hero__portrait {
  width: min(540px, 46%);
  height: auto;
  aspect-ratio: 1 / 1;
  max-height: none;
  object-fit: cover;
  object-position: 50% 30%;
}

/* ---- 33.6 Carousel buttons — button/icon-only, size=LG, circle -------
   Figma 2002:8991. tertiary #e7efee -> hover #bad4d1, disabled #d9d9d9;
   primary #161616 -> hover #0c1e1c. The Articles next button is the same
   primary variant themed pink. */
.carousel-btn {
  /* Without this a disabled <button> keeps appearance:auto and Chrome paints
     the native control, ignoring the author background entirely. */
  appearance: none;
  -webkit-appearance: none;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-pill);
  border: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 200ms var(--ease), color 200ms var(--ease),
              transform 200ms var(--ease), opacity 200ms var(--ease);
}
.carousel-btn__icon { width: 16px; height: 16px; display: block; }
.carousel-btn--tertiary { background: #e7efee; color: var(--text-primary); }
.carousel-btn--tertiary:hover:not(:disabled) { background: #bad4d1; transform: scale(1.08); }
.carousel-btn--primary  { background: var(--ink-500); color: #fff; }
.carousel-btn--primary:hover:not(:disabled) { background: var(--btn-bg-hover); transform: scale(1.08); }
.carousel-btn:active:not(:disabled) { transform: scale(0.94); }
.carousel-btn:disabled { background: #d9d9d9; color: var(--ink-200); cursor: default; }
.stack-card--charcoal .carousel-btn--primary { background: var(--pink-500); color: var(--text-primary); }
.stack-card--charcoal .carousel-btn--primary:hover:not(:disabled) { background: var(--btn-bg-hover); color: #fff; }

/* ---- 33.7 Pagination dots -------------------------------------------- */
.rail-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-24);
  flex-wrap: wrap;
}
.rail-dots { display: flex; align-items: center; gap: var(--sp-8); }
.rail-dot {
  width: 8px; height: 8px;
  border-radius: var(--radius-pill);
  border: 0;
  padding: 0;
  background: var(--ink-200);
  cursor: pointer;
  transition: background-color 200ms var(--ease), width 240ms var(--ease);
}
.rail-dot:hover { background: var(--ink-300); }
.rail-dot[aria-current="true"] { width: 22px; background: var(--ink-500); }
.stack-card--charcoal .rail-dot { background: rgba(255,255,255,0.28); }
.stack-card--charcoal .rail-dot:hover { background: rgba(255,255,255,0.5); }
.stack-card--charcoal .rail-dot[aria-current="true"] { background: var(--pink-500); }

/* ---- 33.8 Articles: the whole card is the interaction ----------------- */
.stack-card--charcoal .article-card {
  background: var(--charcoal-050);
  border: 0;
  border-radius: var(--radius-card);
  padding: var(--sp-16);
  color: var(--text-primary);
  transition: background-color 220ms var(--ease), transform 220ms var(--ease);
}
.stack-card--charcoal .article-card:hover,
.stack-card--charcoal .article-card:focus-visible {
  background: #aea7a7;
  transform: translateY(-2px);
}
.stack-card--charcoal .article-card:hover .article-card__source,
.stack-card--charcoal .article-card:focus-visible .article-card__source { color: var(--text-primary); }

/* =========================================================================
   34. Resume — Figma 2028:1547
   ========================================================================= */

/* The aside sub is a Source Serif italic phrase, not a sans sub-label. */
.resume-section__sub {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--text-h2);
  font-weight: 400;
  line-height: var(--lh-h2);
  letter-spacing: -0.01em;
  color: var(--text-secondary);
}
.resume-section__aside { display: flex; flex-direction: column; gap: var(--sp-4); }

/* The Summary opens on a heavier lede, as the Figma sets it. */
.resume-summary__lede {
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: 600;
  line-height: var(--lh-prose);
  color: var(--text-secondary);
}

/* Company bio at 12, running text at 16, and the rule sits BELOW the bio
   rather than above it. 80px between one company block and the next. */
.resume-job__bio {
  font-family: var(--font-sans);
  font-size: var(--text-label);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
}
.resume-job__rule {
  width: 100%;
  height: 1px;
  border: 0;
  margin: var(--sp-24) 0 var(--sp-8);
  background: var(--border);
}
.resume-section__body,
.resume-job p:not(.resume-job__bio):not(.resume-job__role):not(.resume-job__period),
.resume-list li {
  font-size: var(--text-body);
  line-height: var(--lh-prose);
}
.resume-job + .resume-job { margin-top: var(--sp-80); }
.resume-section__body > .resume-job:first-child { margin-top: 0; }
/* the serif italic phrase needs more room than the old sans sub had */
.resume-section__sub { max-width: 250px; }

/* =========================================================================
   35. About — alignment
   ========================================================================= */

/* Figma puts every Content frame at y=60, i.e. flush to the card's top
   padding, in all seven cards. Centring the text inside the fixed 760px
   card made the heading start at a different height on every one (194,
   314, 263, 289, 201, 132, 271). Top-aligning restores the shared baseline
   the design has, at the cost of some air under the shorter cards. */
.page--stacked .stack-card--about > .about-card__content,
.page--stacked .stack-card--about > .about-hero2__text {
  justify-content: flex-start;
  min-height: 0;
}

/* Tablet and below: the column layout was being overridden by the
   media-left/right text offsets declared later in the file, which pushed
   the text a full photo-width to the side and made it overlap the image
   (gap measured -390px at 900px). Reset them here, last. */
@media (max-width: 900px) {
  .page--stacked .stack-card--about { min-height: 0; }
  .page--stacked .stack-card--about.media-left > .about-card__content,
  .page--stacked .stack-card--about.media-left > .about-hero2__text,
  .page--stacked .stack-card--about.media-right > .about-card__content,
  .page--stacked .stack-card--about.media-right > .about-hero2__text {
    margin-inline: 0;
    width: 100%;
  }
  .page--stacked .stack-card--about > .about-card__media {
    position: static;
    width: 100%;
    order: -1;
    aspect-ratio: 16 / 10;
    border-radius: 12px;
    overflow: hidden;
  }
  .page--stacked .stack-card--about > .about-card__media img {
    width: 100%; height: 100%; object-fit: cover;
  }
}

/* =========================================================================
   36. Stability, responsive fixes and the black-outline button set
   ========================================================================= */

/* ---- 36.1 The pill never reflows -------------------------------------
   Its size is fixed by content; the scroll and hover states only scale it.
   The indicator is absolutely placed and moved by transform, so it is out
   of flow and cannot push the labels around. */
.nav-pill {
  white-space: nowrap;
  /* letter-spacing shifts on state change would resize the label, so the
     label's tracking is pinned here and never animated */
  letter-spacing: -0.25px;
}
.nav-pill-indicator { will-change: transform, width; }

/* ---- 36.2 Home hero: square at every width ---------------------------
   The portrait was 144x540 on a 375 screen (ratio 0.27). Two rules fought:
   `width: min(540px, 46%)` from the stacked layer kept it at 46% of the
   card even after the hero switched to a column, and a leftover height
   pinned it at 540 — with both dimensions set, aspect-ratio is ignored. */
.page--stacked .home2-hero__portrait {
  width: min(540px, 46%);
  height: auto;
  aspect-ratio: 1 / 1;
  max-height: none;
  object-fit: cover;
  object-position: 50% 30%;
}
@media (max-width: 900px) {
  .page--stacked .home2-hero__portrait,
  .home2-hero__portrait {
    /* THE bug: the base rule sets `flex: 0 1 540px`, and once .home2-hero
       switches to a column the flex-basis applies to the MAIN axis — so
       540px became the height and pinned the image vertical. Resetting the
       basis lets aspect-ratio drive it. */
    flex: 0 0 auto;
    width: 100%;
    max-width: 440px;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    object-position: 50% 28%;
    border-radius: 0 96px 0 96px;
  }
}

/* ---- 36.3 Selected work card on mobile -------------------------------
   The media is absolutely placed and full-bleed on desktop; in the column
   layout it becomes a normal block with its own ratio and the card radius,
   so it can neither overlay the text nor leave a gap at the card edge. */
@media (max-width: 900px) {
  .page--stacked .home2-case { flex-direction: column; gap: var(--sp-24); padding: var(--sp-24); }
  .page--stacked .home2-case__media {
    position: static;
    width: 100%;
    aspect-ratio: 16 / 11;
    border-radius: var(--radius-card);
    overflow: hidden;
    order: -1;
  }
  .page--stacked .home2-case__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 45%;
    border-radius: 0;
  }
  .page--stacked .home2-case__text { min-height: 0; flex: 1 1 auto; max-width: none; }
}

/* ---- 36.4 Text buttons: black outline --------------------------------
   Figma button/with-icon, type=secondary: transparent with a #161616
   border and a #161616 label, filling #0c1e1c with a white label on hover.
   Replaces the grey #a6a6a6 outline on the two section buttons. */
.btn--outline {
  background: transparent;
  border-color: var(--btn-outline-border);
  color: var(--text-primary);
}
.btn--outline:hover,
.btn--outline:focus-visible {
  background: var(--btn-bg-hover);
  border-color: var(--btn-bg-hover);
  color: var(--btn-fg);
}
/* the same button on the dark Articles card keeps the Figma pink label */
.btn--outline.btn--on-dark {
  border-color: var(--pink-500);
  color: var(--pink-500);
}
.btn--outline.btn--on-dark:hover,
.btn--outline.btn--on-dark:focus-visible {
  background: var(--pink-500);
  border-color: var(--pink-500);
  color: var(--text-primary);
}
.btn[disabled],
.btn[aria-disabled="true"] {
  background: var(--btn-disabled-bg);
  border-color: var(--btn-disabled-bg);
  color: var(--btn-disabled-fg);
  cursor: default;
  pointer-events: none;
}

/* ---- 36.5 Carousel chevrons: black outline, real disabled ------------- */
.carousel-btn--tertiary,
.carousel-btn--primary {
  background: transparent;
  border: 1px solid var(--ink-500);
  color: var(--text-primary);
}
.carousel-btn--tertiary:hover:not(:disabled),
.carousel-btn--primary:hover:not(:disabled) {
  background: var(--ink-500);
  border-color: var(--ink-500);
  color: #ffffff;
  transform: scale(1.06);
}
.carousel-btn:disabled {
  background: transparent;
  border-color: var(--ink-100, #d9d9d9);
  color: var(--ink-200);
  cursor: default;
  pointer-events: none;
  transform: none;
}
/* on the dark Articles card the same button inverts */
.stack-card--charcoal .carousel-btn--tertiary,
.stack-card--charcoal .carousel-btn--primary {
  background: transparent;
  border-color: var(--pink-500);
  color: var(--pink-500);
}
.stack-card--charcoal .carousel-btn--tertiary:hover:not(:disabled),
.stack-card--charcoal .carousel-btn--primary:hover:not(:disabled) {
  background: var(--pink-500);
  border-color: var(--pink-500);
  color: var(--text-primary);
}
.stack-card--charcoal .carousel-btn:disabled {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.22);
  color: rgba(255, 255, 255, 0.32);
}

/* ---- 36.6 Mobile: no dead space before the footer --------------------
   The trailing spacer and the reserved footer height exist so the last
   card can stay pinned while the footer rises from underneath. Below 900px
   the cards do not stack at all, so both were pure empty screen — measured
   480px of it between the last card and the footer. */
@media (max-width: 900px) {
  .page--stacked .stack-cards::after,
  .stack-cards::after { height: 0; display: none; }
  .page--stacked .stack-cards { margin-bottom: 0; }
  .site-footer--reveal { position: static; }
  .page--stacked .stack-card:last-of-type { margin-bottom: var(--card-gap); }
}

/* =========================================================================
   37. Nav pills — alignment, stable width, horizontal scroll
   Figma 2052:91681: group pad 4 / align centre / h 52; item pad 12-24,
   h 44, centred on both axes, line-height 20, tracking -0.25.
   ========================================================================= */

.nav-pillgroup {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;   /* centring an overflowing scroller makes
                                    its start unreachable; the header centres
                                    the group itself when it fits */
  gap: 4px;
  padding: 6px;
  /* horizontal scroll when the four items no longer fit */
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  overscroll-behavior-x: contain;
}
.nav-pillgroup::-webkit-scrollbar { display: none; }
.nav-pillgroup > li { display: flex; flex: 0 0 auto; scroll-snap-align: center; }

/* Every item is the same box: same padding, same height, same line-height,
   centred on both axes — so the row reads as one baseline. */
.nav-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  padding: 12px 24px;
  line-height: 20px;
  box-sizing: border-box;
  white-space: nowrap;
}

/* The active item is Bold in Figma and the others Medium, which changed the
   item's width the moment the active page changed and shoved its neighbours
   sideways. The label now always reserves its BOLD width: the pseudo holds
   the bold string at zero height, so the box is identical in both weights
   and switching pages moves nothing. */
.nav-pill__label {
  display: inline-block;
  text-align: center;
}
.nav-pill__label::after {
  content: attr(data-label);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
  pointer-events: none;
  speak: never;
}

/* =========================================================================
   38. Cross-document page transition
   The menu order is Home 0 · Short stories 1 · About 2 · Resume 3. Moving
   forward, the old page leaves left and the new one enters from the right;
   moving back, both reverse. site.js sets data-nav-direction by comparing
   the two positions; this stylesheet only picks the direction.
   ========================================================================= */
@view-transition { navigation: auto; }

/* The main content is what slides; naming it keeps the fixed nav out of the
   moving group so the pill does not fly across with the page. */
.page { view-transition-name: page-content; }
.home2-header,
.site-header { view-transition-name: site-nav; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(page-content),
  ::view-transition-new(page-content) {
    animation-duration: 340ms;
    animation-timing-function: cubic-bezier(.2, .8, .2, 1);
    animation-fill-mode: both;
    mix-blend-mode: normal;
  }
  /* forward: out to the left, in from the right */
  ::view-transition-old(page-content) { animation-name: vt-exit-left; }
  ::view-transition-new(page-content) { animation-name: vt-enter-right; }
  /* back: mirrored */
  html[data-nav-direction="back"]::view-transition-old(page-content) { animation-name: vt-exit-right; }
  html[data-nav-direction="back"]::view-transition-new(page-content) { animation-name: vt-enter-left; }

  /* the nav stays put and just cross-fades, so the pill never slides away */
  ::view-transition-old(site-nav),
  ::view-transition-new(site-nav) {
    animation-duration: 200ms;
    animation-timing-function: ease;
    mix-blend-mode: normal;
  }
}

@keyframes vt-exit-left   { to   { opacity: 0; transform: translateX(-4%); } }
@keyframes vt-enter-right { from { opacity: 0; transform: translateX(4%);  } }
@keyframes vt-exit-right  { to   { opacity: 0; transform: translateX(4%);  } }
@keyframes vt-enter-left  { from { opacity: 0; transform: translateX(-4%); } }

/* Reduced motion: navigate with no slide at all. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* the footer's bottom row keeps its wrap */
.site-footer__bottom { flex-wrap: wrap; }

/* =========================================================================
   40. Colour transition
   Colour only, and never on first paint — the head script stamps the theme
   before the stylesheet applies, so there is nothing to animate on load.
   ========================================================================= */
@media (prefers-reduced-motion: no-preference) {
  body,
  .page,
  .stack-card,
  .shell,
  .site-footer,
  .article-card,
  .btn,
  .nav-pillgroup {
    transition: background-color 260ms var(--ease),
                color 260ms var(--ease),
                border-color 260ms var(--ease);
  }
}

/* =========================================================================
   41. Footer and nav variants follow the theme
   The --light / --dark footer variants and the tinted nav pinned their own
   inks back when each page owned its ground. With one semantic ground they
   fought the theme: on the dark theme the footer title and the nav labels
   were dark ink on a dark page and simply disappeared. Both variants now
   read from the semantic layer, so the class only says which footer this is
   — the theme says what colour it takes.
   ========================================================================= */
.site-footer--light,
.site-footer--dark { background: var(--bg-page); }

.site-footer--light .site-footer__title,
.site-footer--dark  .site-footer__title { color: var(--text-primary); }

.site-footer--light .site-footer__question,
.site-footer--dark  .site-footer__question { color: var(--text-muted); }

.site-footer--light .site-footer__email,
.site-footer--dark  .site-footer__email,
.site-footer--light a:not(.site-footer__email):not(.btn),
.site-footer--dark  a:not(.site-footer__email):not(.btn) { color: var(--link); }

.site-footer--light .site-footer__bottom,
.site-footer--dark  .site-footer__bottom { border-top-color: var(--border); }

.site-footer--light :where(a, button):focus-visible,
.site-footer--dark  :where(a, button):focus-visible { outline-color: var(--link); }

/* The nav label is one token everywhere; the glass sits over both grounds. */
.nav-pill,
.page--case .nav-pill,
.page--tinted .nav-pill { color: var(--nav-ink); }
.nav-pill[aria-current="page"],
.page--case .nav-pill[aria-current="page"],
.page--tinted .nav-pill[aria-current="page"] {
  background: transparent;          /* the sliding indicator paints it */
  color: var(--nav-active-fg);
}
.nav-pill-indicator { background: var(--nav-active-bg); }

/* The glass fill is a property of the ground behind it, not of the page. */
:root { --nav-glass: rgba(255, 255, 255, 0.50); }
.nav-pillgroup,
.page--stacked .nav-pillgroup,
.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup {
  background: var(--nav-glass);
  border-color: var(--border-strong);
}

/* =========================================================================
   42. Surfaces that follow the theme vs. surfaces that don't
   Two kinds of ground exist now:

   (a) themed surfaces — they take --bg-surface and their text takes the
       semantic inks, so both sides move together;
   (b) fixed surfaces — the ten story-card fills, the About card pastels,
       the Selected work band and the charcoal Articles card. Their colour
       is content, not interface, so it stays put in both themes. Anything
       whose GROUND is fixed must fix its INK too, or the theme moves the
       text out from under it. These blocks re-pin the semantic ink tokens
       locally, which keeps components referencing only the semantic layer.
   ========================================================================= */

/* ---- (a) themed surfaces --------------------------------------------- */
.stack-card--white,
.stack-card--light { background: var(--bg-surface); }
.page--tinted .shell,
.page--case .shell,
.shell--padded { background: var(--bg-surface); }
/* This card sits ON the fixed blue Selected work card, so it keeps a fixed
   light ground too — taking --bg-surface made it dark while the blue card
   re-pinned the ink dark, and the title vanished. */
.home2-case { background: var(--ground-100); }

.btn--dark {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}
.page-title-block h1 { color: var(--text-primary); }
.page-title-block p  { color: var(--text-muted); }
.story__subject, .story__org { color: var(--text-muted); }
.story__title { color: var(--text-secondary); }
.story__block h3 { color: var(--text-primary); }
.story__block p { color: var(--text-muted); }
.resume-section__sub { color: var(--text-secondary); }
.resume-section__label { color: var(--text-muted); }
.resume-job__org { color: var(--text-primary); }
.resume-job__role, .resume-job__period, .resume-job__bio { color: var(--text-muted); }
.resume-section__body, .resume-list li { color: var(--text-muted); }
.resume-summary__lede { color: var(--text-secondary); }
.metric-big__value { color: var(--text-primary); }
.card-eyebrow { color: var(--text-primary); }
.prose, .card-body .prose p { color: var(--text-muted); }
.home2-exp__org { color: var(--text-primary); }
.home2-exp__role, .home2-exp__period { color: var(--text-muted); }
.tab { color: var(--text-muted); }
.tab[aria-selected="true"] { color: var(--text-primary); }
.tab[aria-selected="true"]::after { background: var(--text-primary); }
.tabs__list { border-bottom-color: var(--border); }
.home2-hero__title { color: var(--text-primary); }
.home2-hero__sub { color: var(--text-muted); }
.site-footer__title { color: var(--text-primary); }

/* ---- (b) fixed surfaces: pin the ink to match the fixed ground -------- */
/* .page--case .case-hero was here, but the #D7E8F7 band was one of the four
   tints that collapsed into --bg-page — it follows the theme now, so its
   ink has to as well. */
.stack-card--about,
.stack-card--blue,
.story-card,
.stack-card--charcoal .article-card {
  --text-primary:   var(--ink-500);
  --text-secondary: var(--ink-400);
  --text-muted:     var(--ink-350);
  --link:           var(--link-300);
  --border:         var(--ink-100);
}
/* the charcoal Articles card is dark in both themes */
.stack-card--charcoal {
  --text-primary:   var(--ground-200);
  --text-secondary: var(--ground-100);
  --text-muted:     var(--ink-muted-on-dark);
  --link:           var(--teal-200);
  --border:         rgba(252, 251, 248, 0.22);
}
.stack-card--charcoal .article-card {
  --text-primary: var(--ink-500);
  --text-muted:   var(--ink-350);
}
.case-hero__title { color: var(--text-primary); }
.about-card__org { color: var(--text-secondary); }
.about-card__period { color: var(--text-muted); }
.about-card__text p { color: var(--text-secondary); }
.about-hero2__title { color: var(--text-primary); }
.about-hero2__lede p { color: var(--text-muted); }
.about-hero2__closing { color: var(--text-primary); }
.story-card__text { color: var(--text-primary); }
.story-card__org { color: var(--text-primary); }
.story-card__sub { color: var(--text-secondary); }

/* The hero card has no ground of its own; it takes the on-ground set from
   the scope below. (A self-referential var() here made the token invalid
   at computed-value time and the hero text fell back to the surface ink.) */
.case-hero__title { color: var(--text-primary); }
.case-hero__meta  { color: var(--text-muted); }

/* =========================================================================
   43. NAV PILLS — isolated component
   Everything about the menu's box and colour lives here and nowhere else.
   It had been corrected three times and kept regressing because 107
   references were spread across ~25 rule sites, so any later edit could
   win by accident. This block is last in the file and its selectors match
   the highest specificity used earlier (.page--tinted .nav-pill is 0,2,0),
   so it is the single owner. Add nav changes HERE, not elsewhere.
   Figma 2052:91681 — group pad 4 / items pad 12-24 / h 44 / centred.
   ========================================================================= */

/* ---- container ------------------------------------------------------- */
.home2-header .nav-pillgroup,
.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup,
.page--stacked .nav-pillgroup {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  padding: 6px;                 /* uniform on all four sides */
  margin: 0;
  width: max-content;
  max-width: 100%;
  height: auto;
  list-style: none;
  position: relative;
  border-radius: var(--radius-pill);
  background: var(--nav-glass);
  /* No border. The component's strokes array is empty — the grey hairline
     was ours, and it is what made the bar read as a plain chip. The edge is
     drawn with light instead, below. */
  border: 0;
  /* Figma GLASS: blur 5, refraction .8, depth 100, lightAngle -45,
     lightIntensity .8, dispersion .51. CSS has no refraction or dispersion,
     so the edge light has to stand in for them: a bright specular rim at
     the top-left where the light comes from, a dimmer counter-rim opposite,
     and an inner bloom for the depth. The backdrop blur is raised above the
     literal 5 because, without refraction, 5px alone reads as nothing. */
  box-shadow:
    inset 1px 1px 0 0 rgba(255, 255, 255, 0.92),
    inset -1px -1px 0 0 rgba(255, 255, 255, 0.38),
    inset 0 0 0 1px rgba(255, 255, 255, 0.45),
    inset 0 1px 20px 0 rgba(255, 255, 255, 0.32),
    0 10px 30px -6px rgba(22, 34, 30, 0.16),
    0 2px 8px -3px rgba(22, 34, 30, 0.10);
  -webkit-backdrop-filter: blur(16px) saturate(190%) brightness(1.06);
  backdrop-filter: blur(16px) saturate(190%) brightness(1.06);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.home2-header .nav-pillgroup::-webkit-scrollbar { display: none; }
.home2-header .nav-pillgroup > li {
  display: flex;
  flex: 0 0 auto;
  margin: 0;
  scroll-snap-align: center;
}

/* ---- item: one box, every state -------------------------------------- */
.nav-pillgroup .nav-pill,
.page--case .nav-pill,
.page--tinted .nav-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: 44px;
  padding: 12px 24px;           /* symmetric, identical on every item */
  border: 0;
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  /* Deliberately constant. Bold on the active item changed its width and
     pushed its neighbours — the alignment bug we chased three times. The
     active state is background + colour only. */
  font-weight: 500;
  line-height: 20px;
  letter-spacing: -0.25px;
  white-space: nowrap;
  text-decoration: none;
  background: transparent;
  color: var(--nav-ink);
  position: relative;
  z-index: 1;
  transition: color 200ms var(--ease);
}
/* The active pill paints ITSELF by default. The sliding indicator only
   takes over once JS has measured and placed it — gated on
   .has-pill-indicator, which the script adds after that first settled
   layout. Without this the pill was transparent from first paint with a
   near-white label on the glass, so the active item was invisible until the
   script ran, and stayed invisible with JS off. */
.nav-pillgroup .nav-pill[aria-current="page"],
.page--case .nav-pill[aria-current="page"],
.page--tinted .nav-pill[aria-current="page"] {
  height: 44px;
  padding: 12px 24px;           /* same box as the others */
  font-weight: 500;             /* same weight as the others */
  background: var(--nav-active-bg);
  color: var(--nav-active-fg);
}
.has-pill-indicator .nav-pillgroup .nav-pill[aria-current="page"],
.has-pill-indicator .page--case .nav-pill[aria-current="page"],
.has-pill-indicator .page--tinted .nav-pill[aria-current="page"] {
  background: transparent;      /* now the indicator paints it */
}
/* The component's real hover, restored. It had been flattened to
   "transparent + active colour" while the palette swap was in; the Nav Pill
   set (2052:89475) fills an inactive pill with #1f3f38 and lightens the
   label. The indicator sits at z-index 0, the label at 1, so an inactive
   pill paints its own fill without disturbing it. */
.nav-pillgroup .nav-pill:hover,
.nav-pillgroup .nav-pill:focus-visible,
.page--case .nav-pill:hover,
.page--tinted .nav-pill:hover {
  background: var(--pill-hover);
  color: var(--pill-hover-ink);
}
/* Active + hover inverts: the indicator goes light and the label dark. The
   indicator is a sibling, so :has is what lets it react to the pill. */
.nav-pillgroup .nav-pill[aria-current="page"]:hover,
.nav-pillgroup .nav-pill[aria-current="page"]:focus-visible,
.page--case .nav-pill[aria-current="page"]:hover,
.page--tinted .nav-pill[aria-current="page"]:hover {
  background: transparent;              /* the indicator paints it */
  color: var(--pill-active-hover-ink);
}
.nav-pillgroup:has(.nav-pill[aria-current="page"]:hover) .nav-pill-indicator,
.nav-pillgroup:has(.nav-pill[aria-current="page"]:focus-visible) .nav-pill-indicator {
  background: var(--pill-active-hover);
}

/* The label span is only here to hold a stable width; with the weight now
   constant it is a no-op guard, kept so a future bold cannot break the row. */
.nav-pillgroup .nav-pill__label { display: inline-block; text-align: center; }
.nav-pillgroup .nav-pill__label::after {
  content: attr(data-label);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 500;
  pointer-events: none;
}

/* ---- the moving indicator -------------------------------------------- */
.nav-pill-indicator {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  border-radius: var(--radius-pill);
  background: var(--nav-active-bg);
  pointer-events: none;
  will-change: transform, width;
  transition: transform 380ms cubic-bezier(.2,.8,.2,1),
              width 380ms cubic-bezier(.2,.8,.2,1),
              background-color 200ms var(--ease);
}

@media (max-width: 640px) {
  .nav-pillgroup .nav-pill,
  .page--case .nav-pill,
  .page--tinted .nav-pill,
  .nav-pillgroup .nav-pill[aria-current="page"] {
    height: 38px;
    padding: 9px 16px;
    font-size: var(--size-14);
  }
  .home2-header .nav-pillgroup,
  .page--case .nav-pillgroup,
  .page--tinted .nav-pillgroup,
  .page--stacked .nav-pillgroup { padding: 5px; gap: 3px; }
}

/* =========================================================================
   44. About cards — one size for all, smaller
   A single shared variable and a single rule, as before, but the height
   comes down. 760 was set to clear the tallest card's natural content at
   1024px; 600 with tighter padding keeps every card on the same box and
   takes ~160px of height out of each one. Content and images untouched.
   ========================================================================= */
.page--about2 {
  --about-card-h: 600px;
  --about-pad-x: clamp(20px, 3vw, 44px);
}
.page--stacked .stack-card--about {
  min-height: var(--about-card-h);
  padding: clamp(20px, 2.4vw, 32px) var(--about-pad-x);
}
.page--stacked .stack-card--about > .about-card__content,
.page--stacked .stack-card--about > .about-hero2__text {
  min-height: 0;
  gap: var(--sp-12);
  padding-block: 0;
}

/* =========================================================================
   45. BUTTONS — isolated component
   Same treatment as the nav: one owning block, last in the file, so a
   later edit cannot win by accident. Every state below is built from the
   --btn-* control tokens rather than raw primitives.
   Figma: button/with-icon (2024:13523) and button/icon-only (2002:8991).
   ========================================================================= */

/* ---- text buttons ----------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-8);
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  font-weight: 500;
  line-height: var(--lh-ui);
  letter-spacing: -0.25px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 180ms var(--ease), color 180ms var(--ease),
              border-color 180ms var(--ease);
}
.btn .btn__icon { color: inherit; }   /* never the fill colour */

/* primary — solid */
.btn--dark {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}
.btn--dark:hover,
.btn--dark:focus-visible {
  background: var(--btn-bg-hover);
  border-color: var(--btn-bg-hover);
  color: var(--btn-fg);
}

/* secondary / outline — the section buttons, and the Selected work card
   button (Figma 2237:22640, type=outline, padding 6/12 via .btn--compact),
   which takes its hover from the whole card link */
.btn--outline,
.btn--outline-dark {
  background: transparent;
  border-color: var(--btn-outline-border);
  color: var(--btn-outline-border);
}
.btn--outline:hover,
.btn--outline:focus-visible,
.home2-case:hover .btn--outline,
.home2-case:focus-visible .btn--outline,
.btn--outline-dark:hover,
.btn--outline-dark:focus-visible {
  background: var(--btn-outline-border);
  border-color: var(--btn-outline-border);
  color: var(--bg-surface);
}
/* the same button on the fixed charcoal Articles card keeps the Figma pink */
.stack-card--charcoal .btn--outline,
.btn--outline.btn--on-dark {
  border-color: var(--pink-500);
  color: var(--pink-500);
}
.stack-card--charcoal .btn--outline:hover,
.stack-card--charcoal .btn--outline:focus-visible,
.btn--outline.btn--on-dark:hover,
.btn--outline.btn--on-dark:focus-visible {
  background: var(--pink-500);
  border-color: var(--pink-500);
  color: var(--ink-500);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  background: transparent;
  border-color: var(--btn-disabled-bg);
  color: var(--btn-disabled-fg);
  cursor: default;
  pointer-events: none;
}

/* ---- icon-only: the carousel chevrons --------------------------------- */
.carousel-btn {
  appearance: none;
  -webkit-appearance: none;      /* a disabled <button> otherwise keeps the
                                    native control and ignores our fill */
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: transparent;
  border: 1px solid var(--btn-outline-border);
  color: var(--btn-outline-border);
  cursor: pointer;
  transition: background-color 180ms var(--ease), color 180ms var(--ease),
              border-color 180ms var(--ease), transform 180ms var(--ease);
}
/* both chevrons are the same button — the only thing that separates them is
   whether they are disabled, which is what the earlier version got wrong */
.carousel-btn--tertiary,
.carousel-btn--primary {
  background: transparent;
  border-color: var(--btn-outline-border);
  color: var(--btn-outline-border);
}
/* The chevron stays an outline in every state — filling it solid was what
   made it read as vanishing against the card. Hover thickens and darkens
   the ring instead of swapping the fill. */
.carousel-btn:hover:not(:disabled),
.carousel-btn:focus-visible:not(:disabled) {
  background: transparent;
  border-color: var(--btn-bg-hover);
  color: var(--btn-bg-hover);
  transform: scale(1.06);
}
.carousel-btn:active:not(:disabled) { transform: scale(0.94); }
/* Disabled means attenuated, never gone. The previous value (#d9d9d9 on
   the sage card) sat at 1.2:1 against its own background, so the chevron
   at the start of the rail read as removed rather than inactive. Both
   chevrons are always rendered; only their state changes. */
.carousel-btn:disabled {
  background: transparent;
  border-color: var(--btn-disabled-border);
  color: var(--btn-disabled-fg);
  opacity: 1;
  cursor: default;
  pointer-events: none;
  transform: none;
}
.carousel-btn__icon { width: 16px; height: 16px; display: block; color: inherit; }

/* on the fixed charcoal card the chevrons follow the pink */
.stack-card--charcoal .carousel-btn,
.stack-card--charcoal .carousel-btn--tertiary,
.stack-card--charcoal .carousel-btn--primary {
  border-color: var(--pink-500);
  color: var(--pink-500);
}
.stack-card--charcoal .carousel-btn:hover:not(:disabled),
.stack-card--charcoal .carousel-btn:focus-visible:not(:disabled) {
  background: transparent;
  border-color: var(--pink-300, #f8b4b4);
  color: var(--pink-300, #f8b4b4);
}
.stack-card--charcoal .carousel-btn:disabled {
  border-color: rgba(252, 251, 248, 0.40);
  color: rgba(252, 251, 248, 0.45);
}

/* ---- pagination dots -------------------------------------------------- */
.rail-dot {
  appearance: none;
  -webkit-appearance: none;
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--border-strong);
  cursor: pointer;
  transition: background-color 200ms var(--ease), width 240ms var(--ease);
}
.rail-dot:hover { background: var(--text-muted); }
.rail-dot[aria-current="true"] { width: 22px; background: var(--text-primary); }
.stack-card--charcoal .rail-dot { background: rgba(252, 251, 248, 0.28); }
.stack-card--charcoal .rail-dot:hover { background: rgba(252, 251, 248, 0.5); }
.stack-card--charcoal .rail-dot[aria-current="true"] { background: var(--pink-500); }

/* the base padding and the MD size variant, kept with the component */
.btn { padding: var(--sp-12) var(--sp-24); }
.btn--md { padding: var(--sp-8) var(--sp-16); }
.btn--compact { padding: 6px var(--sp-12); }

/* =========================================================================
   46. Floating content sheet — Short stories and Resume
   Shadow read from Figma: the "Projects" frame (2028:1344) and the resume
   "Body" frame (2028:1564) both carry one DROP_SHADOW —
   colour rgba(139,156,176,.3), offset 0/6, blur 16, spread 0.
   ========================================================================= */
:root {
  --sheet-shadow-color: rgba(139, 156, 176, 0.3);
  --sheet-shadow: 0 6px 16px 0 var(--sheet-shadow-color);
}
.page--tinted .shell,
.page--qs .shell,
.page--resume .shell { box-shadow: var(--sheet-shadow); }

/* ---- parallax: the sheet rides over the title ------------------------
   The title sticks just under the fixed pill while the sheet scrolls up
   and covers it. The stage bounds the sticky range, so once the sheet has
   passed the title cannot reappear over the footer. */
.page-stage { position: relative; }
/* Short stories on narrow screens: the stage is a flex item of the centred
   .page column, so it sized itself to its widest content — the image pairs —
   and made the shell 661px wide on a 390px screen, clipped at the edge.
   Pinned to the viewport, and the image pairs stack on phones. */
@media (max-width: 900px) {
  .page--qs .page-stage { width: 100%; min-width: 0; }
}
@media (max-width: 640px) {
  .page--qs .story__media { flex-direction: column; }
  .page--qs .story__media img { width: 100%; height: auto; }
}

@media (prefers-reduced-motion: no-preference) {
  .page--qs .page-stage .page-title-block,
  .page--resume .page-stage .page-title-block {
    position: sticky;
    top: calc(var(--header-h) + var(--sp-8));
    z-index: 0;
    /* it is being covered, not read, once the sheet arrives */
    will-change: transform;
  }
  .page--qs .page-stage .shell,
  .page--resume .page-stage .shell {
    position: relative;
    z-index: 1;
  }
}

/* Reduced motion: plain flow, no overlap, shadow kept. */
@media (prefers-reduced-motion: reduce) {
  .page--qs .page-stage .page-title-block,
  .page--resume .page-stage .page-title-block { position: static; }
}

/* =========================================================================
   47. NAV — scroll/hover scaling
   ⚠️  DO NOT REINTRODUCE DIMENSION CHANGES ON SCROLL.
   The bar must only ever be scaled. Any width/height/padding/font-size
   change tied to the scroll state forces a reflow, and the reflow is what
   made the menu snap instead of glide. This block and section 43 own the
   menu; put nav changes there, not in page-level sections.
   ========================================================================= */
.home2-header .nav-pillgroup,
.page--case .nav-pillgroup,
.page--tinted .nav-pillgroup,
.page--stacked .nav-pillgroup {
  transform-origin: 50% 0;
  transform: scale(1);
  /* declared on the BASE so it covers both directions — in and out, scroll
     and hover. A transition living only on :hover animates one way only. */
  transition: transform 300ms ease,
              background-color 200ms var(--ease),
              border-color 200ms var(--ease),
              box-shadow 200ms var(--ease);
  will-change: transform;
}
/* scroll and hover compose into one value each, so neither cancels the
   other mid-flight */
.is-scrolled .home2-header .nav-pillgroup,
.is-scrolled .page--case .nav-pillgroup,
.is-scrolled .page--tinted .nav-pillgroup,
.is-scrolled .page--stacked .nav-pillgroup { transform: scale(0.9); }

.home2-header:hover .nav-pillgroup,
.home2-header:focus-within .nav-pillgroup { transform: scale(1.04); }
.is-scrolled .home2-header:hover .nav-pillgroup,
.is-scrolled .home2-header:focus-within .nav-pillgroup { transform: scale(0.98); }

@media (prefers-reduced-motion: reduce) {
  .home2-header .nav-pillgroup { transition: none; transform: none !important; }
}

/* the bar scales, so nothing may clip it */
.home2-header, .site-header { overflow: visible; }
/* both chevrons are always present — never removed, never display:none */
.rail-nav .carousel-btn { display: inline-flex !important; visibility: visible !important; }

/* =========================================================================
   48. About cards — reverted to the natural-height stack
   A fixed height made every card scroll internally, and that inner scroll
   swallowed the wheel before the page could move on to the next card. The
   cards go back to sizing themselves; only the horizontal padding stays
   trimmed, which shortens them without touching the scroll.
   ========================================================================= */
.page--about2 { --about-pad-x: clamp(20px, 2.6vw, 40px); }
.page--stacked .stack-card--about { padding-inline: var(--about-pad-x); }

/* =========================================================================
   49. Selected work — the container is the same floating sheet
   Figma "Projects" (2048:18419): radius 20 on all four corners and the same
   DROP_SHADOW as Short stories and Resume (0/6, blur 16, 30%). The page had
   neither, which is why the top corners looked square and the sheet sat flat.
   ========================================================================= */
.page--case .shell {
  border-radius: var(--radius-lg);   /* 20px, from the Figma frame */
  box-shadow: var(--sheet-shadow);
  overflow: clip;                    /* clipsContent — rounds the image too */
}

/* the same parallax as the other two: the title stays put and the sheet
   rides up over it */
@media (prefers-reduced-motion: no-preference) {
  .page--case .page-stage .case-hero {
    position: sticky;
    top: calc(var(--header-h) + var(--sp-8));
    z-index: 0;
    will-change: transform;
  }
  .page--case .page-stage .shell {
    position: relative;
    z-index: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .page--case .page-stage .case-hero { position: static; }
}

/* =========================================================================
   50. PagAmerican case — the pieces this case adds
   Everything else reuses the components the Mercado Pago case already has
   (.case-block, .case-eyebrow, .case-text, .case-figure, .case-breakpoint).
   Only three things are new: the opening lede, the three-layer architecture
   row, and the metrics band. Figma 2196:6597.
   ========================================================================= */

/* the paragraph that opens the case, one step up from body copy */
.case-lede {
  font-family: var(--font-body-case);
  font-size: var(--size-20);
  line-height: 1.6;
  color: var(--text-primary);
}

/* the 18px headings inside "Three moves" and the success criteria — below
   .case-breakpoint__title, above body copy */
.case-move__title {
  font-family: var(--font-body-case);
  font-size: var(--size-18);
  font-weight: 500;
  line-height: var(--lh-body);
  color: var(--text-primary);
}

.case-criteria {
  display: flex;
  flex-direction: column;
  gap: var(--sp-24);
}
.case-criteria > div { display: flex; flex-direction: column; gap: var(--sp-8); }
.case-criteria p {
  font-family: var(--font-body-case);
  font-size: var(--size-14);
  line-height: 1.8;
  color: var(--text-secondary);
}

/* ---- the three layers: Foundations / Components / Templates ------------
   Cards are sage with a 12px radius, per the Figma. The illustrations are
   images; only the names are live text, so they can be read and translated. */
.pads-arch {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-12);
  list-style: none;
  margin: 0;
  padding: 0;
}
.pads-arch__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-16);
  padding: var(--sp-16);
  background: var(--sage-100);
  border-radius: 12px;
  min-height: 282px;
  overflow: clip;
}
.pads-arch__card img {
  width: 100%;
  height: auto;
  max-height: 206px;
  object-fit: contain;
  object-position: center;
}
.pads-arch__name {
  font-family: var(--font-display);
  font-size: var(--size-18);
  font-weight: 400;
  color: var(--text-primary);
  text-align: center;
}

/* ---- what the pipeline produced --------------------------------------
   The library sheet is a band of its own above these numbers, not a
   backdrop behind them — so this is plain type on the sheet surface. */
.pads-metrics {
  display: flex;
  flex-direction: column;
  gap: var(--sp-32);
}
.pads-metrics__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-24);
  margin: 0;
}
.pads-metric { display: flex; flex-direction: column; gap: 2px; }
.pads-metric dt {
  font-family: var(--font-body-case);
  font-size: var(--size-12, 0.75rem);
  line-height: 1.6;
  color: var(--text-muted);
}
.pads-metric dd {
  margin: 0;
  font-family: var(--font-body-case);
  font-size: var(--size-24, 1.5rem);
  font-weight: 500;
  line-height: 1.2;
  color: var(--text-primary);
}
.pads-metric__note {
  display: block;
  font-size: 10px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--text-muted);
}
.pads-cost {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-32);
  margin: 0;
  padding-top: var(--sp-24);
  border-top: 1px solid var(--rule);
}
.pads-cost__item { flex: 1 1 200px; }
.pads-cost__item dt {
  font-family: var(--font-body-case);
  font-size: var(--size-14);
  color: var(--text-muted);
}
.pads-cost__item dd {
  margin: 0;
  font-family: var(--font-body-case);
  font-size: var(--size-20);
  font-weight: 500;
  color: var(--text-primary);
}
.pads-cost__unit {
  font-size: var(--size-12, 0.75rem);
  font-weight: 400;
  color: var(--text-muted);
}
.pads-cost__note {
  font-family: var(--font-body-case);
  font-size: 10px;
  color: var(--text-muted);
}

@media (max-width: 720px) {
  .pads-arch { grid-template-columns: 1fr; }
  .pads-arch__card { min-height: 0; }
  .pads-metrics__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 420px) {
  .pads-metrics__grid { grid-template-columns: 1fr; }
}

/* ---- sage/050 cards ---------------------------------------------------
   Figma wraps several blocks of this case in a #F1F1EF card, radius 8,
   padding 12: "Where the friction was", the two cost blocks, each of the
   three moves (heading + copy + image together) and each success
   criterion. The typography inside is unchanged — the card is the
   container, not a new type scale. */
.page--case-pads .case-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  background: var(--sage-050);
  border-radius: 8px;
  padding: var(--sp-12);
}
.page--case-pads .case-card__figure { margin: 0; }
.page--case-pads .case-card__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;      /* the image carries the same radius in Figma */
}
/* the two cost cards sit side by side and should match height */
.page--case-pads .case-facts > .case-card { align-self: stretch; }
.page--case-pads .case-criteria > .case-card { gap: var(--sp-4); }

/* ---- breathing room under the hero ------------------------------------
   Figma "Projects" is a vertical auto-layout with gap 40 between the hero
   image and Main. Without it the first label sat straight under the photo. */
.page--case-pads .shell > .case-result { margin-bottom: 40px; }

/* =========================================================================
   51. Selected work rail — Figma 2205:22655
   The Home's single case card became a rail of two. One card per page,
   each the full width of the card's content box, so the next one peeks at
   the edge exactly as the design shows. Chevrons only: with two cases the
   bullets would say nothing the arrows don't.
   ========================================================================= */
.rail--cases {
  list-style: none;
  /* Bleeds to the RIGHT edge of the blue card. In Figma the rail sits at
     x=120 in a 1280 frame and is 1160 wide, so its right edge lands on the
     frame edge, 120px past the padding box. Without this the peeking card
     stopped short and left a strip of blue after it, which read as a border.
     The stack card clips with overflow:hidden and a 20px radius, so the
     peeking card is cut by the card's own rounded edge. */
  /* The scroller bleeds to BOTH edges of the blue card so a card leaving or
     entering is cut by the card's own rounded edge, with no strip of blue
     left over on either side. The left padding is what keeps the first card
     lined up with the "Selected work" label; it scrolls away with the
     content, and scroll-padding keeps the snap points honest. There is no
     right padding on purpose — that is what lets the peeking card reach the
     edge. */
  margin-inline: calc(-1 * var(--card-pad));
  padding: 0 0 var(--sp-8) var(--card-pad);
  scroll-padding-left: var(--card-pad);
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.rail--cases::-webkit-scrollbar { display: none; }
/* Figma: rail 1160, cards 1040, gap 24 — so a card is 1040/1160 of the
   rail and the next one shows 96px past the gap. Sizing the card at
   "100% - gap" instead put the second card's left edge exactly on the
   rail's right edge, which is why nothing peeked. The rail clips at its own
   content box, which is the blue card's padding edge, so the peeking card
   is cut there on both sides and never escapes the container. */
.rail--cases > li {
  flex: 0 0 89.66%;                      /* 1040 / 1160 */
  display: flex;
  scroll-snap-align: start;
}
.rail--cases > li > .home2-case { flex: 1 1 auto; }

/* the PagAmerican mark is a square badge, not a cropped wordmark */
.home2-case__logo--mark {
  width: 37px;
  height: 37px;
  overflow: visible;
  flex: 0 0 auto;
}
.home2-case__logo--mark img {
  width: 100%;
  height: 100%;
  margin: 0;
  object-fit: contain;
}

/* Figma stacks eyebrow, rail and chevrons in that order, all flush left
   (2205:22655 — vertical auto-layout, counterAxis MIN, gap 24). */
.stack-card--blue { display: flex; flex-direction: column; gap: var(--sp-24); }
.rail-nav--under { justify-content: flex-start; }

/* No mobile override: a full-width card removed the peek entirely, and the
   peek is the thing that tells you a second case exists. The ratio holds at
   every width and the right bleed keeps it flush with the card edge. */

/* =========================================================================
   52. About — continuous page (Figma 2196:10647)
   Replaces the stacked-card About. No sticky cards, no parallax: a static
   hero, a horizontal career timeline grouped in phases (the photo that opens
   a phase, then its role card, then the period on a line underneath), then
   the "outside of all that" card. Content column is 1164px, as in the frame.
   The page keeps .page--home2 for the shared glass header and footer; the
   old .page--about2 / .stack-card--a-* rules no longer match anything.
   ========================================================================= */
.page--about3 {
  --about3-column: 1164px;
  --about3-ink: var(--ink-400);          /* #383838 — every card, one ink */
  --about3-muted: #6b6b6b;               /* 4.65:1 on the page ground */
  --about3-flow: 64px;                   /* one gap between the page's blocks (min 64) */

  /* card type — one scale for every card, the last one included */
  --about3-title-font: var(--font-display);
  --about3-title-size: var(--size-32, 2rem);
  --about3-title-lh: 1.3;
  --about3-body-size: var(--size-14);
  --about3-body-lh: 1.4;
  --about3-card-gap: 16px;               /* title → text */
  --about3-para-gap: 12px;               /* paragraph → paragraph */
  --about3-card-min: 458px;
}
/* .page--home2 > main caps main at 1280; the timeline has to run edge to edge */
.page--about3 > main { max-width: none; }

/* ---- hero -------------------------------------------------------------- */
.about3-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 64px;
  max-width: var(--about3-column);
  margin: 94px auto 0;              /* frame: hero top at 178, header 84 */
}
.about3-hero__text {
  flex: 0 1 794px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  min-width: 0;
}
/* the page title every other page uses (.page-title-block h1) */
.about3-hero__title {
  font-family: var(--font-serif);
  font-size: var(--text-h1);
  font-weight: 400;
  line-height: var(--lh-h1);
  color: var(--text-primary);
}
.about3-hero__lede,
.about3-hero__closing {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: 1.4;
  letter-spacing: 0.2px;
}
.about3-hero__lede { color: var(--about3-muted); }
.about3-hero__closing { color: var(--ink-500); }
.about3-hero__serif { font-family: var(--font-serif); }
.about3-hero__closing em {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
}
.about3-hero__portrait {
  flex: 0 0 306px;
  width: 306px;
  height: 306px;
  border-radius: 50%;
  object-fit: cover;
}

/* ---- timeline ---------------------------------------------------------- */
.about3-timeline { margin-top: var(--about3-flow); }
/* The rail starts at the column's left edge instead of the viewport's, so
   cards leave the scene there. On the right it still runs to the viewport
   edge, ending one inset past the last card. */
.about3-rail {
  --rail-inset: max(24px, calc((100% - var(--about3-column)) / 2));
  margin-left: var(--rail-inset);
  padding: 0 var(--rail-inset) 12px 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-right: var(--rail-inset);
  scrollbar-width: thin;
  scrollbar-color: var(--ink-200) transparent;
}
.about3-rail:focus-visible { outline: 2px solid var(--link-300); outline-offset: 4px; border-radius: 20px; }

.about3-track {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 24px;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* the divider — spans the whole track, BEHIND the periods (z-index 0 vs 1) */
.about3-track::after {
  content: "";
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  bottom: 8px;
  border-top: 1px solid var(--about3-muted);
  pointer-events: none;
}
.about3-phase {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.about3-phase__row {
  flex: 1 1 auto;
  display: flex;
  align-items: stretch;
  gap: 24px;
}

.about3-card {
  flex: 0 0 474px;
  min-height: var(--about3-card-min);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--about3-card-gap);
  padding: 32px;
  border-radius: 20px;
  scroll-snap-align: start;
}
.about3-role--afya  .about3-card { background: #f5eef9; }
.about3-role--pag   .about3-card { background: #eff6ff; }
.about3-role--inter .about3-card { background: #ebddd7; }
.about3-role--meli  .about3-card { background: #eae6d3; }
.about3-role--hot   .about3-card { background: #ecd0d0; }

.about3-card__title {
  font-family: var(--about3-title-font);
  font-size: var(--about3-title-size);
  font-weight: 400;
  line-height: var(--about3-title-lh);
  letter-spacing: -0.01em;
  color: var(--about3-ink);
}
.about3-card__text p {
  font-family: var(--font-sans);
  font-size: var(--about3-body-size);
  font-weight: 400;
  line-height: var(--about3-body-lh);
  letter-spacing: 0.2px;
  color: var(--about3-ink);
}
.about3-card__text p + p { margin-top: var(--about3-para-gap); }

.about3-photo {
  flex: 0 0 400px;
  width: 400px;
  /* The height attribute maps to a CSS height and made every card 1030px.
     height: auto + contain: size drop the photo's own height from the row,
     so the cards set the row and the photo stretches to fill it. */
  height: auto;
  contain: size;
  min-height: var(--about3-card-min);
  object-fit: cover;
  border-radius: 20px;
  display: block;
  scroll-snap-align: start;
}
.about3-photo--wide { flex-basis: 454px; width: 454px; }

/* One year per phase, on the divider: the year the phase began, under the
   right end of its card (the card closes each phase row). The newest phase
   is marked "Present" under its left end instead. Read left to right:
   Present, 2025, 2024, 2022, 2017. The label sits above the divider
   (z-index 1 vs 0) and its ground cuts the line 12px on either side. */
.about3-period {
  position: relative;
  z-index: 1;
  align-self: flex-end;
  padding-left: 12px;
  background: var(--bg-page);
  box-shadow: 12px 0 0 var(--bg-page);    /* 12px clear on the right, no layout */
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: 17px;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--about3-muted);
}
.about3-period--start {
  align-self: flex-start;
  padding-left: 0;
  padding-right: 12px;
  box-shadow: -12px 0 0 var(--bg-page);   /* 12px clear on the left */
}

/* ---- outside of all that ----------------------------------------------
   Figma 2196:10909: the photo fills a 331px column top to bottom, flush
   with the card's left, top and bottom edges (the card clips it to the
   radius); the text starts at x=360, so 29px after the photo, with 32px
   padding on the other three sides. */
.about3-extra {
  display: grid;
  grid-template-columns: 331px 1fr;
  gap: 29px;
  max-width: var(--about3-column);
  margin: var(--about3-flow) auto 0;
  background: #d5ddc8;
  border-radius: 20px;
  overflow: clip;
}
.about3-extra__photo {
  width: 100%;
  height: 100%;
  /* the text sets the row; the photo's own 1000x1250 ratio must not */
  contain: size;
  min-height: 230px;
  object-fit: cover;
  object-position: 50% 50%;
  display: block;
}
.about3-extra__content {
  display: flex;
  flex-direction: column;
  gap: 24px;                          /* frame: title -> text */
  padding: 32px 32px 32px 0;
}
/* frame: one blank line between paragraphs in this card */
.about3-extra { --about3-para-gap: 1.4em; }

/* the footer is a block of the page too: same gap as the others */
.page--about3 .site-footer { margin-top: var(--about3-flow); }

/* ---- narrow screens ---------------------------------------------------- */
@media (max-width: 1212px) {
  .about3-hero, .about3-extra { margin-inline: 24px; }
}
@media (max-width: 900px) {
  .page--about3 {
    --about3-title-size: var(--size-24, 1.5rem);
    --about3-card-min: 420px;
  }
  .about3-hero {
    flex-direction: column-reverse;
    align-items: flex-start;
    gap: 32px;
    margin-top: 40px;
  }
  /* in a column the 794px basis became a 794px HEIGHT: the empty fold */
  .about3-hero__text { flex: 0 0 auto; }
  .about3-hero__portrait { flex-basis: auto; width: 200px; height: 200px; align-self: center; }
  .about3-card { flex-basis: min(474px, 82vw); padding: 24px; }
  .about3-photo,
  .about3-photo--wide { flex-basis: min(400px, 70vw); width: min(400px, 70vw); }
  .about3-extra { grid-template-columns: 1fr; gap: 0; }
  /* stacked: the photo keeps its own 4:5 frame instead of a 240px strip —
     whole on phones, capped at 480px on tablets, where full width at 4:5
     ran to 900–1060px and pushed the text a screen down */
  .about3-extra__photo { min-height: 0; height: auto; aspect-ratio: 4 / 5; max-height: 480px; }
  .about3-extra__content { padding: 24px; }
}

/* =========================================================================
   53. Case pages — back to Home (Figma 2205:16917)
   button/icon-only, 44px circle, #161616 with the #fcfbf8 arrow-left,
   24px to the left of the pill group. The menu itself is untouched: the
   button is absolutely placed against the <nav>, so it takes no part in the
   header's flex centring and the pill group never moves. The nav becomes
   the containing block only where it holds the button (:has), and the pill
   indicator is unaffected — its offsets are relative to the group.
   The .carousel-btn base supplies size, circle and transitions; the colours
   are its own, because .carousel-btn--primary became an outline in 36.5
   and this one is filled in the frame.
   ========================================================================= */
.home2-header > nav:has(> .case-back) { position: relative; }
.carousel-btn.case-back {
  position: absolute;
  top: 50%;
  right: calc(100% + var(--sp-24));
  transform: translateY(-50%);
  border: 0;
  background: var(--ink-500);
  color: #fcfbf8;
  text-decoration: none;
}
.carousel-btn.case-back:hover,
.carousel-btn.case-back:focus-visible { background: var(--btn-bg-hover); color: #fcfbf8; }
.carousel-btn.case-back:hover  { transform: translateY(-50%) scale(1.06); }
.carousel-btn.case-back:active { transform: translateY(-50%) scale(0.94); }
@media (prefers-reduced-motion: reduce) {
  .carousel-btn.case-back:hover,
  .carousel-btn.case-back:active { transform: translateY(-50%); }
}
/* It needs 44 + 24px beside the pill group plus the header gutter. The group
   is 356px wide on phones, so that room runs out below ~516px; there the
   button is dropped rather than pushing or overlapping the menu — the Home
   pill is still one tap away. */
@media (max-width: 519px) {
  .carousel-btn.case-back { display: none; }
}

/* =========================================================================
   54. Scrollbars hidden site-wide
   Every scroll container keeps its overflow and snap; only the bar is not
   painted. Last in the file so it wins over the earlier thin-bar rules
   (.rail, .story__media, .about3-rail) at the same specificity. Wheel,
   trackpad, keyboard and touch scrolling all keep working.
   ========================================================================= */
html,
body,
.rail,
.rail--cases,
.story__media,
.about3-rail,
.nav-pillgroup,
.nav-chips ul {
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* legacy Edge / IE */
}
html::-webkit-scrollbar,
body::-webkit-scrollbar,
.rail::-webkit-scrollbar,
.rail--cases::-webkit-scrollbar,
.story__media::-webkit-scrollbar,
.about3-rail::-webkit-scrollbar,
.nav-pillgroup::-webkit-scrollbar,
.nav-chips ul::-webkit-scrollbar { display: none; }   /* Chrome / Safari */
