/* ==========================================================================
   IronFit marketing site
   Single dark theme. Arabic-first, RTL authored. Logical properties only:
   there is no `left` or `right` in this file, so both directions share it.
   ========================================================================== */

/* --- Fonts: self-hosted variable subsets, Arabic + Latin only -------------- */

@font-face {
  font-family: 'Changa';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/changa-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
  font-family: 'Changa';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/changa-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Readex Pro';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('/assets/fonts/readex-arabic.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
  font-family: 'Readex Pro';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('/assets/fonts/readex-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
  --ink-900: #050807;
  --ink-800: #0b1210;
  --ink-700: #101c17;
  --ink-600: #16261f;
  --line: #24392d;
  --line-strong: #4a6b58;
  /* Section indices are quiet but they are still readable text, so they clear
     4.5:1 on every surface rather than sitting at the border tone. */
  --numeral: #6e9781;
  --fg: #f3f7f5;
  --fg-muted: #a6b5ac;
  --emerald: #00e88a;
  --danger: #e8523f;

  --display: 'Changa', 'Segoe UI', system-ui, sans-serif;
  --body: 'Readex Pro', 'Segoe UI', system-ui, sans-serif;
  /* Brand/nav chrome only: the wordmark and English nav labels are always
     Latin, so a technical monospace face reads fine there without ever
     touching Arabic body copy. */
  --mono: ui-monospace, 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;

  --shell: 1280px;
  --gutter: clamp(20px, 4vw, 40px);

  --s1: 4px;  --s2: 8px;   --s3: 12px;  --s4: 16px;  --s5: 24px;
  --s6: 32px; --s7: 48px;  --s8: 64px;  --s9: 96px;  --s10: 128px;

  --band-y: clamp(56px, 8vw, 112px);
  --r-control: 4px;
  --r-media: 12px;
  --r-panel: 20px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 140ms;
  --t-mid: 260ms;
  --t-slow: 480ms;

  color-scheme: dark;
}

@supports (color: oklch(50% 0.1 180)) {
  :root {
    --ink-900: oklch(12.9% 0.007 175);
    --ink-800: oklch(17.4% 0.012 175);
    --ink-700: oklch(21.3% 0.020 167);
    --ink-600: oklch(25.5% 0.024 165);
    --line: oklch(32.3% 0.034 159);
    --line-strong: oklch(46% 0.040 159);
    --numeral: oklch(64% 0.056 161);
    --fg: oklch(97.3% 0.005 165);
    --fg-muted: oklch(75.9% 0.021 160);
    --emerald: oklch(81.8% 0.199 156);
    --danger: oklch(65% 0.190 25);
  }
}

/* --- Reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-block-start: 96px;

  /* 100vw includes the scrollbar; the root element's own width does not. The
     difference is the scrollbar, which lets --vw describe the space actually
     available and keeps a full-bleed block from overhanging by a few pixels. */
  --sbw: calc(100vw - 100%);
  --vw: calc(100vw - var(--sbw));
  /* Distance from the shell edge to the viewport edge, so a block can break the
     grid and run to the edge without a hardcoded breakpoint. */
  --bleed: calc((var(--vw) - min(var(--vw) - (var(--gutter) * 2), var(--shell))) / 2);
}

body {
  background: var(--ink-900);
  color: var(--fg);
  font-family: var(--body);
  font-size: 17px;
  font-weight: 300;
  line-height: 1.75;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;              /* Arabic cursive joins break under tracking */
  -webkit-font-smoothing: antialiased;
  min-height: 100svh;
  overflow-x: hidden;
}

@media (min-width: 900px) { body { font-size: 18px; } }

html[lang='en'] body { line-height: 1.65; }

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; }

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--emerald);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--emerald); color: var(--ink-900); }

/* --- Typography ----------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}
html[lang='en'] h1, html[lang='en'] h2, html[lang='en'] h3 { letter-spacing: -0.01em; }

.t-hero {
  font-size: clamp(2.5rem, 1.4rem + 4.6vw, 4.75rem);
  font-weight: 800;
  line-height: 1.08;
}
.t-band { font-size: clamp(1.85rem, 1.2rem + 2.4vw, 3rem); }
.t-sub  { font-size: clamp(1.3rem, 1.05rem + 0.9vw, 1.75rem); }
.t-item { font-size: clamp(1.1rem, 1rem + 0.4vw, 1.3rem); font-weight: 600; }

.lede {
  color: var(--fg-muted);
  font-size: clamp(1.02rem, 0.97rem + 0.3vw, 1.2rem);
  max-inline-size: 62ch;
  text-wrap: pretty;
}
.prose-measure { max-inline-size: 68ch; }
.muted { color: var(--fg-muted); }

/* --- Layout primitives ---------------------------------------------------- */

.shell {
  inline-size: min(100% - (var(--gutter) * 2), var(--shell));
  margin-inline: auto;
}

.band {
  border-block-start: 1px solid var(--line);
  padding-block: var(--band-y);
  position: relative;
  transition: border-color var(--t-slow) var(--ease);
}
.band--flush { border-block-start: 0; }
.band--alt { background: var(--ink-800); }

/* The programming-sheet device: a two-digit index directly above the heading,
   and a rule that goes emerald while the section is the one being read.
   Deliberately not a margin column: a `split` section keeps its heading inside
   the copy column beside the media rather than full-width above it, so an
   index sitting beside a title that isn't there floated alone with nothing to
   align to. Stacking on top is the one placement every section can give it,
   whether the heading follows immediately (most bands) or the index is
   rendered on its own right before a heading that lives one column over
   (`split`). */
.band-head {
  display: grid;
  gap: var(--s3) var(--s6);
  margin-block-end: var(--s7);
}

.band-index {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--numeral);
  padding-block-start: 0.55rem;
  transition: color var(--t-mid) var(--ease);
}
.band[data-active='true'] .band-index { color: var(--emerald); }
.band[data-active='true'] { border-block-start-color: var(--emerald); }

.stack > * + * { margin-block-start: var(--s5); }
.stack-tight > * + * { margin-block-start: var(--s3); }

.grid { display: grid; gap: var(--s6); }
@media (min-width: 760px) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* --- Skip link ------------------------------------------------------------ */

.skip {
  position: fixed;
  inset-block-start: var(--s3);
  inset-inline-start: var(--s3);
  z-index: 200;
  background: var(--emerald);
  color: var(--ink-900);
  font-weight: 600;
  padding: var(--s3) var(--s5);
  border-radius: var(--r-control);
  transform: translateY(-200%);
  transition: transform var(--t-fast) var(--ease);
}
.skip:focus { transform: none; }

/* --- Header --------------------------------------------------------------- */

.header {
  position: sticky;
  inset-block-start: 0;
  z-index: 100;
  background: var(--ink-900);
  border-block-end: 1px solid var(--line);
}

/* Where the browser can blur behind it, the bar sits on the page rather than
   on top of it, and the hero's photography carries on underneath. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .header {
    background: rgba(5, 8, 7, 0.7);
    -webkit-backdrop-filter: blur(18px) saturate(1.4);
            backdrop-filter: blur(18px) saturate(1.4);
  }
}

.header-row {
  display: flex;
  align-items: center;
  gap: var(--s5);
  min-block-size: 72px;
}

.brand {
  font-family: var(--mono);
  font-weight: 800;
  font-size: 1.2rem;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  gap: 0.55rem;
  white-space: nowrap;
}
.brand-mark { inline-size: 24px; block-size: 24px; border-radius: 6px; flex: none; }
.brand-accent { color: var(--emerald); }
/* The wordmark is always Latin regardless of locale, so the technical
   uppercase/tracked treatment applies on both pages alike. Tracking stays
   off the Arabic nav/body copy: cursive joins break under it. */
.brand-word { text-transform: uppercase; letter-spacing: 0.08em; }

.header-nav { display: none; }
.header-accent { display: none; }
.header-tail { display: flex; align-items: center; gap: var(--s3); margin-inline-start: auto; }
.header-tail > .btn, .header-tail > .store-icon { display: none; }

@media (min-width: 1024px) {
  /* Three tracks, so the navigation is centred on the header and not on the
     space left over beside the brand. The outer tracks share what remains. */
  .header-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: var(--s4);
  }
  .header-nav { display: flex; align-items: center; gap: var(--s3); justify-content: center; }
  .header-accent {
    display: inline-flex;
    color: var(--emerald);
    margin-inline-start: var(--s3);
    opacity: 0.85;
  }
  .header-accent svg { inline-size: 14px; block-size: 14px; }
  .header-tail { margin-inline-start: 0; justify-self: end; }
  .header-tail > .btn, .header-tail > .store-icon { display: inline-flex; }
  .header-tail > .nav-toggle { display: none; }
}

.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  padding-inline: var(--s3);
  color: var(--fg-muted);
  text-decoration: none;
  font-size: 0.97rem;
  transition: color var(--t-fast) var(--ease);
}
.nav-link:hover { color: var(--fg); }
.nav-link[aria-current='page'] { color: var(--fg); font-weight: 500; }

/* Slash-divided, monospace, uppercase nav is a Latin device — see the
   wordmark comment above. Arabic keeps the body face and natural casing but
   the same dividers and dark chrome. */
html[lang='en'] .header-nav {
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
html[lang='en'] .nav-link { font-size: 0.85rem; font-weight: 600; }

/* A sibling, not part of the link: living inside `.nav-link` widened the
   anchor with the slash's own box, so the active-page rule below (which
   insets from the anchor's edges) rode off-centre under the label whenever
   a slash preceded it. As a sibling it adds width to the row, not to the
   link, so `.nav-link::after` stays centred on the label alone. */
.nav-sep { display: inline-flex; align-items: center; color: var(--line-strong); }

/* The current page is marked with a rule under the label rather than a dot
   after it: the rule scales with the word and never pushes the row around. */
.nav-link::after {
  content: '';
  position: absolute;
  inset-block-end: 12px;
  inset-inline: var(--s3);
  block-size: 2px;
  border-radius: 1px;
  background: var(--emerald);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--t-mid) var(--ease);
}
.nav-link:hover::after { transform: scaleX(0.5); }
.nav-link[aria-current='page']::after { transform: scaleX(1); }

.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-block-size: 44px;
  min-inline-size: 44px;
  padding-inline: var(--s4);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--fg-muted);
  text-decoration: none;
  font-size: 0.9rem;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.lang-switch svg { inline-size: 17px; block-size: 17px; flex: none; }
.lang-switch:hover { border-color: var(--emerald); color: var(--emerald); }
/* The switch always names the *other* language in its own script, so a
   Latin target ("English") gets the same technical treatment as the nav;
   an Arabic target keeps its natural casing. */
.lang-switch span[lang='en'] { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.05em; }

/* Icon-only store chip: the header CTA slot, sized to match .lang-switch / .nav-toggle. */
.store-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 44px;
  block-size: 44px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--fg-muted);
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.store-icon svg { inline-size: 19px; block-size: 19px; flex: none; }
.store-icon:hover { border-color: var(--emerald); color: var(--emerald); }

.header-tail > .btn { border-radius: 999px; min-block-size: 44px; font-size: 0.95rem; }

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 44px;
  block-size: 44px;
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.nav-toggle:hover { border-color: var(--emerald); color: var(--emerald); }
.nav-toggle svg { inline-size: 20px; block-size: 20px; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded='true'] .icon-open { display: none; }
.nav-toggle[aria-expanded='true'] .icon-close { display: block; }

.mobile-nav {
  border-block-start: 1px solid var(--line);
  padding-block: var(--s4) var(--s6);
  display: grid;
  gap: var(--s1);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav a {
  display: flex;
  align-items: center;
  min-block-size: 52px;
  padding-inline: var(--s4);
  border-radius: 10px;
  text-decoration: none;
  color: var(--fg-muted);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.mobile-nav a:hover { color: var(--fg); background: var(--ink-700); }
.mobile-nav a[aria-current='page'] { color: var(--emerald); background: var(--ink-700); }
.mobile-nav .btn { margin-block-start: var(--s4); border-radius: 999px; }
.mobile-nav .stores { margin-block-start: var(--s4); }
@media (min-width: 1024px) { .mobile-nav { display: none !important; } }

/* --- Buttons and links ---------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-block-size: 48px;
  padding-inline: var(--s5);
  border-radius: var(--r-control);
  font-family: var(--display);
  font-weight: 700;
  font-size: 1rem;
  text-decoration: none;
  text-align: center;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.btn:active { transform: scale(0.98); }

.btn--primary { background: var(--emerald); color: var(--ink-900); }
.btn--primary:hover { background: color-mix(in oklab, var(--emerald) 86%, var(--fg)); }

.btn--ghost { border: 1px solid var(--line-strong); color: var(--fg); }
.btn--ghost:hover { border-color: var(--emerald); color: var(--emerald); }

.btn--block { inline-size: 100%; }
.btn[aria-disabled='true'] { opacity: 0.55; cursor: not-allowed; }
.btn[aria-disabled='true']:active { transform: none; }

/* Explicit stacking context, ranked above later reveal siblings (highlights,
   dash-stats): those also sit in a `.hero-stagger`/`.reveal-stagger` group,
   whose animation leaves them with a resolved (if identity) transform once
   it finishes rather than the literal keyword `none` — which still counts as
   a stacking context, and being later in the DOM it would otherwise paint
   over an open "Get the app" dropdown here regardless of the dropdown's own
   z-index, since that only ranks within .btn-row's own context. */
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s3); position: relative; z-index: 1; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-block-size: 44px;
  color: var(--emerald);
  font-weight: 500;
  text-decoration: none;
  border-block-end: 1px solid transparent;
}
.link-arrow:hover { border-block-end-color: var(--emerald); }
.link-arrow svg {
  inline-size: 15px; block-size: 15px; flex: none;
  transition: transform var(--t-fast) var(--ease);
}
html[dir='ltr'] .link-arrow svg { transform: scaleX(-1); }
.link-arrow:hover svg { transform: translateX(-3px); }
html[dir='ltr'] .link-arrow:hover svg { transform: scaleX(-1) translateX(-3px); }

.text-link { color: var(--fg); text-underline-offset: 4px; text-decoration-color: var(--line-strong); }
.text-link:hover { text-decoration-color: var(--emerald); color: var(--emerald); }

/* --- Hero ----------------------------------------------------------------- */

.hero { border-block-end: 1px solid var(--line); }
.hero-inner { display: grid; gap: var(--s7); padding-block: var(--s7) var(--s8); }

.hero-copy { align-self: center; }
.hero-copy .lede { margin-block-start: var(--s5); }
.hero-copy .btn-row { margin-block-start: var(--s6); }

.hero-kicker {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--emerald);
  margin-block-end: var(--s4);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.hero-kicker::after {
  content: '';
  block-size: 1px;
  flex: 1;
  background: var(--line);
  max-inline-size: 120px;
}

.hero-media {
  border-radius: var(--r-media);
  overflow: hidden;
  background: var(--ink-800);
  border: 1px solid var(--line);
}
.hero-media img { inline-size: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

@media (min-width: 900px) {
  .hero-inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
    align-items: center;
    padding-block: var(--s9) var(--s10);
    gap: var(--s8);
  }
  /* The photograph breaks the grid and runs to the viewport edge. The type
     stays on the measure, which is what makes the composition asymmetric
     rather than a two-column split. */
  .hero-media {
    margin-inline-end: calc(var(--bleed) * -1);
    border-inline-end: 0;
    border-start-end-radius: 0;
    border-end-end-radius: 0;
  }
  .hero-media img { aspect-ratio: 4 / 3.4; block-size: 100%; }
  .hero-media--phone { margin-inline-end: 0; border-inline-end: 1px solid var(--line); border-radius: var(--r-media); }
}

/* Hero variant carrying a portrait phone render instead of photography. */
.hero-media--phone { background: var(--ink-800); display: grid; place-items: center; padding: var(--s6); }
.hero-media--phone img { aspect-ratio: auto; object-fit: contain; max-block-size: 620px; inline-size: auto; }

/* --- Hero: the cinematic stage -------------------------------------------
   The home hero only. A full-bleed stage rather than a two-column band:
   photography flanks a centred app render, the type holds the inline-start
   third, and the marks, brackets, dot fields and readouts are chrome drawn
   here in CSS. All of that chrome is aria-hidden in the markup, so the hero
   still reads as kicker, heading, lede, two links, three highlights.

   Authored on logical properties like the rest of the file, so in Arabic the
   whole composition mirrors and the copy stays on the reading edge. The one
   exception is unavoidable: a gradient takes no logical direction keyword, so
   the two physical directions are named once, here, and every rule below
   refers to them by role instead of by side.
   ------------------------------------------------------------------------ */

html[dir='rtl'] { --to-inline-end: to left;  --to-inline-start: to right; }
html[dir='ltr'] { --to-inline-end: to right; --to-inline-start: to left; }

.hero--cine {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  overflow: clip;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  background: var(--ink-900);
}

/* A cinematic hero carries its own top edge, so the header stops drawing one.
   Its call takes the hero's treatment too: an emerald block at the top of this
   composition reads as a third accent, competing with the kicker and the rim
   light rather than joining them. */
body:has(.hero--cine) .header { border-block-end-color: transparent; }
body:has(.hero--cine) .header .btn--primary {
  background: var(--fg);
  color: var(--ink-900);
  border-radius: 999px;
}
body:has(.hero--cine) .header .btn--primary:hover { background: #ffffff; }

/* --- backdrop --- */

.cine-bg { position: absolute; inset: 0; z-index: -1; }

.cine-fig { position: absolute; inset-block: 0; inline-size: 100%; }
.cine-fig picture { display: block; block-size: 100%; }
.cine-fig img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Near monochrome, well under the type: the photography sets the room, it
     does not compete with the heading. */
  filter: grayscale(0.4) contrast(1.05) brightness(0.62);
}

.cine-glow {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(5, 8, 7, 0.86) 0, rgba(5, 8, 7, 0) 20%,
                    rgba(5, 8, 7, 0) 72%, rgba(5, 8, 7, 0.93) 100%),
    linear-gradient(var(--to-inline-end), rgba(5, 8, 7, 0.95) 0 24%,
                    rgba(5, 8, 7, 0.55) 38%, rgba(5, 8, 7, 0) 52%);
}

.cine-dots {
  position: absolute;
  inline-size: 128px;
  block-size: 88px;
  background-image: radial-gradient(circle, rgba(0, 232, 138, 0.32) 1px, transparent 1.2px);
  background-size: 11px 11px;
  opacity: 0.55;
}
.cine-dots--top { inset-block-start: 14%; inset-inline-end: 4%; }
.cine-dots--base { inset-block-end: 16%; inset-inline-end: 1%; }

/* --- copy --- */

.cine-inner {
  position: relative;
  display: grid;
  gap: var(--s7);
  align-content: center;
  padding-block: var(--s7) var(--s6);
}

.cine-copy { display: grid; gap: var(--s5); justify-items: start; }
.cine-copy .lede { margin: 0; }

.cine-kicker {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  color: var(--emerald);
}
html[lang='en'] .cine-kicker { text-transform: uppercase; letter-spacing: 0.22em; }

/* The house dash. Shared by the kicker, the margin marks and the base rail so
   they read as one family of annotations. */
.cine-tick {
  flex: none;
  inline-size: 22px;
  block-size: 2px;
  border-radius: 1px;
  background: var(--emerald);
}

.hero--cine .btn {
  border-radius: 999px;
  min-block-size: 54px;
  padding-inline: var(--s6);
}

.cine-highlights {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
  margin: 0;
  padding-block-start: var(--s2);
}
.cine-highlights li {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding-inline-end: var(--s5);
  border-inline-end: 1px solid var(--line);
}
.cine-highlights li:last-child { padding-inline-end: 0; border-inline-end: 0; }
.cine-hl-glyph { flex: none; color: var(--emerald); }
.cine-hl-glyph svg { inline-size: 21px; block-size: 21px; }
.cine-hl-text { display: grid; line-height: 1.4; }
.cine-hl-text strong { font-family: var(--display); font-weight: 600; font-size: 0.9rem; }
html[lang='en'] .cine-hl-text strong { text-transform: uppercase; letter-spacing: 0.1em; }
.cine-hl-text span { color: var(--fg-muted); font-size: 0.85rem; }

/* --- stage --- */

.cine-stage { position: relative; display: grid; place-items: center; min-block-size: 0; }

/* The render ships its own near-black surround, so instead of masking it the
   stage puts a matching dark core behind it and the two disappear into each
   other. The emerald sits outside that core as a rim, never over the screen. */
.cine-phone { position: relative; isolation: isolate; }
.cine-phone::before,
.cine-phone::after { content: ''; position: absolute; }
.cine-phone::before {
  inset: -10% -26%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(5, 8, 7, 0.96) 0 52%, rgba(5, 8, 7, 0) 100%);
}
.cine-phone::after {
  inset: -20% -46%;
  z-index: -2;
  background: radial-gradient(closest-side, rgba(0, 232, 138, 0.2) 0, rgba(0, 232, 138, 0) 72%);
}
.cine-phone img { inline-size: min(70vw, 280px); block-size: auto; }

.cine-corner {
  position: absolute;
  inline-size: 16px;
  block-size: 16px;
  border: 0 solid var(--emerald);
  opacity: 0.9;
}
.cine-corner--ss { inset-block-start: 0; inset-inline-start: 0; border-block-start-width: 1px; border-inline-start-width: 1px; }
.cine-corner--se { inset-block-start: 0; inset-inline-end: 0;   border-block-start-width: 1px; border-inline-end-width: 1px; }
.cine-corner--es { inset-block-end: 0;   inset-inline-start: 0; border-block-end-width: 1px;   border-inline-start-width: 1px; }
.cine-corner--ee { inset-block-end: 0;   inset-inline-end: 0;   border-block-end-width: 1px;   border-inline-end-width: 1px; }

.cine-mark {
  position: absolute;
  display: grid;
  gap: 0.05rem;
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.68rem;
  line-height: 1.55;
  color: var(--fg-muted);
}
html[lang='en'] .cine-mark { text-transform: uppercase; letter-spacing: 0.16em; }
/* Small type directly on photography: the shadow is what holds it at 4.5:1
   when the frame behind it lands on a lit shoulder instead of the far wall. */
.cine-mark span { text-shadow: 0 0 10px rgba(5, 8, 7, 0.95), 0 1px 3px rgba(5, 8, 7, 0.9); }
.cine-mark::after {
  content: '';
  inline-size: 20px;
  block-size: 2px;
  margin-block-start: 0.55rem;
  border-radius: 1px;
  background: var(--emerald);
}
.cine-mark--start { inset-block-start: 4%; inset-inline-start: 0; }
.cine-mark--end { inset-block-start: 12%; inset-inline-end: 0; text-align: end; justify-items: end; }

.cine-stat {
  position: absolute;
  inline-size: 196px;
  display: grid;
  gap: 0.15rem;
  padding: var(--s4);
  background: rgba(9, 15, 13, 0.78);
  border: 1px solid var(--line);
  border-radius: 14px;
  backdrop-filter: blur(12px);
}
.cine-stat--start { inset-inline-start: 0; inset-block-end: 18%; }
.cine-stat--end { inset-inline-end: 0; inset-block-end: 5%; }

.cine-stat-label {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.62rem;
  color: var(--fg-muted);
}
html[lang='en'] .cine-stat-label { text-transform: uppercase; letter-spacing: 0.14em; }
.cine-stat-value {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.65rem;
  line-height: 1.15;
}
.cine-stat-unit { font-size: 0.7rem; font-weight: 600; color: var(--fg-muted); }
.cine-stat-delta {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  color: var(--emerald);
  font-size: 0.78rem;
  font-weight: 500;
}
.cine-stat-note { margin: 0; color: var(--fg-muted); font-size: 0.78rem; }
.cine-stat-chart { margin-block-start: var(--s2); }

.cine-chart { display: block; inline-size: 100%; block-size: auto; }
.cine-chart-line { fill: none; stroke: var(--emerald); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cine-chart-fill { fill: rgba(0, 232, 138, 0.16); stroke: none; }
.cine-bar { fill: var(--emerald); }
.cine-bar-track { fill: rgba(243, 247, 245, 0.07); }

/* Arabic carries no capitals and has no tracking to open it up, so the sizes
   that read as precise annotation in Latin caps read as unreadably small here.
   Every tracked label in this hero gets one step back for Arabic. */
html[lang='ar'] .cine-mark,
html[lang='ar'] .cine-rail { font-size: 0.8rem; }
html[lang='ar'] .cine-stat-label { font-size: 0.74rem; }
html[lang='ar'] .cine-kicker { font-size: 0.92rem; }
html[lang='ar'] .cine-hl-text strong { font-size: 0.97rem; }
html[lang='ar'] .cine-hl-text span { font-size: 0.88rem; }

/* --- base rail --- */

.cine-rail {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s6);
  align-items: center;
  justify-content: space-between;
  padding-block-end: var(--s5);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.68rem;
  color: var(--fg-muted);
}
html[lang='en'] .cine-rail { text-transform: uppercase; letter-spacing: 0.18em; }
.cine-rail-item { display: flex; align-items: center; gap: 0.7rem; margin: 0; }
.cine-rail-item--end { gap: 0.5rem; }
.cine-slash { color: var(--emerald); }

/* --- the composition assembles at 900px ---------------------------------- */

/* Under that width the stage would stack the chrome on top of the copy, so the
   chrome is dropped rather than shrunk: one photograph, a strong scrim, the
   type, then the render. Nothing that carries meaning is in the part removed. */
@media (max-width: 899px) {
  .cine-fig--end { display: none; }
  .cine-mark, .cine-stat, .cine-corner, .cine-dots { display: none; }
  .cine-glow {
    background:
      linear-gradient(to bottom, rgba(5, 8, 7, 0.9) 0, rgba(5, 8, 7, 0.72) 40%,
                      rgba(5, 8, 7, 0.86) 72%, rgba(5, 8, 7, 0.97) 100%);
  }
  .cine-rail { font-size: 0.62rem; gap: var(--s2) var(--s4); }
  .cine-rail-item--end { display: none; }
}

/* Once the highlights wrap, the rule after the last item on a row hangs off
   the end of it with nothing to divide. Below the wrap they are dropped. */
@media (max-width: 639px) {
  .cine-highlights { gap: var(--s3) var(--s6); }
  .cine-highlights li { padding-inline-end: 0; border-inline-end: 0; }
}

@media (min-width: 900px) {
  /* A hard block-size (not a minimum) so the rail at the foot of the stage
     never grows the composition past one screen: the 1fr copy/stage row
     above it can only shrink to fit, never push the rail below the fold. */
  .hero--cine { block-size: min(calc(100svh - 72px), 880px); }

  /* Two narrow bands flanking the render, not two halves. Keeping the far
     edges black is what lets the type hold the inline-start edge with nothing
     behind it, and it crops each figure tight enough to read at this size. */
  .cine-fig {
    inline-size: 27%;
    -webkit-mask-image: linear-gradient(var(--to-inline-end), transparent 0, #000 22%, #000 78%, transparent 100%);
            mask-image: linear-gradient(var(--to-inline-end), transparent 0, #000 22%, #000 78%, transparent 100%);
  }
  /* The start band begins where the copy measure ends, so no line of type ever
     has a face behind it. */
  .cine-fig--start { inset-inline-start: 34%; }
  .cine-fig--end { inset-inline-end: 4%; }

  .cine-inner {
    grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
    gap: clamp(24px, 3vw, 56px);
    align-items: center;
    block-size: 100%;
  }

  /* One size down from the site's hero scale. At the full clamp the sentence
     breaks mid-phrase in this narrower column. */
  .hero--cine .t-hero {
    font-size: clamp(2.5rem, 1.5rem + 3.1vw, 4rem);
    text-wrap: normal;
  }

  .cine-kicker::before {
    content: '';
    position: absolute;
    inset-block-end: calc(100% + var(--s5));
    inset-inline-start: 0;
    inline-size: 14px;
    block-size: 14px;
    border-block-start: 1px solid var(--emerald);
    border-inline-start: 1px solid var(--emerald);
  }

  .cine-phone img { inline-size: auto; block-size: min(74svh, 720px); max-inline-size: 100%; }
}

/* A short viewport (a laptop at 720-820px tall) can't fit the full-size
   heading, lede, highlights and rail inside one screen-height stage now that
   .hero--cine is capped to it, so the scale steps down together here the
   same way .hero--dash already does, instead of the rail clipping off. */
@media (min-width: 900px) and (max-height: 820px) {
  .hero--cine .t-hero { font-size: clamp(2rem, 1.3rem + 2.2vw, 3.2rem); }
  .cine-copy .lede { font-size: 0.92rem; }
  .cine-inner { gap: var(--s6); padding-block: var(--s5) var(--s4); }
  .cine-highlights { padding-block-start: var(--s1); gap: var(--s2) var(--s4); }
  .cine-phone img { block-size: min(52svh, 440px); }
  .cine-stat { inline-size: 168px; padding: var(--s3); }
  .cine-rail { padding-block-end: var(--s4); }
}

/* The readouts need a stage wide enough to sit beside the render, not on it. */
@media (max-width: 1199px) {
  .cine-stat { display: none; }
}

/* --- Hero: the dashboard variant -------------------------------------------
   A page with no photography of its own borrows the cinematic stage's kicker
   tick, corner marks and base rail, but skips the backdrop figures: the
   render just sits large on a plain dark ground in the normal two-column
   hero grid instead of a full-bleed stage. `dash-stats` is a plain proof-point
   row under the actions, not the floating readouts the cinematic image carries.
   ------------------------------------------------------------------------ */

.hero--dash {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  overflow: clip;
  background: var(--ink-900);
  border-block-end-color: transparent;
}
.hero-inner--dash { position: relative; }

@media (min-width: 900px) {
  /* Fills the viewport under the fixed header exactly, rather than only a
     minimum: a grid container rather than flex, since grid's default stretch
     is what lets the shell fill the row without an explicit width, the way
     .cine-inner already relies on for the home hero. */
  .hero--dash { display: grid; block-size: calc(100svh - 72px); align-content: center; }
  /* Top-heavy on purpose: centring the content block still let it crowd the
     header when the image grew, so the top gutter is fixed and generous
     while the bottom one is free to compress first. */
  .hero-inner--dash { padding-block: var(--s8) var(--s6); }
  .hero-media--dash img { max-block-size: min(72svh, 680px); inline-size: auto; }
  .hero-media--dash-phone img { max-block-size: min(78svh, 740px); }
}

/* A short viewport (a laptop at 720-800px tall) can't fit the full-size
   heading, lede and three stats inside one screen-height stage, so the type
   scale and gaps step down together here instead of letting the hero grow
   past the fold or the last stat clip against the viewport edge. */
@media (min-width: 900px) and (max-height: 820px) {
  .hero--dash .t-hero { font-size: clamp(2rem, 1.3rem + 2.4vw, 3.4rem); }
  .hero--dash .lede { font-size: 0.95rem; }
  .hero-inner--dash { padding-block: var(--s6) var(--s4); }
  .hero-copy .lede { margin-block-start: var(--s3); }
  .hero-copy .btn-row { margin-block-start: var(--s4); }
  .dash-stats { padding-block-start: var(--s2); gap: var(--s2) var(--s5); }
  .hero-media--dash img { max-block-size: min(58svh, 500px); }
}

.hero-media--dash {
  position: relative;
  display: grid;
  place-items: center;
  padding: var(--s5);
  background: none;
  border: 0;
  border-radius: 0;
}
.hero-media--dash::before {
  content: '';
  position: absolute;
  inset: 6%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(0, 232, 138, 0.18) 0, rgba(0, 232, 138, 0) 70%);
}
.hero-media--dash img { inline-size: 100%; max-inline-size: 680px; block-size: auto; aspect-ratio: auto; object-fit: contain; }
.hero-media--dash .cine-mark { display: none; }

/* A portrait phone render in the dashboard stage: the column is sized for
   wide dashboard screenshots, so a phone left at that width strands its
   marks and glow far from the render itself and reads as dead space. The
   box is given a real (not fit-content) measure so the marks, anchored to
   its edges, keep a fixed clearance from the phone regardless of how
   narrow the render itself is. */
.hero-media--dash-phone img { max-inline-size: 300px; }

/* --- Hero: the photo variant ------------------------------------------------
   A page with real photography but no app screen or honest figure to run
   beside it (About): the same screen-height stage and kicker tick as the
   dashboard hero, but the media stretches to fill its column edge-to-edge
   instead of sitting centred and contained, since a photograph reads as a
   wall behind the copy rather than a floating render. */

.hero--photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  overflow: clip;
  background: var(--ink-900);
  border-block-end-color: transparent;
}

@media (min-width: 900px) {
  .hero--photo { display: grid; block-size: calc(100svh - 72px); }
  /* Flex, not grid, for the inner row: grid's auto-sized track would not
     stretch to the section's full height no matter what align-content was
     set to, but flex's default cross-axis stretch reliably fills it. The
     copy re-centres itself inside that stretched row; the photo takes the
     stretch as-is, so it runs edge-to-edge top and bottom. */
  .hero-inner--photo { display: flex; align-items: stretch; padding-block: var(--s8) var(--s6); }
  .hero-inner--photo .hero-copy { flex: 1 1 0; min-inline-size: 0; align-self: center; }
  .hero-inner--photo .hero-media--photostage { flex: 1.08 1 0; min-inline-size: 0; }
}

@media (min-width: 900px) and (max-height: 820px) {
  .hero--photo .t-hero { font-size: clamp(2rem, 1.3rem + 2.4vw, 3.4rem); }
  .hero-inner--photo { padding-block: var(--s6) var(--s4); }
  .hero-copy .lede { margin-block-start: var(--s3); }
  .hero-copy .btn-row { margin-block-start: var(--s4); }
}

.hero-media--photostage { position: relative; display: flex; }
.hero-media--photostage picture { display: block; inline-size: 100%; }
.hero-media--photostage::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(5, 8, 7, 0.4), transparent 38%);
  pointer-events: none;
}
.hero-media--photostage .cine-mark { display: none; }

@media (min-width: 900px) {
  .hero-media--photostage img { block-size: 100%; aspect-ratio: auto; }
  .hero-media--photostage .cine-mark { display: grid; }
  .hero-media--photostage .cine-mark--start { inset-block-start: var(--s5); inset-inline-start: var(--s5); }
  .hero-media--photostage .cine-mark--end { inset-block-start: var(--s5); inset-inline-start: auto; inset-inline-end: var(--s5); }
}

.dash-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s6);
  margin: 0;
  padding-block-start: var(--s5);
}
.dash-stat {
  display: grid;
  gap: 0.2rem;
  padding-inline-end: var(--s5);
  border-inline-end: 1px solid var(--line);
}
.dash-stat:last-child { padding-inline-end: 0; border-inline-end: 0; }
.dash-stat-value { margin: 0; font-family: var(--display); font-weight: 800; font-size: 1.6rem; color: var(--fg); }
.dash-stat-label { margin: 0; color: var(--fg-muted); font-size: 0.78rem; }
html[lang='en'] .dash-stat-label { text-transform: uppercase; letter-spacing: 0.1em; }

@media (min-width: 900px) {
  .hero-media--dash { margin-inline-end: 0; padding-inline-end: 0; }
  .hero-media--dash .cine-mark { display: grid; }
  .hero-media--dash .cine-mark--start { inset-inline-start: 0; }
  .hero-media--dash .cine-mark--end { inset-inline-end: 0; }
  /* The copy column is narrow enough that flex-wrap otherwise drops the
     third stat to its own row; the numbers and labels are short, so one
     row holds all three with room to spare. */
  .dash-stats { flex-wrap: nowrap; gap: var(--s3) var(--s5); }
  .dash-stat { padding-inline-end: var(--s4); }
}

@media (max-width: 899px) {
  .hero-media--dash .cine-mark { display: none; }
  .hero--dash .cine-dots { display: none; }
}

@media (min-width: 900px) {
  /* Overrides the wide-image bleed above: a real, symmetric box the marks
     can sit clear of, centred in the column instead of docked to its
     inline-end edge. */
  .hero-media--dash-phone {
    inline-size: min(100%, 560px);
    margin-inline: auto;
    padding-inline-end: var(--s5);
  }
  .hero-media--dash-phone img { max-block-size: min(62svh, 600px); }
}

/* --- the primary call, with its arrow ------------------------------------ */

.btn--light { background: var(--fg); color: var(--ink-900); }
.btn--light:hover { background: #ffffff; }

.btn--quiet {
  background: rgba(11, 18, 16, 0.55);
  border: 1px solid rgba(243, 247, 245, 0.26);
  color: var(--fg);
  backdrop-filter: blur(8px);
}
.btn--quiet:hover { border-color: var(--emerald); color: var(--emerald); }

/* Drawn rather than set, so it needs no glyph the subsetted fonts do not carry. */
.btn--light::after {
  content: '';
  flex: none;
  inline-size: 17px;
  block-size: 9px;
  background: currentColor;
  clip-path: polygon(0 3.5px, 10px 3.5px, 10px 0, 17px 4.5px, 10px 9px, 10px 5.5px, 0 5.5px);
}
html[dir='rtl'] .btn--light::after { transform: scaleX(-1); }

/* --- Role spread (the two paths) ------------------------------------------
   A facing spread out of a training log: two halves of one sheet either side
   of a hairline spine. No panel, no radius, no elevation, no lift on hover.
   The rules divide and the type carries the weight, which is what the section
   grammar already does one level up.

   The lede claims both halves of the same relationship, so the halves are
   equal. What separates them is accent under hover and focus, not size.

   Spacing is margins rather than grid gap throughout, because the set rows
   have to stay gapless for their rules to run continuously, while the title
   and the link need room. One mechanism covers both the subgrid path and the
   fallback.
   ------------------------------------------------------------------------ */

.roles { display: grid; gap: 0; }

.role {
  position: relative;
  display: grid;
  align-content: start;
}

/* Below the band title, well above the body: three clearly separated steps
   rather than the timid sub-heading this section used to carry. */
.role-title {
  font-size: clamp(1.6rem, 1.15rem + 1.8vw, 2.35rem);
  font-weight: 800;
  line-height: 1.1;
  margin-block-end: var(--s5);
}

/* The set rows. Ruled top and bottom so the stack reads as a logged session,
   with the figure hanging in the margin the way the band index does. */
.role-points { border-block-start: 1px solid var(--line); }
.role-points li {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: var(--s4);
  align-items: baseline;
  align-content: start;
  padding-block: var(--s4);
  border-block-end: 1px solid var(--line);
  color: var(--fg-muted);
  transition: color var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease);
}
.role-point-num {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--numeral);
  transition: color var(--t-mid) var(--ease);
}
.role-point-body { text-wrap: pretty; }

.role-go { margin-block-start: var(--s5); }

/* The half is the target. The link stretches over it, so the point text stays
   out of the accessible name while the hit area covers the whole column. */
.role-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

.role:hover .role-points { border-block-start-color: var(--line-strong); }
.role:hover .role-points li { color: var(--fg); border-block-end-color: var(--line-strong); }
.role:hover .role-point-num { color: var(--emerald); }
.role:hover .link-arrow { border-block-end-color: var(--emerald); }
.role:hover .link-arrow svg { transform: translateX(-3px); }
html[dir='ltr'] .role:hover .link-arrow svg { transform: scaleX(-1) translateX(-3px); }

/* Focus belongs to the whole half, since the whole half is what activates.
   Gated on :has() support, so an engine without it keeps the link's own ring
   rather than losing the focus indicator altogether. */
@supports selector(:has(*)) {
  .role-link:focus-visible { outline: none; }
  .role:has(.role-link:focus-visible) {
    outline: 2px solid var(--emerald);
    outline-offset: clamp(12px, 2vw, 24px);
  }
  .role:has(.role-link:focus-visible) .role-points { border-block-start-color: var(--line-strong); }
  .role:has(.role-link:focus-visible) .role-points li { color: var(--fg); border-block-end-color: var(--line-strong); }
  .role:has(.role-link:focus-visible) .role-point-num { color: var(--emerald); }
}

/* Stacked, the spine lies down and becomes the rule between the two halves. */
.role + .role {
  margin-block-start: var(--s7);
  padding-block-start: var(--s7);
  border-block-start: 1px solid var(--line);
}

@media (min-width: 860px) {
  .roles { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .role:first-child { padding-inline-end: clamp(32px, 5vw, 72px); }
  .role + .role {
    margin-block-start: 0;
    padding-block-start: 0;
    border-block-start: 0;
    border-inline-start: 1px solid var(--line);
    padding-inline-start: clamp(32px, 5vw, 72px);
  }

  /* A spread only reads as a spread if the rules line up across the spine.
     Both halves borrow the same row track list, so set 02 sits opposite set
     02 no matter which side wraps to a second line. `--role-rows` is written
     by the renderer from the longest list. Without subgrid the halves simply
     size independently, which is the layout this replaced. */
  @supports (grid-template-rows: subgrid) {
    .roles { grid-template-rows: auto repeat(var(--role-rows, 3), auto) auto; }
    .role { grid-row: 1 / -1; grid-template-rows: subgrid; }
    .role-points {
      grid-row: 2 / span var(--role-rows, 3);
      display: grid;
      grid-template-rows: subgrid;
    }
    .role-go { grid-row: -2 / -1; }
  }
}

/* --- Pillars (vertical bays) ------------------------------------------------
   Four verticals sharing one continuous top and bottom rule, divided on
   hairlines: one structure split into four, not four separate cards. Each bay
   opens with a square render, since the asset set already has purpose-made
   art for the feature set and nothing on the page had used it yet.

   Every bay is one target. The link stretches over the whole column, same
   pattern as the role spread: a four-way choice deserves a target bigger than
   one arrow glyph.
   ------------------------------------------------------------------------ */

.pillars {
  display: grid;
  gap: var(--s6);
  border-block-start: 1px solid var(--line);
  border-block-end: 1px solid var(--line);
  padding-block: var(--s7);
}

.pillar {
  position: relative;
  display: grid;
  gap: var(--s3);
  align-content: start;
  transition: transform var(--t-mid) var(--ease);
}

.pillar-art {
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--ink-800);
  border-radius: var(--r-media);
  margin-block-end: var(--s2);
}
.pillar-art img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}

.pillar-num {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--numeral);
  transition: color var(--t-mid) var(--ease);
}

.pillar-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.2rem;
  line-height: 1.2;
}

.pillar-note { color: var(--fg-muted); font-size: 0.95rem; }

.pillar-go {
  margin: 0;
  margin-block-start: var(--s2);
  color: var(--numeral);
  transition: color var(--t-fast) var(--ease), transform var(--t-mid) var(--ease);
}
.pillar-go svg { inline-size: 18px; block-size: 18px; }
html[dir='ltr'] .pillar-go svg { transform: scaleX(-1); }

/* The whole bay is the target; the visible label lives in the arrow and the
   title, so the link itself carries only the accessible name (WCAG 2.5.3:
   the visible title leads it, same pattern as the role spread and the
   language switcher). */
.pillar-link {
  position: absolute;
  inset: 0;
}

.pillar:hover, .pillar:focus-within { transform: translateY(-2px); }
.pillar:hover .pillar-art img, .pillar:focus-within .pillar-art img { transform: scale(1.04); }
.pillar:hover .pillar-num, .pillar:focus-within .pillar-num { color: var(--emerald); }
.pillar:hover .pillar-go, .pillar:focus-within .pillar-go { color: var(--emerald); transform: translateX(-4px); }
html[dir='ltr'] .pillar:hover .pillar-go, html[dir='ltr'] .pillar:focus-within .pillar-go { transform: translateX(4px); }

.pillar-link:focus-visible { outline: 2px solid var(--emerald); outline-offset: 4px; }

@media (min-width: 860px) {
  .pillars { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }
  .pillar {
    padding-inline: clamp(20px, 2.4vw, 32px);
    border-inline-start: 1px solid var(--line);
  }
  .pillar:first-child { padding-inline-start: 0; border-inline-start: 0; }
  .pillar:last-child { padding-inline-end: 0; }

  /* The four notes run different lengths (workout plans wraps to three lines,
     the rest to two), so without a shared row grid the titles and arrows
     drifted to whatever height each bay's own note happened to need. All four
     bays borrow one row track list, the same fix the role spread uses above,
     so art, number, title, note and arrow all land level across the row. */
  @supports (grid-template-rows: subgrid) {
    .pillars { grid-template-rows: auto auto auto auto auto; align-items: stretch; }
    .pillar { grid-row: 1 / -1; display: grid; grid-template-rows: subgrid; align-content: start; }
  }
}

@media (max-width: 859px) {
  .pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s6) var(--s5); }
}

@media (max-width: 539px) {
  .pillars { grid-template-columns: minmax(0, 1fr); }
}

/* --- Split section (copy + media) ----------------------------------------- */

/* Top-aligned, not centred: the copy column is usually shorter than the
   render beside it, and centring it floated the section title ~150px below
   the band index it belongs to. The day band opts back into centring, where
   the two columns are close in height. */
.split { display: grid; gap: var(--s7); align-items: start; }
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s8); }
  .split--reverse > :first-child { order: 2; }
}
.split-copy .lede { margin-block-start: var(--s4); }

/* A small category badge in front of the heading, for the split sections
   that name one feature among several siblings (workouts, nutrition,
   trainees, analytics) and benefit from a glance-able mark. Optional: a
   split with no `icon` in content renders the heading exactly as before. */
.split-title { display: flex; align-items: center; gap: var(--s3); }
.split-icon {
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: 999px;
  background: rgba(0, 232, 138, 0.12);
  color: var(--emerald);
  flex: none;
}
.split-icon svg { inline-size: 18px; block-size: 18px; }
.split-copy .link-arrow { margin-block-start: var(--s5); }

.checks { display: grid; gap: var(--s4); margin-block-start: var(--s6); }
.checks li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.85rem; align-items: start; }
.checks svg { inline-size: 20px; block-size: 20px; color: var(--emerald); margin-block-start: 0.3rem; flex: none; }
.checks strong { font-weight: 600; display: block; }
.checks span { color: var(--fg-muted); font-size: 0.97rem; }

/* --- Check cards: a numbered problem list drawn as bordered panels rather
   than the ruled `.checks` list above. Scoped to `split` sections with
   `variant: "cards"` — a "here is the time you are losing" framing that
   reads better as three equal blocks than as a checklist. */
.check-cards { display: grid; gap: var(--s5); margin-block-start: var(--s7); }

.check-card {
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r-panel);
  padding: var(--s5);
  display: grid;
  gap: var(--s4);
  align-content: start;
}

.check-card-head { display: flex; align-items: center; gap: var(--s3); }
.check-card-num {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--emerald);
}
.check-card-rule { flex: 1; border-block-start: 1px dashed var(--line-strong); }
.check-card-dots { display: inline-flex; align-items: center; gap: 5px; flex: none; }
.check-card-dots i { inline-size: 5px; block-size: 5px; border-radius: 999px; background: var(--line-strong); }
.check-card-dots i:first-child { background: var(--emerald); }

.check-card-icon {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-control);
  color: var(--emerald);
}
.check-card-icon svg { inline-size: 22px; block-size: 22px; }

.check-card-note { color: var(--fg-muted); font-size: 0.95rem; }

@media (min-width: 760px) {
  .check-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- Status split: confirmed against pending ------------------------------
   A facing pair that runs the band's full width instead of one narrow notice
   card: a checklist reads as settled fact, the quieter column beside it
   reads as pending. */
.status-grid { display: grid; gap: var(--s7); }
@media (min-width: 760px) {
  .status-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s9); }
}

.status-label {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 var(--s4);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--emerald);
}
html[lang='en'] .status-label { text-transform: uppercase; letter-spacing: 0.1em; }
.status-label svg { inline-size: 18px; block-size: 18px; flex: none; }
.status-col--pending .status-label { color: var(--fg-muted); }

.status-list { display: grid; gap: var(--s3); margin: 0; }
.status-list li { display: flex; align-items: center; gap: 0.7rem; }
.status-list svg { inline-size: 18px; block-size: 18px; color: var(--emerald); flex: none; }

.status-col--pending { color: var(--fg-muted); }
.status-col--pending p { margin: 0 0 var(--s3); }
.status-col--pending p:last-of-type { margin-block-end: 0; }
.status-link { margin-block-start: var(--s3); }

/* --- The day scale -------------------------------------------------------
   The home page's "app in your day" band. The three points were already
   sequential, so the sequence is what gets drawn: an ordered run of stations
   down a ruled edge, each naming the moment it belongs to.

   The rule is a ruler rather than a timeline. Minor ticks between the stations
   are decoration and carry no reading; the major emerald tick marks where a
   station sits. The motif is already inside the product, down the edge of the
   intro progress screen, so it is borrowed from the app and not from the web.
   ------------------------------------------------------------------------ */

.day-scale {
  display: grid;
  gap: var(--s6);
  margin-block-start: var(--s6);
  padding-inline-start: var(--s6);
  border-inline-start: 1px solid var(--line);
  position: relative;
}

/* The graduations, in two lengths so the run reads as measured rather than as
   a dashed line: a short tick every 9px, a longer brighter one every fifth.
   Two elements rather than two background layers, because a gradient takes no
   logical inline anchor and the lengths differ; each is pinned with
   inset-inline-start so both directions place them against the rule. One field
   for the whole run each, so they stay continuous through the station gaps. */
.day-scale::before,
.day-scale::after {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
}
.day-scale::before {
  inline-size: 5px;
  background-image: repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px 9px);
}
.day-scale::after {
  inline-size: 11px;
  background-image: repeating-linear-gradient(to bottom, var(--line-strong) 0 1px, transparent 1px 45px);
}

.day-station { position: relative; }

/* The major graduation, pulled back out of the list's padding to meet the
   rule. Sits on the phase label's optical centre. */
.day-station::before {
  content: '';
  position: absolute;
  inset-inline-start: calc(var(--s6) * -1);
  inset-block-start: 0.5em;
  inline-size: 16px;
  block-size: 2px;
  background: var(--emerald);
}

.day-phase {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.75rem;
  color: var(--emerald);
  margin-block-end: var(--s2);
}
html[lang='en'] .day-phase { text-transform: uppercase; letter-spacing: 0.18em; }
/* Arabic has no capitals and takes no tracking, so it needs the size instead. */
html[lang='ar'] .day-phase { font-size: 0.88rem; }

.day-station h3 { margin-block-end: var(--s2); }
.day-note { color: var(--fg-muted); font-size: 0.97rem; max-inline-size: 46ch; }

/* The render leaves its panel here and sits on the page ground, the way the
   hero's does: the file already carries its own near-black surround, so a
   bordered box around it is a box drawn around a composition. */
.split--day .frame--phone {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}
.split--day .frame--phone img { max-block-size: clamp(400px, 46vw, 560px); }

/* The day band keeps the top alignment the rest of the splits now use. Centring
   it floated the render above the section heading, since the figure carries the
   conceptual note and runs taller than the copy beside it. */

/* Without the panel the note has no box to sit in, so it takes its own measure
   rather than running the full width of the column. */
.split--day .note-conceptual { max-inline-size: 52ch; }

/* --- Paired app screens --------------------------------------------------
   A phone render standing alone runs about 690px tall against roughly 475px
   of copy, which left ~214px of dead column in every `kind: phone` split. Two
   screens side by side are wider and shorter, so the pair fills the space with
   product rather than with air, and the two columns end near each other.

   Stepped rather than aligned: level tops would read as a comparison, and
   these are consecutive moments. Both sit unboxed on the page ground, since
   each file already carries its own near-black surround.
   ------------------------------------------------------------------------ */

.screens-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(8px, 1.1vw, 16px);
  align-items: start;
  justify-items: stretch;
}
.screens-pair .screen { display: block; position: relative; isolation: isolate; }

/* Each file carries its own near-black surround at #030504. On the page ground
   that is invisible, but on an alternating band it reads as a lighter-than-
   background rectangle around every screen. A soft-edged plate of exactly that
   black sits under the image and dissolves the edge into whichever band the
   section happens to land on. Masking the image itself would bite into the
   device, since the phone fills close to 90% of the plate. */
.screens-pair .screen::before {
  content: '';
  position: absolute;
  inset: -3% -9%;
  z-index: -1;
  border-radius: 20px;
  background: #030504;
  filter: blur(12px);
}

/* Each screen takes its full half of the column. A height cap kept the pair
   short but left wide margins either side and rendered the screens at ~190px,
   too small to read anything on them. Width first: the column is the budget. */
.screens-pair img { inline-size: 100%; block-size: auto; }

/* The second screen drops, so the pair has a reading order. Kept shallow,
   since the step is added to the tallest screen's height. */
.screen--trail { margin-block-start: clamp(16px, 3vw, 44px); }

/* Without a panel the note has no box to sit in, so it takes its own measure
   rather than running the full width of the column. */
.screens .note-conceptual { max-inline-size: 52ch; }

/* --- Roster list (the coach band's status echo) ---------------------------
   Scoped to the one section that sits beside a screenshot already showing
   status pills (On Track / Needs Attention). A dot plus label, not a check:
   the checkmark reads as "task done," the dot reads as "status," which is
   what a coach is actually scanning for in a trainee roster.
   ------------------------------------------------------------------------ */

.roster-list { display: grid; gap: var(--s5); margin-block-start: var(--s6); }
.roster-list li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.85rem; align-items: start; }
.roster-list strong { font-weight: 600; display: block; }
.roster-list span span { color: var(--fg-muted); font-size: 0.97rem; }

.roster-dot {
  inline-size: 10px;
  block-size: 10px;
  border-radius: 50%;
  background: var(--emerald);
  flex: none;
  margin-block-start: 0.5rem;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--emerald) 20%, transparent);
}

/* --- Media frames --------------------------------------------------------- */

.frame {
  border: 1px solid var(--line);
  border-radius: var(--r-media);
  overflow: hidden;
  background: var(--ink-800);
}
.frame img { inline-size: 100%; }

.frame--photo img { aspect-ratio: 3 / 2; object-fit: cover; }
.frame--square img { aspect-ratio: 1; object-fit: cover; }

/* Phone renders are never cropped: contain on an ink panel. */
.frame--phone {
  display: grid;
  place-items: center;
  padding: clamp(20px, 3vw, 36px);
  background: radial-gradient(120% 90% at 50% 0%, var(--ink-700), var(--ink-900) 70%);
}
.frame--phone img { inline-size: auto; max-block-size: 560px; object-fit: contain; }

.figure { display: grid; gap: var(--s3); }
.figure figcaption { color: var(--fg-muted); font-size: 0.88rem; line-height: 1.6; }

.note-conceptual {
  color: var(--fg-muted);
  font-size: 0.85rem;
  display: flex;
  gap: 0.5rem;
  align-items: start;
  line-height: 1.6;
}
.note-conceptual svg { inline-size: 15px; block-size: 15px; flex: none; margin-block-start: 0.35rem; color: var(--line-strong); }

/* Enlarge affordance sits on the frame, keyboard reachable. */
.zoom {
  position: relative;
  display: block;
  text-decoration: none;
}
.zoom-btn {
  position: absolute;
  inset-block-end: var(--s3);
  inset-inline-end: var(--s3);
  inline-size: 44px;
  block-size: 44px;
  display: grid;
  place-items: center;
  background: var(--ink-900);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-control);
  color: var(--fg);
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.zoom:hover .zoom-btn, .zoom:focus-within .zoom-btn { opacity: 1; }
.zoom-btn:hover { border-color: var(--emerald); color: var(--emerald); }
.zoom-btn svg { inline-size: 18px; block-size: 18px; }

/* --- Steps ---------------------------------------------------------------- */

.steps { display: grid; gap: 0; counter-reset: step; }
.step {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  gap: var(--s4);
  padding-block: var(--s6);
  border-block-start: 1px solid var(--line);
}
.step:last-child { border-block-end: 1px solid var(--line); }
.step-num {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.5rem;
  color: var(--emerald);
  line-height: 1.2;
}
.step h3 { margin-block-end: var(--s2); }
.step p { color: var(--fg-muted); max-inline-size: 60ch; }

@media (min-width: 900px) {
  .steps--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s6); }
  .steps--3 .step { border-block-end: 1px solid var(--line); }
}

/* --- Role tabs ------------------------------------------------------------ */

.tabs { display: grid; gap: var(--s6); }
.tablist {
  display: inline-flex;
  gap: var(--s1);
  padding: var(--s1);
  background: var(--ink-700);
  border: 1px solid var(--line);
  border-radius: 999px;
  inline-size: fit-content;
}
.tab {
  min-block-size: 44px;
  padding-inline: var(--s5);
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  color: var(--fg-muted);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.tab[aria-selected='true'] { background: var(--emerald); color: var(--ink-900); }
.tab:hover:not([aria-selected='true']) { color: var(--fg); }
.tabpanel[hidden] { display: none; }

/* Without JS every panel stays visible under its own heading. */
.no-js .tablist { display: none; }
.no-js .tabpanel[hidden] { display: block; }
.tabpanel-heading { display: none; }
.no-js .tabpanel-heading { display: block; margin-block-end: var(--s4); }

/* --- Comparison table ----------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-media);
  -webkit-overflow-scrolling: touch;
}
table { inline-size: 100%; border-collapse: collapse; min-inline-size: 560px; }
caption {
  text-align: start;
  padding: var(--s4) var(--s5);
  color: var(--fg-muted);
  font-size: 0.9rem;
  border-block-end: 1px solid var(--line);
}
th, td { padding: var(--s4) var(--s5); text-align: start; vertical-align: top; }
thead th {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  background: var(--ink-700);
  border-block-end: 1px solid var(--line);
}
tbody tr + tr th, tbody tr + tr td { border-block-start: 1px solid var(--line); }
tbody th { font-weight: 500; color: var(--fg); }
tbody td { color: var(--fg-muted); }

/* --- FAQ (native details, works with JS off) ------------------------------ */

.faq { border-block-start: 1px solid var(--line); }
.faq details { interpolate-size: allow-keywords; border-block-end: 1px solid var(--line); }
.faq summary {
  display: flex;
  align-items: center;
  gap: var(--s4);
  justify-content: space-between;
  margin-inline: calc(var(--s4) * -1);
  padding-inline: var(--s4);
  padding-block: var(--s5);
  min-block-size: 44px;
  border-radius: var(--r-control);
  cursor: pointer;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.08rem;
  list-style: none;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover, .faq summary:focus-visible { color: var(--emerald); background: var(--ink-700); }

/* Native details snap open/closed instantly. `::details-content` is the box
   the UA already draws around everything after <summary>, so animating it
   needs no markup change and falls back to the old instant snap wherever a
   browser does not yet support it. */
.faq details::details-content {
  overflow: hidden;
  height: 0;
  opacity: 0;
  transition: height var(--t-mid) var(--ease), opacity var(--t-fast) var(--ease),
    content-visibility var(--t-mid) allow-discrete;
}
.faq details[open]::details-content { height: auto; opacity: 1; }
.faq-sign {
  flex: none;
  inline-size: 22px; block-size: 22px;
  position: relative;
  color: var(--line-strong);
  transition: color var(--t-fast) var(--ease), transform var(--t-mid) var(--ease);
}
.faq-sign::before, .faq-sign::after {
  content: '';
  position: absolute;
  background: currentColor;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  transform: translate(50%, -50%);
}
html[dir='ltr'] .faq-sign::before, html[dir='ltr'] .faq-sign::after { transform: translate(-50%, -50%); }
.faq-sign::before { inline-size: 14px; block-size: 2px; }
.faq-sign::after { inline-size: 2px; block-size: 14px; transition: opacity var(--t-fast) var(--ease); }
.faq details[open] .faq-sign { color: var(--emerald); }
.faq details[open] .faq-sign::after { opacity: 0; }
.faq-body { padding-block-end: var(--s5); color: var(--fg-muted); max-inline-size: 68ch; }
.faq-body > * + * { margin-block-start: var(--s3); }
.faq details:target summary { color: var(--emerald); }

/* --- Final CTA ------------------------------------------------------------ */

.cta {
  position: relative;
  isolation: isolate;
  border-block-start: 1px solid var(--line);
  overflow: hidden;
}
.cta-bg { position: absolute; inset: 0; z-index: -2; }
.cta-bg img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.cta::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom, rgba(5, 8, 7, 0.82), rgba(5, 8, 7, 0.94));
}
.cta-inner { padding-block: clamp(72px, 10vw, 144px); }
.cta-copy {
  display: grid;
  gap: var(--s5);
  justify-items: start;
  max-inline-size: 46ch;
}
.cta-kicker {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--emerald);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.cta-kicker::after {
  content: '';
  block-size: 1px;
  flex: 1;
  background: var(--line-strong);
  max-inline-size: 120px;
}

/* --- Store buttons -------------------------------------------------------- */

.stores { display: grid; gap: var(--s4); }
@media (min-width: 620px) { .stores { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.store {
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding: var(--s4) var(--s5);
  min-block-size: 68px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-control);
  text-decoration: none;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.store:hover { border-color: var(--emerald); background: var(--ink-700); }
.store svg { inline-size: 26px; block-size: 26px; flex: none; }
.store-text { display: grid; line-height: 1.35; }
.store-text small { color: var(--fg-muted); font-size: 0.8rem; }
.store-text strong { font-family: var(--display); font-weight: 600; font-size: 1.05rem; }

/* --- Get-the-app dropdown --------------------------------------------------
   The hero/CTA "download" action becomes this once two or more stores are
   live: a native <details> disclosure (same idiom as the FAQ accordion)
   revealing a small panel with the store links, instead of a link to the
   on-site /download page.

   The panel is `position: absolute` within `.dl-dropdown` (not `fixed`, and
   not left in normal flow): normal flow grew the hero/CTA copy column when
   open, which reflowed the whole grid row and resized the paired image
   beside it; `fixed` was cut off in testing, because `.hero-stagger`'s
   reveal animation leaves its animated ancestor with a resolved (if
   identity) `transform`, which makes it a containing block for
   fixed-position descendants after all. `.dl-dropdown`'s own
   `position: relative` sidesteps that: it is the containing block an
   absolutely-positioned child looks for first, so the search never reaches
   that ancestor. */

.dl-dropdown { position: relative; }

.dl-trigger { list-style: none; cursor: pointer; }
.dl-trigger::marker, .dl-trigger::-webkit-details-marker { display: none; }
.dl-trigger::after { content: none; } /* not a link to somewhere: no arrow */
.dl-trigger svg { inline-size: 16px; block-size: 16px; flex: none; transition: transform var(--t-fast) var(--ease); }
.dl-dropdown[open] .dl-trigger svg { transform: rotate(180deg); }

.dl-menu {
  position: absolute;
  inset-inline-start: 0;
  top: calc(100% + var(--s2));
  z-index: 5;
  display: grid;
  gap: var(--s2);
  min-inline-size: 240px;
  max-inline-size: 320px;
  padding: var(--s3);
  background: var(--ink-800);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-media);
  box-shadow: 0 16px 32px -12px rgb(0 0 0 / 0.4);
}

.dl-item {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3);
  border-radius: var(--r-control);
  text-decoration: none;
  color: var(--fg);
  transition: background var(--t-fast) var(--ease);
}
.dl-item:hover, .dl-item:focus-visible { background: var(--ink-700); }
.dl-item svg { inline-size: 22px; block-size: 22px; flex: none; }

/* --- Notice / callout ----------------------------------------------------- */

.notice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s5);
  background: var(--ink-700);
  border: 1px solid var(--line);
  border-radius: var(--r-media);
  color: var(--fg-muted);
}
.notice svg { inline-size: 20px; block-size: 20px; color: var(--emerald); margin-block-start: 0.2rem; }
.notice strong { color: var(--fg); font-weight: 600; display: block; margin-block-end: var(--s1); }
.notice a { color: var(--fg); text-underline-offset: 4px; }

/* --- Forms ---------------------------------------------------------------- */

.form { display: grid; gap: var(--s5); max-inline-size: 640px; }
.field { display: grid; gap: var(--s2); }
.field label { font-weight: 500; display: flex; gap: 0.5rem; align-items: baseline; }
.field label span { color: var(--fg-muted); font-size: 0.82rem; font-weight: 300; }
.field .hint { color: var(--fg-muted); font-size: 0.87rem; }

.field input, .field textarea, .field select {
  min-block-size: 52px;
  padding: var(--s3) var(--s4);
  background: var(--ink-800);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-control);
  color: var(--fg);
  inline-size: 100%;
  transition: border-color var(--t-fast) var(--ease);
}
.field textarea { min-block-size: 160px; resize: vertical; line-height: 1.7; }
.field input::placeholder, .field textarea::placeholder { color: var(--fg-muted); opacity: 0.65; }
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--fg-muted); }
.field [aria-invalid='true'] { border-color: var(--danger); }

.field-error {
  color: var(--danger);
  font-size: 0.88rem;
  display: flex;
  gap: 0.4rem;
  align-items: center;
  min-block-size: 0;
}
.field-error:empty { display: none; }

.form-status {
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--r-control);
  background: var(--ink-700);
}
.form-status:empty { display: none; }
.form-status[data-state='error'] { border-color: var(--danger); }
.form-status[data-state='success'] { border-color: var(--emerald); }

/* --- Support search ------------------------------------------------------- */

.search { display: grid; gap: var(--s2); max-inline-size: 560px; }
.search input {
  min-block-size: 52px;
  padding: var(--s3) var(--s5);
  background: var(--ink-800);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-control);
  inline-size: 100%;
}
.search-count { color: var(--fg-muted); font-size: 0.9rem; min-block-size: 1.4em; }
.faq-group[hidden], .faq details[hidden] { display: none; }

/* --- Quick access cards --------------------------------------------------- */

.quick { display: grid; gap: var(--s4); }
@media (min-width: 760px) { .quick { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.quick a {
  display: grid;
  gap: var(--s2);
  padding: var(--s5);
  background: var(--ink-700);
  border: 1px solid var(--line);
  border-radius: var(--r-media);
  text-decoration: none;
  transition: border-color var(--t-fast) var(--ease);
}
.quick a:hover { border-color: var(--emerald); }
.quick strong { font-family: var(--display); font-weight: 600; font-size: 1.05rem; }
.quick span { color: var(--fg-muted); font-size: 0.92rem; }

/* --- Long-form reading (legal pages) -------------------------------------- */

.reading { display: grid; gap: var(--s7); }
@media (min-width: 1000px) {
  .reading { grid-template-columns: 250px minmax(0, 1fr); gap: var(--s8); align-items: start; }
  .toc { position: sticky; inset-block-start: 104px; }
}
.toc { border-inline-start: 1px solid var(--line); padding-inline-start: var(--s5); }
.toc h2 { font-size: 0.95rem; margin-block-end: var(--s3); color: var(--fg-muted); }
.toc ol { display: grid; gap: var(--s2); counter-reset: toc; }
.toc a { display: block; padding-block: 0.35rem; color: var(--fg-muted); text-decoration: none; font-size: 0.93rem; }
.toc a:hover { color: var(--emerald); }

.doc { max-inline-size: 68ch; }
.doc h2 { font-size: clamp(1.4rem, 1.2rem + 1vw, 1.9rem); margin-block: var(--s8) var(--s4); scroll-margin-block-start: 100px; }
.doc h2:first-child { margin-block-start: 0; }
.doc h3 { font-size: 1.15rem; margin-block: var(--s6) var(--s3); }
.doc p, .doc li { color: var(--fg-muted); }
.doc p + p { margin-block-start: var(--s4); }
.doc ul { display: grid; gap: var(--s3); margin-block-start: var(--s4); }
.doc ul li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.75rem; }
.doc ul li::before { content: ''; inline-size: 6px; block-size: 6px; background: var(--line-strong); border-radius: 1px; margin-block-start: 0.65em; }
.doc-meta { color: var(--fg-muted); font-size: 0.9rem; margin-block-end: var(--s6); }

/* --- Gallery (manual, no autoplay) ---------------------------------------- */

.gallery { display: grid; gap: var(--s5); }
@media (min-width: 760px) { .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.gallery figcaption { color: var(--fg-muted); font-size: 0.9rem; }
.gallery-note { margin-block-start: var(--s5); }

/* --- Lightbox ------------------------------------------------------------- */

dialog.lightbox {
  border: 0;
  padding: 0;
  background: transparent;
  max-inline-size: 100vw;
  max-block-size: 100vh;
  inline-size: 100%;
  block-size: 100%;
}
dialog.lightbox::backdrop { background: rgba(5, 8, 7, 0.94); }
.lightbox-inner {
  block-size: 100%;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--s4);
  padding: var(--s4);
}
.lightbox-bar { display: flex; justify-content: flex-end; }
.lightbox-close {
  inline-size: 48px; block-size: 48px;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-control);
  background: var(--ink-900);
  color: var(--fg);
}
.lightbox-close:hover { border-color: var(--emerald); color: var(--emerald); }
.lightbox-inner img { inline-size: 100%; block-size: 100%; object-fit: contain; }

/* --- Footer --------------------------------------------------------------- */

.footer {
  border-block-start: 1px solid var(--line);
  padding-block: var(--s8) var(--s6);
  background: var(--ink-800);
}
.footer-grid { display: grid; gap: var(--s7); }
@media (min-width: 700px) { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .footer-grid { grid-template-columns: 1.4fr repeat(4, minmax(0, 1fr)); } }

.footer-brand { display: grid; gap: var(--s4); align-content: start; max-inline-size: 34ch; }
.footer-brand p { color: var(--fg-muted); font-size: 0.93rem; }
.footer-brand .stores { grid-template-columns: 1fr; max-inline-size: 240px; }

.footer h2 {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--fg-muted);
  margin-block-end: var(--s4);
}
.footer ul { display: grid; gap: 0.1rem; }
.footer ul a {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
  color: var(--fg);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 300;
}
.footer ul a:hover { color: var(--emerald); }

.footer-base {
  margin-block-start: var(--s8);
  padding-block-start: var(--s5);
  border-block-start: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s6);
  align-items: center;
  justify-content: space-between;
  color: var(--fg-muted);
  font-size: 0.88rem;
}
.footer-base a { display: inline-flex; align-items: center; min-block-size: 44px; }

/* Copyright and contact read as one cluster of "about this site" facts,
   set apart from the language switch on the other end of the line. */
.footer-base-info {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) var(--s5);
}
.footer-email {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-block-size: 44px;
  color: var(--fg-muted);
  text-decoration: none;
}
.footer-email svg { inline-size: 16px; block-size: 16px; flex: none; }
.footer-email:hover { color: var(--emerald); }

/* --- Scroll reveal --------------------------------------------------------
   Content is visible by default and only hidden once the script has confirmed
   it can reveal it again. A stylesheet that loads without its script therefore
   never hides anything. */

.reveal { opacity: 1; }
html.js.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
html.js.reveal-ready .reveal.is-in { opacity: 1; transform: none; }

/* `.reveal-stagger`: the block itself no longer moves as one rigid unit; its
   direct children rise one after another instead, each a little behind the
   last. Reuses the same `is-in` flag the observer already sets on the block,
   so no script change is needed to add this to another section. Delay steps
   flatten out after the fifth child so a long list never reads as sluggish. */
html.js.reveal-ready .reveal.reveal-stagger { opacity: 1; transform: none; transition: none; }
html.js.reveal-ready .reveal-stagger > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
html.js.reveal-ready .reveal-stagger.is-in > * { opacity: 1; transform: none; }
html.js.reveal-ready .reveal-stagger > *:nth-child(1) { transition-delay: 0ms; }
html.js.reveal-ready .reveal-stagger > *:nth-child(2) { transition-delay: 70ms; }
html.js.reveal-ready .reveal-stagger > *:nth-child(3) { transition-delay: 140ms; }
html.js.reveal-ready .reveal-stagger > *:nth-child(4) { transition-delay: 210ms; }
html.js.reveal-ready .reveal-stagger > *:nth-child(n+5) { transition-delay: 280ms; }

/* Hero copy is above the fold: stagger it on first paint, never on scroll. */
.js .hero-stagger > * { opacity: 0; transform: translateY(10px); animation: rise var(--t-slow) var(--ease) forwards; }
.js .hero-stagger > *:nth-child(1) { animation-delay: 60ms; }
.js .hero-stagger > *:nth-child(2) { animation-delay: 130ms; }
.js .hero-stagger > *:nth-child(3) { animation-delay: 200ms; }
.js .hero-stagger > *:nth-child(4) { animation-delay: 270ms; }
.js .hero-stagger > *:nth-child(5) { animation-delay: 340ms; }

@keyframes rise { to { opacity: 1; transform: none; } }

/* --- Accessibility utilities ---------------------------------------------- */

.visually-hidden {
  position: absolute;
  inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Reduced motion ------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, .reveal-stagger > *, .js .hero-stagger > * { opacity: 1 !important; transform: none !important; }
  .f-row:hover, .pillar:hover, .pillar:focus-within { transform: none; }
  .pillar:hover .pillar-art img, .pillar:focus-within .pillar-art img { transform: none; }
}

/* --- Print ---------------------------------------------------------------- */

@media print {
  .header, .footer, .skip, .cta, .zoom-btn { display: none; }
  body { background: #fff; color: #000; }
  .band { border-color: #ccc; padding-block: 16px; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 0.8em; }
}
