/* ==========================================================================
   COURAGEOUS — MOTION SYSTEM
   "Built before your eyes"

   One place for every duration, easing and stagger on the site. Nothing
   animates with a hard-coded number; if a value is not in this file it does
   not belong in a component.

   The interaction language is drawn from construction, not from web fashion:
     LINES DRAW   — plans are set out before anything is built
     PANELS SLIDE — components arrive and are placed
     MASKS WIPE   — a finished surface is applied over structure
     STAMPS LAND  — work is inspected and approved
   Those are the only four verbs. Everything on the site is one of them.
   ========================================================================== */

:root {
  /* ---- Durations ------------------------------------------------------
     Bands, not arbitrary values. A component picks a band, not a number. */
  --t-micro:      180ms;   /* button press, checkbox, tap feedback         */
  --t-micro-slow: 260ms;   /* hover state, underline, cursor state change  */
  --t-comp:       420ms;   /* accordion, tab, filter, card                 */
  --t-comp-slow:  640ms;   /* panel open, drawer, menu                     */
  --t-cine:       900ms;   /* section reveal, mask wipe                    */
  --t-cine-slow: 1300ms;   /* line draw, hero entrance                     */
  --t-page:       700ms;   /* route transition                             */

  /* ---- Easing ---------------------------------------------------------
     No springs, no overshoot except --ease-press. Buildings do not bounce. */
  --e-out:      cubic-bezier(.22, 1, .36, 1);      /* default arrival      */
  --e-out-deep: cubic-bezier(.16, 1, .3, 1);       /* cinematic arrival    */
  --e-in-out:   cubic-bezier(.65, .05, .36, 1);    /* moves both ways      */
  --e-draw:     cubic-bezier(.37, 0, .18, 1);      /* line drawing         */
  --e-panel:    cubic-bezier(.76, 0, .24, 1);      /* heavy panel, weighted*/
  --e-press:    cubic-bezier(.34, 1.4, .64, 1);    /* ONLY button feedback */

  /* ---- Stagger --------------------------------------------------------- */
  --s-tight:  40ms;   /* letters, rules            */
  --s-base:   70ms;   /* cards in a row            */
  --s-loose: 110ms;   /* full-width sections       */

  /* ---- Distance -------------------------------------------------------- */
  --d-nudge:  8px;
  --d-rise:  26px;
  --d-lift:  44px;

  /* ---- Motion switch --------------------------------------------------
     JS flips --motion to 0 on reduced-motion or low-capability devices.
     Components multiply by it, so one switch disables everything. */
  --motion: 1;
}

/* ==========================================================================
   REDUCED MOTION / LOW CAPABILITY
   Information and functionality are unchanged. Only movement is removed.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion: 0;
    --t-micro: 1ms; --t-micro-slow: 1ms;
    --t-comp: 1ms;  --t-comp-slow: 1ms;
    --t-cine: 1ms;  --t-cine-slow: 1ms;
    --t-page: 1ms;
    --s-tight: 0ms; --s-base: 0ms; --s-loose: 0ms;
    --d-nudge: 0px; --d-rise: 0px; --d-lift: 0px;
  }
}
html[data-motion="off"] {
  --motion: 0;
  --t-micro: 1ms; --t-micro-slow: 1ms; --t-comp: 1ms; --t-comp-slow: 1ms;
  --t-cine: 1ms; --t-cine-slow: 1ms; --t-page: 1ms;
  --s-tight: 0ms; --s-base: 0ms; --s-loose: 0ms;
  --d-nudge: 0px; --d-rise: 0px; --d-lift: 0px;
}
/* With motion off, every primitive shows its final state immediately. */
html[data-motion="off"] [data-anim] { opacity: 1 !important; transform: none !important; clip-path: none !important; }

/* ==========================================================================
   PRIMITIVE 1 — RISE
   The workhorse. Content arrives from below, once, and settles.
   ========================================================================== */
[data-anim="rise"] {
  opacity: 0;
  transform: translate3d(0, var(--d-rise), 0);
  transition: opacity var(--t-cine) var(--e-out-deep),
              transform var(--t-cine) var(--e-out-deep);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="rise"].is-in { opacity: 1; transform: none; }

/* ==========================================================================
   PRIMITIVE 2 — DRAW
   A line sets itself out, the way a plan is drawn before work starts.
   Applied to any SVG path carrying data-anim="draw".
   ========================================================================== */
[data-anim="draw"] {
  stroke-dasharray: var(--len, 1000);
  stroke-dashoffset: var(--len, 1000);
  transition: stroke-dashoffset var(--t-cine-slow) var(--e-draw);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="draw"].is-in { stroke-dashoffset: 0; }

/* Horizontal measurement rule that grows beside content. */
[data-anim="rule"] {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-cine) var(--e-draw);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="rule"].is-in { transform: scaleX(1); }

/* ==========================================================================
   PRIMITIVE 3 — MASK
   A finished surface is applied over what is underneath. Used for imagery.
   ========================================================================== */
[data-anim="mask"] {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--t-cine-slow) var(--e-panel);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="mask"].is-in { clip-path: inset(0 0 0 0); }

[data-anim="mask-x"] {
  clip-path: inset(0 100% 0 0);
  transition: clip-path var(--t-cine-slow) var(--e-panel);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="mask-x"].is-in { clip-path: inset(0 0 0 0); }

/* ==========================================================================
   PRIMITIVE 4 — PANEL
   A component is lifted into place. Heavier easing: it has weight.
   ========================================================================== */
[data-anim="panel"] {
  opacity: 0;
  transform: translate3d(0, var(--d-lift), 0);
  transition: opacity var(--t-comp-slow) var(--e-panel),
              transform var(--t-comp-slow) var(--e-panel);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="panel"].is-in { opacity: 1; transform: none; }

/* ==========================================================================
   PRIMITIVE 5 — SPLIT
   Headlines reveal by PHRASE, never by random letter. Each line is masked
   and rises from behind its own edge, the way a course of work is laid.
   ========================================================================== */
.split-line { display: block; overflow: hidden; }
.split-line > span {
  display: block;
  transform: translate3d(0, 105%, 0);
  transition: transform var(--t-cine) var(--e-out-deep);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="split"].is-in .split-line > span { transform: none; }

/* ==========================================================================
   PRIMITIVE 6 — STAMP
   Inspection approved. Lands with compression, no bounce.
   ========================================================================== */
[data-anim="stamp"] {
  opacity: 0;
  transform: scale(1.14);
  transition: opacity var(--t-comp) var(--e-out),
              transform var(--t-comp) var(--e-panel);
  transition-delay: var(--anim-delay, 0ms);
}
[data-anim="stamp"].is-in { opacity: 1; transform: scale(1); }

/* ==========================================================================
   STAGGER
   A parent sets the rhythm; children inherit their position in it.
   ========================================================================== */
[data-stagger] > * { --anim-delay: calc(var(--i, 0) * var(--s-base)); }
[data-stagger="tight"] > * { --anim-delay: calc(var(--i, 0) * var(--s-tight)); }
[data-stagger="loose"] > * { --anim-delay: calc(var(--i, 0) * var(--s-loose)); }
