/* ==========================================================================
   physicsbase — motion layer (cinematic)
   Refined-but-expressive scroll & interaction motion on top of the existing
   "datasheet" design. Transform/opacity/filter only, for GPU smoothness.

   Safety contract:
   - All initial-hidden states are gated on `html.pb-motion`, added by motion.js
     only when JS runs AND reduced motion is not requested. No JS / reduced
     motion => everything renders fully visible.
   - No new colours except the shared accent (inherited per page).
   ========================================================================== */

:root {
  --pb-ease: cubic-bezier(.16, .84, .34, 1);      /* long, cinematic settle */
  --pb-ease-out: cubic-bezier(.22, .61, .36, 1);
  --pb-accent: #FF3B00;
}

/* ---- scroll reveal (blocks) ----------------------------------------------- */
html.pb-motion [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 46px, 0) scale(.972);
  transition:
    opacity .95s var(--pb-ease),
    transform 1.05s var(--pb-ease);
}
html.pb-motion [data-reveal].pb-anim { will-change: opacity, transform, filter; }
html.pb-motion [data-reveal].pb-in { opacity: 1; transform: none; }

/* directional entrances for side-by-side layouts */
html.pb-motion [data-reveal].pb-left  { transform: translate3d(-54px, 22px, 0) scale(.98); }
html.pb-motion [data-reveal].pb-right { transform: translate3d( 54px, 22px, 0) scale(.98); }
html.pb-motion [data-reveal].pb-left.pb-in,
html.pb-motion [data-reveal].pb-right.pb-in { transform: none; }

/* softer, blur-in variant for dense prose blocks (paragraphs, lists) */
html.pb-motion [data-reveal="soft"] {
  transform: translate3d(0, 26px, 0);
  filter: blur(6px);
  transition:
    opacity .8s var(--pb-ease-out),
    transform .8s var(--pb-ease-out),
    filter .8s var(--pb-ease-out);
}
html.pb-motion [data-reveal="soft"].pb-in { filter: none; }

/* ---- hero intro (bespoke, runs once on load) ------------------------------ */
html.pb-motion .pb-hero-item {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  transition: opacity 1s var(--pb-ease), transform 1.1s var(--pb-ease);
  will-change: opacity, transform;
}
html.pb-motion .pb-hero-item.pb-in { opacity: 1; transform: none; }

/* headline word-by-word settle, with a gentle blur lift */
html.pb-motion .pb-word {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 1em, 0) rotate(1.2deg);
  filter: blur(8px);
  transition:
    opacity .85s var(--pb-ease),
    transform .95s var(--pb-ease),
    filter .85s var(--pb-ease);
  will-change: opacity, transform, filter;
}
html.pb-motion .pb-word.pb-in { opacity: 1; transform: none; filter: none; }

/* parallax targets (translation set inline by JS) */
html.pb-motion .pb-parallax { transition: transform .45s var(--pb-ease-out); will-change: transform; }
html.pb-motion .pb-scroll-parallax { will-change: transform; }

/* ---- ambient living hero glow --------------------------------------------
   A slow-drifting warm glow behind the hero. Very low opacity so it reads as
   depth, never as a coloured block. Sits under content (z-index 0). */
html.pb-motion .hero { position: relative; overflow: hidden; }
html.pb-motion .pb-hero-glow {
  position: absolute; inset: -30% -10% -30% -10%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(38% 44% at 22% 28%, rgba(255, 59, 0, .12), transparent 70%),
    radial-gradient(34% 40% at 82% 72%, rgba(255, 59, 0, .08), transparent 72%);
  filter: saturate(115%);
  animation: pb-glow-drift 22s ease-in-out infinite alternate;
}
html.pb-motion .hero > *:not(.pb-hero-glow):not(.pb-scroll-parallax) { position: relative; z-index: 1; }
@keyframes pb-glow-drift {
  0%   { transform: translate3d(-3%, -2%, 0) scale(1.02); opacity: .9; }
  50%  { transform: translate3d( 2%,  3%, 0) scale(1.08); opacity: 1; }
  100% { transform: translate3d( 4%, -1%, 0) scale(1.04); opacity: .85; }
}

/* slow ambient drift of the faint engineering column grid (page-wide) */
html.pb-motion .sheet::before { animation: pb-grid-drift 60s linear infinite; }
@keyframes pb-grid-drift {
  from { background-position: 0 0; }
  to   { background-position: 0 -80px; }
}

/* ---- interactive hover: magnetic buttons & tilt cards --------------------- */
html.pb-motion .pb-magnetic { transition: transform .28s var(--pb-ease-out); }
html.pb-motion .pb-tiltable {
  transition: transform .3s var(--pb-ease-out), box-shadow .3s var(--pb-ease-out);
  transform-style: preserve-3d;
}
html.pb-motion .pb-lift { transition: transform .25s var(--pb-ease-out), box-shadow .25s var(--pb-ease-out); }
html.pb-motion .pb-lift:hover { transform: translateY(-3px); }

/* ---- scroll progress bar (thin accent line at the very top) --------------- */
.pb-progress {
  position: fixed; top: 0; left: 0; height: 2.5px; width: 0;
  background: linear-gradient(90deg, var(--pb-accent), #ff7a4d);
  z-index: 60; pointer-events: none;
  box-shadow: 0 0 12px rgba(255, 59, 0, .5);
  transition: width .12s linear; opacity: .95;
}

/* ---- header condense on scroll -------------------------------------------- */
html.pb-motion header.pb-scrolled {
  box-shadow: 0 1px 0 rgba(20, 19, 16, .06), 0 12px 34px -18px rgba(20, 19, 16, .4);
}

/* count-up numbers hold their box so digits don't reflow */
html.pb-motion [data-pb-count] { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Accessibility: honour reduced-motion no matter what JS did.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.pb-motion [data-reveal],
  html.pb-motion .pb-hero-item,
  html.pb-motion .pb-word,
  html.pb-motion .pb-parallax,
  html.pb-motion .pb-scroll-parallax {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
  }
  html.pb-motion .pb-hero-glow,
  html.pb-motion .sheet::before { animation: none !important; }
  .pb-progress { display: none; }
}
