/* BourneWise motion tokens — one hand on every transition.
   Three curves, three durations; interactive CSS should reference these
   instead of inventing new cubic-beziers. Decorative/ambient animations
   (mountains, clouds, casting board) keep their own tuned timings. */
:root{
  --ease-out: cubic-bezier(.23,1,.32,1);       /* things arriving / reacting */
  --ease-in-out: cubic-bezier(.77,0,.175,1);   /* things moving elsewhere */
  --ease-drawer: cubic-bezier(.32,.72,0,1);    /* off-canvas surfaces */
  --ease-spring: cubic-bezier(.2,.85,.3,1.18); /* restrained playful feedback */
  --dur-fast: 140ms;   /* press, hover tint */
  --dur-base: 190ms;   /* menus, reveals */
  --dur-slow: 360ms;   /* panels, page-level */
  /* ⚠️ 普查补的一档:全站 18 处时长落在 500–600ms,而令牌在 360 和 760 之间是空的,
     于是每个调用点各自敲了一个数(.45 / .5 / .52 / .55 / .6 / .68)。
     补一档是系统设计;为了迁就某一页改一个数才是漂移。 */
  --dur-slower: 520ms; /* long settles — drawers, page-scale chrome */

  /* Editorial reveal curves — the long, weighted easings that give a
     smooth-scrolled page its "settling into place" feel. --ease-cinematic is
     the signature: slow-out/slow-in, nothing snaps. Used by the scroll-reveal
     + split-heading system (ds-motion.js) so every scrolling surface shares
     one motion signature instead of each page inventing its own. */
  --ease-cinematic: cubic-bezier(.16,1,.3,1);   /* reveals arriving — long tail */
  --ease-quart:     cubic-bezier(.76,0,.24,1);  /* section-scale moves */
  --dur-reveal: 760ms;  /* element rising into view */
  --dur-lede:  980ms;   /* a headline unfurling word-by-word */
}

/* Press state — interactive controls give slightly under the finger.
   !important is deliberate: :active must beat page-level hover transforms
   (e.g. translateY lifts) for the moment the pointer is down, and this file
   loads before every page's inline styles. */
@media (prefers-reduced-motion: no-preference){
  .pressable{transition:transform var(--dur-fast) var(--ease-out)}
  .pressable:active{transform:scale(.97) !important}
}

/* Cross-document root transitions are intentionally disabled. Duplicating the
   full-screen animated SVG and every backdrop-filter during navigation forces
   Chromium to composite two expensive page trees and can expose a bright frame.
   The shared mountain clock provides continuity without stacking pages. */

/* ── Scroll-reveal system ─────────────────────────────────────────────────
   Elements marked [data-reveal] start just below their resting place, dimmed,
   and settle up as they enter the viewport (ds-motion.js adds .is-in via an
   IntersectionObserver). One shared curve, so the whole site breathes in the
   same rhythm. [data-reveal] variants change the entrance vector; the numbered
   --i custom property staggers siblings without per-element CSS. */
[data-reveal]{
  opacity:0;
  transform:translateY(28px);
  transition:opacity var(--dur-reveal) var(--ease-cinematic),
             transform var(--dur-reveal) var(--ease-cinematic);
  transition-delay:calc(var(--i,0) * 90ms);
  will-change:opacity,transform;
}
[data-reveal="rise-lg"]{transform:translateY(52px)}
[data-reveal="fade"]{transform:none}
[data-reveal="left"]{transform:translateX(-36px)}
[data-reveal="right"]{transform:translateX(36px)}
[data-reveal].is-in{opacity:1;transform:none}

/* ── Split-heading ────────────────────────────────────────────────────────
   ds-motion.js wraps each word of a [data-split] heading in <span class="w">
   <span class="ww">word</span></span>; the inner span is lifted and clipped,
   then rises on reveal — the SplitText move. Falls back to a plain heading if
   JS never runs (the words are just normal text). */
[data-split] .w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.06em}
[data-split] .ww{display:inline-block;transform:translateY(112%);
  transition:transform var(--dur-lede) var(--ease-cinematic);
  transition-delay:calc(var(--wi,0) * 70ms)}
[data-split].is-in .ww{transform:none}

/* ── Scroll progress rail — a hairline that fills as the document scrolls,
   the quiet "how far in" read used on the long-form pages. Driven by a single
   CSS var (--scroll) set once per frame from the Lenis loop. */
.scroll-rail{position:fixed;top:0;left:0;right:0;height:2px;z-index:60;background:transparent;pointer-events:none}
.scroll-rail i{display:block;height:100%;width:100%;transform:scaleX(var(--scroll,0));transform-origin:0 50%;
  background:var(--terracotta,#B5502C);opacity:.85}

/* Honour reduced-motion: everything is simply present, no travel, no stagger. */
@media (prefers-reduced-motion: reduce){
  [data-reveal],[data-split] .ww{opacity:1 !important;transform:none !important;transition:none !important}
  .scroll-rail{display:none}
}

/* Touch-target hardening used to live here. It has moved to
   tokens/refinement.css — every one of the ten routes loads that sheet,
   motion.css is not the owner of chrome geometry, and the rule needed
   rewriting: it named nine selectors for position:relative and only four of
   them for the ::after, so five controls carried the positioning and no hit
   area at all. One of them was .send, the Cast button. */
