/* Motion layer. Patterns studied from Vast (shared easing, word-rise headlines,
   scroll-aware header), Harbinger (staggered fade-up) and Lightship (image wipes).
   Every rule is scoped to html.motion, which motion.js sets only when the visitor
   has not asked for reduced motion; without it the page renders fully static. */
:root{--ease-out:cubic-bezier(.23,1,.32,1);--ease-io:cubic-bezier(.62,.05,.01,.99)}

/* Header: Vast-style out (0.7 s, power3.in) and in (0.7 s, power3.out). */
header{position:sticky;top:0;z-index:5;transition:transform .7s cubic-bezier(.55,.06,.68,.19),opacity .7s cubic-bezier(.55,.06,.68,.19),box-shadow .3s ease}
html.motion header:not(.is-hidden){transition-timing-function:cubic-bezier(.22,.61,.36,1)}
html.motion header.is-hidden{transform:translateY(-100%);opacity:0}
header.is-scrolled{box-shadow:0 1px 0 var(--line)}

/* Headlines rise word by word, once. */
html.motion .rise .w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
html.motion .rise .w>span{display:inline-block;transform:translateY(105%);transition:transform .95s var(--ease-out);transition-delay:calc(var(--i) * 45ms)}
html.motion .rise.in .w>span{transform:none}

/* Fade-up groups; children stagger. */
html.motion .reveal{opacity:0;transform:translateY(24px);transition:opacity .8s var(--ease-out),transform .9s var(--ease-out);transition-delay:calc(var(--i, 0) * 80ms)}
html.motion .reveal.in{opacity:1;transform:none}

/* Image wipes upward; the photograph settles from a slight scale. */
html.motion .wipe{clip-path:inset(100% 0 0 0);transition:clip-path 1.1s var(--ease-out)}
html.motion .wipe img{transform:scale(1.06);transition:transform 1.6s var(--ease-out)}
html.motion .wipe.in{clip-path:inset(0)}
html.motion .wipe.in img{transform:none}

/* Dimension callouts: lines draw left to right, labels follow. */
html.motion .dim-canvas svg{clip-path:inset(0 100% 0 0);transition:clip-path 1.4s var(--ease-io) .2s}
html.motion .dim-canvas .dim-label{opacity:0;transition:opacity .6s ease}
html.motion .dim-canvas.in svg{clip-path:inset(0)}
html.motion .dim-canvas.in .dim-label{opacity:1}
html.motion .dim-canvas.in .dim-bay{transition-delay:.7s}
html.motion .dim-canvas.in .dim-deck{transition-delay:1.1s}
html.motion .dim-canvas.in .dim-tyre{transition-delay:1.3s}
html.motion .dim-canvas.in .dim-height{transition-delay:1.5s}

/* Hero: side-to-plan progress rail inside the sticky canvas. */
.tilt-progress{position:absolute;left:var(--gutter);bottom:20px;display:flex;align-items:center;gap:12px;font:10px/1 var(--mono);letter-spacing:.08em;color:var(--muted);pointer-events:none;transition:opacity .4s ease}
.tilt-progress i{position:relative;display:block;width:clamp(96px,12vw,180px);height:1px;background:#c9c6bd}
.tilt-progress i::after{content:"";position:absolute;inset:0;background:var(--orange);transform-origin:left;transform:scaleX(var(--p,0))}
.tilt-progress .cue{position:absolute;left:0;bottom:18px;white-space:nowrap;transition:opacity .4s ease}
.tilt-progress.started .cue{opacity:0}
.scroll-stage.is-alt .tilt-progress{opacity:0}

/* Statement: muted copy that fills with ink word by word while scrolling. */
.statement{padding:clamp(88px,12vw,180px) var(--gutter);background:var(--paper)}
.statement p{margin:0;max-width:22ch;font-size:clamp(30px,4.2vw,64px);line-height:1.04;letter-spacing:-.035em;font-weight:500;color:var(--ink)}
.statement .eyebrow{display:block;margin-bottom:32px}
html.motion .statement .sw{color:#c4c0b6;transition:color .1s ease-out}
html.motion .statement .sw.lit{color:var(--ink)}

/* Odometer numbers: digit columns roll into place once (2 s, primary in-out). */
.odometer{white-space:nowrap;font-variant-numeric:tabular-nums}
html.motion .odo{display:inline-block;height:1em;line-height:1;overflow:hidden;vertical-align:-.1em}
html.motion .odo>span{display:block;transform:translateY(0);transition:transform 2s var(--ease-io);transition-delay:calc(var(--i) * 70ms)}
html.motion .odo i{display:block;height:1em;font-style:normal;text-align:center}
html.motion .odometer.in .odo>span{transform:translateY(calc(var(--d) * -1em))}

/* Small hover affordances. */
.textlink span,.spec-entry span:last-child{display:inline-block;transition:transform .5s var(--ease-io)}
.textlink:hover span,.spec-entry:hover span:last-child{transform:translateX(4px)}
.textlink[href^="#"]:hover span{transform:translateY(3px)}
.component-row img,.detailstrip img{transition:transform 1.2s var(--ease-out)}

@media(max-width:800px){.tilt-progress{bottom:14px}}
@media(prefers-reduced-motion:reduce){header{transition:none}.tilt-progress .cue{display:none}}
.metrics b .odo,.metrics b .odo span{font-size:inherit;margin-left:0;letter-spacing:inherit}
