/* ============================================================================
   eyefx.css — the "watching animals" auth companion (js/eyefx.js, AtlasEyeFX).
   A trio of creatures (fox · owl · cat) sits to the RIGHT of the sign-in card,
   follows the cursor with pupils + a subtle head tilt (--ex/--ey/--hx set by
   JS), sways tails, twitches ears, and covers its eyes the moment the password
   field is focused or has text — fox+cat with rounded paws, the owl with its
   wings. Eyes squeeze shut a beat BEFORE the paws land and the cover ripples
   across the trio (--d = 0/.07/.14s per creature). "Show password" makes them
   peek guiltily (pupils dart aside, the cat keeps one eye shut); uncovering
   bounces the arms down and fires a quick double-blink (.eyefx--wake).
   Bespoke vanilla SVG — no external libraries, no build step.

   PERF: pointer tracking + all idle animation run ONLY when motion is allowed
   and the tab is visible (.eyefx-active). reduced-motion / data-anim=off
   (tier2) / data-perf=3 / AtlasPerf.static() => creatures render static, still
   cover on password (a CSS transition, cheap) but with no cursor-tracking rAF.
   PERF LAW: no backdrop-filter / filter anywhere — the caption pill is faux-
   glass (layered translucent gradients + hairline border).
   The stage is display:none under 720px so it never crowds the card on mobile.
============================================================================ */

/* ---- two-column layout: card LEFT, creatures RIGHT (only when mounted) ----
   .auth-page is a centered column by default (one card). When eyefx mounts it
   adds .has-eyefx and the page becomes a centered ROW on wide screens, which
   naturally pushes the card left-of-centre and seats the creatures at its right. */
@media (min-width:900px){
  .auth-page.has-eyefx{flex-direction:row;align-items:center;justify-content:center;
    gap:clamp(28px,4.5vw,80px)}
  .auth-page.has-eyefx .auth-card-page{margin:0;flex:0 0 auto}
}
/* 720–900px: creatures ride ABOVE the card, smaller */
@media (min-width:720px) and (max-width:899.98px){
  .auth-page.has-eyefx .eyefx-stage{order:-1;margin-bottom:8px;
    width:clamp(260px,44vw,330px)}
}
@media (max-width:719.98px){
  .eyefx-stage{display:none}
}

/* ---- stage ---------------------------------------------------------------- */
.eyefx-stage{position:relative;z-index:1;pointer-events:none;
  width:clamp(300px,30vw,400px);
  display:flex;flex-direction:column;align-items:center;gap:18px;
  /* palette — 2-3 tones per creature + shared accents */
  --owl:#3a4560;--owl2:#4a577a;--owl0:#2f3850;
  --fox:#c06a34;--fox2:#dd8145;
  --cat:#2a3042;--cat2:#3a4560;
  --cream:#f2e6cf;--amber:#f6b03c;--dark:#141a2a;--rim:#5b7cfa;
  opacity:0;transform:translateY(14px);
  animation:eyefxIn .6s var(--ease) .1s both}
@keyframes eyefxIn{to{opacity:1;transform:none}}

.eyefx-row{display:flex;align-items:flex-end;justify-content:center;gap:clamp(2px,1vw,12px);width:100%}
/* --d staggers the cover/uncover ripple across the trio (fox → owl → cat);
   the wraps also fade in one by one on mount (opacity only — the mid wrap
   keeps its base transform) */
.crt-wrap{flex:1 1 0;max-width:134px;min-width:0;opacity:0;
  animation:crtIn .5s var(--ease) both}
.crt-wrap--l{--d:0s;animation-delay:.18s}
.crt-wrap--mid{--d:.07s;animation-delay:.3s;transform:translateY(-8px) scale(1.07);z-index:2}
.crt-wrap--r{--d:.14s;animation-delay:.42s}
@keyframes crtIn{to{opacity:1}}
.crt{display:block;width:100%;height:auto;overflow:visible}

/* ---- shared creature parts ------------------------------------------------ */
.crt .shadow{fill:rgba(0,0,0,.28)}
.crt .eyeball{fill:var(--cream)}
.crt .pupil{fill:var(--dark)}
.crt .shine{fill:#fff}
.crt .iris--amber{fill:var(--amber)}
.crt .iris--green{fill:#7fe0a0}
.crt .iris--rust{fill:#f6a04c}
.crt .eye-shut{fill:none;stroke:var(--dark);stroke-width:3;stroke-linecap:round;opacity:0;
  transition:opacity .1s linear calc(var(--d,0s) + .06s)}
.crt--cat .eye-shut{stroke:rgba(242,230,207,.8)}      /* dark head needs a light lid line */
.crt--owl .ring{fill:var(--owl)}                       /* owl spectacles */
.crt .rim{fill:none;stroke:var(--rim);stroke-width:2.4;stroke-linecap:round;opacity:.4}
.crt .line{fill:none;stroke:var(--dark);stroke-width:1.8;stroke-linecap:round;opacity:.75}
.crt .toes{fill:none;stroke:var(--dark);stroke-width:2;stroke-linecap:round;opacity:.45}
.crt .stripe{fill:none;stroke:var(--dark);stroke-width:3;stroke-linecap:round;opacity:.5}
.crt--owl .scallop{fill:none;stroke:var(--owl2);stroke-width:2;stroke-linecap:round;opacity:.6}
.crt--owl .foot{fill:none;stroke:var(--amber);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.crt--cat .whisk path{fill:none;stroke:rgba(242,230,207,.5);stroke-width:1.4;stroke-linecap:round}
.crt--cat .tailline{fill:none;stroke:var(--cat2);stroke-width:8.5;stroke-linecap:round}

/* ---- pupils follow the cursor: js sets --ex/--ey in [-1,1] on the stage ----
   per-creature multiplier so the trio doesn't track in lock-step */
.crt{--em:1}
.crt--fox{--em:.8}
.crt--cat{--em:1.15}
.crt .pupils{
  transform:translate(calc(var(--ex,0)*var(--em,1)*3px),calc(var(--ey,0)*var(--em,1)*3px));
  transition:transform .14s linear}

/* ---- head tilts subtly toward the cursor (js sets --hx on the stage) ------ */
.crt .head{transform-box:view-box;transform-origin:60px 76px;
  transform:rotate(calc(var(--hx,0)*5deg));transition:transform .18s linear}
.crt--owl .head{transform:rotate(calc(var(--hx,0)*7deg))}   /* owls commit to the tilt */
.crt--fox .head{transform:rotate(calc(var(--hx,0)*3.5deg))}

/* ---- eyes: squeeze shut (scaleY) BEFORE the paws land ---------------------- */
.crt .eye-open{transform-box:fill-box;transform-origin:center;
  transition:transform .16s cubic-bezier(.6,0,.8,.5) var(--d,0s),
             opacity .1s linear calc(var(--d,0s) + .08s)}
.eyefx--cover .crt .eye-open{transform:scaleY(.08);opacity:0}
.eyefx--cover .crt .eye-shut{opacity:1}
/* peek: eyes reopen but pupils dart away guiltily; the cat keeps one shut */
.eyefx--cover.eyefx--peek .crt .eye-open{transform:none;opacity:1}
.eyefx--cover.eyefx--peek .crt .eye-shut{opacity:0}
.eyefx--cover.eyefx--peek .crt .pupils{transform:translate(4.5px,1px)}
.eyefx--cover.eyefx--peek .crt--fox .pupils{transform:translate(-4.5px,1px)}
.eyefx--cover.eyefx--peek .crt--cat .eye--l .eye-open{transform:scaleY(.08);opacity:0}
.eyefx--cover.eyefx--peek .crt--cat .eye--l .eye-shut{opacity:1}

/* ---- the covering paws/wings ----------------------------------------------
   Shared spring drives all three (springy overshoot up, slight bounce down);
   fox+cat translate their paws up over the eyes, the owl ROTATES its wings up
   around the shoulder pivots so they cross over its face. */
.crt .arm{transform-box:fill-box;transform-origin:center;
  transition:transform .55s cubic-bezier(.34,1.8,.4,1) var(--d,0s)}
.crt--owl .arm{transform-box:view-box}
.crt--owl .arm--l{transform-origin:29px 66px}
.crt--owl .arm--r{transform-origin:91px 66px}
.eyefx--cover .crt .arm--l{transform:translate(2px,-48px) rotate(8deg)}
.eyefx--cover .crt .arm--r{transform:translate(-2px,-48px) rotate(-8deg)}
.eyefx--cover .crt--owl .arm--l{transform:rotate(-115deg)}
.eyefx--cover .crt--owl .arm--r{transform:rotate(115deg)}
/* peek: arms drop to half-mast */
.eyefx--cover.eyefx--peek .crt .arm--l{transform:translate(2px,-26px) rotate(4deg)}
.eyefx--cover.eyefx--peek .crt .arm--r{transform:translate(-2px,-26px) rotate(-4deg)}
.eyefx--cover.eyefx--peek .crt--owl .arm--l{transform:rotate(-55deg)}
.eyefx--cover.eyefx--peek .crt--owl .arm--r{transform:rotate(55deg)}

/* ---- idle life (only while .eyefx-active): breathe · blink · tail · ears -- */
.eyefx-active .crt{animation:crtBreathe 4.4s ease-in-out infinite}
.eyefx-active .crt-wrap--mid .crt{animation-delay:.6s}
.eyefx-active .crt-wrap--r .crt{animation-delay:1.1s}
@keyframes crtBreathe{0%,100%{transform:translateY(0)}50%{transform:translateY(-2.5px)}}

.eyefx-active:not(.eyefx--cover) .crt .eye-open{animation:crtBlink 5.6s ease-in-out infinite}
.eyefx-active:not(.eyefx--cover) .crt--fox .eye-open{animation-delay:1.7s}
.eyefx-active:not(.eyefx--cover) .crt--cat .eye-open{animation-delay:3.2s}
@keyframes crtBlink{0%,92.5%,100%{transform:scaleY(1)}95.5%{transform:scaleY(.08)}}

/* uncover → quick double-blink (js flips .eyefx--wake for ~.9s) */
.eyefx-active.eyefx--wake .crt .eye-open{animation:crtWake .75s ease-in-out both}
@keyframes crtWake{0%,26%,58%,100%{transform:scaleY(1)}13%,42%{transform:scaleY(.1)}}

/* tails sway on different periods; the cat flicks */
.crt .tail{transform-box:view-box}
.crt--fox .tail{transform-origin:84px 100px}
.crt--cat .tail{transform-origin:38px 114px}
.crt--owl .tail{transform-origin:84px 112px}
.eyefx-active .crt--fox .tail{animation:tailSway 3.6s ease-in-out infinite}
.eyefx-active .crt--cat .tail{animation:tailFlick 5.2s ease-in-out infinite}
.eyefx-active .crt--owl .tail{animation:tailSway 5.8s ease-in-out infinite reverse}
@keyframes tailSway{0%,100%{transform:rotate(-3deg)}50%{transform:rotate(3.5deg)}}
@keyframes tailFlick{0%,55%,100%{transform:rotate(0)}68%{transform:rotate(8deg)}82%{transform:rotate(-4deg)}}

/* occasional ear twitch, one ear each, long offbeat periods */
.crt .ear{transform-box:fill-box;transform-origin:50% 92%}
.eyefx-active .crt--fox .ear--r{animation:earTwitch 7s linear 3s infinite}
.eyefx-active .crt--cat .ear--l{animation:earTwitch 9s linear 5.5s infinite}
.eyefx-active .crt--owl .ear--l{animation:earTwitch 11s linear 8s infinite}
@keyframes earTwitch{0%,90%,100%{transform:rotate(0)}93%{transform:rotate(-9deg)}96.5%{transform:rotate(4deg)}}

/* ---- the show/hide-password toggle eyefx injects into the password field -- */
.auth-field{position:relative}
.eyefx-toggle{position:absolute;right:9px;bottom:7px;width:33px;height:33px;
  display:grid;place-items:center;border:0;border-radius:9px;cursor:pointer;
  background:transparent;color:rgba(255,255,255,.5);pointer-events:auto;
  transition:color .2s var(--ease),background .2s var(--ease)}
.eyefx-toggle:hover{color:#fff;background:rgba(255,255,255,.08)}
.eyefx-toggle svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.eyefx-toggle .icon-off{display:none}
.eyefx-toggle[aria-pressed="true"] .icon-on{display:none}
.eyefx-toggle[aria-pressed="true"] .icon-off{display:block}
/* keep typed password clear of the toggle */
.auth-field input[type="password"],.auth-field.has-eye input{padding-right:44px}

/* ---- perf / a11y: freeze tracking + idle, keep the cover transition -------- */
html[data-anim="off"] .eyefx-stage,html[data-anim="off"] .eyefx-stage *,
html[data-perf="3"] .eyefx-stage,html[data-perf="3"] .eyefx-stage *{
  animation:none!important}
html[data-anim="off"] .eyefx-stage,html[data-perf="3"] .eyefx-stage{opacity:1;transform:none}
html[data-anim="off"] .crt-wrap,html[data-perf="3"] .crt-wrap{opacity:1}
html[data-perf="3"] .crt .pupils,html[data-anim="off"] .crt .pupils{transform:none!important}
html[data-perf="3"] .crt .head,html[data-anim="off"] .crt .head{transform:none!important}
html[data-perf="3"] .crt .head{transform:none!important}
@media (prefers-reduced-motion:reduce){
  .eyefx-stage,.eyefx-stage *{animation:none!important}
  .eyefx-stage{opacity:1;transform:none}
  .crt-wrap{opacity:1}
  .crt .arm,.crt .eye-open,.crt .eye-shut,.crt .pupils,.eyefx-cap span{transition:none!important}
  .crt .pupils,.crt .head{transform:none!important}
}
