/* ════════════════════════════════════════════════════════════════════
   L8 CINEMA · motion + circadian layer  ·  7SLF STUDIOS / OMNISOFT
   ──────────────────────────────────────────────────────────────────
   The companion to l8-modern.css. That layer made surfaces look right
   standing still; this one decides how they move and how they change
   across a day.

   TWO IDEAS, AND BOTH ARE DRIVEN BY SOMETHING REAL

   1 · CIRCADIAN. The page reads the actual local clock and shifts its
       warmth, luminance and pulse rate through dawn → day → golden →
       dusk → night. Nothing is randomised. At 03:00 the surface is
       cooler, dimmer and breathing slower than the same surface at
       13:00, because that is what the clock says, and the phase name
       is printed on the page so the reason is never a mystery.

   2 · BREATH. Living things do not hold perfectly still. Panels carry
       a very small oscillation — a fraction of a percent of scale and
       a few percent of glow — on a period that lengthens at night.
       It should read as "alive" from the corner of the eye and be
       invisible when looked at directly. If you can see it pulsing,
       it is too strong and the value is wrong.

   MOTION IS OPT-OUT AT THE OS LEVEL. Every animation here is disabled
   by prefers-reduced-motion. Not softened — disabled. A person who has
   asked their system for stillness has already told us the answer.

   USAGE
     <link rel="stylesheet" href="assets/l8-modern.css">
     <link rel="stylesheet" href="assets/l8-cinema.css">
     <script src="assets/l8-cinema.js"></script>
   The script sets data-cir="dawn|morning|day|golden|dusk|night" on
   <html> and keeps the variables below in sync.
   ════════════════════════════════════════════════════════════════════ */

:root{
  /* ── circadian channel · the script writes these, CSS only consumes them ── */
  --cir-warm:0deg;        /* hue rotation applied to ambient light      */
  --cir-lum:1;            /* ambient luminance multiplier               */
  --cir-sat:1;            /* ambient saturation multiplier              */
  --cir-pulse:5.2s;       /* breath period — longer at night            */
  --cir-accent:#2fe8a8;   /* the hour's light                           */
  --cir-accent-2:#8f7dff;
  --cir-veil:rgba(0,0,0,0);/* night dimming veil                        */

  /* ── motion vocabulary · one spring, used everywhere ── */
  --ez-spring:cubic-bezier(.22,1.28,.36,1);
  --ez-out:cubic-bezier(.16,1,.3,1);
  --ez-soft:cubic-bezier(.4,0,.2,1);
  --t-fast:.18s; --t-mid:.34s; --t-slow:.62s; --t-cine:1.1s;
}

/* ════════════════════════════════════════════════════════════════
   AMBIENT · the living backdrop
   ════════════════════════════════════════════════════════════════ */
.cine-amb{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  filter:hue-rotate(var(--cir-warm)) saturate(var(--cir-sat)) brightness(var(--cir-lum));
  transition:filter 4s linear;
}
.cine-amb canvas{position:absolute;inset:0;width:100%;height:100%;display:block}

/* aurora sheets — three, at different speeds, so the drift never repeats visibly */
.cine-aurora{position:fixed;inset:-18%;z-index:0;pointer-events:none;opacity:.55;
  filter:blur(64px) hue-rotate(var(--cir-warm)) saturate(var(--cir-sat));
  transition:opacity 3s var(--ez-soft), filter 4s linear}
.cine-aurora i{position:absolute;border-radius:48% 52% 60% 40%/50% 46% 54% 50%;display:block;
  mix-blend-mode:screen;will-change:transform}
.cine-aurora i:nth-child(1){width:58%;height:62%;left:-6%;top:-14%;
  background:radial-gradient(circle at 40% 40%,var(--cir-accent),transparent 66%);
  opacity:.30;animation:drift-a 46s var(--ez-soft) infinite alternate}
.cine-aurora i:nth-child(2){width:52%;height:56%;right:-8%;top:-6%;
  background:radial-gradient(circle at 55% 45%,var(--cir-accent-2),transparent 66%);
  opacity:.26;animation:drift-b 61s var(--ez-soft) infinite alternate}
.cine-aurora i:nth-child(3){width:66%;height:48%;left:18%;bottom:-22%;
  background:radial-gradient(circle at 50% 50%,var(--cir-accent),transparent 70%);
  opacity:.18;animation:drift-c 78s var(--ez-soft) infinite alternate}
@keyframes drift-a{0%{transform:translate3d(0,0,0) scale(1) rotate(0deg)}
                  100%{transform:translate3d(9%,7%,0) scale(1.16) rotate(22deg)}}
@keyframes drift-b{0%{transform:translate3d(0,0,0) scale(1.08) rotate(0deg)}
                  100%{transform:translate3d(-11%,9%,0) scale(.92) rotate(-18deg)}}
@keyframes drift-c{0%{transform:translate3d(0,0,0) scale(.95)}
                  100%{transform:translate3d(7%,-8%,0) scale(1.2)}}

/* the night veil — a real dimming, not a colour trick */
.cine-veil{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:var(--cir-veil);transition:background 4s linear}

/* keep page content above the ambient layers */
body>.wrap,body>main,body>header,body>nav,body>section,body>footer{position:relative;z-index:2}

/* ════════════════════════════════════════════════════════════════
   BREATH · the small oscillation that reads as alive
   ════════════════════════════════════════════════════════════════ */
@keyframes breathe{
  0%,100%{transform:translateZ(0) scale(1);      filter:brightness(1)}
  50%    {transform:translateZ(0) scale(1.0035); filter:brightness(1.035)}
}
.breathe{animation:breathe var(--cir-pulse) var(--ez-soft) infinite;will-change:transform,filter}
.breathe.slow{animation-duration:calc(var(--cir-pulse) * 1.6)}
.breathe.off{animation:none}
/* stagger so a grid of panels does not pulse in lockstep — that reads mechanical */
.breathe:nth-child(2n){animation-delay:-1.3s}
.breathe:nth-child(3n){animation-delay:-2.7s}
.breathe:nth-child(5n){animation-delay:-3.9s}

/* a status dot that actually beats */
@keyframes beat{0%,100%{opacity:1;box-shadow:0 0 8px currentColor}
                50%{opacity:.55;box-shadow:0 0 16px currentColor}}
.beat{animation:beat var(--cir-pulse) var(--ez-soft) infinite}

/* ════════════════════════════════════════════════════════════════
   ENTRANCE · cinematic reveal, staggered
   ════════════════════════════════════════════════════════════════ */
@keyframes rise{
  from{opacity:0;transform:translate3d(0,18px,0) scale(.985);filter:blur(6px)}
  to  {opacity:1;transform:translate3d(0,0,0)    scale(1);   filter:blur(0)}
}
.reveal{opacity:0}
.reveal.in{animation:rise var(--t-slow) var(--ez-spring) forwards}
.reveal.in.d1{animation-delay:.05s} .reveal.in.d2{animation-delay:.10s}
.reveal.in.d3{animation-delay:.15s} .reveal.in.d4{animation-delay:.20s}
.reveal.in.d5{animation-delay:.25s} .reveal.in.d6{animation-delay:.30s}
.reveal.in.d7{animation-delay:.35s} .reveal.in.d8{animation-delay:.40s}

/* pane transitions — a cut, but a soft one */
@keyframes paneIn{from{opacity:0;transform:translate3d(0,10px,0) scale(.994)}
                  to{opacity:1;transform:none}}
.pane.on{animation:paneIn var(--t-mid) var(--ez-out)}

/* ════════════════════════════════════════════════════════════════
   SURFACES · depth that responds
   ════════════════════════════════════════════════════════════════ */
.cine-lift{transition:transform var(--t-mid) var(--ez-spring),
                      box-shadow var(--t-mid) var(--ez-soft),
                      border-color var(--t-fast) linear}
.cine-lift:hover{transform:translate3d(0,-3px,0)}

/* light that follows the cursor across a card — set by the script */
.cine-glow{position:relative;overflow:hidden}
.cine-glow::before{
  content:'';position:absolute;inset:0;pointer-events:none;opacity:0;
  transition:opacity var(--t-mid) var(--ez-soft);
  background:radial-gradient(340px circle at var(--mx,50%) var(--my,50%),
             color-mix(in srgb,var(--cir-accent) 13%,transparent),transparent 62%);
}
.cine-glow:hover::before{opacity:1}

/* a sweep of light across primary actions, once every long while */
@keyframes sheen{0%{transform:translateX(-140%)}60%,100%{transform:translateX(240%)}}
.cine-sheen{position:relative;overflow:hidden}
.cine-sheen::after{
  content:'';position:absolute;top:0;bottom:0;width:38%;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.30),transparent);
  animation:sheen 7s var(--ez-soft) infinite;
}

/* ════════════════════════════════════════════════════════════════
   DATA IN MOTION
   ════════════════════════════════════════════════════════════════ */
/* bars grow to their measured width rather than appearing at it */
.bar i,.bar>span{transition:width var(--t-cine) var(--ez-out)}

/* SVG lines draw themselves — the script sets the dash length per path */
.cine-draw{stroke-dasharray:var(--len,1200);stroke-dashoffset:var(--len,1200);
           animation:draw 1.5s var(--ez-out) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
.cine-draw.d1{animation-delay:.10s} .cine-draw.d2{animation-delay:.24s}
.cine-draw.d3{animation-delay:.38s}

/* chart marks fade up after the geometry lands */
@keyframes markIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.cine-mark{animation:markIn .5s var(--ez-out) both;animation-delay:.7s}

/* counted numbers get a tabular lock so they do not jitter while counting */
.cine-count{font-variant-numeric:tabular-nums}

/* value changed since last render — a brief flare, then back */
@keyframes flare{0%{background:color-mix(in srgb,var(--cir-accent) 24%,transparent)}
                 100%{background:transparent}}
.cine-flare{animation:flare 1.4s var(--ez-out);border-radius:6px}

/* ════════════════════════════════════════════════════════════════
   PHASE TINTS · what each part of the day looks like
   The script writes data-cir on <html>; these are the destinations
   it eases toward. Values chosen so text contrast never drops below
   the readable threshold at any hour — night dims the SURFACE, not
   the type.
   ════════════════════════════════════════════════════════════════ */
:root[data-cir="dawn"]   {--cir-warm:14deg; --cir-lum:.94; --cir-sat:1.06; --cir-pulse:5.6s;
                          --cir-accent:#ff9d7a; --cir-accent-2:#ffd08a; --cir-veil:rgba(12,6,24,.10)}
:root[data-cir="morning"]{--cir-warm:6deg;  --cir-lum:1.02;--cir-sat:1.05; --cir-pulse:4.6s;
                          --cir-accent:#2fe8a8; --cir-accent-2:#3ddcff; --cir-veil:rgba(0,0,0,0)}
:root[data-cir="day"]    {--cir-warm:0deg;  --cir-lum:1.06;--cir-sat:1.00; --cir-pulse:4.2s;
                          --cir-accent:#3ddcff; --cir-accent-2:#2fe8a8; --cir-veil:rgba(0,0,0,0)}
:root[data-cir="golden"] {--cir-warm:-12deg;--cir-lum:1.0; --cir-sat:1.12; --cir-pulse:5.0s;
                          --cir-accent:#ffb545; --cir-accent-2:#ff7ad9; --cir-veil:rgba(20,8,0,.06)}
:root[data-cir="dusk"]   {--cir-warm:-24deg;--cir-lum:.92; --cir-sat:1.08; --cir-pulse:6.0s;
                          --cir-accent:#8f7dff; --cir-accent-2:#ff7ad9; --cir-veil:rgba(8,4,26,.16)}
:root[data-cir="night"]  {--cir-warm:-34deg;--cir-lum:.84; --cir-sat:.92;  --cir-pulse:6.8s;
                          --cir-accent:#6f8cff; --cir-accent-2:#8f7dff; --cir-veil:rgba(2,4,18,.28)}

/* the readout the script fills — the phase is always stated, never just felt */
.cine-clock{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border-radius:999px;
  font-size:11px;font-weight:600;background:rgba(125,170,255,.07);
  border:1px solid rgba(125,170,255,.16);color:var(--cir-accent);white-space:nowrap;
  transition:color 3s linear,border-color 3s linear}
.cine-clock .ph{text-transform:uppercase;letter-spacing:.13em;font-size:9.5px;opacity:.8}
.cine-clock .tm{font-family:var(--lm-mono,'JetBrains Mono',monospace);color:inherit}
.cine-sun{width:9px;height:9px;border-radius:50%;background:currentColor;flex:none;
  box-shadow:0 0 10px currentColor;animation:beat var(--cir-pulse) var(--ez-soft) infinite}

/* ════════════════════════════════════════════════════════════════
   STILLNESS · asked for at the OS level, honoured completely
   ════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important; animation-iteration-count:1!important;
    transition-duration:.001ms!important; scroll-behavior:auto!important;
  }
  .reveal{opacity:1!important}
  .cine-aurora,.cine-amb{display:none}
  .cine-sheen::after{display:none}
}
