/* Orca Systems - home page motion and section rhythm (staging, 2026-11-01).
   Loaded by index.html only, after styles.css. Rules for everything in this file:
   - transform and opacity only, 150 to 700 ms, the site's --ease-out;
   - every animation sits inside prefers-reduced-motion: no-preference, so the default state is the final,
     fully visible state: no script, reduced motion, print and full-page screenshots all see the finished page;
   - nothing moves the layout (CLS 0), nothing loops, nothing plays video.
   Sources of the ideas (credited in MOTION_IMPLEMENTATION_2026-11-01.md): iart-kinetic-typography (mask reveal),
   iart-animation-principles (ease-out enter, stagger 40 to 80 ms, three layers), iart-motion-background (slow
   ambient layer, finite, paused offscreen), motionmaxxing (enter by moving, hold before the payoff). */

/* ---------- Hero: night band, owner voice, two real screens ---------- */
.hero--story { background: var(--color-band); color: var(--color-on-band); padding-bottom: var(--space-7); }
.hero--story::before { display: none; }
.hero--story h1, .hero--story h2 { color: var(--color-on-band); }
.hero--story .hero-badge { color: var(--color-on-band); }
.hero--story .hero-lede { color: var(--color-on-band-muted); }
.hero--story .hero-proof { color: var(--color-on-band-muted); }
.hero--story .hero-proof svg { color: var(--color-on-band); }
.hero--story .hero-proof a { color: var(--color-on-band); text-decoration-color: var(--color-accent); }
.hero--story .btn-ghost { color: #fff; border-color: rgba(255, 255, 255, 0.65); }
.hero--story .btn-ghost:hover { background: rgba(255, 255, 255, 0.12); border-color: #fff; }
.hero--story :is(a, button):focus-visible { outline-color: #fff; }
.hero--story .hero-h1 { max-width: none; }
/* Two lines, each one a mask: the line rises out of its own baseline. Bottom padding keeps descenders (y, p) whole. */
.hero-h1 .ln { display: block; overflow: hidden; padding-bottom: 0.16em; margin-bottom: -0.16em; }
.hero-h1 .ln > span { display: block; }

/* Ambient layer: a warm lamp bottom left, a cool wash top right. Static by default; moves once, 14 s, then holds. */
.hero-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.glow { position: absolute; border-radius: 50%; aspect-ratio: 1; will-change: transform; }
.glow--warm { width: 62%; left: -14%; bottom: -46%; background: radial-gradient(closest-side, rgba(234, 106, 46, 0.30), rgba(234, 106, 46, 0)); transform: translate(6%, -4%) scale(1.06); }
.glow--cool { width: 58%; right: -10%; top: -40%; background: radial-gradient(closest-side, rgba(110, 140, 255, 0.26), rgba(110, 140, 255, 0)); transform: translate(-5%, 6%) scale(1.04); }

/* The two screens. Rate rules in front of the nightly price row, both real captures (sales/images/hook). */
.hero-stack { position: relative; max-width: 700px; }
.hs-rule, .hs-cal { margin: 0; }
.hs-rule .hw { background: #fff; }
.hs-cal { position: relative; z-index: 2; width: 78%; margin: -10.4% 0 0 auto; overflow: hidden; border-radius: 12px; border: 1px solid color-mix(in srgb, var(--color-ink) 18%, var(--color-border)); box-shadow: var(--shadow-frame); background: var(--color-card); }
.hs-cal::before { content: ""; display: block; height: 34px; border-bottom: 1px solid var(--color-border); background: radial-gradient(circle at 18px 17px, #C2C9DB 0 4.5px, transparent 5px), radial-gradient(circle at 36px 17px, #C2C9DB 0 4.5px, transparent 5px), radial-gradient(circle at 54px 17px, #C2C9DB 0 4.5px, transparent 5px), var(--color-muted); }
.hs-cal img { display: block; width: 100%; max-width: none; height: auto; }
.hs-ring { position: absolute; left: 26%; top: 29.5%; width: 18%; height: 12%; border: 2px solid var(--color-accent); border-radius: 8px; pointer-events: none; }
.hs-cap { margin: var(--space-3) 0 0; max-width: 56ch; font-size: 0.88rem; line-height: 1.5; color: var(--color-on-band-muted); }
@media (max-width: 960px) {
  .hero--story { padding-bottom: var(--space-6); }
  .hero-stack { max-width: none; }
}
@media (max-width: 720px) {
  .hs-cal { width: 100%; margin: var(--space-3) 0 0; }
  /* keep the capture at 0.36 of its file width or more even on a 360 px phone: crop the right edge, never shrink */
  .hs-cal img { width: max(100%, 358px); }
  .hs-ring { display: none; }
}

/* ---------- Motion (all of it opt-in) ---------- */
@media (prefers-reduced-motion: no-preference) {
  @keyframes mo-rise { from { opacity: 0; transform: translateY(14px); } }
  @keyframes mo-mask { from { transform: translateY(108%); } }
  @keyframes mo-slide { from { transform: translateY(28px); } }
  @keyframes mo-ring { from { opacity: 0; transform: scale(1.18); } }
  @keyframes mo-warm { from { opacity: 0; transform: translate(-6%, 8%) scale(0.9); } 12% { opacity: 1; } }
  @keyframes mo-cool { from { opacity: 0; transform: translate(6%, -6%) scale(0.92); } 12% { opacity: 1; } }

  .hero--story .mo-in { animation: mo-rise 560ms var(--ease-out) both; animation-delay: var(--mo-t, 0ms); }
  .hero-h1 .ln > span { animation: mo-mask 640ms var(--ease-out) both; animation-delay: calc(var(--l) * 110ms + 40ms); }
  /* the first screen is the largest thing in view, so it only slides (no fade): it is painted from the first frame */
  .hs-rule { animation: mo-slide 640ms var(--ease-out) both; animation-delay: 120ms; }
  .hs-cal { animation: mo-rise 600ms var(--ease-out) both; animation-delay: 420ms; }
  .hs-ring { animation: mo-ring 420ms var(--ease-out) both; animation-delay: 1000ms; }
  .glow--warm { animation: mo-warm 14s var(--ease-in-out) both; }
  .glow--cool { animation: mo-cool 14s var(--ease-in-out) both; }
  /* on a phone the screens sit below the first screen: wait until the page reveals them */
  .hero-stack.reveal-pending:not(.is-in) :is(.hs-rule, .hs-cal, .hs-ring) { animation-play-state: paused; }
  .hero--story.is-paused :is(.glow, .mo-in) { animation-play-state: paused; }

  /* scroll reveal, tightened: 480 ms (was 640), 14 px (was 20), 45 ms per step (was 60) */
  .reveal-pending { transform: translateY(14px); }
  .reveal-pending.is-in { transition-duration: 480ms; transition-delay: calc(var(--i, 0) * 45ms); }
}

/* Touch screens have no hover: do not leave a lifted button behind after a tap */
@media (hover: none) {
  .btn:hover { transform: none; box-shadow: none; }
  .shot-link:hover, .frame > a.zoomable:hover { transform: none; }
}

/* ---------- Section rhythm, from existing tokens only ---------- */
/* fact strip: light, so the night hero and the navy price band are not the same colour twice in a row */
.logo-strip--light { background: var(--color-card); color: var(--color-ink); border-bottom: 1px solid var(--color-border); }
.logo-strip--light .container > span + span { border-left-color: var(--color-border); }
@media (max-width: 760px) { .logo-strip--light .container > span + span { border-top-color: var(--color-border); } }
/* reviews: a white band between the tinted showcase / navy price above and the paper blog below */
.band-card { background: var(--color-card); border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
/* the price figure counts up once (js/motion-home.js); tabular figures and a reserved width keep it from moving anything */
.price-band .count { display: inline-block; font-variant-numeric: tabular-nums; }
