/* MineChef — page-level motion. Owned by the "motion" piece.
   0 parallax frame · 1 load choreography · 2 ambient life in the scene · 3 micro-interactions
   4 below ground (reveals + ambient) · 5 reduced motion. Transforms/opacity only for anything
   continuous; slow and warm; all of it under prefers-reduced-motion: no-preference. */

/* 0. parallax frame — js/main.js writes --px/--py (pointer + idle drift) and --sy (scroll) on .hero.
   Layers: --depth for the pointer, --sink for the scroll. The surface stays glued to the earth
   below; sky and hills sink away (the sun sets) as you scroll down into the mine. */
/* js/main.js writes the parallax transform straight onto each moving element (inline style wins over the rules
   below). It deliberately does NOT drive them through a custom property on .hero: an inherited custom property
   invalidates style for the entire hero subtree (~1400 nodes once the scene SVGs are inline) on every pointer
   move, which on a large screen drops the fold to ~12 fps and shows unpainted (black) compositor tiles.
   These rules are the no-JS / pre-script resting state: --depth and --sink stay declarative so JS can read them,
   and scale() keeps the layers overscanned so a shifted layer never exposes an edge. */
.hero { --px: 0px; --py: 0px; --sy: 0px; --ix: 0px; --iy: 0px; }
.scene__layer {
  transform: translate3d(calc((var(--px) + var(--ix)) * var(--depth, 0)), calc((var(--py) + var(--iy)) * var(--depth, 0) + var(--sy) * var(--sink, 0)), 0) scale(1.06);
}
.scene__layer--sky    { --depth: .25; --sink: .5;  }
.scene__layer--far    { --depth: .45; --sink: .32; }
.scene__layer--near   { --depth: .7;  --sink: .16; }
.scene__layer--ground { --depth: 1;   --sink: 0;   }
/* title column: mid-depth for the pointer, leads the scroll a touch (nearest the camera);
   the cue is pinned to the ground so the cart can never drift into it */
/* the lockup rides the pointer only, on its own compositor layer, so it moves without being repainted */
.hero__content { transform: translate3d(calc(var(--px) * .35), calc(var(--py) * .35 - var(--sy) * .15), 0); will-change: transform; }
.hero__cue     { translate: var(--px) var(--py); }

@media (prefers-reduced-motion: no-preference) {

  /* 1. load choreography. The PICTURE arrives as one piece — a single opacity fade on .scene, which is one
        compositor layer — instead of sliding and scaling each of its eight layers separately: staged per-layer
        entrances made the fold visibly rebuild itself (measured: two 75-90% frame changes 250ms apart) and any
        dropped frame in that window read as a glitch. Only the words still stagger; they are cheap text nodes.
        The wordmark (the LCP element) never starts transparent. */
  @keyframes mc-rise   { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
  @keyframes mc-settle { from { transform: translateY(14px) scale(.985); } to { transform: none; } }
  @keyframes mc-fade-in { from { opacity: 0; } to { opacity: 1; } }

  /* The picture itself carries NO entrance: it is painted as soon as the browser has it. Fading or sliding it
     in only made the fold assemble itself in stages, and holding it back (an opacity gate, or waiting on
     img.decode) cost 5 Lighthouse points and moved the LCP off the wordmark onto the sky image. Only the words
     animate — they are cheap text nodes and they are what the eye follows anyway. */
  .scene__motes { animation: mc-fade-in 900ms ease 900ms backwards; }

  .wordmark { animation: mc-settle 800ms cubic-bezier(.2,.7,.2,1) 60ms backwards; }
  .topbar, .hero__eyebrow, .tagline, .notify, .hero__cue { animation: mc-rise 760ms cubic-bezier(.2,.7,.2,1) backwards; }
  .topbar        { animation-delay: 140ms; }
  .hero__eyebrow { animation-delay: 220ms; }
  .tagline       { animation-delay: 380ms; }
  .notify        { animation-delay: 520ms; }
  .hero__cue     { animation-delay: 900ms; }
  /* once the entrance has played (js/main.js adds .is-settled) the one-shot animations are dropped, so a
     later style flip (viewport emulation, print, screenshot tooling) can never replay the fade-ins */
  .hero.is-settled .scene__motes,
  .hero.is-settled .wordmark, .hero.is-settled .topbar, .hero.is-settled .hero__eyebrow,
  .hero.is-settled .tagline, .hero.is-settled .notify, .hero.is-settled .hero__cue { animation: none; }

  @keyframes mc-nudge { 0%,100% { transform: translateY(0); } 50% { transform: translateY(6px); } }
  .cue__arrow { animation: mc-nudge 1.8s ease-in-out infinite; }

  /* 2. ambient life.
        The scene layers are <img>s and each SVG animates itself from its own <style> (js/main.js explains why we
        no longer inline them), so the rules here only reach what IS inline in index.html: the light companion
        over the mine mouth, the birds, and the two bough images. */
  @keyframes mc-glow-pool { 0%,100% { opacity: .78; } 38% { opacity: 1; } 64% { opacity: .86; } }
  @keyframes mc-glow-rays { 0%,100% { opacity: .7; } 22% { opacity: 1; } 51% { opacity: .82; } 76% { opacity: .95; } }
  @keyframes mc-fire {
    0% { opacity: .55; scale: 1 1; } 23% { opacity: .95; scale: 1.04 1.08; } 47% { opacity: .7; scale: 1.01 1.02; }
    68% { opacity: 1; scale: 1.06 1.1; } 100% { opacity: .55; scale: 1 1; }
  }
  .scene__layer--light .tl-core { transform-box: fill-box; transform-origin: 50% 100%; animation: mc-fire 3.1s ease-in-out -1.2s infinite; }
  .scene__layer--light .tl-pool { animation: mc-glow-pool 4.6s ease-in-out infinite; }
  .scene__layer--light .tl-rays { animation: mc-glow-rays 5.2s ease-in-out -2s infinite; }

  /* boughs breathe from their anchored corner; birds glide toward the sun, wings beating */
  @keyframes mc-bough-l { from { rotate: -1.1deg; } to { rotate: 1.1deg; } }
  @keyframes mc-bough-r { from { rotate: 1.1deg; } to { rotate: -1.1deg; } }
  /* the entrance rides `translate`/`opacity` and the sway rides `rotate`, so they are two independent
     properties: nothing has to be re-declared when .is-settled lands, and the boughs never restart mid-sway
     (re-declaring the shorthand there used to snap them back to the start of the swing) */
  .scene__bough--left  { transform-origin: 0 0;    animation: mc-bough-l 7s ease-in-out infinite alternate; }
  .scene__bough--right { transform-origin: 100% 0; animation: mc-bough-r 7s ease-in-out -3.5s infinite alternate; }
  @keyframes mc-glide { from { translate: 0 0; } to { translate: -46px -14px; } }
  @keyframes mc-flap  { from { scale: 1 1; } to { scale: 1 .45; } }
  .scene__birds { animation: mc-glide 28s ease-in-out infinite alternate; }
  .scene__birds path { transform-box: fill-box; transform-origin: center; animation: mc-flap .7s ease-in-out infinite alternate; }
  .scene__birds path:nth-child(2) { animation-delay: -.25s; animation-duration: .8s; }
  .scene__birds path:nth-child(3) { animation-delay: -.5s; animation-duration: .65s; }

  /* 3. micro-interactions */
  /* primary CTA: a warm halo breathing at rest, a slow shine every few seconds; lifts and brightens */
  @keyframes mc-halo  { 0%,100% { opacity: .35; } 50% { opacity: .9; } }
  @keyframes mc-shine { 0%,78% { background-position: 100% 0; } 100% { background-position: 0% 0; } }
  .notify__button { position: relative; isolation: isolate; transition: transform 180ms ease, box-shadow 180ms ease, filter 180ms ease; }
  .notify__button::before, .notify__button::after { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; }
  .notify__button::before { box-shadow: 0 0 22px 6px rgba(255, 200, 87, .45); animation: mc-halo 3.2s ease-in-out infinite; }
  .notify__button::after {
    background: linear-gradient(112deg, transparent 43%, rgba(255, 255, 255, .42) 50%, transparent 57%) no-repeat;
    background-size: 250% 100%; background-position: 100% 0;
    animation: mc-shine 6.5s ease-in-out 2.4s infinite;
  }
  .notify__button:hover::before, .notify__button:focus-visible::before { animation-play-state: paused; opacity: 1; }
  .notify__button:hover, .notify__button:focus-visible { transform: translateY(-2px); filter: brightness(1.05); box-shadow: 0 5px 0 #C97A18, 0 14px 26px rgba(201, 122, 24, .42); }
  .notify__button:active { transform: translateY(2px) scale(.985); filter: brightness(.98); }
  /* the whole capsule brightens and lifts when you approach or focus it */
  .notify__row { transition: box-shadow 260ms ease, transform 260ms cubic-bezier(.2,.7,.2,1); }
  .notify__row:hover, .notify__row:focus-within { transform: translateY(-1px); box-shadow: 0 14px 34px rgba(58, 34, 56, .32), inset 0 0 0 1px rgba(58, 34, 56, .08), 0 0 0 4px rgba(255, 200, 87, .22); }
  .notify__row:focus-within { box-shadow: 0 14px 34px rgba(58, 34, 56, .32), inset 0 0 0 1px rgba(58, 34, 56, .08), 0 0 0 4px rgba(255, 200, 87, .42); }
  .bedrock .notify__row:hover, .bedrock .notify__row:focus-within { box-shadow: 0 14px 34px rgba(20, 17, 42, .5), inset 0 0 0 1px rgba(58, 34, 56, .08), 0 0 0 4px rgba(255, 184, 92, .34); }
  /* scroll cue: glows and beckons faster on hover, squashes on press (hero.css owns its translate) */
  .cue { transition: scale 200ms cubic-bezier(.2,.7,.2,1), filter 200ms ease; }
  .cue:hover, .cue:focus-visible { filter: brightness(1.08) drop-shadow(0 0 10px rgba(255, 200, 87, .45)); }
  .cue:hover .cue__arrow, .cue:focus-visible .cue__arrow { animation-duration: .8s; }
  .cue:active { scale: .94; }
  .footer a { transition: color 200ms ease, translate 260ms cubic-bezier(.2,.7,.2,1); }
  .footer a:hover { translate: 0 -2px; }

  /* 4. below ground. Hidden states apply only once JS confirmed motion is on (html.mc-motion),
        so no-JS never hides copy; transitions live on the visible state so hiding is instant. */
  html.mc-motion .reveal:not(.is-visible) { opacity: 0; transform: translateY(30px); }
  .reveal.is-visible { opacity: 1; transform: none; transition: opacity 760ms cubic-bezier(.2,.7,.2,1), transform 760ms cubic-bezier(.2,.7,.2,1), translate 260ms ease, box-shadow 260ms ease; }
  .features .reveal.is-visible:nth-child(2) { transition-delay: 100ms; }
  .features .reveal.is-visible:nth-child(3) { transition-delay: 200ms; }
  /* section head: eyebrow, title, copy arrive one after another */
  html.mc-motion .section-head.reveal:not(.is-visible) > * { opacity: 0; transform: translateY(14px); }
  .section-head.reveal.is-visible > * { opacity: 1; transform: none; transition: opacity 640ms cubic-bezier(.2,.7,.2,1), transform 640ms cubic-bezier(.2,.7,.2,1); }
  .section-head.reveal.is-visible > :nth-child(1) { transition-delay: 60ms; }
  .section-head.reveal.is-visible > :nth-child(2) { transition-delay: 140ms; }
  .section-head.reveal.is-visible > :nth-child(3) { transition-delay: 220ms; }
  /* feature cards: the gem pops in after the card, then floats and glints; cards lift on hover */
  @keyframes mc-gem-float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
  @keyframes mc-gem-glint { 0%,86%,100% { filter: brightness(1) drop-shadow(0 0 0 rgba(255,255,255,0)); } 92% { filter: brightness(1.45) drop-shadow(0 0 8px rgba(255, 246, 229, .55)); } }
  html.mc-motion .feature.reveal:not(.is-visible) .feature__icon { opacity: 0; transform: scale(.55) rotate(-14deg); }
  .feature.reveal.is-visible .feature__icon {
    opacity: 1; transform: none;
    transition: opacity 320ms ease 260ms, transform 720ms cubic-bezier(.34, 1.56, .64, 1) 260ms;
    animation: mc-gem-float 4.4s ease-in-out 1.2s infinite, mc-gem-glint 6s ease-in-out 1.6s infinite;
  }
  .feature:nth-child(2).is-visible .feature__icon { animation-delay: 1.9s, 3.4s; }
  .feature:nth-child(3).is-visible .feature__icon { animation-delay: 2.6s, 5.1s; }
  .feature.is-visible:hover { translate: 0 -3px; box-shadow: inset 0 0 0 1px var(--line-strong), 0 12px 28px rgba(20, 17, 42, .35); }
  /* ruler: marks tick in; an amber line digs down to where you are, with a pulsing marker */
  html.mc-motion .ruler__mark:not(.is-visible) { opacity: 0; transform: translate(-8px, -50%); }
  .ruler__mark.is-visible { opacity: 1; transform: translate(0, -50%); transition: opacity 600ms ease, transform 600ms cubic-bezier(.2,.7,.2,1); }
  .ruler { --dig: 0; }
  .ruler__fill {
    position: absolute; left: -2px; top: 0; width: 2px; height: 100%; pointer-events: none;
    background: linear-gradient(to bottom, var(--lantern-soft, #FFD37A), var(--lantern, #FFB347));
    box-shadow: 0 0 10px rgba(255, 184, 92, .6);
    transform-origin: top; transform: scaleY(var(--dig)); will-change: transform;
  }
  @keyframes mc-you { 0% { transform: scale(1); opacity: .6; } 100% { transform: scale(3.2); opacity: 0; } }
  .ruler__you {
    position: absolute; left: -6px; top: calc(var(--dig) * 100%); width: 10px; height: 10px; margin-top: -5px; pointer-events: none;
    border-radius: 50%; background: var(--lantern-hot, #FFE7A3);
    box-shadow: 0 0 0 3px rgba(255, 184, 92, .25), 0 0 14px rgba(255, 184, 92, .7);
  }
  .ruler__you::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--lantern, #FFB347); animation: mc-you 2.4s cubic-bezier(.2,.7,.2,1) infinite; }
  /* bedrock CTA: an ember glow smoulders behind the card */
  @keyframes mc-embers { 0%,100% { opacity: .55; transform: scale(1); } 50% { opacity: 1; transform: scale(1.03); } }
  .bedrock { position: relative; isolation: isolate; }
  .bedrock::before {
    content: ""; position: absolute; inset: -60px -48px -70px; z-index: -1; pointer-events: none; will-change: opacity;
    /* both gradients must reach full transparency INSIDE this box, or its straight edges read as a
       rectangle of light around the card (closest-side keeps the falloff shorter than the box). */
    background:
      radial-gradient(closest-side at 34% 68%, rgba(255, 150, 60, .30), rgba(255, 150, 60, .09) 52%, transparent 78%),
      radial-gradient(closest-side at 76% 64%, rgba(255, 184, 92, .18), transparent 72%);
    animation: mc-embers 5s ease-in-out infinite;
  }
  /* dust canvas (created by JS) sits behind the copy, over the strata */
  .dust { position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
}

/* invalid email nudge (form feedback: a state change, kept under reduced motion too) */
@keyframes mc-shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
.notify__input.is-shaking { animation: mc-shake 320ms ease-in-out; }
.notify__input[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--ember); }

/* 5. reduced motion: no continuous motion, no parallax, everything visible (JS bails too) */
@media (prefers-reduced-motion: reduce) {
  .scene__layer, .hero__content, .hero__cue { transform: none; translate: none; }
  .reveal, .section-head.reveal > *, .feature__icon, .ruler__mark { opacity: 1; transform: none; transition: none; }
  .ruler__mark { transform: translateY(-50%); }
  .notify__input.is-shaking { animation: none; }
  .dust { display: none; }
}
