/* Tangram Studios, motion
   Personality: confidently expressive. Things move as if they have weight and
   intent. Distance sets duration; a spring is allowed when something is being
   grabbed, dropped, or swapped, never as decoration.

   The vocabulary is fourteen named moves (see guidelines/motion-moves.card.html).
   Four are foundational and appear in every surface; ten are expressive and are
   chosen deliberately, at most two or three per screen.

   Scope: marketing site, case-study/editorial pages, product UI, social and
   campaign assets. Printed documents never move.

   Three temperaments were explored (see guidelines/motion-personality.card.html).
   "Considered" remains the base timing; the expressive layer sits on top of it. */
:root {
  /* ---- Durations, pick by travel distance, not by element type ---- */
  /* color, opacity, tiny state flips */
  --motion-instant: 90ms; /* @kind other */
  /* hover, press, small reveals */
  --motion-quick:   160ms; /* @kind other */
  /* menus, accordions, tabs */
  --motion-base:    240ms; /* @kind other */
  /* modals, drawers, page sections */
  --motion-calm:    380ms; /* @kind other */
  /* hero and scroll-in choreography */
  --motion-scenic:  620ms; /* @kind other */
  /* full-width wipes, morphs across a layout */
  --motion-epic:    900ms; /* @kind other */

  /* Expressive-move durations */
  /* masked wipe across a block */
  --motion-wipe:    520ms; /* @kind other */
  /* lateral slide & swap */
  --motion-swap:    320ms; /* @kind other */
  /* shape or layout morph */
  --motion-morph:   420ms; /* @kind other */
  /* stroke, rule, or chart drawing itself */
  --motion-draw:    900ms; /* @kind other */
  /* figures counting up */
  --motion-count:   900ms; /* @kind other */
  /* ambient float loop */
  --motion-drift:   18s; /* @kind other */
  /* marquee loop, one full pass */
  --motion-marquee: 32s; /* @kind other */

  /* ---- Curves ---- */
  /* default, symmetric */
  --motion-ease:       cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */
  /* things arriving */
  --motion-ease-out:   cubic-bezier(0.16, 1, 0.3, 1); /* @kind other */
  /* things leaving, run one duration step faster */
  --motion-ease-in:    cubic-bezier(0.5, 0, 0.9, 0.3); /* @kind other */
  /* one soft overshoot */
  --motion-ease-firm:  cubic-bezier(0.34, 1.2, 0.64, 1); /* @kind other */
  /* long editorial travel, slow in and out */
  --motion-ease-scenic: cubic-bezier(0.65, 0, 0.35, 1); /* @kind other */

  /* Springs. Real physics, expressed as linear() so CSS can run them.
     Use for grabbed/dropped/swapped things and for confirmation moments. */
  /* barely overshoots, safe default spring */
  --motion-spring-soft:  linear(0, 0.218 8%, 0.63 18%, 0.905 27%, 1.045 36%, 1.075 45%, 1.03 60%, 0.995 75%, 1.002 88%, 1); /* @kind other */
  /* visible settle, for drops and swaps */
  --motion-spring-firm:  linear(0, 0.35 9%, 0.82 20%, 1.09 31%, 1.13 40%, 1.03 55%, 0.975 68%, 1.008 82%, 1); /* @kind other */
  /* fast and lively, small elements only */
  --motion-spring-snap:  linear(0, 0.55 7%, 1.02 16%, 1.14 24%, 1.05 38%, 0.98 52%, 1.012 70%, 1); /* @kind other */
  /* matching durations, a spring needs room to settle */
  --motion-spring-dur:      560ms; /* @kind other */
  --motion-spring-dur-long:  760ms; /* @kind other */
  /* scroll-linked scrubbing is never eased, the finger is the easing */
  --motion-scrub: linear; /* @kind other */

  /* ---- Ready-made transitions ---- */
  --transition-hover: color var(--motion-quick) var(--motion-ease), background-color var(--motion-quick) var(--motion-ease), border-color var(--motion-quick) var(--motion-ease), box-shadow var(--motion-quick) var(--motion-ease); /* @kind other */
  --transition-press: transform var(--motion-instant) var(--motion-ease-out); /* @kind other */
  --transition-panel: opacity var(--motion-base) var(--motion-ease-out), transform var(--motion-base) var(--motion-ease-out); /* @kind other */
  --transition-layer: opacity var(--motion-calm) var(--motion-ease-out), transform var(--motion-calm) var(--motion-ease-out); /* @kind other */
  --transition-lean:  transform var(--motion-base) var(--motion-ease-out); /* @kind other */
  --transition-swap:  transform var(--motion-swap) var(--motion-spring-soft), opacity var(--motion-quick) var(--motion-ease); /* @kind other */
  --transition-morph: transform var(--motion-morph) var(--motion-spring-soft), border-radius var(--motion-morph) var(--motion-ease-out), background-color var(--motion-morph) var(--motion-ease); /* @kind other */
  --transition-spring: transform var(--motion-spring-dur) var(--motion-spring-soft); /* @kind other */

  /* ---- Displacement, how far things travel ---- */
  --motion-rise-sm: 6px; /* @kind other */
  --motion-rise-md: 14px; /* @kind other */
  --motion-rise-lg: 28px; /* @kind other */
  --motion-rise-xl: 48px; /* @kind other */
  /* stagger step for lists and grids entering together, cap at six items */
  --motion-stagger: 60ms; /* @kind other */
  /* word-by-word type rise */
  --motion-stagger-word: 55ms; /* @kind other */
  /* pointer lean, maximum rotation toward the cursor */
  --motion-lean: 9deg; /* @kind other */
  /* pointer lean on large surfaces, half a step */
  --motion-lean-sm: 5.5deg; /* @kind other */
  /* magnetic pull, maximum travel toward the cursor */
  --motion-magnet: 6px; /* @kind other */
  /* ambient drift amplitude */
  --motion-drift-amp: 10px; /* @kind other */

  /* Parallax rates, multiply by scroll offset. Foreground stays at 0. */
  --motion-parallax-slow: 0.06; /* @kind other */
  --motion-parallax-mid:  0.12; /* @kind other */
  --motion-parallax-fast: 0.22; /* @kind other */

  /* ---- Cursor & focus ---- */
  /* diameter of the follow cursor over media */
  --motion-cursor-size: 64px; /* @kind other */
  /* per-frame lerp toward the pointer, lower is heavier */
  --motion-cursor-lag: 0.18; /* @kind other */
  /* the disc appearing, disappearing, changing label */
  --motion-cursor-dur: 260ms; /* @kind other */
  /* the focus ring travelling between fields */
  --motion-focus-travel: 200ms; /* @kind other */
  --motion-focus-ring: 3px; /* @kind other */

  /* ---- Scroll scenes ---- */
  /* longest a pinned scene may hold the viewport */
  --motion-scene-pin: 180vh; /* @kind other */
  /* dead zone at each end of a scrubbed scene, as progress */
  --motion-scene-lead: 0.12; /* @kind other */

  /* ---- Text effects ---- */
  /* a line rising out of its own mask */
  --motion-mask-line: 620ms; /* @kind other */
  /* character stagger, figures and short labels only */
  --motion-stagger-char: 26ms; /* @kind other */
  /* link underline sweep */
  --motion-underline: 260ms; /* @kind other */

  /* ---- Empty to full ---- */
  /* skeleton shimmer loop */
  --motion-skeleton: 1.4s; /* @kind other */
  /* stagger as real content replaces placeholders */
  --motion-fill-stagger: 70ms; /* @kind other */
  /* form becoming confirmation, upload becoming tick */
  --motion-confirm: 520ms; /* @kind other */

  /* Scroll-in defaults for reveal observers */
  --motion-reveal-threshold: 0.15; /* @kind other */
  --motion-reveal-margin: -8%; /* @kind other */
}

/* Shared keyframes for the looping and self-drawing moves. */
@keyframes tg-drift { 0%,100% { transform: translate3d(0,0,0) } 50% { transform: translate3d(0, calc(var(--motion-drift-amp) * -1), 0) } }
@keyframes tg-marquee { from { transform: translate3d(0,0,0) } to { transform: translate3d(-50%,0,0) } }
@keyframes tg-wipe-in { from { clip-path: inset(0 100% 0 0) } to { clip-path: inset(0 0 0 0) } }
@keyframes tg-draw { from { stroke-dashoffset: var(--tg-draw-length, 1000) } to { stroke-dashoffset: 0 } }
@keyframes tg-rise-in { from { opacity: 0; transform: translate3d(0, var(--motion-rise-md), 0) } to { opacity: 1; transform: none } }
@keyframes tg-mask-up { from { transform: translate3d(0, 100%, 0) } to { transform: none } }
@keyframes tg-shimmer { from { background-position: -160% 0 } to { background-position: 260% 0 } }
@keyframes tg-underline { from { transform: scaleX(0) } to { transform: scaleX(1) } }

/* Respect the OS setting. Always. Expressive moves collapse to a plain state change:
   loops stop, parallax and lean flatten, wipes and draws land finished. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-instant: 0ms; /* @kind other */
    --motion-quick: 0ms; /* @kind other */
    --motion-base: 0ms; /* @kind other */
    --motion-calm: 0ms; /* @kind other */
    --motion-scenic: 0ms; /* @kind other */
    --motion-epic: 0ms; /* @kind other */
    --motion-wipe: 0ms; /* @kind other */
    --motion-swap: 0ms; /* @kind other */
    --motion-morph: 0ms; /* @kind other */
    --motion-draw: 0ms; /* @kind other */
    --motion-count: 0ms; /* @kind other */
    --motion-spring-dur: 0ms; /* @kind other */
    --motion-spring-dur-long: 0ms; /* @kind other */
    --motion-stagger: 0ms; /* @kind other */
    --motion-stagger-word: 0ms; /* @kind other */
    --motion-rise-sm: 0px; /* @kind other */
    --motion-rise-md: 0px; /* @kind other */
    --motion-rise-lg: 0px; /* @kind other */
    --motion-rise-xl: 0px; /* @kind other */
    --motion-lean: 0deg; /* @kind other */
    --motion-lean-sm: 0deg; /* @kind other */
    --motion-magnet: 0px; /* @kind other */
    --motion-drift-amp: 0px; /* @kind other */
    --motion-parallax-slow: 0; /* @kind other */
    --motion-parallax-mid: 0; /* @kind other */
    --motion-parallax-fast: 0; /* @kind other */
    --motion-cursor-size: 0px; /* @kind other */
    --motion-cursor-lag: 1; /* @kind other */
    --motion-cursor-dur: 0ms; /* @kind other */
    --motion-focus-travel: 0ms; /* @kind other */
    --motion-mask-line: 0ms; /* @kind other */
    --motion-stagger-char: 0ms; /* @kind other */
    --motion-underline: 0ms; /* @kind other */
    --motion-fill-stagger: 0ms; /* @kind other */
    --motion-confirm: 0ms; /* @kind other */
  }
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
}
