/* neil-motion.css - the motion kit (dashboard-reel feel, Neil's dark-glow theme untouched).
   Opt in with attributes, no layout changes:
     data-reveal            element rises + unblurs when it scrolls into view
     data-stagger           its direct children reveal one after another (~70ms apart)
     data-count="1280"      number counts up (optional data-prefix / data-suffix / data-decimals)
     data-draw              SVG path/line/polyline draws itself (stroke-dashoffset)
     data-bars              children with --h (e.g. style="--h:70%") grow up from the baseline
     data-matte="up|left|right|circle"  track-matte reveal: a mask wipes across the element (section/image transition)
     data-pullback          camera pull-back: element starts pushed in close (scale 1.14, soft) and pulls back to rest
     data-push              horizontal push: element slides in from the side as if pushing the previous section off (data-push="left" for from-left)
     data-lift              card lifts on hover with a cursor-following glow (mouse only)
     data-squircle          corner-shape:squircle on an element that already has a border-radius (JS also tags cards/buttons/inputs/media automatically; data-squircle="off" opts out)
     data-one               "one idea at a time": children sit dimmed and the one nearest the middle of the screen lights up as you scroll (opacity only)
   Page transitions: none (cross-page View Transitions froze Chromium 149 - see note below).
   Everything is off under prefers-reduced-motion. Without JS nothing is hidden (html.nm-on is set by the JS). */
:root{
  --nm-ease:cubic-bezier(.22,1,.36,1);      /* ease-out-quint: fast start, long soft landing */
  --nm-dur:700ms; --nm-rise:22px; --nm-step:70ms;
  --nm-glow:rgba(120,140,255,.22);
  --nm-spring:linear(0,.28 8%,.7 18%,1.04 32%,1.07 40%,1.02 56%,.995 70%,1);  /* spring settle (overshoot then rest); falls back to --nm-ease where linear() is unsupported */
}
html{-webkit-tap-highlight-color:transparent}
/* Squircle corners (alfiewoelfe reel 2026-10-27): the continuous-curve corner between a circle and a rounded rect. Needs corner-shape (Chromium 139+);
   everywhere else the element keeps its plain border-radius, so nothing breaks. Pills and circles are never tagged. */
@supports (corner-shape:squircle){.nm-sq,[data-squircle]:not([data-squircle=off]){corner-shape:squircle}}
a,button,[role=button],summary,label,input,select,textarea,[data-lift]{touch-action:manipulation}  /* no 300ms tap delay, instant touch response */
[data-lift]:active,button:active,[role=button]:active{transition-duration:90ms}
@media (prefers-reduced-motion:no-preference){
  html.nm-on [data-reveal]:not(.nm-done),html.nm-on [data-stagger]:not(.nm-done)>*{
    opacity:0; transform:translate3d(0,var(--nm-rise),0) scale(.985); filter:blur(6px); will-change:opacity,transform;
  }
  /* the transition lives on the LANDED state only: hiding is instant (no fade-out flash when the JS arms the page), revealing animates */
  html.nm-on [data-reveal].nm-in:not(.nm-done),html.nm-on [data-stagger].nm-in:not(.nm-done)>*{opacity:1;transform:none;filter:none;will-change:auto;
    transition:opacity var(--nm-dur) var(--nm-ease),transform var(--nm-dur) var(--nm-ease),filter var(--nm-dur) var(--nm-ease);
    transition-delay:calc(var(--i,0)*var(--nm-step))} /* .nm-done (added by the JS ~1.9s after landing) un-matches these rules so the element's OWN transitions/transforms (hover states, data-lift) take back over. will-change:auto after landing: a lingering will-change:transform would trap position:fixed descendants */
  html.nm-on [data-stagger]>.nm-skip{opacity:1!important;transform:none!important;filter:none!important;transition:none!important}
  html.nm-on [data-draw]{stroke-dasharray:var(--len,1);stroke-dashoffset:var(--len,1)}
  html.nm-on [data-draw].nm-in{stroke-dashoffset:0;transition:stroke-dashoffset 1400ms var(--nm-ease)}
  html.nm-on [data-bars]>*{transform-origin:50% 100%;transform:scaleY(0)}
  html.nm-on [data-bars].nm-in>*{transform:scaleY(1);transition:transform 900ms var(--nm-ease);transition-delay:calc(var(--i,0)*50ms)}
  [data-lift]{--mx:50%;--my:50%;position:relative;transition:translate 260ms var(--nm-ease),scale 260ms var(--nm-ease),box-shadow 260ms var(--nm-ease)}
  [data-lift]::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;transition:opacity 260ms;
    background:radial-gradient(260px circle at var(--mx) var(--my),var(--nm-glow),transparent 70%)}
  @media (hover:hover) and (pointer:fine){
    [data-lift]:hover{translate:0 -4px;box-shadow:0 14px 34px -14px rgba(0,0,0,.6)}
    [data-lift]:hover::after{opacity:1}
  }
  [data-lift]:active{translate:0 -1px;scale:.985;transition-duration:90ms}

  /* Scroll transitions (reel 3 simple transitions, 2026-10-27): matte wipe, camera pull-back, push. Same arm/land/settle pipeline as data-reveal. */
  html.nm-on [data-matte]:not(.nm-done){clip-path:inset(0 0 100% 0);will-change:clip-path}
  html.nm-on [data-matte="left"]:not(.nm-done){clip-path:inset(0 100% 0 0)}
  html.nm-on [data-matte="right"]:not(.nm-done){clip-path:inset(0 0 0 100%)}
  html.nm-on [data-matte="circle"]:not(.nm-done){clip-path:circle(0% at 50% 50%)}
  html.nm-on [data-matte].nm-in:not(.nm-done){clip-path:inset(0 0 0 0);will-change:auto;transition:clip-path 1000ms cubic-bezier(.77,0,.18,1)}
  html.nm-on [data-matte="circle"].nm-in:not(.nm-done){clip-path:circle(150% at 50% 50%);transition-duration:1200ms}
  html.nm-on [data-pullback]:not(.nm-done){opacity:0;transform:scale(1.14);filter:blur(8px);transform-origin:50% 40%;will-change:opacity,transform}
  html.nm-on [data-pullback].nm-in:not(.nm-done){opacity:1;transform:none;filter:none;will-change:auto;
    transition:opacity 700ms var(--nm-ease),transform 1200ms var(--nm-ease),filter 900ms var(--nm-ease)}
  html.nm-on [data-push]:not(.nm-done){opacity:0;transform:translate3d(9vw,0,0);will-change:opacity,transform}
  html.nm-on [data-push="left"]:not(.nm-done){transform:translate3d(-9vw,0,0)}
  html.nm-on [data-push].nm-in:not(.nm-done){opacity:1;transform:none;will-change:auto;transition:opacity 600ms var(--nm-ease),transform 900ms var(--nm-ease)}
  /* One idea at a time: dim everything except the child nearest the middle of the viewport (opacity only, no layout) */
  html.nm-on [data-one]>*{opacity:.42;transition:opacity 500ms var(--nm-ease)}
  html.nm-on [data-one]>.nm-focus{opacity:1}
  html.nm-lite [data-pullback]{filter:none!important}
  /* Smoothness governor (JS adds html.nm-lite when frames run long, e.g. 60Hz phones under load): drop the expensive effects (blur filters, glow layer), keep transform+opacity only */
  html.nm-lite [data-reveal],html.nm-lite [data-stagger]>*{filter:none!important}
  html.nm-lite [data-lift]::after{display:none}
  @supports (transition-timing-function:linear(0,1)){[data-lift]{transition-timing-function:var(--nm-spring)}}
  /* Cross-page View Transitions (@view-transition{navigation:auto}) REMOVED 2026-10-22 by security QA: in Chromium 149
     (headed and headless) every same-origin link click froze rendering (no frames, rAF stalled, "Transition was skipped"),
     and Edge 155 threw "Transition was aborted because of invalid state" on each navigation. Do not re-add without testing. */
}
