/* ═══════════════════════════════════════════════════════════════════════════
   MIRELLE SINE — iOS Software Engineer
   Apple design system. apple.com marketing grammar, HIG components, SF type.

   Rules this file obeys, and the reason each one exists:
   · Two font weights (400/600). SF has no marketing use for 300/500/700.
   · Fixed px type at exactly two breakpoints. clamp()/vw type appears nowhere
     in apple.com's CSS and is the loudest generic-template tell there is.
   · Apple's tracking is a U-curve: negative small, POSITIVE 19-32px, negative
     again at display sizes. A flat -0.02em is instantly visibly wrong.
   · text-transform:uppercase appears zero times. So it appears zero times here.
   · One interface blue for links and buttons. Colour lives in one place: the
     Apple Intelligence palette in css/ios.css (glow, gradient ink, icons).
   · Glass only where iOS itself uses it: the nav, the lightbox, and the
     widgets and dock inside the phones.
   · Cards carry no shadow. Surfaces separate by ground inversion and radius.
   · The only continuous motion is the Apple Intelligence glow, and it stops
     off screen and under reduced motion.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── FONTS ─────────────────────────────────────────────────────────────────
   -apple-system sits BEFORE Inter so every Mac/iPhone/iPad renders genuine
   San Francisco at zero network cost. system-ui appears nowhere: it resolves
   to Segoe UI on Windows and would steal Inter's slot.                      */
:root {
  --font-display: "SF Pro Display", "SF Pro Icons", -apple-system, BlinkMacSystemFont,
                  "Inter", "Segoe UI Variable Display", "Segoe UI", Roboto,
                  "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-text:    "SF Pro Text", "SF Pro Icons", -apple-system, BlinkMacSystemFont,
                  "Inter", "Segoe UI Variable Text", "Segoe UI", Roboto,
                  "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono:    "SF Mono", SFMono-Regular, ui-monospace, Menlo, Consolas,
                  "Cascadia Mono", "Roboto Mono", monospace;
}

/* Apple's U-curve. Applied when real SF is rendering. */
:root {
  --ls-80: -.015em; --ls-64: -.009em; --ls-56: -.005em; --ls-48: -.003em;
  --ls-40: 0em;     --ls-32: .004em;  --ls-28: .007em;  --ls-24: .009em;
  --ls-21: .011em;  --ls-19: .012em;  --ls-17: -.022em; --ls-14: -.016em;
  --ls-12: -.01em;
}
/* Inter is wider than SF Pro and its optimum tracking has the opposite sign
   at reading sizes. One class swap re-tracks the whole page. */
html.no-sf {
  --ls-80: -.022em; --ls-64: -.022em; --ls-56: -.022em; --ls-48: -.022em;
  --ls-40: -.022em; --ls-32: -.022em; --ls-28: -.021em; --ls-24: -.02em;
  --ls-21: -.018em; --ls-19: -.016em; --ls-17: -.013em; --ls-14: -.006em;
  --ls-12: 0em;
}

/* ── TOKENS · LIGHT ───────────────────────────────────────────────────────── */
:root {
  color-scheme: light;

  /* grounds */
  --page:           #ffffff;
  --band:           #f5f5f7;
  --surface:        #ffffff;   /* a card sitting ON --band */
  --surface-alt:    #f5f5f7;   /* a card sitting ON --page */
  --plate:          #f5f5f7;

  /* ink */
  --ink:     #1d1d1f;   /* 16.83:1 on white */
  --ink-2:   #6e6e73;   /* 5.07:1 — the AA floor. Do not lighten. */
  --ink-3:   #86868b;   /* 3.62:1 — large/bold decorative only */
  --ink-inv: #ffffff;

  /* lines */
  --hairline:     #d2d2d7;
  --hairline-ios: rgba(0, 0, 0, .15);
  --keyline:      rgba(0, 0, 0, .16);
  --control-edge: #949494;
  --card-stroke:  transparent;

  /* iOS system fills — reads iOS without spending a hue */
  --fill-3: rgba(118, 118, 128, .12);
  --fill-2: rgba(118, 118, 128, .16);

  /* the single accent */
  --accent:        #0071e3;
  --link:          #0066cc;   /* 5.6:1 — #0071e3 is 4.1:1 and fails AA for body */
  --focus:         var(--accent);
  --focus-offset:  1px;
  --focus-offset-container: 3px;
  --focus-offset-nav: -7px;

  /* neutral button — apple.com's own CTA is neutral, not blue.
     Blue is Apple's commerce colour; a blue pill on a person reads "Buy". */
  --btn:        #1d1d1f;
  --btn-hover:  #272729;
  --btn-active: #18181a;
  --btn-ink:    #ffffff;
  --disabled:   .42;

  /* nav glass (1 of 2 glass surfaces) */
  --nav-bg-opaque: rgba(250, 250, 252, .92);
  --nav-bg:        rgba(250, 250, 252, .80);
  --nav-filter:    saturate(180%) blur(20px);
  --nav-ink:       rgba(0, 0, 0, .8);
  --nav-ink-hover: #000000;

  /* segmented control — Apple's WEB tabnav: dark thumb on a light track */
  --seg-track:      #e8e8ed;
  --seg-thumb:      #1d1d1f;
  --seg-ink:        rgba(0, 0, 0, .8);
  --seg-ink-active: #ffffff;

  /* paddlenav */
  --paddle-bg:        #e8e8ed;
  --paddle-bg-hover:  #ececf0;
  --paddle-bg-active: #dfdfe4;
  --paddle-ink:       rgba(0, 0, 0, .56);
  --paddle-ink-hover: rgba(0, 0, 0, .64);
  --paddle-media-bg:  rgba(210, 210, 215, .64);

  /* shadows — cards get none in both themes */
  --shadow-card: none;
  --device-shadow:
      0 calc(var(--dw) * .006) calc(var(--dw) * .018) rgba(0, 0, 0, .05),
      0 calc(var(--dw) * .034) calc(var(--dw) * .078) rgba(0, 0, 0, .09),
      0 calc(var(--dw) * .110) calc(var(--dw) * .220) calc(var(--dw) * -.05) rgba(0, 0, 0, .14);
  --device-inset: 0 0 transparent;
  --device-glow:  none;

  /* radii — a closed family of five, never scaled at mobile */
  --r-pill:  980px;
  --r-card:  28px;
  --r-tile:  18px;
  --r-block: 12px;
  --r-badge: 5px;

  /* layout */
  --rail-max:     1260px;
  --rail-chrome:   980px;
  --measure:        60ch;
  --measure-lede:  692px;
  --section-pad:   112px;
  --head-gap:       80px;
  --grid-gap:       20px;
  --nav-h:          64px;
  --scroll-offset: calc(var(--nav-h) + 24px);

  /* motion */
  --ease:      cubic-bezier(.4, 0, .6, 1);      /* 122 of 144 uses on apple.com */
  --ease-out:  cubic-bezier(0, 0, .5, 1);
  --ease-nav:  cubic-bezier(.28, .11, .32, 1);
  --t-hover:  100ms;  --t-ui:    240ms;  --t-panel: 320ms;
  --t-slide:  400ms;  --t-move:  700ms;  --t-fade:  900ms;
}

@media (max-width: 1068px) { :root { --section-pad: 96px; --head-gap: 64px } }
@media (max-width:  833px) { :root { --nav-h: 56px } }
@media (max-width:  734px) { :root { --section-pad: 56px; --head-gap: 48px } }

/* Light theme only, by request: no prefers-color-scheme branches anywhere.
   The phones keep their own iOS UI; the page itself is always light. */

/* ── ACCESSIBILITY OVERRIDES ──────────────────────────────────────────────── */
@media (prefers-contrast: more) {
  :root {
    --ink-2: #1d1d1f; --ink-3: #3d3d41; --hairline: #6e6e73;
    --hairline-ios: rgba(0, 0, 0, .45); --focus-offset: 2px;
  }
  .localnav { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--nav-bg-opaque) }
}
/* Chrome/Edge only — which is exactly why the .92 opaque nav base must pass
   contrast on its own for Safari and Firefox. */
@media (prefers-reduced-transparency: reduce) {
  .localnav, .lightbox { -webkit-backdrop-filter: none; backdrop-filter: none }
  .localnav { background: var(--nav-bg-opaque) }
  .lightbox { background: rgba(0, 0, 0, .94) }
}
@media (forced-colors: active) {
  .localnav { backdrop-filter: none; background: Canvas; border-bottom: 1px solid CanvasText }
  .localnav::after { display: none }
  .device, .tile { forced-color-adjust: none }
  .seg__thumb { background: Highlight }
}

/* ── RESET ────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box }

html {
  font-size: 100%;
  quotes: "\201C" "\201D";
  scroll-behavior: smooth;
  /* No overflow-x:hidden. It masks bugs, and on <body> it makes the body its
     own scroll container, corrupting scrollY/scrollHeight in the progress
     ticker. Zero overflow is guaranteed structurally instead. */
}

body {
  margin: 0;
  min-width: 320px;
  font: 400 17px/25px var(--font-text);
  letter-spacing: var(--ls-17);
  color: var(--ink);
  background: var(--page);
  isolation: isolate;
}

/* font-synthesis:none is what stops a browser faking a 600 from a 400 face. */
body, button, input, select, textarea {
  font-synthesis: none;
  -moz-font-feature-settings: "kern";
}

img, svg, video { display: block; max-width: 100% }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer }
a { color: var(--link) }
ul, ol { list-style: none; margin: 0; padding: 0 }
h1, h2, h3, h4, p, figure, dl, dd, blockquote { margin: 0 }

:where(a, button, [tabindex], summary, input, select, textarea):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: var(--focus-offset);
}
.zoomable:focus-visible, .button:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: var(--focus-offset-container);
}
.localnav a:focus-visible, .localnav button:focus-visible { outline-offset: var(--focus-offset-nav) }

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

.skip-link {
  position: absolute; left: 16px; top: -100%; z-index: 200;
  background: var(--btn); color: var(--btn-ink); padding: 10px 16px;
  border-radius: var(--r-block);
  font: 600 14px/18px var(--font-text); letter-spacing: var(--ls-14);
  text-decoration: none;
}
.skip-link:focus { top: 8px }

/* Never ship an unguarded 0.5px — at DPR 1 it blends to a washed grey. */
.hair   { border-top: 1px solid var(--hairline) }
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .hair { border-top-width: .5px }
}

/* ── TYPE SCALE ───────────────────────────────────────────────────────────
   Fixed px. Two breakpoints. Two weights. Every line-height a whole pixel. */
.t-hero    { font: 600 80px/84px var(--font-display); letter-spacing: var(--ls-80);
             text-wrap: balance }
.t-section { font: 600 48px/52px var(--font-display); letter-spacing: var(--ls-48);
             text-wrap: balance; max-width: 20ch }
.t-stat    { font: 600 56px/60px var(--font-display); letter-spacing: var(--ls-56);
             font-variant-numeric: tabular-nums }
.t-sub     { font: 600 28px/32px var(--font-display); letter-spacing: var(--ls-28) }
.t-eyebrow { font: 600 21px/25px var(--font-display); letter-spacing: var(--ls-21);
             color: var(--ink-2) }
.t-intro   { font: 400 21px/29px var(--font-display); letter-spacing: var(--ls-21);
             max-width: var(--measure) }
.t-body    { font: 400 17px/25px var(--font-text); letter-spacing: var(--ls-17);
             max-width: var(--measure) }
.t-callout { font: 600 17px/21px var(--font-text); letter-spacing: var(--ls-17) }
.t-meta    { font: 400 14px/20px var(--font-text); letter-spacing: var(--ls-14); color: var(--ink-2) }
.t-meta-b  { font: 600 14px/18px var(--font-text); letter-spacing: var(--ls-14) }
.t-caption { font: 400 12px/16px var(--font-text); letter-spacing: var(--ls-12); color: var(--ink-2) }
/* The 01–07 index numerals. Nothing else on the page is mono. */
.t-mono    { font: 400 12px/16px var(--font-mono); letter-spacing: 0;
             font-variant-numeric: tabular-nums }

@media (max-width: 1068px) {
  .t-hero    { font-size: 64px; line-height: 68px; letter-spacing: var(--ls-64) }
  .t-section { font-size: 40px; line-height: 44px; letter-spacing: var(--ls-40) }
  .t-stat    { font-size: 48px; line-height: 52px; letter-spacing: var(--ls-48) }
  .t-sub     { font-size: 24px; line-height: 28px; letter-spacing: var(--ls-24) }
}
@media (max-width: 734px) {
  .t-hero    { font-size: 48px; line-height: 52px; letter-spacing: var(--ls-48) }
  .t-section { font-size: 32px; line-height: 36px; letter-spacing: var(--ls-32) }
  .t-stat    { font-size: 40px; line-height: 44px; letter-spacing: var(--ls-40) }
  .t-sub     { font-size: 21px; line-height: 25px; letter-spacing: var(--ls-21) }
  .t-eyebrow { font-size: 19px; line-height: 23px; letter-spacing: var(--ls-19) }
  .t-intro   { font-size: 19px; line-height: 27px; letter-spacing: var(--ls-19) }
}
/* .t-body, .t-callout, .t-meta, .t-caption, .t-mono never change size. */

.prose p + p { margin-top: .7em }

/* ── LAYOUT ───────────────────────────────────────────────────────────────── */
.rail { width: 87.5%; max-width: var(--rail-max); margin-inline: auto }
@media (max-width: 734px) { .rail { max-width: none } }

.rail-chrome {
  width: 100%; max-width: var(--rail-chrome); margin-inline: auto;
  padding-inline: max(22px, env(safe-area-inset-left)) max(22px, env(safe-area-inset-right));
}

section { padding-block: var(--section-pad); scroll-margin-top: var(--scroll-offset) }
.bg-alt      { background: var(--band) }
.no-pad-top  { padding-top: 0 }
.no-pad-bot  { padding-bottom: 0 }

.grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--grid-gap) }
.grid > * { min-width: 0 }   /* grid children default to min-content — mandatory */

/* Chapter header: headline left, trailing meta/CTA right. */
.chead {
  display: flex; justify-content: space-between; align-items: flex-end;
  column-gap: 120px; row-gap: 20px; padding-bottom: var(--head-gap);
}
.chead__main { max-width: 75% }
.chead__side { flex: none }
.chead .t-eyebrow + .t-section { margin-top: 8px }
/* Stacks from tablet down: side by side, a long side line (the Wefit role)
   never shrinks, and at ~800px it left the headline a 260px column. */
@media (max-width: 1068px) {
  .chead { flex-direction: column; align-items: flex-start; gap: 16px }
  .chead__main { max-width: 100% }
}
@media (max-width: 734px) {
  .chead .t-eyebrow + .t-section { margin-top: 6px }
}

.center { text-align: center }
.center .t-section, .center .t-intro { margin-inline: auto }

/* ═══ NAV ═══════════════════════════════════════════════════════════════════ */
.localnav {
  position: sticky; top: 0; z-index: 100;
  height: var(--nav-h);
  isolation: isolate;
  background: var(--nav-bg-opaque);           /* the fallback IS the opaque one */
  transition: background var(--t-ui) var(--ease-nav);
}
/* Only drop to .80 when the blur actually exists. */
@supports (backdrop-filter: initial) or (-webkit-backdrop-filter: initial) {
  .localnav {
    background: var(--nav-bg);
    -webkit-backdrop-filter: var(--nav-filter);
            backdrop-filter: var(--nav-filter);
  }
}
/* A border-bottom escapes the filtered layer and reads as a hard grey line. */
.localnav::after {
  content: ""; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  width: min(87.5%, var(--rail-max)); height: 1px; background: var(--keyline);
}
@media (max-width: 1068px) {
  .localnav::after { left: 0; transform: none; width: 100% }
}

.localnav__inner { display: flex; align-items: center; height: 100%; gap: 24px }
.localnav__mark {
  font: 600 17px/22px var(--font-text); letter-spacing: var(--ls-17);
  color: var(--ink); text-decoration: none; flex: none;
}
.localnav__links { display: flex; align-items: center; gap: 32px; margin-inline: auto }
.localnav__links a {
  position: relative;
  font: 400 14px/1 var(--font-text); letter-spacing: var(--ls-14);
  color: var(--nav-ink); text-decoration: none;
  display: flex; align-items: center; height: var(--nav-h);   /* hit box = the whole bar */
  transition: color 20ms var(--ease);
}
.localnav__links a:hover { color: var(--nav-ink-hover) }
/* Active = colour only. A weight flip would reflow the row every scroll frame. */
.localnav__links a { color: rgba(0, 0, 0, calc(.8 + .2 * var(--on, 0))) }
.localnav__links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--accent); border-radius: 1px;
  opacity: var(--on, 0); transition: opacity var(--t-hover) linear;
}
.localnav__actions { display: flex; align-items: center; gap: 16px; flex: none }

.localnav__bar {
  position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  /* no transition — it must track scroll exactly */
}

.burger {
  display: none; width: 44px; height: 44px; position: relative; flex: none;
  margin-inline-end: -10px;
}
.burger span {
  position: absolute; left: 13px; width: 18px; height: 1px; background: var(--ink);
  transition: transform var(--t-panel) var(--ease), opacity var(--t-hover) linear;
}
.burger span:nth-child(1) { top: 20px }
.burger span:nth-child(2) { top: 25px }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(2.5px) rotate(45deg) }
.burger[aria-expanded="true"] span:nth-child(2) { transform: translateY(-2.5px) rotate(-45deg) }

/* Mobile sheet — two-phase disclosure, exactly as iOS reveals a menu. */
.mobile-nav {
  position: fixed; top: var(--nav-h); left: 0; right: 0; z-index: 99;
  background: var(--page); border-bottom: 1px solid var(--hairline);
  max-height: 0; overflow: hidden;
  transition: max-height var(--t-panel) var(--ease);
}
.mobile-nav[hidden] { display: none }
.mobile-nav.is-open { max-height: 380px }
.mobile-nav__inner { opacity: 0; transition: opacity var(--t-panel) var(--ease) }
.mobile-nav.is-open .mobile-nav__inner { opacity: 1; transition-delay: var(--t-ui) }
.mobile-nav a {
  display: flex; align-items: center; min-height: 44px;
  padding: 10px 0; margin-inline: 22px;
  font: 400 17px/25px var(--font-text); letter-spacing: var(--ls-17);
  color: var(--ink); text-decoration: none;
}
.mobile-nav a + a { border-top: 1px solid var(--hairline-ios) }

@media (max-width: 833px) {
  .localnav__links { display: none }
  .localnav__mark { margin-inline-end: auto }
  .burger { display: block }
}

/* ═══ BUTTONS ═══════════════════════════════════════════════════════════════
   content-box with the border subtracted from the padding is why a filled and
   a bordered button are pixel-identical: 20 + 11 + 11 + 1 + 1 = 44px exactly. */
.button {
  --pv: 9px; --ph: 16px; --bw: 1px; --mw: 60px;
  display: inline-block; box-sizing: content-box;
  padding-block: calc(var(--pv) - var(--bw));
  padding-inline: calc(var(--ph) - var(--bw));
  min-width: calc(var(--mw) - var(--ph) * 2);
  border: var(--bw) solid transparent; border-radius: var(--r-pill);
  font: 400 14px/1.2857742857 var(--font-text); letter-spacing: var(--ls-14);
  text-align: center; white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: background-color var(--t-hover) linear,
              color var(--t-hover) linear,
              border-color var(--t-hover) linear;
}
.button--reduced  { --pv: 4px;  --ph: 11px; --mw: 45px;
                    font-size: 12px; line-height: 1.3333733333; letter-spacing: var(--ls-12) }
.button--elevated { --pv: 12px; --ph: 22px; --mw: 70px;
                    font-size: 17px; line-height: 1.1764805882; letter-spacing: var(--ls-17) }

.button--neutral         { background: var(--btn); color: var(--btn-ink) }
.button--neutral:hover   { background: var(--btn-hover); color: var(--btn-ink) }
.button--neutral:active  { background: var(--btn-active) }

.button--secondary { background: transparent; color: var(--ink); border-color: currentColor }
/* border-color:transparent is load-bearing — the ring must dissolve as the
   fill arrives or the hover reads doubled. */
.button--secondary:hover  { background: var(--btn-hover); color: var(--btn-ink); border-color: transparent }
.button--secondary:active { background: var(--btn-active); color: var(--btn-ink); border-color: transparent }

/* A full-width button drops the pill. A 980px radius on a block is a lozenge. */
.button--block { box-sizing: border-box; display: block; width: 100%; border-radius: var(--r-block) }

/* Buttons NEVER move. No transform, no shadow, no opacity dim.
   A lifting button is the loudest non-Apple tell there is. */

/* ═══ CHEVRON LINK ══════════════════════════════════════════════════════════ */
.more {
  text-decoration: none; color: var(--link);
  font: 400 17px/1.1764805882 var(--font-text); letter-spacing: var(--ls-17);
}
.more:hover { text-decoration: underline }
.more-end { white-space: nowrap }             /* the chevron can never orphan */
/* The chevron sits in the cap band, like a capital: .66em tall, its foot a
   hair above the baseline. Taller, it hung below the text in Safari. */
.more-chev {
  display: inline-block; padding-inline-start: .24em;
  position: relative; top: -.03em; text-decoration: none;
}
.more-chev svg { display: block; width: .354em; height: .66em }

/* ═══ SEGMENTED CONTROL ═════════════════════════════════════════════════════ */
.seg {
  --seg-h: 44px; --seg-pad: 4px;
  position: relative; display: inline-flex; align-items: center;
  height: var(--seg-h); padding: var(--seg-pad);
  border-radius: var(--r-pill); background: var(--seg-track);
  overflow: hidden; max-width: 100%;
  /* No backdrop-filter: the track is painted opaque. It would blur nothing and
     buy a compositing layer plus a backdrop root. */
}
.seg__thumb {
  position: absolute; top: var(--seg-pad); bottom: var(--seg-pad);
  left: var(--x, 0px); width: calc(var(--w, 0px) - 1px);
  background: var(--seg-thumb); border-radius: var(--r-pill);
  pointer-events: none;
  transition-property: left, width;
  transition-duration: 320ms;
  transition-timing-function: ease-out;   /* Apple ships the literal keyword here */
}
.seg [role="tab"] {
  position: relative; z-index: 1; height: 100%; padding: 0 16px;
  border-radius: var(--r-pill); white-space: nowrap; background: transparent;
  font: 400 14px/1.2857742857 var(--font-text); letter-spacing: var(--ls-14);
  color: var(--seg-ink); opacity: .8;
  transition: color .12s ease-out, opacity .1s ease-in-out;
}
.seg [role="tab"]:hover { opacity: 1 }
/* THE detail: the arriving label turns 160ms late, so the text flips exactly
   as the pill lands under it — never before. Four lines, no JS timing. */
.seg [role="tab"][aria-selected="true"] {
  color: var(--seg-ink-active); opacity: 1; cursor: auto;
  transition: color .16s ease-in .16s;
}
html.no-js .seg__thumb { display: none }
html.no-js .seg [role="tab"][aria-selected="true"] {
  background: var(--seg-thumb); color: var(--seg-ink-active);
}
@media (max-width: 734px) {
  /* Four segments will not fit at 320px and wrapping breaks the pill maths. */
  .seg { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none }
  .seg::-webkit-scrollbar { width: 0; height: 0 }
}

/* Language mini-segment in the nav */
.seg--lang { --seg-h: 36px; --seg-pad: 3px }
.seg--lang [role="tab"], .seg--lang .lang__btn {
  padding: 0 14px; font-size: 14px; letter-spacing: var(--ls-14);
}
.seg--lang .lang__btn {
  position: relative; z-index: 1; height: 100%; border-radius: var(--r-pill);
  background: transparent; color: var(--seg-ink); opacity: .8;
  font-family: var(--font-text); font-weight: 400; line-height: 1;
  transition: color .12s ease-out, opacity .1s ease-in-out;
}
.seg--lang .lang__btn:hover { opacity: 1 }
.seg--lang .lang__btn[aria-pressed="true"] {
  background: var(--seg-thumb); color: var(--seg-ink-active); opacity: 1;
  transition: background .2s ease-out, color .16s ease-in .08s;
}

/* ═══ CHIPS ═════════════════════════════════════════════════════════════════
   Every chip identical. A per-technology rainbow is the exact opposite of the
   discipline. Chips are content, not controls — no hover, not focusable. */
.chip {
  display: inline-flex; align-items: center; min-height: 32px; padding: 7px 14px;
  border-radius: var(--r-pill); background: var(--fill-3); color: var(--ink);
  font: 600 14px/18px var(--font-text); letter-spacing: var(--ls-14);
}
.chips { display: flex; flex-wrap: wrap; gap: 8px }
.chips--center { justify-content: center; max-width: 820px; margin-inline: auto }

/* ═══ BADGE — exactly one on the page ═══════════════════════════════════════ */
.badge {
  display: inline-block; padding: 4px 6px; border-radius: var(--r-badge);
  border: 1px solid var(--control-edge); color: var(--ink-2);
  font: 400 12px/16px var(--font-text); letter-spacing: var(--ls-12);
}

/* ═══ HERO ══════════════════════════════════════════════════════════════════ */
.hero { padding-top: 96px; padding-bottom: 80px }
@media (max-width: 1068px) { .hero { padding-top: 72px } }
@media (max-width:  734px) { .hero { padding-top: 56px; padding-bottom: 56px } }

.hero__grid { align-items: center }
.hero__copy  { grid-column: 1 / span 6 }
.hero__stage { grid-column: 7 / span 6; justify-self: end; width: 100%; max-width: 540px }

.hero__h1 { display: block }
.hero__h1 .t-eyebrow { display: block }
.hero__h1 .t-hero { display: block; margin-top: 8px; color: var(--ink) }
@media (max-width: 734px) { .hero__h1 .t-hero { margin-top: 6px } }

.hero__intro { margin-top: 32px; max-width: 52ch }
.hero__actions { margin-top: 32px; display: flex; flex-wrap: wrap; align-items: center; gap: 20px }
.hero__proof  { margin-top: 24px }
.hero__skills { margin-top: 8px }

@media (max-width: 1068px) {
  .hero__copy, .hero__stage { grid-column: 1 / -1 }
  .hero__stage { max-width: 520px; margin-inline: auto; margin-top: 56px; width: 100% }
  .hero__intro { margin-top: 28px }
}
@media (max-width: 734px) {
  .hero__intro, .hero__actions { margin-top: 24px }
  .hero__stage { max-width: 100%; margin-top: 40px }
}

/* ── The portrait plate — the pop-out kept from the previous layout,
      re-pigmented. Opaque plate, one static colour field, no translucency,
      no shadow, no halo, no tilt. ─────────────────────────────────────────── */
.plate {
  position: relative;
  border-radius: var(--r-card);
  background: var(--plate);
  border: 1px solid var(--card-stroke);
  aspect-ratio: 6 / 7;
  --pw: 112%;              /* portrait width vs plate — sets how far the head rises */
}
.about__frame.plate { background: var(--surface) }   /* shape and --pw: ios.css */

.frame-clip {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden; z-index: 0;
}
/* Top-open window: clipped at the sides and bottom so the portrait stays
   inside the rounded corners, open at the top so the head rises above. */
.frame-pop {
  position: absolute; inset: -36% 0 0; z-index: 1;
  overflow: hidden; border-radius: 0 0 var(--r-card) var(--r-card);
}
.plate__portrait {
  position: absolute; bottom: 0; left: 50%;
  width: var(--pw); max-width: none; height: auto;
  transform: translateX(-50%);
  transition: opacity var(--t-slide) var(--ease);
}
/* popGate's fade — this selector must survive. */
.frame-pop img.is-loading { opacity: 0 }

/* ═══ STATS — the cards and the gradient ink live in ios.css ═══════════════ */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; padding-top: 40px }
.stat .t-stat { color: var(--ink) }
.stat .t-meta { margin-top: 8px; max-width: 34ch }
@media (max-width: 734px) {
  .stats { grid-template-columns: 1fr; gap: 0 }
  .stat + .stat { border-top: 1px solid var(--hairline); margin-top: 28px; padding-top: 28px }
}

/* ═══ INSET-GROUPED LIST (iOS) ══════════════════════════════════════════════
   The leading inset matching the text origin is the entire iOS signal.
   Trailing inset is 0 — the rule runs to the container's edge. */
.list {
  overflow: hidden; border-radius: var(--r-card);
  background: var(--surface); border: 1px solid var(--card-stroke);
  box-shadow: var(--shadow-card);
}
.list__row { position: relative; min-height: 60px; padding: 14px 20px }
.list__row + .list__row::before {
  content: ""; position: absolute; top: 0; right: 0; left: 20px;
  height: 1px; background: rgba(0, 0, 0, .10);
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .list__row + .list__row::before { height: .5px; background: var(--hairline-ios) }
}
.list__row .t-meta { margin-top: 4px }

/* ═══ SPEC TABLE — case-study facts AND the About pillars. One component. ════
   No card, no shadow, no radius, no icon. The hairline is the container. */
.specs { display: grid; gap: 0 }
.specs--4 { grid-template-columns: repeat(4, 1fr); gap: var(--grid-gap) }
@media (max-width: 1068px) { .specs--4 { grid-template-columns: repeat(2, 1fr) } }
@media (max-width:  734px) { .specs--4 { grid-template-columns: 1fr } }
.spec { border-top: 1px solid var(--hairline); padding-top: 20px }
.spec__k { font: 600 14px/18px var(--font-text); letter-spacing: var(--ls-14); color: var(--ink-2) }
.spec__v { font: 400 17px/25px var(--font-text); letter-spacing: var(--ls-17);
           color: var(--ink); margin-top: 6px }
.specs--rows .spec { display: grid; grid-template-columns: 120px 1fr; gap: var(--grid-gap);
                     padding-block: 20px }
.specs--rows .spec__v { margin-top: 0 }
@media (max-width: 734px) {
  .specs--rows .spec { grid-template-columns: 1fr }
  .specs--rows .spec__v { margin-top: 6px }
}

/* ═══ DEVICE FRAMES ═════════════════════════════════════════════════════════
   THE LAW:  screen_radius = device_radius − bezel
   One knob per frame: --dw. Everything else is calc()'d from it. The variable
   is --dw on EVERY frame: a calc(var(--w) …) on an element that never defines
   --w is invalid at computed-value time and silently drops the whole
   declaration — which is how a device loses its entire box-shadow.
   NO island, NO status bar, NO home indicator, NO lens dot: they are already
   painted into the screenshots.                                             */
.device {
  position: relative; box-sizing: border-box;
  box-shadow: var(--device-inset), var(--device-shadow);
  corner-shape: squircle;        /* progressive enhancement; unknown prop drops */
}
.device__screen { position: relative; height: 100%; overflow: hidden; background: #000 }
.device__screen img,
.device__screen [data-slide] { display: block; width: 100%; height: 100%; object-fit: cover }
.device::before {
  content: ""; position: absolute; z-index: -1; left: 8%; right: 8%;
  bottom: calc(var(--dw) * -.04); height: calc(var(--dw) * .10);
  border-radius: 50%; background: var(--device-glow);
  filter: blur(calc(var(--dw) * .03));
}

/* iPad Pro 13" — body 281.6 × 215.5 mm, screen 264.78 × 198.58 ⇒ bezel 8.44 mm.
   Radius derived from the SCREEN outward; deriving inward from a guessed body
   radius yields a visually square corner, which is what makes fake iPads read
   as fake. Ceiling --dw ≤ 691px at DPR 2 for a 1300px source. */
.dev-ipad {
  --dw: min(640px, 100cqi);
  --bezel: calc(var(--dw) * .030);
  --r-scr: calc(var(--dw) * .0207);
  --r-dev: calc(var(--r-scr) + var(--bezel));
  width: var(--dw); aspect-ratio: 281.6 / 215.5;
  padding: var(--bezel); border-radius: var(--r-dev);
  background: linear-gradient(160deg, #3a3a3e 0%, #1a1a1c 22%, #101012 55%,
                                      #242427 82%, #4a4a4e 100%);
  margin-inline: auto;
}
/* Sized by width: the body's 281.6:215.5 makes 4:3 of the inner width equal
   the inner height. height:100% resolved against the padded box in Safari
   and pushed the screen out through the right bezel. */
.dev-ipad .device__screen { width: 100%; height: auto; border-radius: max(var(--r-scr), 2px); aspect-ratio: 4 / 3 }
@media (max-width: 1068px) { .dev-ipad { --dw: min(560px, 100cqi) } }

/* Straight-on only. No rotateY, no perspective, no tilt, no glare streak,
   no reflection sweep, no brand-tinted body. */

.zoomable { display: block; border-radius: var(--r-tile) }

/* ═══ FEATURED CASE ═════════════════════════════════════════════════════════ */
.feature__body { margin-top: 64px }
.feature__main { grid-column: 1 / span 7 }
.feature__side { grid-column: 8 / span 5 }
@media (max-width: 1068px) { .feature__main, .feature__side { grid-column: 1 / -1 } }
.feature__side { margin-top: 0 }
@media (max-width: 1068px) { .feature__side { margin-top: 40px } }

.credential { margin: 32px 0 0; max-width: 260px }
.credential img { width: 100%; height: auto; border-radius: var(--r-tile); border: 1px solid var(--hairline) }
.credential figcaption { margin-top: 10px }

/* ═══ SLIDESHOW CHROME — below the device, never on the glass ═══════════════ */
.slides__controls {
  margin-top: 24px; display: flex; align-items: center; justify-content: center; gap: 16px;
}
.paddle {
  --d: 56px; width: var(--d); height: var(--d); border-radius: var(--d);
  display: grid; place-items: center; flex: none;
  background: var(--paddle-bg); color: var(--paddle-ink);
  transition: background var(--t-hover) linear, color var(--t-hover) linear;
}
.paddle:hover  { background: var(--paddle-bg-hover); color: var(--paddle-ink-hover) }
.paddle:active { background: var(--paddle-bg-active) }
.paddle[disabled] { opacity: .32; pointer-events: none }
.paddle svg { width: 36px; height: 36px; fill: currentColor }
.paddle--sm { --d: 44px } .paddle--sm svg { width: 22px; height: 22px }
@media (max-width: 734px) { .paddle { --d: 44px } .paddle svg { width: 26px; height: 26px } }

.dots { display: flex; gap: 8px }
.dots button {
  position: relative; width: 8px; height: 8px; border-radius: 50%;
  background: var(--hairline); transition: background var(--t-hover) linear;
}
.dots button[aria-current="true"] { background: var(--accent) }
.dots button::before {   /* 44px hit area on an 8px dot */
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}

/* ═══ STACK — panels that cross-fade in one grid cell ═══════════════════════
   minmax(0,1fr) + min-width:0: a grid item defaults to its min-content width,
   which would let one wide child stretch the page at a 390px viewport. */
.stack { display: grid; grid-template-columns: minmax(0, 1fr) }
.stack > * { grid-area: 1 / 1; min-width: 0 }

/* ═══ ABOUT ═════════════════════════════════════════════════════════════════ */
#about { overflow-x: clip }   /* the full-bleed plate is 100vw; a desktop scrollbar must not widen the page */
.about__stage { grid-column: 1 / span 5 }
.about__copy  { grid-column: 7 / span 6 }
@media (max-width: 1068px) {
  .about__stage, .about__copy { grid-column: 1 / -1 }
  /* Edge to edge: the colour plate leaves the rail and spans the screen. */
  .about__stage { width: auto; margin-inline: calc(50% - 50vw) }
  /* No grey band above the edge-to-edge plate: page white runs straight into
     the colour. The white layer reaches the middle of the plate (it is opaque,
     so that edge never shows) and the grey carries on below it. */
  #about { background: linear-gradient(var(--page), var(--page)) top / 100% calc(var(--section-pad) + 37.5vw) no-repeat, var(--band) }
  .about__copy  { margin-top: 56px }
}
@media (max-width: 734px) { #about { background-size: 100% calc(var(--section-pad) + 50vw), auto } }
.about__copy .t-section { margin-top: 8px }
.about__copy .prose { margin-top: 24px }
.pillars { margin-top: 64px }

/* ═══ EXPERTISE ═════════════════════════════════════════════════════════════ */
.expertise { margin-top: 40px; text-align: center }
.skills__chips { margin-top: 40px }
.skills__note  { max-width: 60ch; margin: 20px auto 0 }
.stack--flat { min-height: 220px }
.skills[aria-hidden="true"]  { opacity: 0; visibility: hidden;
  transition: opacity var(--t-ui) var(--ease), visibility var(--t-ui) step-end }
.skills[aria-hidden="false"] { opacity: 1; visibility: visible;
  transition: opacity var(--t-ui) var(--ease) 80ms, visibility var(--t-ui) step-start 80ms }

/* ═══ CONTACT ═══════════════════════════════════════════════════════════════ */
.contact__actions {
  margin-top: 32px; display: flex; flex-wrap: wrap; justify-content: center; gap: 14px;
}
.contact__email {
  display: inline-block; margin-top: 24px;
  font: 400 17px/25px var(--font-text); letter-spacing: var(--ls-17);
  color: var(--link); text-decoration: none;
}
.contact__email:hover { text-decoration: underline }
@media (max-width: 734px) {
  .contact__actions { flex-direction: column; gap: 12px }
  .contact__actions .button { width: 100%; box-sizing: border-box; display: block;
                              border-radius: var(--r-block) }
}

/* ═══ SOSUMI FOOTNOTE ═══════════════════════════════════════════════════════ */
.sosumi { padding-block: 32px }
.sosumi p + p { margin-top: 6px }

/* ═══ LIGHTBOX (glass surface 2 of 2) ═══════════════════════════════════════ */
.lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: 1fr auto;
  align-items: center; gap: clamp(8px, 2vw, 24px); padding: clamp(16px, 4vw, 48px);
  background: rgba(0, 0, 0, .88);
  opacity: 0; transition: opacity 200ms ease;
  contain: paint;
}
@supports (backdrop-filter: initial) or (-webkit-backdrop-filter: initial) {
  .lightbox {
    background: rgba(0, 0, 0, .72);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
  }
}
.lightbox[hidden] { display: none }
.lightbox.is-open { opacity: 1 }
.lightbox__img {
  grid-column: 2; grid-row: 1; justify-self: center;
  /* --lb-max is set from the image's own naturalWidth so a 460px screenshot
     never renders at 815 device px and comes out blurrier than the frame it
     came from. */
  max-width: min(92vw, var(--lb-max, 1280px));
  max-height: 82vh; width: auto; height: auto;
  object-fit: contain; border-radius: var(--r-tile);
}
@supports (max-height: 82svh) { .lightbox__img { max-height: 82svh } }
.lightbox__caption {
  grid-column: 1 / -1; grid-row: 2; text-align: center;
  color: #f5f5f7; margin: 0;
}
.lightbox .paddle { background: var(--paddle-media-bg); color: rgba(255, 255, 255, .8) }
.lightbox .paddle:hover { color: #fff }
.lightbox__nav--prev { grid-column: 1; grid-row: 1 }
.lightbox__nav--next { grid-column: 3; grid-row: 1 }
.lightbox__close {
  position: absolute; top: clamp(12px, 3vw, 28px); right: clamp(12px, 3vw, 28px);
  --d: 44px; width: var(--d); height: var(--d); border-radius: var(--d);
  display: grid; place-items: center;
  background: var(--paddle-media-bg); color: rgba(255, 255, 255, .8);
  font-size: 17px; line-height: 1;
  transition: background var(--t-hover) linear, color var(--t-hover) linear;
}
.lightbox__close:hover { color: #fff }
/* Two-ring focus, because the ring sits over unpredictable media. */
.lightbox :focus-visible { outline: none; box-shadow: 0 0 0 3px #000, 0 0 0 5px var(--accent) }
body.is-locked { overflow: hidden }

/* ═══ ASSEMBLY ══════════════════════════════════════════════════════════════ */
button svg { pointer-events: none }
/* Sections take focus from in-page links (tabindex -1): the ring belongs to
   the link that was pressed, never to a whole section. */
section[tabindex="-1"]:focus { outline: none }
.device, .device__screen { display: block }

/* --device-shadow references --dw, so it must be declared ON the device: a
   custom property resolves var() where it is declared, and on :root --dw
   does not exist — which silently kills every device shadow. */
.device {
  --device-shadow:
    0 calc(var(--dw) * .006) calc(var(--dw) * .018) rgba(0, 0, 0, .05),
    0 calc(var(--dw) * .034) calc(var(--dw) * .078) rgba(0, 0, 0, .09),
    0 calc(var(--dw) * .110) calc(var(--dw) * .220) calc(var(--dw) * -.05) rgba(0, 0, 0, .14);
}

.t-eyebrow + .t-section { margin-top: 8px }
@media (max-width: 734px) { .t-eyebrow + .t-section { margin-top: 6px } }
.chead__side { color: var(--ink-2) }
a.chead__side { color: var(--link) }
.chead__deck { margin-top: 24px }
@media (max-width: 734px) { .chead__deck { margin-top: 20px } }

.impact .list { margin-top: 56px; max-width: 760px }

.feature__device { container-type: inline-size }
.feature__platform { margin-top: 14px }
.feature__prose { margin-top: 16px }

.slide { position: absolute; inset: 0; margin: 0; opacity: 0; transition: opacity var(--t-slide) var(--ease) }
.slide:first-child { opacity: 1 }
.slide .zoomable { width: 100%; height: 100%; border-radius: 0 }
.slide img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 0 }
.zoomable--fill:focus-visible { outline-offset: -4px }

.paddle [data-icon] { display: none }
.paddle[data-state="playing"] [data-icon="pause"],
.paddle[data-state="paused"] [data-icon="play"] { display: block }

.contact__rail { padding-top: var(--section-pad) }

html.no-js .stack { display: block }
html.no-js .stack > * { opacity: 1 !important; visibility: visible !important }
html.no-js .stack > * + * { margin-top: 24px }

/* language crossfade — a soft swap, never an instant reflow */
body { transition: opacity 240ms ease }
body.is-lang-fading { opacity: 0 }

@media (max-width: 480px) { .nav-cta { display: none } }

/* ═══ REVEAL ════════════════════════════════════════════════════════════════
   Exactly two properties. opacity 0→1 over 900ms, translateY(30px)→0 over
   700ms. The 200ms asymmetry IS the texture: the element arrives at its final
   position while still faintly transparent, then settles. No scale, no blur,
   no clip-path, no rotation. Never reverses on scroll-up.
   The start state lives here, in CSS — not as an inline style, so the
   reduced-motion and no-JS safety nets can actually beat it.                */
[data-reveal] {
  opacity: 0; transform: translateY(30px);
  transition: opacity var(--t-fade) var(--ease) var(--rd, 0ms),
              transform var(--t-move) var(--ease) var(--rd, 0ms);
}
[data-reveal].is-in { opacity: 1; transform: none }

/* ═══ REDUCED MOTION — gate the JS too, not just the CSS ════════════════════ */
html.reduced-motion [data-reveal],
html.no-js [data-reveal] { opacity: 1; transform: none; transition: none }
html.reduced-motion { scroll-behavior: auto }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1 !important; transform: none !important; transition: none }
  html { scroll-behavior: auto }
  .button, .chip, .paddle, .seg [role="tab"], .seg__thumb,
  .localnav, .mobile-nav, .mobile-nav__inner {
    transition: none;
  }
}

/* ═══ PRINT ═════════════════════════════════════════════════════════════════ */
@media print {
  .localnav, .mobile-nav, .lightbox, .slides__controls, .skip-link { display: none !important }
  [data-reveal] { opacity: 1 !important; transform: none !important }
  .stack { display: block }
  body { background: #fff; color: #000 }
}
