/* Skarv Rock Light — motion (owner: frontend-claude)
   Reads from JS: --progress (per [data-scroll]), --storm / --scroll (:root), html[data-stage], html.is-flash.
   Compositor-friendly properties only (opacity, transform). */

@keyframes rise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes caret { 50% { opacity: 0; } }
/* Fl(2) W 12s: flash at 0.0 s and 2.0 s, each about 0.5 s */
@keyframes flash12 {
  0% { opacity: 0; } 1% { opacity: 1; } 4.2% { opacity: 0; }
  16.6% { opacity: 0; } 17.6% { opacity: 1; } 20.8% { opacity: 0; } 100% { opacity: 0; }
}
@keyframes sweep { to { transform: translateX(100cqw); } }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- hero entrance (CSS only: works without JS) ---- */
.hero-inner > * { animation: rise 1s var(--ease-out) both; }
.hero-inner > :nth-child(1) { animation-delay: 80ms; }
.hero-inner > :nth-child(2) { animation-delay: 180ms; animation-duration: 1.3s; }
.hero-inner > :nth-child(3) { animation-delay: 420ms; }
.hero-inner > :nth-child(4) { animation-delay: 540ms; }
.hero-inner > :nth-child(5) { animation-delay: 660ms; }
.scroll-hint { animation: fade 1.2s 1.2s var(--ease-out) both; }
.scroll-hint-line { transform-origin: 50% 0; animation: bob 2.4s var(--ease-swell) infinite; }

/* ---- the light: brand, lamp section ---- */
.brand-flash, .lamp-flash { animation: flash12 12s linear infinite; }
.lamp-timeline { container-type: inline-size; }
.lamp-cursor { animation: sweep 12s linear infinite; }
.room[data-room="lamp-room"] .room-window::before { animation: spin 12s linear infinite; }
.lamp-ring { animation: spin 90s linear infinite; }

/* ---- scroll reveals (ui.js adds [data-reveal], .reveal-ready, then .is-armed just below the fold and .is-revealed on entry).
   Only elements armed by ui.js are ever hidden, so far-off content is never invisible to tools that do not scroll. ---- */
html.reveal-ready [data-reveal].is-armed:not(.is-revealed) { opacity: 0; transform: translateY(28px); transition: none; }
html.reveal-ready .room[data-reveal].is-armed:not(.is-revealed) { transform: translateY(40px) scale(0.98); }
html.reveal-ready [data-reveal].is-revealed { transition: opacity 0.9s var(--ease-out) var(--d, 0ms), transform 0.9s var(--ease-out) var(--d, 0ms); }

html.reveal-ready .room[data-reveal].is-revealed { transition: opacity 0.9s var(--ease-out) var(--d, 0ms), transform 0.9s var(--ease-out) var(--d, 0ms), border-color var(--t-fast), box-shadow var(--t-med); }
/* hover lift must still win once revealed */
html.reveal-ready .room[data-reveal].is-revealed:hover,
html.reveal-ready .room[data-reveal].is-revealed:focus-within { transform: translateY(-3px); transition-delay: 0ms; }

/* the crossing draws itself: chart rises slowly with scroll progress */
#crossing .chart-frame { transform: translateY(calc((0.5 - var(--progress, 0.5)) * 36px)); will-change: transform; }

/* ---- the weather turns ---- */
html::before { /* page dims as the storm rises */
  content: ""; position: fixed; inset: 0; z-index: 5; pointer-events: none;
  background: #0a1522; opacity: calc(var(--storm) * 0.26);
}
#storm-canvas { position: fixed; inset: 0; inline-size: 100%; block-size: 100%; z-index: 4; pointer-events: none; opacity: var(--storm); }
html[data-stage="storm"] .reading dd { animation: shake 0.18s linear infinite alternate; }
@keyframes shake { from { transform: translate(-0.6px, 0.4px); } to { transform: translate(0.6px, -0.4px); } }
html[data-stage="clear"] .reading dd { animation: none; }
/* one lightning flash, applied by scroll.js for 120 ms */
html.is-flash::after {
  content: ""; position: fixed; inset: 0; z-index: 60; pointer-events: none; background: #dfe9ff; mix-blend-mode: difference;
}

/* ---- the lighthouse beam over the whole page: canvas#beam-canvas is drawn by js/hero.js (or beam.js).
   Above the content (main is z 2, so 3 here), below the rain (4). Screen at night, multiply by day, so text stays readable. ---- */
#beam-canvas { position: fixed; inset: 0; inline-size: 100%; block-size: 100%; z-index: 3; pointer-events: none; mix-blend-mode: screen; }
html[data-theme="light"] #beam-canvas { mix-blend-mode: multiply; }

/* ---- micro-interactions ---- */
.brand:hover .brand-name { letter-spacing: 0.03em; }
.brand-name { transition: letter-spacing var(--t-med) var(--ease-out); }
.reading dd { display: inline-block; }
.lamp-specs > div { transition: transform var(--t-med) var(--ease-out); }
.lamp-specs > div:hover { transform: translateY(-4px); }
.form-confirmation { animation: rise 0.8s var(--ease-out) both; }
.theme-ripple { position: fixed; z-index: 70; border-radius: 50%; pointer-events: none; background: var(--foam); mix-blend-mode: difference; transform: scale(0); animation: ripple 0.7s var(--ease-out) forwards; }
@keyframes ripple { 0% { transform: scale(0); opacity: 0.9; } 100% { transform: scale(1); opacity: 0; } }

/* ---- prefers-reduced-motion: static, readable, lamp lit ---- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-delay: 0ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; transition-delay: 0ms !important; scroll-behavior: auto !important; }
  html.reveal-ready [data-reveal].is-armed:not(.is-revealed) { opacity: 1; transform: none; }
  #crossing .chart-frame { transform: none; will-change: auto; }
  .weather-inner { transform: none; }
  #storm-canvas { display: none; }
  html::before, html.is-flash::after { display: none; }
  .reading dd { animation: none !important; }
  .lamp-flash { animation: none; opacity: 1; }
  .brand-flash { animation: none; opacity: 0.7; }
  .lamp-cursor { animation: none; transform: translateX(16%); }
  #beam-canvas { display: none; }
  .theme-ripple { display: none; }
  .room:hover, .room:focus-within { transform: none; }
  .lamp-ring, .scroll-hint-line, .room[data-room="lamp-room"] .room-window::before { animation: none; }
}
