:root {
    --landing-bg-light-top: hsl(0 0% 100% / 0.98);
    --landing-bg-light-mid: hsl(230 100% 99% / 0.96);
    --landing-bg-light-bottom: hsl(220 33% 97% / 0.92);
    --landing-bg-dark-top: hsl(222 47% 11% / 0.98);
    --landing-bg-dark-mid: hsl(224 71% 4% / 0.96);
    --landing-bg-dark-bottom: hsl(222 47% 11% / 0.92);
    --landing-grid-light: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.08);
    --landing-grid-dark-primary: hsl(234 89% 74% / 0.10);
    --landing-grid-dark-secondary: hsl(199 89% 48% / 0.08);
    --landing-ribbon-brand-strong: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.18);
    --landing-ribbon-brand: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.10);
    --landing-ribbon-blue: hsl(217 91% 60% / 0.08);
    --landing-ribbon-sky: hsl(199 89% 48% / 0.10);
    --landing-ribbon-dark-strong: hsl(234 89% 74% / 0.24);
    --landing-ribbon-dark: hsl(234 89% 74% / 0.12);
    --landing-ribbon-dark-blue: hsl(199 89% 48% / 0.10);
    --landing-ribbon-teal: hsl(174 72% 56% / 0.10);
    --landing-clear-light: hsl(0 0% 100% / 0);
    --landing-clear-dark: hsl(222 47% 11% / 0);
    --landing-glow-brand-strong: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.16);
    --landing-glow-brand: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.08);
    --landing-glow-brand-soft: hsl(var(--brand-h) var(--brand-s) var(--brand-l) / 0.04);
    --landing-glow-blue: hsl(217 91% 60% / 0.05);
    --landing-glow-dark-strong: hsl(234 89% 74% / 0.22);
    --landing-glow-dark: hsl(234 89% 74% / 0.10);
    --landing-glow-dark-blue: hsl(199 89% 48% / 0.08);
    --landing-fade-light-top: hsl(0 0% 100% / 0.42);
    --landing-fade-light-bottom: hsl(0 0% 100% / 0.18);
    --landing-fade-dark-top: hsl(222 47% 11% / 0.18);
    --landing-fade-dark-bottom: hsl(222 47% 11% / 0.08);
    --landing-frame-ring: hsl(0 0% 0% / 0.06);
    --landing-frame-shadow-soft: hsl(0 0% 0% / 0.04);
    --landing-frame-shadow: hsl(0 0% 0% / 0.08);
    --landing-frame-ring-dark: hsl(0 0% 100% / 0.08);
    --landing-frame-shadow-dark-soft: hsl(0 0% 0% / 0.20);
    --landing-frame-shadow-dark: hsl(0 0% 0% / 0.45);
    --landing-card-shadow-soft: hsl(222 47% 11% / 0.04);
    --landing-card-shadow-deep: hsl(222 47% 11% / 0.06);
}

/* Hero background — layered motion, but restrained enough to stay behind the content */
.hero-bg {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    background:
        linear-gradient(180deg, var(--landing-bg-light-top) 0%, var(--landing-bg-light-mid) 58%, var(--landing-bg-light-bottom) 100%);
}
.dark .hero-bg {
    background:
        linear-gradient(180deg, var(--landing-bg-dark-top) 0%, var(--landing-bg-dark-mid) 58%, var(--landing-bg-dark-bottom) 100%);
}
.hero-bg__layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
}
/* Stripe-inspired structural grid, faded so it reads as depth, not texture */
.hero-bg__grid {
    position: absolute;
    inset: 2rem -8% auto;
    height: 36rem;
    background-image:
        linear-gradient(var(--landing-grid-light) 1px, transparent 1px),
        linear-gradient(90deg, var(--landing-grid-light) 1px, transparent 1px);
    background-size: 120px 120px;
    opacity: 0.34;
    transform: perspective(1200px) rotateX(77deg) translateY(-6%);
    transform-origin: top center;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 16%, black 74%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, black 16%, black 74%, transparent 100%);
}
.dark .hero-bg__grid {
    background-image:
        linear-gradient(var(--landing-grid-dark-primary) 1px, transparent 1px),
        linear-gradient(90deg, var(--landing-grid-dark-secondary) 1px, transparent 1px);
    opacity: 0.26;
}
/* Large color ribbons create motion without pulling focus from the headline */
.hero-bg__ribbon {
    position: absolute;
    border-radius: 3rem;
    will-change: transform, opacity;
}
.hero-bg__ribbon--primary {
    top: 4rem;
    right: -10%;
    width: min(60vw, 56rem);
    height: 22rem;
    background: linear-gradient(135deg,
        var(--landing-ribbon-brand-strong) 0%,
        var(--landing-ribbon-brand) 24%,
        var(--landing-ribbon-blue) 58%,
        var(--landing-clear-light) 88%);
    opacity: 0.9;
    transform: rotate(-16deg);
    animation: hero-ribbon-float 24s cubic-bezier(0.45, 0, 0.2, 1) infinite alternate;
}
.hero-bg__ribbon--secondary {
    left: -12%;
    bottom: 2rem;
    width: min(42vw, 34rem);
    height: 16rem;
    background: linear-gradient(135deg,
        var(--landing-ribbon-sky) 0%,
        var(--landing-glow-brand) 42%,
        var(--landing-clear-light) 92%);
    opacity: 0.6;
    transform: rotate(18deg);
    animation: hero-ribbon-float-alt 20s cubic-bezier(0.45, 0, 0.2, 1) infinite alternate;
}
.dark .hero-bg__ribbon--primary {
    background: linear-gradient(135deg,
        var(--landing-ribbon-dark-strong) 0%,
        var(--landing-ribbon-dark) 24%,
        var(--landing-ribbon-dark-blue) 58%,
        var(--landing-clear-dark) 88%);
    opacity: 0.72;
}
.dark .hero-bg__ribbon--secondary {
    background: linear-gradient(135deg,
        var(--landing-ribbon-teal) 0%,
        var(--landing-glow-dark) 42%,
        var(--landing-clear-dark) 92%);
    opacity: 0.48;
}
/* Soft blooms keep the section feeling luminous rather than flat */
.hero-bg__glow {
    position: absolute;
    border-radius: 9999px;
    filter: blur(10px);
    will-change: transform, opacity;
}
.hero-bg__glow--right {
    top: 6rem;
    right: 10%;
    width: 30rem;
    height: 24rem;
    background: radial-gradient(circle at center, var(--landing-glow-brand-strong) 0%, var(--landing-glow-brand) 36%, var(--landing-glow-blue) 54%, transparent 76%);
    animation: hero-glow-float 18s cubic-bezier(0.45, 0, 0.2, 1) infinite alternate;
}
.hero-bg__glow--left {
    left: -4rem;
    top: 5rem;
    width: 18rem;
    height: 18rem;
    background: radial-gradient(circle at center, var(--landing-ribbon-brand) 0%, var(--landing-glow-brand-soft) 52%, transparent 78%);
    animation: hero-glow-float-alt 16s cubic-bezier(0.45, 0, 0.2, 1) infinite alternate;
}
.dark .hero-bg__glow--right {
    background: radial-gradient(circle at center, var(--landing-glow-dark-strong) 0%, var(--landing-glow-dark) 36%, var(--landing-glow-dark-blue) 54%, transparent 76%);
}
.dark .hero-bg__glow--left {
    background: radial-gradient(circle at center, var(--landing-ribbon-teal) 0%, var(--landing-glow-dark-blue) 48%, transparent 78%);
}
.hero-bg__fade {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at top, var(--landing-fade-light-top), transparent 46%),
        linear-gradient(180deg, transparent 0%, var(--landing-fade-light-bottom) 100%);
}
.dark .hero-bg__fade {
    background:
        radial-gradient(circle at top, var(--landing-fade-dark-top), transparent 46%),
        linear-gradient(180deg, transparent 0%, var(--landing-fade-dark-bottom) 100%);
}
@keyframes hero-ribbon-float {
    from { transform: rotate(-16deg) translate3d(0, 0, 0) scale(1); }
    to { transform: rotate(-11deg) translate3d(-2%, 4%, 0) scale(1.04); }
}
@keyframes hero-ribbon-float-alt {
    from { transform: rotate(18deg) translate3d(0, 0, 0) scale(1); }
    to { transform: rotate(14deg) translate3d(3%, -5%, 0) scale(1.05); }
}
@keyframes hero-glow-float {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to { transform: translate3d(3%, -4%, 0) scale(1.08); }
}
@keyframes hero-glow-float-alt {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to { transform: translate3d(-2%, 3%, 0) scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
    .hero-bg__ribbon,
    .hero-bg__glow {
        animation: none;
    }
}
/* On small screens the decorative layers overlap readable text — fade them out */
@media (max-width: 639px) {
    .hero-bg .hero-bg__ribbon { opacity: 0.25; }
    .hero-bg .hero-bg__glow { opacity: 0.15; }
    .hero-bg .hero-bg__grid { opacity: 0.15; }
}
/* Screenshot frame — hairline ring only, no elevation lift */
.ss-frame {
    box-shadow: 0 0 0 1px var(--landing-frame-ring);
}
.dark .ss-frame {
    box-shadow: 0 0 0 1px var(--landing-frame-ring-dark);
}
.landing-flag {
    display: inline-block;
    width: 18px;
    height: 13px;
    flex-shrink: 0;
    background-size: cover;
    font-size: 14px;
}
.landing-flag--current {
    width: 20px;
    height: 15px;
    font-size: 16px;
}
.landing-check {
    font-size: 9px;
}
.landing-media-frame {
    aspect-ratio: 800 / 520;
    overflow: hidden;
}
.landing-media-frame img {
    object-fit: contain;
}
/* No elevation shadow — surfaces separate via hairline border on the element. */
.landing-card-shadow {
    box-shadow: none;
}
.dark .landing-card-shadow {
    box-shadow: none;
}
/* Departure-board cascade: badge → h1 → desc slide in from above */
@keyframes heroRowIn {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: translateY(0); }
}
.hero-anim .hero-badge,
.hero-badge.hero-anim { animation: heroRowIn 0.18s ease-out both; }
.hero-anim .hero-h1,
.hero-h1.hero-anim    { animation: heroRowIn 0.22s 0.08s ease-out both; }
.hero-anim .hero-desc,
.hero-desc.hero-anim  { animation: heroRowIn 0.22s 0.18s ease-out both; }
/* Grid stack: all slides share one cell → container height = tallest slide, no overflow */
.hero-slide-stack { display: grid; grid-template-areas: 'stack'; }
.hero-slide-stack > * { grid-area: stack; }
/* Crossfade is a plain CSS transition on Alpine-written opacity. If the tab is
   backgrounded mid-fade the transition snaps to its target — it can never
   strand a slide half-visible the way x-transition's rAF machinery did. */
.hero-slide { transition: opacity 0.45s ease; }
@media (prefers-reduced-motion: reduce) {
    .hero-slide { transition: none; }
}
/* Loading skeleton: a faint shimmer sits BEHIND the slides, so until the
   first screenshot decodes the frame reads "content coming" instead of an
   empty browser mockup (the page's worst first impression on slow links).
   Opaque slide images cover it completely once loaded — no JS needed. */
.hero-slide-stack {
    background:
        linear-gradient(100deg,
            transparent 30%,
            color-mix(in srgb, var(--theme-text) 5%, transparent) 50%,
            transparent 70%)
        var(--theme-bg-secondary);
    background-size: 220% 100%;
    animation: heroSkeleton 1.6s ease-in-out infinite;
}
@keyframes heroSkeleton {
    from { background-position: 120% 0; }
    to   { background-position: -120% 0; }
}
@media (prefers-reduced-motion: reduce) {
    .hero-slide-stack { animation: none; }
}
/* Progress bar sweeps left→right in exactly 5 s (matches auto-advance interval) */
@keyframes heroProgress {
    from { width: 0%; }
    to   { width: 100%; }
}
.hero-progress-run { animation: heroProgress 5s linear forwards; }

/* ── Hero WebGL gradient backdrop (surgical) ──────────────────────────────────
   A low-opacity animated mesh gradient sits BEHIND the hero content (which is
   .relative.z-10). Masked so the colour concentrates top-right and fades to
   clear behind the headline + CTA, keeping dark text fully legible. Paints via
   app/static/js/wm_gradient.js (off-screen-paused, reduced-motion + no-WebGL
   fallback handled there). Decorative → aria-hidden in the markup. */
.landing-hero { position: relative; overflow: hidden; }
.landing-hero-gradient {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    /* Fills the hero instead of hugging the top-right corner — the old tight
       mask left most of the first viewport plain white. Fades off the headline
       column so the display text keeps its contrast.

       That last sentence was the INTENT and not the behaviour. The mask was
       `radial-gradient(145% 135% at 72% 8%, #000 34%, transparent 88%)`: sized at
       145%/135% of the box, the `transparent 88%` stop lands beyond the viewport,
       so the gradient never faded anywhere a reader could see and the headline and
       subhead sat directly on full-strength colour. Sized to the box (100%/100%)
       the stops mean what they say, and the copy column is genuinely calm.

       Text over a multi-hue field has no single contrast ratio — the same reason
       the founding-store badge failed only over a brand tint (docs/BUG_JOURNAL.md).
       The fix is to keep strong colour away from text rather than to hunt for a
       text colour that survives every blob position. */
    opacity: 0.44;
    pointer-events: none;
    -webkit-mask-image: radial-gradient(100% 100% at 82% 6%, #000 6%, transparent 68%);
            mask-image: radial-gradient(100% 100% at 82% 6%, #000 6%, transparent 68%);
}
[data-theme="dark"] .landing-hero-gradient,
.dark .landing-hero-gradient { opacity: 0.42; }

/* ── Closing-zone WebGL gradient (founding stores + final CTA) ────────────────
   Second wm_gradient canvas, one zone behind both closing sections. Masked to
   the RIGHT half — the headline column stays on calm ground while the aurora
   fills the whitespace and backs the CTA button. Same engine: off-screen
   paused, reduced-motion static, WebGL-less fallback handled in JS. */
.landing-cta-zone {
    position: relative;
    isolation: isolate;
    overflow: clip;
    background: var(--theme-bg-secondary);
}
.landing-cta-zone > section { position: relative; z-index: 1; }
.landing-cta-gradient {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    opacity: 0.26;
    pointer-events: none;
    -webkit-mask-image: radial-gradient(130% 150% at 84% 50%, #000 26%, transparent 76%);
            mask-image: radial-gradient(130% 150% at 84% 50%, #000 26%, transparent 76%);
}
[data-theme="dark"] .landing-cta-gradient,
.dark .landing-cta-gradient { opacity: 0.40; }

/* ── "Opening takes about two minutes." — editorial stepper ───────────────────
   The stand-out is structural, not decorative: a display-scale headline with
   the CTA on its baseline, then three columns split by vertical hairlines
   with oversized faint tabular-mono numerals. Printed-spec rhythm — no cards,
   no gradients, no glow. */
.hiw-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3) var(--space-8);
}
.hiw-h {
    margin: 0;
    font-family: var(--font-family-heading);
    font-size: clamp(34px, 4.6vw, 52px);
    font-weight: 740;
    line-height: 1.04;
    letter-spacing: -0.022em;
    color: var(--theme-text);
    max-width: 16ch;
}
.hiw-cta {
    padding-left: 0;
    font-weight: 650;
    white-space: nowrap;
}
.hiw-steps {
    list-style: none;
    margin: var(--space-10) 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
}
.hiw-step { padding: 0; }
.hiw-num {
    display: block;
    margin-top: var(--space-4);
    font-family: var(--font-family-mono);
    font-size: 30px;
    font-weight: 560;
    letter-spacing: 0.04em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--theme-text-tertiary);
}
.hiw-title {
    margin: var(--space-4) 0 0;
    font-size: 17.5px;
    font-weight: 680;
    color: var(--theme-text);
}
.hiw-desc {
    margin: var(--space-2) 0 0;
    font-size: 14.5px;
    line-height: 1.65;
    color: var(--theme-text-secondary);
    max-width: 34ch;
}
@media (min-width: 768px) {
    .hiw-steps { grid-template-columns: repeat(3, 1fr); gap: 0 var(--space-6); }
}
@media (max-width: 767.98px) {
    .hiw-step + .hiw-step { margin-top: var(--space-7, 28px); }
    /* `.hiw-desc`'s 34ch is right for the three-up columns above (301px each, so
       the cap barely binds). Below 768px `.hiw-steps` is a single 1fr column and
       each step becomes the full container width — measured at a 760px viewport,
       the step was 720px and the description still 311px, 43% of it, with ~409px
       empty on each of three steps.

       Same stale-measure shape as the `.lp-*` card copy, and the same rule: a
       tight measure is a tool, but it has to be tied to the width it was chosen
       for. 60ch keeps the line inside the readable 45–75 band rather than letting
       it run the full 720px.

       This lives in the EXISTING max-width block on purpose — it already sits
       below `.hiw-desc`'s base declaration, so the override cannot be defeated by
       source order the way the `.lp-20` one was. */
    .hiw-desc { max-width: 60ch; }
}

/* ── Timeline rail: the stroke-draw trick ─────────────────────────────────────
   Each step's node + line is an SVG stroke with pathLength="1", hidden by
   dashoffset and drawn by transitioning it to 0 — staggered so the rail runs
   left→right (top→bottom when stacked) through the section. The rail also IS
   the divider structure, so the section needs no extra hairlines.
   States: no JS → `.hiw-anim` never lands → everything paints final.
   JS adds `.hiw-anim` at init (arms the hidden state) and `.hiw-inview` when
   the section enters the viewport (plays it). Reduced motion: no transition,
   final state immediately. */
.hiw-rail-wrap { position: relative; }
.hiw-rail {
    display: block;
    width: 100%;
    height: 12px;
    overflow: visible;
}
/* Runner: a brand-colored dot that travels the rail on a loop once the
   stroke-draw has finished — the "something is moving through the process"
   life that a static line can't give. Pure CSS; never exists for no-JS
   (the hidden state is armed by .hiw-anim) or reduced-motion visitors. */
.hiw-runner {
    position: absolute;
    top: 6px;
    left: 16px;
    right: 4px;
    height: 0;
    pointer-events: none;
}
.hiw-runner::before {
    content: "";
    position: absolute;
    top: -2.5px;
    left: 0;
    width: 5px;
    height: 5px;
    border-radius: 999px;
    background: var(--brand-primary);
    /* No residual glow — solid brand dot only (Linear: no elevation/glow lift). */
    box-shadow: none;
    opacity: 0;
}
.hiw.hiw-anim.hiw-inview .hiw-runner::before {
    animation: hiwRunner 3.4s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
}
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(1) .hiw-runner::before { animation-delay: 1.7s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-runner::before { animation-delay: 2.25s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-runner::before { animation-delay: 2.8s; }
@keyframes hiwRunner {
    0%   { left: 0%; opacity: 0; }
    10%  { opacity: 0.9; }
    82%  { opacity: 0.9; }
    96%  { left: calc(100% - 5px); opacity: 0; }
    100% { left: calc(100% - 5px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .hiw.hiw-anim.hiw-inview .hiw-runner::before { animation: none; }
}
.hiw-rail-node {
    fill: transparent;
    stroke: var(--theme-text-tertiary);
    stroke-width: 1.5;
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
}
.hiw-rail-line {
    stroke: color-mix(in srgb, var(--theme-text) 24%, transparent);
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
}
.hiw.hiw-anim .hiw-rail-node,
.hiw.hiw-anim .hiw-rail-line { stroke-dashoffset: 1; }
.hiw.hiw-anim .hiw-num { color: color-mix(in srgb, var(--theme-text-tertiary) 40%, transparent); }
.hiw.hiw-anim.hiw-inview .hiw-rail-node {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 0.4s ease-out;
}
.hiw.hiw-anim.hiw-inview .hiw-rail-line {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 0.65s cubic-bezier(0.3, 0, 0.2, 1) 0.12s;
}
.hiw.hiw-anim.hiw-inview .hiw-num {
    color: var(--theme-text-tertiary);
    transition: color 0.5s ease 0.3s;
}
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-rail-node { transition-delay: 0.55s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-rail-line { transition-delay: 0.67s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-num       { transition-delay: 0.85s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-rail-node { transition-delay: 1.1s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-rail-line { transition-delay: 1.22s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-num       { transition-delay: 1.4s; }
@media (prefers-reduced-motion: reduce) {
    .hiw.hiw-anim .hiw-rail-node,
    .hiw.hiw-anim .hiw-rail-line { stroke-dashoffset: 0; transition: none; }
    .hiw.hiw-anim .hiw-num { color: var(--theme-text-tertiary); transition: none; }
}

/* Step meta row: the numeral and a small mono clock share a baseline. The
   clocks tick 0:00 → 0:40 / 1:20 / 2:00 as each rail arrives — the heading's
   "two minutes" made literal instead of asserted. */
.hiw-step-meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-4);
}
.hiw-step-meta .hiw-num { margin-top: 0; }
.hiw-time {
    font-family: var(--font-family-mono);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.03em;
    font-variant-numeric: tabular-nums;
    color: var(--theme-text-tertiary);
}
/* Step content rises in after its rail draws (same stagger rhythm). */
.hiw.hiw-anim .hiw-time,
.hiw.hiw-anim .hiw-title,
.hiw.hiw-anim .hiw-desc { opacity: 0; transform: translateY(10px); }
.hiw.hiw-anim.hiw-inview .hiw-time,
.hiw.hiw-anim.hiw-inview .hiw-title,
.hiw.hiw-anim.hiw-inview .hiw-desc {
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.45s ease, transform 0.5s cubic-bezier(0.3, 0.7, 0.3, 1);
}
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(1) .hiw-time  { transition-delay: 0.2s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(1) .hiw-title { transition-delay: 0.28s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(1) .hiw-desc  { transition-delay: 0.36s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-time  { transition-delay: 0.75s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-title { transition-delay: 0.83s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(2) .hiw-desc  { transition-delay: 0.91s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-time  { transition-delay: 1.3s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-title { transition-delay: 1.38s; }
.hiw.hiw-anim.hiw-inview .hiw-step:nth-child(3) .hiw-desc  { transition-delay: 1.46s; }
@media (prefers-reduced-motion: reduce) {
    .hiw.hiw-anim .hiw-time,
    .hiw.hiw-anim .hiw-title,
    .hiw.hiw-anim .hiw-desc { opacity: 1; transform: none; transition: none; }
}

/* ── Mock-UI live fill ────────────────────────────────────────────────────────
   The miniature order/delivery/inventory cards play once when scrolled into
   view: bars fill to their --fill target, key numbers count up (JS), status
   rows rise in. Without JS (.mock-anim never lands) everything paints final;
   reduced motion renders final immediately. */
.mock-fill {
    display: block;
    width: var(--fill, 100%);
}
.mock-anim .mock-fill { width: 0; }
.mock-anim.mock-inview .mock-fill {
    width: var(--fill, 100%);
    transition: width 0.9s cubic-bezier(0.25, 0.6, 0.25, 1) var(--fill-delay, 0.15s);
}
.mock-anim .mock-rise { opacity: 0; transform: translateY(8px); }
.mock-anim.mock-inview .mock-rise {
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.45s ease var(--rise-delay, 0s),
        transform 0.5s cubic-bezier(0.3, 0.7, 0.3, 1) var(--rise-delay, 0s);
}
@media (prefers-reduced-motion: reduce) {
    .mock-anim .mock-fill { width: var(--fill, 100%); transition: none; }
    .mock-anim .mock-rise { opacity: 1; transform: none; transition: none; }
}

/* Extracted from repeated inline style= in landing.html (identical CSS). */
.lp-1 { padding: var(--space-6); }
.lp-2 { margin-top: var(--space-3); max-width: 32ch; }
.lp-3 { font-size: 22px; line-height: 1.2; margin-top: var(--space-3); margin-bottom: 0; max-width: 15ch; }

.lp-4 { font-size: 13.5px; font-weight: 600; color: var(--theme-text); }
.lp-5 { background: var(--theme-hover); }
.lp-6 { font-weight: 600; color: var(--theme-text); }
.lp-7 { border-bottom: 1px solid var(--border-subtle); }
.lp-8 { margin-top: var(--space-3); }
.lp-9 { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--theme-bg-secondary); padding: var(--space-4); }
.lp-10 { color: var(--theme-text-secondary); }
.lp-11 { border-bottom: 1px solid var(--border-subtle); background: var(--theme-bg-secondary); }
.lp-12 { background: var(--border-strong); }
.lp-13 { border-top: 1px solid var(--border-subtle); padding-top: var(--space-12); padding-bottom: var(--space-16); margin-top: 0; }
.lp-14 { font-size: 32px; margin-bottom: 0; }
.lp-15 { border-radius: var(--radius-sm); background: var(--theme-card-bg); border: 1px solid var(--border-subtle); padding: 6px 0; }
.lp-16 { color: var(--theme-text); }
.lp-17 { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--theme-card-bg); }
.lp-18 { opacity: 0; }
.lp-19 { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--theme-bg-secondary); }
.lp-20 { font-size: 22px; line-height: 1.2; margin-top: var(--space-3); margin-bottom: 0; max-width: 16ch; }
.lp-21 { color: var(--theme-text-tertiary); }

/* NOTE: this block must stay AFTER every .lp-* declaration above. Placed
   beside .lp-3 it silently did nothing for .lp-20, declared further down:
   equal specificity, later source order wins, so the base 16ch kept
   applying and that headline still used 25% of its card. Exactly the trap
   the .sf-checkout--split comment warns about, made in the same session. */
/* The card copy measures above are tuned for the THREE-UP grid, where each card
   is 336px and 15ch/32ch fill it. They are unconditional, so they stayed put when
   `lg:grid-cols-3` collapses to one column below 1024px and each card becomes the
   full container width. Measured at a 1000px viewport: card 952px, headline 222px
   (23% of the card), description 272px (29%) — 680px of every card sitting empty
   beside a headline broken over two lines.

   A tight measure is a real typographic tool, but 15ch/32ch are far under the
   45–75 characters that read comfortably; they only look deliberate because the
   3-up card happens to be that narrow. So relax them exactly where the card is
   wide and leave the 3-up alone.

   Keyed to the same 1024px breakpoint that drives the grid, so the two cannot
   disagree — the measure depends on the CARD's width, and below `lg` the card's
   width is the container's. (A container query would express that directly, but
   `container-type` introduces a containment context around the animated mock
   inside these cards for no behavioural gain here.)

   Deliberately NOT touching `.hiw-title`'s 16ch: that is a
   clamp(34px, 4.6vw, 52px) DISPLAY headline where a tight measure is the point —
   it forces the stacked line breaks the section is built around. */
@media (max-width: 1023.98px) {
  .lp-2 { max-width: 62ch; }
  .lp-3 { max-width: 30ch; }
  .lp-20 { max-width: 32ch; }
}
.lp-22 { font-size: 13px; font-weight: 600; color: var(--warning-text); }