/* =============================================================================
   Digital Art Factory — BASE + COMPONENTS  (assets/css/base.css)
   Load AFTER tokens.css.

   Contains, in order:
     1. Reset + base element defaults
     2. Reduced-motion global guard (second layer; tokens.css is the first)
     3. Layout shell (header / nav / main / footer) + skip link
     4. Accessibility + utility primitives (.visually-hidden, .num, .caps,
        .muted, .cluster, the section rhythm rules) + the facet glyph set
     5. SHARED components — the chrome and the legal/404 pages: buttons,
        alerts, toasts, language switcher, prose, not-found block
     6. Responsive rules for the shared chrome
     7. HOMEPAGE layer (index.html only): hero + motif, facet-cut capability
        cards, the flow beam path, the trust spec list, the closing CTA band,
        and its own min-width enhancements

   Sections 5 and 7 are deliberately separate: 5 is what every page uses, 7 is
   the homepage redesign. Nothing in 7 is referenced by legal/*, 404.html or
   shell.js, so the homepage layer can be reworked without touching them.

   Everything is responsive and RTL-aware via CSS logical properties.
   Components reference ONLY the tokens in tokens.css.
   ============================================================================= */

/* ============================================================================
   1. RESET + BASE ELEMENTS
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

/* The HTML `hidden` attribute must always win. Components below set
   `display:flex`, which otherwise overrides the UA `[hidden]{display:none}`
   rule and leaves JS-toggled elements visible. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-block-start: calc(var(--header-h) + var(--s-4));
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--c-text);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 var(--s-3);
  line-height: var(--lh-tight);
  font-weight: var(--fw-semi);
  color: var(--c-text);
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); }

p { margin: 0 0 var(--s-4); }

a { color: var(--c-accent); text-decoration: none; }
a:hover { color: var(--c-accent-hover); text-decoration: underline; }

img, svg, picture, video { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0 0 var(--s-4); padding-inline-start: var(--s-5); }

dl { margin: 0 0 var(--s-4); }
dt { font-weight: var(--fw-semi); }
dd { margin-inline-start: 0; margin-block-end: var(--s-3); color: var(--c-text-2); }

hr {
  border: 0;
  border-block-start: 1px solid var(--c-divider);
  margin-block: var(--s-5);
}

button, input, select, textarea { font: inherit; color: inherit; }

/* Global visible focus. Never remove an outline without a replacement. */
:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--shadow-focus);
  border-radius: inherit;      /* keep each control's own radius (pills stay pill) */
}
/* Suppress the legacy outline only where :focus-visible is honored. */
:focus:not(:focus-visible) { outline: none; }

::selection { background: color-mix(in srgb, var(--c-accent) 30%, transparent); }

/* ============================================================================
   2. REDUCED-MOTION GLOBAL GUARD (WCAG 2.3.3)
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   3. LAYOUT SHELL
   ========================================================================== */
.shell {
  inline-size: 100%;
  max-inline-size: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--s-4);
}
.shell--narrow { max-inline-size: var(--maxw-narrow); }

main.shell {
  flex: 1 0 auto;
  padding-block: var(--s-6) var(--s-8);
}
main:focus { outline: none; } /* programmatic focus target; skip-link gives context */

/* Skip link — first focusable element (WCAG 2.4.1). */
.skip-link {
  position: absolute;
  inset-block-start: var(--s-2);
  inset-inline-start: var(--s-2);
  z-index: var(--z-modal);
  display: inline-flex;
  align-items: center;
  min-block-size: var(--tap);
  padding: var(--s-2) var(--s-4);
  background: var(--c-accent);
  color: var(--c-accent-ink);
  border-radius: var(--r-sm);
  font-weight: var(--fw-semi);
  transform: translateY(-200%);
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus {
  transform: translateY(0);
  text-decoration: none;
}

/* Header */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  background: var(--c-surface-2);
  border-block-end: 1px solid var(--c-border);
}
.hdr {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  block-size: var(--header-h);
}
.brand {
  display: inline-flex;
  align-items: center;
  /* --tap in BOTH axes: on a phone the brand contracts to a 22px mark (below),
     which is a full-size tap target only if the box is held open. */
  min-block-size: var(--tap);
  min-inline-size: var(--tap);
  gap: var(--s-2);
  color: var(--c-text);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-caps);
  text-decoration: none;
  white-space: nowrap;
}
.brand:hover { color: var(--c-text); text-decoration: none; }
.brand__mark { color: var(--c-accent); font-size: 1.75em; line-height: 1; }
.brand__word { font-size: var(--t-h4); }

/* PHONE: the brand contracts to its mark. A 360px bar cannot hold the wordmark
   (185px) AND the three controls that all have to stay — theme, the language
   <select> that 45 locales depend on, and the nav disclosure — which together
   need 216px before gaps; that arithmetic (433px of content in 360px) is what
   pushed the toggle off-canvas and made the nav unreachable. The ◆ is the brand
   mark and the page's whole thesis, so it is the part that survives. .brand's
   aria-label ("Farmer Diamonds home", key brand.home) is untouched, so the link
   still ANNOUNCES the full name — nothing is lost to assistive tech. */
.brand__word { display: none; }
@media (min-width: 480px) {
  .brand__mark { font-size: 1.25em; }
  .brand__word { display: inline; }
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  margin-inline-start: var(--s-3);
}
.nav a {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--tap);
  padding-inline: var(--s-3);
  border-radius: var(--r-sm);
  color: var(--c-text-2);
  font-weight: var(--fw-med);
  text-decoration: none;
  white-space: nowrap;
}
.nav a:hover { color: var(--c-text); background: var(--c-surface-3); text-decoration: none; }
.nav a[aria-current="page"] {
  color: var(--c-accent);
  background: var(--c-accent-soft);
}

.hdr__tools {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

/* ── Nav disclosure — mobile-first (base = phone, min-width enhances up) ─────
   BASE (phone): the disclosure toggle is present and the nav is a closed panel.
   shell.js ships the nav [hidden] below --bp-nav and opens it on the toggle.

   SPECIFICITY, NOT SOURCE ORDER. `.nav__toggle`/`.hdr__signin` are (0,1,0) and
   so are the `.icon-btn`/`.btn` component rules that set `display:inline-flex`
   further down this file — a bare `.nav__toggle { display:none }` LOSES to them
   on source order (a media query adds no specificity). That is why the toggle
   used to render off-canvas at 360 AND beside the expanded nav at 1280. Every
   display rule below is therefore (0,2,0) so it cannot be undercut again.

   BREAKPOINT: the nav releases at 1000px because that is where the desktop
   header actually fits in ALL 45 locales, not just English. Measured intrinsic
   header width with the nav expanded: 964px (ta), 899px (ms), 872px (ru),
   847px (de), 826px (en). Releasing it at the old 720 opened a dead band from
   721 to ~964 where the desktop nav was rendered in a space too small to hold
   it, which is why 768 (iPad portrait) lost its controls off the right edge.
   1000 clears the worst locale (ta) by 21px.
   This value is mirrored in shell.js (matchMedia) and nojs.css — all three MUST
   move together, or the nav renders as a permanently-open panel over <main>. */
.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: var(--tap);
  min-block-size: var(--tap);
}
.nav {
  position: absolute;
  inset-block-start: var(--header-h);
  inset-inline: 0;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  margin-inline-start: 0;
  padding: var(--s-2);
  background: var(--c-surface-2);
  border-block-end: 1px solid var(--c-border);
  box-shadow: var(--shadow-2);
}
/* The portal CTA stays reachable in the hero, so it is the first thing to go
   when the header runs out of room. */
.hdr__tools .hdr__signin { display: none; }

@media (min-width: 1000px) {
  .hdr .nav__toggle { display: none; }
  .nav {
    position: static;
    flex-direction: row;
    align-items: center;
    gap: var(--s-1);
    margin-inline-start: var(--s-3);
    padding: 0;
    background: none;
    border-block-end: 0;
    box-shadow: none;
  }
}

/* The sign-in label is locale-sized: "Sign in" 64px, "Anmelden" 105px,
   "Log Masuk" (ms) 130px. It returns only once the header has room for the
   widest of the 45 — measured worst case 1079px (ta), cleared here by 46px. */
@media (min-width: 1140px) {
  .hdr__tools .hdr__signin { display: inline-flex; }
}

/* Footer */
.site-footer {
  flex: 0 0 auto;
  background: var(--c-surface-2);
  border-block-start: 1px solid var(--c-border);
  margin-block-start: var(--s-8);
}
.ft {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-5);
  padding-block: var(--s-5);
}
.ft__tagline { margin: 0; color: var(--c-text-2); font-size: var(--t-sm); }
.ft__nav {
  margin-inline-start: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
}
/* These four are the trust links — imprint/privacy/terms/accessibility are what
   a decision-maker taps to check the company is real. They shipped at 22px tall.
   --tap in BOTH axes: English labels are wide enough to hide the inline-size
   problem, but short ones are not ("Tiráž" 31px, bn "ইমপ্রিন্ট" 42px). */
.ft__nav a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--tap);
  min-inline-size: var(--tap);
  color: var(--c-text-2);
  font-size: var(--t-sm);
  text-decoration: none;
}
.ft__nav a:hover { color: var(--c-accent); text-decoration: underline; }
.ft__meta { flex-basis: 100%; margin: 0; color: var(--c-text-3); font-size: var(--t-xs); }

/* ============================================================================
   4. ACCESSIBILITY / UTILITY PRIMITIVES
   ========================================================================== */
.visually-hidden {
  position: absolute !important;
  inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Numbers / identifiers: tabular, monospaced, isolated LTR so they never
   reorder under RTL. Applied to phone numbers, registry ids, dates. */
.num {
  font-family: var(--font-num);
  font-feature-settings: "tnum" 1, "lnum" 1;
  font-variant-numeric: tabular-nums lining-nums;
  direction: ltr;
  unicode-bidi: isolate;
}

.muted { color: var(--c-text-3); }
.caps {
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  font-size: var(--t-xs);
  color: var(--c-text-3);
}

/* Section helpers.
   RHYTHM IS SINGLE-SOURCED HERE. .section owns the gap to whatever follows it
   (--s-section: 48px phone → 96px desktop). Adjacent block margins COLLAPSE, so
   the moment a neighbour also declares margin-block-start the larger silently
   wins and this token looks broken — that is exactly what a fixed --s-8 on
   .cta-band used to do. Every homepage neighbour now declares 0 and lets this
   rule be the only writer. Do not re-add a margin-block-start below. */
.section { margin-block-end: var(--s-section); scroll-margin-block-start: calc(var(--header-h) + var(--s-4)); }
.section__head { max-inline-size: var(--measure); margin-block-end: var(--s-block); }
.section__title { margin: 0 0 var(--s-2); font-size: var(--t-h2); line-height: var(--lh-tight); }
.section__lede  {
  margin: 0;
  color: var(--c-text-2);
  font-size: var(--t-h4);
  font-weight: var(--fw-reg);   /* the jump away from the --fw-semi title above */
  max-inline-size: var(--measure);
}
/* .cluster is NOT homepage furniture — 404.html:28 is its only consumer. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

/* ── The facet glyph set — "The Cut" (MOVE 2) ────────────────────────────────
   Ten stroke glyphs, each an operation on the hero gem's own rhombus, living in
   an inline <symbol> sprite at the top of <body> and drawn with <use href="#…">.
   Inline is not a preference: <use> pointing at an EXTERNAL file is not
   supported in Chrome/Safari, and a data: URI background would lose currentColor
   (and so the theme). They replaced ten emoji, which were a silent dependency on
   the OS emoji font, could not take the accent, and could not respond to a
   theme change.

   The sprite carries geometry only — fill/stroke/width are presentation
   attributes on each <symbol> resolving to `currentColor`. So the ONLY thing a
   consumer supplies is size and colour, and the container's `color` (both glyph
   boxes set --c-accent) paints the glyph for free in both themes.

   Sized at --s-5 (24px) = the sprite's own optical grid, 1:1, so no stroke is
   ever resampled: 48px .cap__glyph box → 12px of air; 24px .pillar__glyph box
   → exact fit, and the symbols' 2px live-area inset supplies the optical
   padding. The reset's `svg { height: auto }` (0,0,1) is outranked here.
   ────────────────────────────────────────────────────────────────────────── */
/* The sprite itself is a geometry bank, never painted. It MUST be hidden from a
   stylesheet, not a style="" attribute: the CSP is `style-src 'self'` with no
   'unsafe-inline', and style-src-attr FALLS BACK to style-src — so an inline
   style attribute is blocked outright and the sprite lays out at its default
   500x150, wedging a dead band between the header and <main>. */
.glyph-sprite {
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: hidden;
}

.glyph {
  inline-size: var(--s-5);
  block-size: var(--s-5);
  flex: 0 0 auto;
  color: inherit;
}
/* Three of the ten encode a direction — g-video advances, g-voice radiates
   outward, g-key's notch is bitten from the inline-end vertex — so they, and
   ONLY they, mirror in ar/ur/fa/he. The other seven are symmetric or would read
   wrong flipped; a blanket mirror of the sprite is a bug, not a shortcut.
   (The hero's [dir=rtl] .hero__motif flip cannot reach here: separate <svg>.) */
[dir="rtl"] .glyph--dir { transform: scaleX(-1); }

/* ============================================================================
   5. SHARED COMPONENTS (chrome + legal/404 pages)
   The homepage layer is section 7. Everything here is used by legal/*.html,
   404.html or shell.js as well as (or instead of) index.html.
   ========================================================================== */

/* ── 5.1 Buttons ── */
.btn {
  --_bg: var(--c-surface-3);
  --_fg: var(--c-text);
  --_bd: var(--c-border-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-block-size: var(--tap);
  padding-inline: var(--s-5);
  padding-block: var(--s-2);
  border: 1px solid var(--_bd);
  border-radius: var(--r-md);
  background: var(--_bg);
  color: var(--_fg);
  font-weight: var(--fw-semi);
  font-size: var(--t-body);
  line-height: 1.1;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:hover { background: color-mix(in srgb, var(--_bg) 86%, var(--c-text)); color: var(--_fg); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  pointer-events: none;
}
.btn[aria-busy="true"] { cursor: progress; }

.btn--primary {
  --_bg: var(--c-accent);
  --_fg: var(--c-accent-ink);
  --_bd: transparent;
}
.btn--primary:hover { --_bg: var(--c-accent-hover); background: var(--_bg); }
.btn--primary:active { --_bg: var(--c-accent-press); }

.btn--ghost {
  --_bg: transparent;
  --_fg: var(--c-text);
  --_bd: var(--c-border-strong);
}
.btn--sm { min-block-size: var(--tap); padding-inline: var(--s-4); font-size: var(--t-sm); }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: var(--tap);
  min-block-size: var(--tap);
  padding: var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-text-2);
  cursor: pointer;
}
.icon-btn:hover { background: var(--c-surface-3); color: var(--c-text); }
.icon-btn svg { inline-size: 20px; block-size: 20px; }

/* ── 5.2 Alert / notice (legal banners) ── */
.alert {
  display: flex;
  gap: var(--s-3);
  margin-block-end: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  border: 1px solid var(--c-border);
  border-inline-start-width: 4px;
  background: var(--c-surface);
  color: var(--c-text);
}
.alert--info    { border-inline-start-color: var(--c-info); background: var(--c-info-soft); }
.alert--warn    { border-inline-start-color: var(--c-warn); background: var(--c-warn-soft); }
.alert--error   { border-inline-start-color: var(--c-down); background: var(--c-down-soft); }
.alert--success { border-inline-start-color: var(--c-up);   background: var(--c-up-soft); }

/* ── 5.3 Toast ── */
.toast-region {
  position: fixed;
  inset-block-end: var(--s-4);
  inset-inline-end: var(--s-4);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  max-inline-size: min(360px, calc(100vw - var(--s-6)));
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  background: var(--c-surface-2);
  color: var(--c-text);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
  font-size: var(--t-sm);
  animation: af-toast-in var(--dur-slow) var(--ease);
}
.toast--success { border-inline-start: 4px solid var(--c-up); }
.toast--error   { border-inline-start: 4px solid var(--c-down); }
.toast__close {
  margin-inline-start: auto;
  background: none; border: 0; cursor: pointer;
  color: var(--c-text-3); min-inline-size: 28px; min-block-size: 28px;
}
.toast__close:hover { color: var(--c-text); }
@keyframes af-toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── 5.4 Language switcher ── */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.lang-switch select {
  min-block-size: var(--tap);
  /* A bare <select> sizes to its LONGEST option, so "Bahasa Indonesia" drove a
     180px track in every locale, including English. The dropdown list itself is
     UA-rendered and stays full-width, so nothing becomes unreadable. */
  max-inline-size: 7rem;
  text-overflow: ellipsis;
  padding-inline: var(--s-3);
  padding-block: var(--s-1);
  background: var(--c-surface-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  color: var(--c-text);
  cursor: pointer;
}
.lang-switch select:hover { border-color: var(--c-border-strong); }

/* ── 5.5 Prose (legal pages) ── */
.prose { max-inline-size: 70ch; }
.prose h2 { margin-block-start: var(--s-6); }
.prose h3 { margin-block-start: var(--s-5); }
.prose p, .prose li { color: var(--c-text-2); }
.prose .alert p { margin: 0; color: var(--c-text); }
.prose__toc {
  font-size: var(--t-sm);
  color: var(--c-text-3);
}

/* ── 5.6 Not-found (404) page ── */
.notfound {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: var(--s-3);
  min-block-size: 50vh;
  text-align: center;
}
.notfound__code {
  font-size: var(--t-display);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  color: var(--c-accent);
  margin: 0;
}
.notfound__cta { justify-content: center; margin-block-start: var(--s-4); }

/* ============================================================================
   6. RESPONSIVE (shared chrome)
   The ONE remaining max-width query in this file is PRE-EXISTING and lives
   here. It is the last of the desktop-first residue the mobile-first audit
   flagged — the other was the nav disclosure's @media (max-width: 720px), now
   restructured into a mobile-first base + min-width enhancement (section 3).
   No new work may add one (design-plan constraint 4 — enhance upward only).
   This block's .panel / .card / .step padding overrides were deleted with their
   components in MOVE 5; only the shell and the footer nav remain.
   ========================================================================== */
@media (max-width: 600px) {
  main.shell { padding-block: var(--s-5) var(--s-7); }
  .ft__nav { margin-inline-start: 0; flex-basis: 100%; }
}

/* ============================================================================
   7. HOMEPAGE (redesign) — MOBILE-FIRST
   Additive component layer for index.html. Base rules target small screens;
   min-width media queries enhance upward. Everything styles through tokens and
   logical properties, so RTL + both themes come for free. The hero motif is the
   single deliberate motion moment and is frozen under prefers-reduced-motion.
   ========================================================================== */

/* ── 7.0 Shared section eyebrow (uppercase label above a section title) ── */
.section__eyebrow {
  margin: 0 0 var(--s-2);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--c-accent);
}

/* ── 7.1 Hero — the signature ────────────────────────────────────────────────
   This is the ONE hero layer. There used to be two (a base .hero in §5.9 and a
   redesign .hero here) fighting over gap/padding/align-items with identical
   specificity, so source order silently decided the winner and half of §5.9 was
   dead. §5.9 is gone; everything hero lives here.

   The composition: the refraction motif is not a picture beside the copy, it is
   the ground the copy sits on. It is present at 360px — that is the whole point
   — and gains presence upward. The type never gets weaker to pay for it; the
   motif does (blur + opacity + a fan that starts BELOW the headline).

   Geometry contract, do not break it casually:
     .hero__stage is a 2-row grid. Row 1 holds .hero__motif and .hero__content
     in the SAME cell, so the motif's box is exactly the copy block and its
     bottom edge is exactly the top edge of .hero__formats. Row 2 is
     .hero__formats, whose border-block-start IS the surface the rays land on.
     There is no row gap — the air above the rule is .hero__content's
     padding-block-end, so it stays inside the motif's box.

     In the motif's viewBox (0 0 400 480): the fan apex is (250,214) = 62.5%
     44.583%, and the facet's top vertex is (250,54) = 62.5% 11.25%. The facet
     element is anchored to the apex by translate(-50%,-100%) and is exactly
     33.333% (=160/480) tall, which is what makes the beam land on its top
     vertex at any box size. Four numbers move together: this block-size, the
     beam's x2/y2 in index.html, the facet's own viewBox, and its aspect-ratio.
   ────────────────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  /* Full-bleed: cancel the shell's inline padding, re-apply it inside. The
     motif then runs to the viewport edge on a phone, and overflow-x: clip
     contains the beam's overhang so the body never scrolls sideways. */
  margin-inline: calc(var(--s-4) * -1);
  padding-inline: var(--s-4);
  padding-block: var(--s-7) var(--s-6);
  overflow-x: clip;
  display: grid;
  gap: var(--s-5);
}

.hero__stage { position: relative; display: grid; }

.hero__content {
  grid-area: 1 / 1;
  position: relative;
  z-index: 1;                    /* over the motif — both are positioned */
  display: grid;
  gap: var(--s-4);
  min-inline-size: 0;
  padding-block-end: var(--s-6); /* the air above the landing rule */
}

.hero__eyebrow {
  margin: 0;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--c-accent);
}
.hero__title {
  margin: 0;
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);   /* large sizes only — never at body size */
  font-weight: var(--fw-bold);
  max-inline-size: 18ch;
}
.hero__subtitle {
  margin: 0;
  font-size: var(--t-h4);
  font-weight: var(--fw-reg);          /* the jump away from --fw-bold above */
  line-height: var(--lh-body);
  color: var(--c-text-2);
  max-inline-size: var(--measure);
}
/* .hero__ctas is the sole owner of the CTA row now — the old .hero__cta class
   carried the flex and .hero__ctas only the margin, on the same element. */
.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-block-start: var(--s-2);
}

/* The landing edge. ONE element, ONE string (45 locales) — the rays point at it
   rather than into it, so nothing here depends on word count or word order. */
.hero__formats {
  grid-area: 2 / 1;
  margin: 0;
  padding-block-start: var(--s-3);
  border-block-start: 1px solid var(--c-border);
  font-family: var(--font-formats);    /* these are data: five named formats */
  font-size: var(--t-sm);              /* .caps ships --t-xs; too quiet for the payoff line */
  letter-spacing: var(--ls-formats);
  word-spacing: var(--ws-formats);
  color: var(--c-text-2);              /* AA+ in both themes, over the motif too */
}

/* Not a flex row: as one, flex-wrap stranded the ◆ alone on line 1 with the
   text wrapping beneath it. It is a mark on a sentence, so it flows inline. */
.hero__trustline {
  margin: 0;
  color: var(--c-text-3);
  font-size: var(--t-sm);
  line-height: var(--lh-body);
}
.hero__trustline .brand__mark { margin-inline-end: var(--s-1); }

/* ── The motif ──────────────────────────────────────────────────────────────
   One layer, not three: the old .hero::before wash and the old .hero__aura
   blurred circle were separate boxes stacked at z-index:-1 in the same place.
   Both are folded into this element's background, centred on the facet. */
.hero__motif {
  grid-area: 1 / 1;
  position: relative;
  z-index: 0;
  pointer-events: none;
  margin-inline: calc(var(--s-4) * -1);  /* out to the hero's bled edges */
  /* ONE aura, centred on the facet. Its extent is deliberately arithmetic: the
     last stop (72%) x the radius (46%/48%) must not reach any edge from the
     centre (62.5% 36%), or the gradient gets cut by the box and the "ambient"
     glow becomes a visible rectangle. Left 29.5 / right 95.5 / top 1.4 /
     bottom 70.6 — all inside. Move the centre and you must redo this. */
  background: radial-gradient(46% 48% at 62.5% 36%,
    color-mix(in srgb, var(--c-accent-2) 20%, transparent) 0%,
    color-mix(in srgb, var(--c-accent) 9%, transparent) 46%,
    transparent 72%);
}
/* The drawing is authored LTR (dir="ltr" on the element). Mirroring the whole
   layer — SVG, facet and termini together — keeps the beam reading input →
   output in ar/ur/fa/he, and no text lives inside it to come out backwards. */
[dir="rtl"] .hero__motif { transform: scaleX(-1); }

/* Rays + beam. Stretched to the box (preserveAspectRatio="none") — straight
   lines stay straight under any aspect, the fan just opens wider on desktop.
   non-scaling-stroke keeps the weight honest. Blurred and dimmed because they
   cross the subtitle: this is the decoration earning its contrast, not the type
   giving any up. */
.facet-motif {
  position: absolute;              /* contributes no height: the row is the copy */
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
  filter: blur(1px);               /* strokes read as light, not as a diagram */
}
/* Stop colours come from the tokens, so both themes and any future palette
   change are free. stop-color/stop-opacity are real CSS properties — this is
   the only way to keep the gradient tokenized (a var() in a presentation
   attribute would not resolve). */
.fm-grad--a stop, .fm-grad--in stop, .fm-grad--gem stop { stop-color: var(--c-accent); }
.fm-grad--b stop                                        { stop-color: var(--c-accent-2); }
/* Every stop-opacity below is a MEASURED contrast budget, not a taste call.
   Ceilings, from rendered pixels (worst case = a stroke join, which doubles
   coverage, so the budgets are set ~25% under the arithmetic limit):
     behind .hero__subtitle / .hero__eyebrow (4.5:1 floor) -> accent alpha <= .35 / .22
     behind .hero__title    (>=24px bold, 3.0:1 floor)     -> accent alpha <= .70
   Raise any of these and re-run the contrast probe; do not raise them by eye. */
/* Rays: apex -> landing edge. */
.fm-stop--0 { stop-opacity: 0; }    /* at the apex: nothing. No convergence hotspot. */
.fm-stop--1 { stop-opacity: .30; }  /* crossing the subtitle: barely there */
.fm-stop--2 { stop-opacity: 1; }    /* on the rule: full. The light arrives. */
/* Beam: arrives quietly past the eyebrow, brightest over the headline, spent. */
.fm-stop--in0 { stop-opacity: .10; }
.fm-stop--in1 { stop-opacity: .15; }
.fm-stop--in2 { stop-opacity: .45; }
.fm-stop--in3 { stop-opacity: .10; }
/* Facet: top -> bottom vertex. */
.fm-stop--g0 { stop-opacity: .55; }
.fm-stop--g1 { stop-opacity: .38; }
.fm-stop--g2 { stop-opacity: .04; }

.facet-motif__in {
  /* stroke (the paint server) is a presentation attribute in index.html, NOT a
     declaration here: url(#id) inside an external stylesheet resolves against
     the STYLESHEET's URL in some engines, which silently kills the gradient.
     The colours still come from the tokens, via the stop rules above. */
  stroke-width: 2;
  stroke-linecap: round;
}
.facet-motif .ray {
  stroke-width: 2;
  stroke-linecap: round;
  fill: none;
  opacity: .55;                    /* == the 100% keyframe: the reduced-motion resting value */
  animation: facet-shimmer 5.5s var(--ease) infinite;
}

/* The facet. Anchored by its bottom vertex to the fan's apex; 128/480 of the
   box tall, so its top vertex is always exactly where the beam arrives. */
.facet-motif__facet {
  position: absolute;
  inset-inline-start: 62.5%;       /* apex x */
  inset-block-start: 44.583%;      /* apex y = 214/480 */
  block-size: 33.333%;             /* = 160/480 */
  inline-size: auto;
  aspect-ratio: 11 / 16;           /* the gem's own 44:64 profile */
  transform: translate(-50%, -100%);
  overflow: visible;
  opacity: .85;                    /* the stop-opacities above carry the budget */
}
.facet-motif__gem {
  fill: color-mix(in srgb, var(--c-accent-2) 7%, transparent);
  stroke-width: 2;              /* paint server: see .facet-motif__in */
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.facet-motif__cut {
  fill: none;
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

/* Ray termini. Nothing crosses them, so they are the one crisp thing in the
   motif — the composition resolves ON the formats line. Straddling the rule is
   the point: the light pools where the names are. */
.facet-motif__nodes { position: absolute; inset: 0; }
.facet-motif__nodes .node {
  position: absolute;
  inset-block-end: 0;
  inline-size: 8px;
  block-size: 12px;                /* the seed rhombus, taller than wide */
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  transform: translate(-50%, 50%);
  background: currentColor;
  /* clip-path would eat a box-shadow; drop-shadow is applied to the clipped
     result, so the node pools light onto the rule instead of sitting on it. */
  filter: drop-shadow(0 0 5px color-mix(in srgb, currentColor 70%, transparent));
  opacity: .55;                    /* == the 100% keyframe (see above) */
  animation: facet-shimmer 5.5s var(--ease) infinite;
}
/* x = the ray termini, as a fraction of the viewBox width (8/106/204/302/392 of 400) */
.facet-motif__nodes .node--1 { inset-inline-start:  2%;   color: var(--c-accent); }
.facet-motif__nodes .node--2 { inset-inline-start: 26.5%; color: var(--c-accent-2); }
.facet-motif__nodes .node--3 { inset-inline-start: 51%;   color: var(--c-accent); }
.facet-motif__nodes .node--4 { inset-inline-start: 75.5%; color: var(--c-accent-2); }
.facet-motif__nodes .node--5 { inset-inline-start: 98%;   color: var(--c-accent); }

.facet-motif .ray--1, .facet-motif__nodes .node--1 { animation-delay: 0s; }
.facet-motif .ray--2, .facet-motif__nodes .node--2 { animation-delay: .5s; }
.facet-motif .ray--3, .facet-motif__nodes .node--3 { animation-delay: 1s; }
.facet-motif .ray--4, .facet-motif__nodes .node--4 { animation-delay: 1.5s; }
.facet-motif .ray--5, .facet-motif__nodes .node--5 { animation-delay: 2s; }

/* The page's one motion moment: slow, ambient, non-looping-looking. 100% is the
   RESTING value and must equal the static opacity declared above — the
   reduced-motion guard (§2) collapses the duration and drops fill-mode, so the
   element lands back on that static value. Freeze-frame correctness lives here. */
@keyframes facet-shimmer {
  0%   { opacity: .35; }
  50%  { opacity: .85; }
  100% { opacity: .55; }   /* resting value the reduced-motion guard freezes to */
}

/* ── 7.2 Creative capabilities — FACET-CUT CARDS ─────────────────────────────
   Texture 1 of 3: six parallel, browsable things. They stay cards, because that
   is what six parallel browsable things are — but the box is CUT, not rounded.
   The gradient rail that used to sit on top is gone: an accent bar across a
   rounded card is the single most generic device available, and it was doing
   the gem's job badly.

   How the hairline survives the cut. clip-path takes the border with it — a
   `border: 1px` under a clip is simply sliced away on the diagonal, which is
   the one edge that has to look deliberate. So the card is drawn as two clipped
   layers instead: the element's own background IS the hairline, and ::before is
   the surface inset by 1px and clipped to the same polygon. The 1px that shows
   through traces the whole outline, cut face included — the diagonal reads as a
   polished facet rather than a mistake.

   ::before is absolutely positioned, so it would paint over the card's in-flow
   content; `.cap > *` are given position:relative to join the same paint layer,
   where DOM order puts them on top. No z-index, no stacking context.

   clip-path also eats a box-shadow, which is why there is none — and that is
   the right answer anyway: the page gets quieter to pay for the hero.
   The cut depth and its RTL mirror both live in tokens.css (--cut/--clip-facet);
   this file writes one declaration and direction is free. ─────────────────── */
.cap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--s-4);
  margin: 0;
  padding: 0;
  list-style: none;
}
.cap {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--s-5);
  background: var(--c-border);       /* the hairline, seen through ::before's inset */
  clip-path: var(--clip-facet);
  transition: transform var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.cap::before {
  content: "";
  position: absolute;
  inset: 1px;
  clip-path: var(--clip-facet);
  background: var(--c-surface);
}
.cap > * { position: relative; }     /* over ::before, by DOM order alone */
.cap:hover {
  transform: translateY(-3px);
  background: var(--c-border-strong);  /* the cut edge catches the light */
}
.cap__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 48px; block-size: 48px;
  margin-block-end: var(--s-3);
  clip-path: var(--clip-facet);      /* the same cut, one order of magnitude down */
  background: var(--grad-facet-soft);
  color: var(--c-accent);            /* the .glyph's currentColor — see §4 */
}
.cap__title { margin: 0 0 var(--s-1); font-size: var(--t-h4); }
/* Demoted from an uppercase accent label to quiet meta (MOVE 4: the page had
   four competing uppercase devices). These strings are lists of formats —
   "Stills · Series · Storyboards" — i.e. DATA, so they take --font-num and the
   muted floor. The .caps class was removed from the markup: .cap__tag never
   declared text-transform, so restyling here alone could not have demoted it. */
.cap__tag {
  margin: 0 0 var(--s-3);
  color: var(--c-text-3);
  font-family: var(--font-num);
  font-size: var(--t-xs);
  font-weight: var(--fw-reg);
  line-height: var(--lh-tight);
}
.cap__body { margin: 0; color: var(--c-text-2); font-size: var(--t-sm); }

/* ── 7.3 Flow (how teams work) — THE BEAM PATH ───────────────────────────────
   Texture 2 of 3: four steps that are a real SEQUENCE (brief → produce → refine
   → ship), so they are not cards. Four boxes in a row assert an order that only
   their reading direction actually carries; a rail SHOWS it. The rail is the
   hero's beam continued into the page — one line, four termini, cut from the
   same rhombus as the hero's ray nodes and alternating accent / accent-2 on the
   same 1-3-5 / 2-4 rhythm.

   The numbers stay (the sequence is true information) but they stop being a
   counter badge asserting what the rail already shows: they are now quiet
   tabular meta above each title, in --font-num, per MOVE 4's rule that
   --font-num is reserved for things that are DATA.

   i18n: the counter lives on .flow__title::before. A PSEUDO-element is not a
   DOM child, so it survives i18n.js's `el.textContent = t(key)` wipe — putting
   a <span> in there instead would be deleted the moment i18n boots. The digits
   are also direction-isolated: 01 must not reorder in ar/ur/fa/he.

   Rail geometry, one number in two places: the node is 11px wide, flush to the
   inline-start edge, so its centre sits at 5.5px and the 1px rail sits at 5px.
   Node block-start is 5px with a 15px node → centre y 12.5px, which is where
   the first step's rail begins and the last step's rail ends, so the beam
   terminates ON the outer nodes instead of overshooting into space.
   ────────────────────────────────────────────────────────────────────────── */
.flow {
  counter-reset: flow;
  display: grid;
  gap: 0;                       /* the rail is continuous: the steps butt together */
  margin: 0;                    /* rhythm belongs to .ship (single writer) */
  padding: 0;
  list-style: none;
}
.flow__step {
  counter-increment: flow;
  position: relative;
  padding-inline-start: var(--s-6);   /* the rail's channel */
  padding-block-end: var(--s-5);
}
.flow__step:last-child { padding-block-end: 0; }
/* the rail */
.flow__step::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 5px;
  inline-size: 1px;
  background: var(--c-border-strong);
}
.flow__step:first-child::before { inset-block-start: 12.5px; }
.flow__step:last-child::before  { inset-block-end: auto; block-size: 12.5px; }
/* the node */
.flow__step::after {
  content: "";
  position: absolute;
  inset-block-start: 5px;
  inset-inline-start: 0;
  inline-size: 11px; block-size: 15px;   /* the seed rhombus: taller than wide */
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  background: var(--c-accent);
}
.flow__step:nth-child(even)::after { background: var(--c-accent-2); }
.flow__title { margin: 0 0 var(--s-2); font-size: var(--t-h4); }
.flow__title::before {
  content: counter(flow, decimal-leading-zero);
  display: block;
  margin-block-end: var(--s-1);
  font-family: var(--font-num);
  font-size: var(--t-xs);
  font-weight: var(--fw-reg);
  letter-spacing: var(--ls-caps);
  color: var(--c-text-3);
  direction: ltr;               /* .num semantics: digits never reorder under RTL */
  unicode-bidi: isolate;
}
.flow__body { margin: 0; color: var(--c-text-2); font-size: var(--t-sm); max-inline-size: var(--measure); }

/* ── 7.4 "What teams ship" list — where the beam lands ── */
.ship {
  margin-block-start: var(--s-block);
  padding-block-start: var(--s-block);
  border-block-start: 1px solid var(--c-border);
}
.ship__label { margin: 0 0 var(--s-4); color: var(--c-accent); }
.ship__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ship__item {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  font-size: var(--t-h4);
  color: var(--c-text);
}
.ship__mark { flex: 0 0 auto; color: var(--c-accent); line-height: 1.4; }

/* ── 7.5 Trust & GDPR — THE SPEC LIST ────────────────────────────────────────
   Texture 3 of 3: six assurances. Assurances are a FACT SHEET, so this reads
   like one — hairline-divided rows, no surface, no border box, no radius and
   no shadow. It is the lightest thing on the page on purpose: it is the third
   texture, and it is also where the page proves it is not just more boxes.

   The rows are ruled top-and-bottom by the grid's own border-block-end plus a
   border-block-start per row, so the sheet closes cleanly at both ends without
   a divider hanging off the last item.

   Structure survives: still <ul>/<li>, still an unkeyed aria-hidden glyph
   sibling, and .pillar__title is still an <h3> — flattening these to <dt>/<dd>
   would have dropped six headings out of the AT outline.

   From 720px the row becomes a true spec line: mark | fact | detail, the title
   column fixed so the six facts stack into a readable column of labels.
   ────────────────────────────────────────────────────────────────────────── */
.pillar-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: 0 0 var(--s-block);
  padding: 0;
  list-style: none;
  border-block-end: 1px solid var(--c-border);
}
.pillar {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--s-3);
  padding-block: var(--s-4);
  border-block-start: 1px solid var(--c-border);
}
.pillar__glyph {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 24px; block-size: 24px;
  color: var(--c-accent);
  /* Still live: p1 (◆) and p5 (✓) are CHARACTERS, not emoji — core-font
     geometric shapes that the plan keeps as the brand mark. The other four
     pillars carry a .glyph <svg>, which ignores font-size. */
  font-size: 1rem;
  line-height: 1;
}
.pillar__title {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  font-size: var(--t-body);
  font-weight: var(--fw-semi);
}
.pillar__body {
  grid-column: 2;
  margin: var(--s-1) 0 0;
  color: var(--c-text-2);
  font-size: var(--t-sm);
  font-weight: var(--fw-reg);
  max-inline-size: var(--measure);
}

/* ── 7.6 Closing CTA band ─────────────────────────────────────────────────────
   Cut like a .cap and built the same way (hairline background + 1px-inset
   clipped ::before), so the page closes on the geometry it opened with. The
   drop shadow is gone — same reason as everywhere else in this layer.

   NO margin-block-start: #security's .section margin is the single writer of
   the gap above this band. The two used to declare --s-8 at each other and
   collapse, which is precisely why swapping one of them for a fluid token would
   have measured as "nothing happened".

   clip-path clips a focus ring, and this band DOES contain focusable elements —
   the two CTAs. They are centred inside --s-7 of padding, so the ring is
   nowhere near the cut. Do not shrink that padding to less than the cut depth.
   ────────────────────────────────────────────────────────────────────────── */
.cta-band {
  position: relative;
  margin-block-start: 0;
  background: var(--c-border);       /* the hairline */
  clip-path: var(--clip-facet);
}
.cta-band::before {
  content: "";
  position: absolute;
  inset: 1px;
  clip-path: var(--clip-facet);
  background: var(--grad-facet-soft), var(--c-surface);
  pointer-events: none;
}
.cta-band__inner {
  position: relative;
  display: grid;
  gap: var(--s-4);
  justify-items: center;
  text-align: center;
  max-inline-size: 60ch;
  margin-inline: auto;
  padding: var(--s-7) var(--s-5);
}
.cta-band__title { margin: 0; font-size: var(--t-h1); }
.cta-band__body {
  margin: 0;
  max-inline-size: 52ch;
  color: var(--c-text-2);
  font-size: var(--t-h4);
}
.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3);
  margin-block-start: var(--s-2);
}
/* NOT --c-text-3, and not by taste. --c-text-3 is the muted FLOOR, calibrated
   against --c-bg (6.2:1 dark / 5.1:1 light) with no headroom to spare. This
   note does not sit on --c-bg: it sits on the band's facet wash, which lifts
   the background and drops the note to 4.14:1 dark / 4.28:1 light at 12px —
   under AA in BOTH themes. Measured, not eyeballed. --c-text-2 restores it to
   6.6:1 / 7.1:1 and is still visibly quiet. The same trap applies to anything
   else placed on this band: the floor tokens assume the page ground. */
.cta-band__note { margin: 0; color: var(--c-text-2); }

/* ── 7.7 Large button (hero + CTA emphasis) ── */
.btn--lg {
  min-block-size: 52px;
  padding-inline: var(--s-6);
  font-size: var(--t-h4);
}

/* ── 7.8 Homepage responsive enhancements (min-width, mobile-first) ──────────
   Blocks are ordered ASCENDING by breakpoint. Media queries carry no
   specificity, so where two blocks touch the same selector the later one wins
   — .cap-grid is set at 560 and again at 900, and it only lands on 3 columns
   because 900 comes second. Keep this list sorted or that stops being true. */

/* Six is 2×3 or 3×2, never 4+2. auto-fit was picking 4 columns at 1280 and
   stranding two orphans on a second row — an accident of the track size, not a
   composition. The count is known and fixed, so state it. */
@media (min-width: 560px) {
  .cap-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 700px) {
  .ship__list { grid-template-columns: repeat(2, 1fr); gap: var(--s-3) var(--s-5); }
  .cta-band__inner { padding: var(--s-8) var(--s-6); }
}
/* The spec sheet becomes a real spec line: mark | fact | detail. */
@media (min-width: 720px) {
  .pillar {
    grid-template-columns: auto minmax(12rem, 16rem) 1fr;
    column-gap: var(--s-5);
    padding-block: var(--s-4);
  }
  .pillar__title { grid-column: 2; grid-row: 1; }
  .pillar__body  { grid-column: 3; grid-row: 1; margin: 0; }
}
/* The beam turns the corner: the rail runs inline instead of block. Same node,
   same 5.5px centre — only the axis changes. Each step's rail bridges its own
   column AND the gap to the next node, hence the negative inline-end inset; the
   last step has no next node, so no rail. The mobile :first/:last-child rules
   are (0,2,0) and would outrank a bare .flow__step::before here, so they are
   re-stated in the group rather than left to fight it. */
@media (min-width: 900px) {
  .cap-grid { grid-template-columns: repeat(3, 1fr); }
  .flow {
    grid-template-columns: repeat(4, 1fr);
    column-gap: var(--s-5);
  }
  .flow__step {
    padding-inline-start: 0;
    padding-block: var(--s-5) 0;      /* the rail's channel, overhead */
  }
  .flow__step::before,
  .flow__step:first-child::before,
  .flow__step:last-child::before {
    inset-block: 12px auto;
    block-size: 1px;
    inset-inline-start: 5.5px;
    inset-inline-end: calc(-1 * var(--s-5) - 5.5px);
    inline-size: auto;
  }
  .flow__step:last-child::before { content: none; }
  .flow__step::after { inset-block-start: 5px; }
}
@media (min-width: 900px) {
  /* The hero gains presence rather than changing shape: same one-column
     composition, more room. The stage is capped so the fan cannot splay across
     a 1200px shell and land its outer rays on bare rule — the motif and the
     formats line keep the same edges at every width. */
  .hero { padding-block: var(--s-9) var(--s-8); }
  .hero__stage { max-inline-size: 40rem; }
  .hero__content { gap: var(--s-5); padding-block-end: var(--s-7); }
  /* Tracked and spaced out so the five names occupy most of the rule they sit
     under — the termini then read into the words, not past them. The tracking
     itself rides --ls-formats/--ws-formats, which tokens.css steps up at this
     same 900px boundary and zeroes for cursive scripts. */
  .hero__formats {
    font-size: var(--t-h4);
    color: var(--c-text);
  }
  .facet-motif__facet { opacity: .92; }  /* more air to read over */
  .facet-motif__nodes .node { inline-size: 10px; block-size: 15px; }
}
