/* ============================================================================
   PN MOTION LIVE — the ambient/arrival layer (CEO 2026-07-31: "our game is very
   static so needs bringing to life", ref brik.space).
   Pairs with assets/js/pn-motion-live.js. Everything here is transform/opacity
   only, scoped to the management surfaces (body[data-view="office"]), and OFF
   during the pitch cinema (body.pn-call-live / data-view="pitch") which owns its
   own pacing. UX_RULES §4 + §11: motion sells the moment; prefers-reduced-motion
   is a first-class rendering, not an afterthought.

   CLS DISCIPLINE: nothing here or in the module is injected into the flow after
   paint. The one box that changes size (the wire ticker) only ever does so inside
   the tab click that mounts it — the browser's recent-input window — and only when
   the module has measured that the copy overruns.
   ========================================================================== */

/* ── 2. AMBIENT DRIFT — the idle surfaces breathe ───────────────────────────
   Long, unsynchronised periods (7–34s) so nothing ever reads as a metronome.
   Only decorative plates/marks move; never a scrim that carries AA contrast,
   never a control, never text a player is reading. */
@media (prefers-reduced-motion: no-preference) {

  /* the graded agency-film plate behind the Performance hero — a slow push-in.
     .pn-vibe-media already rests at scale(1.05); the drift extends that, so the
     resting frame is unchanged and nothing can pop. */
  body[data-view="office"]:not(.pn-call-live) .pn-vibe-media {
    animation: pnLiveKen 26s cubic-bezier(.42,0,.58,1) infinite alternate;
  }

  /* the live-floor footage — the same move, deliberately out of phase */
  body[data-view="office"]:not(.pn-call-live) .floor-bg {
    animation: pnLiveKenSlow 34s cubic-bezier(.42,0,.58,1) infinite alternate;
  }

  /* the diegetic drywipe pipeline diagram behind the masthead — a faint breath */
  body[data-view="office"]:not(.pn-call-live) .glasswall svg {
    animation: pnLiveBreath 9s ease-in-out infinite alternate;
    transform-origin: 60% 50%;
  }
  /* the glass edge highlight — a slow travelling glint */
  body[data-view="office"]:not(.pn-call-live) .glasswall .gw-edge {
    animation: pnLiveGlint 6.5s ease-in-out infinite alternate;
  }

  /* the oversized bleed word behind each section head — barely-there pulse */
  body[data-view="office"]:not(.pn-call-live) .dash-bleed {
    animation: pnLiveBleed 11s ease-in-out infinite alternate;
  }
}

@keyframes pnLiveKen     { from { transform: scale(1.05) translate3d(0,0,0); }
                           to   { transform: scale(1.105) translate3d(-1.2%, -0.9%, 0); } }
@keyframes pnLiveKenSlow { from { transform: scale(1) translate3d(0,0,0); }
                           to   { transform: scale(1.055) translate3d(1%, -1%, 0); } }
@keyframes pnLiveBreath  { from { transform: scale(1) translate3d(0,0,0); opacity: .78; }
                           to   { transform: scale(1.035) translate3d(0,-4px,0); opacity: 1; } }
@keyframes pnLiveGlint   { from { opacity: .35; transform: translate3d(0,4%,0); }
                           to   { opacity: 1;   transform: translate3d(0,-4%,0); } }
@keyframes pnLiveBleed   { from { opacity: .55; transform: translate3d(0,0,0); }
                           to   { opacity: 1;   transform: translate3d(-8px,0,0); } }

/* ── 4. THE WIRE TICKER — "On the wire // live" becomes a crawl ─────────────
   A ticker exists because there is more news than fits. Everything here hangs off
   .pn-tick-on, which the module only adds once it has MEASURED an overrun — so a
   quiet week (or a world with no JS, or a failed script) shows the plain, whole,
   motionless list and nothing is ever silently clipped. The class is applied
   inside the tab-click that mounts the view, i.e. within the browser's recent-input
   window, so it costs no CLS. Under reduced motion the module never runs at all. */
@media (prefers-reduced-motion: no-preference) {
  body[data-view="office"] .s2-wire.pn-tick-on {
    max-height: 118px;
    overflow: hidden;
    position: relative;
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 22px), transparent 100%);
            mask-image: linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 22px), transparent 100%);
  }
  body[data-view="office"] .s2-wire.pn-tick-on .pn-tick-track {
    display: flex;
    flex-direction: column;
    gap: 7px;
    will-change: transform;
    animation: pnLiveTick var(--pn-tick-dur, 26s) linear infinite;
  }
  /* pausable — hover OR keyboard focus inside the column stops the crawl dead */
  body[data-view="office"] .s2-wire.pn-tick-on:hover .pn-tick-track,
  body[data-view="office"] .s2-wire.pn-tick-on:focus-within .pn-tick-track {
    animation-play-state: paused;
  }
  /* the crawl is only a reading aid if the eye can find "now" — the leading
     marker of the live copy stays lit, the clones read as history */
  body[data-view="office"] .s2-wire .pn-tick-clone { opacity: .72; }
}
@keyframes pnLiveTick { from { transform: translate3d(0,0,0); } to { transform: translate3d(0,-50%,0); } }

/* belt-and-braces: if the OS setting flips while the page is live, everything
   this layer added resolves to its static, fully-legible truth. */
@media (prefers-reduced-motion: reduce) {
  .pn-vibe-media, .floor-bg, .glasswall svg, .glasswall .gw-edge, .dash-bleed,
  .s2-wire .pn-tick-track { animation: none !important; }
  .s2-wire { max-height: none !important; overflow: visible !important;
             -webkit-mask-image: none !important; mask-image: none !important; }
  .s2-wire .pn-tick-clone { display: none !important; }
}
