/* ============================================================================
 * canonical-motion-bundle.v1.css — THE Stethon scroll-reveal motion bundle
 * ============================================================================
 * v1 · 2026-07-12 · W-CSS deliverable of the 2026-07-11 WP-generation mega
 * audit (REPORT.md §7 Layer 3). This file + canonical-motion-hook.v1.js are
 * the SINGLE source of truth for reveal motion on every future Stethon build.
 * See ref 20 §9c for the governing doc. Lint gate: css_lint.js must pass with
 * zero errors on any bundle that embeds this.
 *
 * DEPLOY: paste this whole file into Customizer → Additional CSS (Layer 7 —
 * justification: GB Pro 2.x has no Animation panel; motion infrastructure is
 * a legitimate Layer-7 inexpressible per layer-7-css-doctrine). Pair with
 * canonical-motion-hook.v1.js in a GP Hook Element at wp_head (inline, no
 * defer — js-ready must land before first paint).
 *
 * ---------------------------------------------------------------------------
 * THE MECHANISM (non-negotiable — ends the P0-6 no-JS blackout class):
 * Content is VISIBLE BY DEFAULT. The hidden pre-reveal state exists ONLY
 * under `html.js-ready`, which the hook JS sets as its first statement.
 * No JS (blocked, failed, crawler, reader mode) → the selector never matches
 * → the page renders fully visible. This is the GLUE-CSS-TARGET-v1.css
 * L31-32 pattern (Thrivion, 2026-05-31), canonized for all clients.
 *
 * ---------------------------------------------------------------------------
 * DURATION CANON (fork resolved 2026-07-12 — restrained-MH register):
 *   base 350ms · ease cubic-bezier(0.22, 0.9, 0.36, 1) · stagger 40ms/step
 *   · data-delay clamp ≥200 → 120ms · distance 16px
 * WHY: this is the only live-measured, operator-accepted calibration we own
 * (Gryzbek 2026-05-20/21): 12-element stack settles in ~790ms (< the 800ms
 * perceived-sluggish bar), 6-element in ~550ms. Perceived speed is governed
 * by the stagger ladder, not base duration (ref 20 §9b.2).
 * SUPERSEDES (timing values only):
 *   1. memory `stethon-mh-animation-bundle-canon` — its 200ms data-delay
 *      clamp (earlier lever text; the later-validated Gryzbek Section-12
 *      iteration clamps to 120ms).
 *   2. ref 20 §10 checklist — its "0.45s base" line (stale; §9b.2's shipped
 *      block was already 0.35s).
 *   3. GLUE-CSS-TARGET-v1.css — its 600ms base + 150/300ms delays (pre-
 *      calibration draft; its js-ready MECHANISM is kept, its timings are not).
 *
 * ---------------------------------------------------------------------------
 * PER-CLIENT OVERRIDE CONTRACT:
 * Clients customize by re-declaring the four :root tokens below in their OWN
 * :root block ABOVE this bundle — NEVER by re-declaring any rule in this
 * file. Rules here are frozen; a client bundle that redefines [data-gbc~="gbp-reveal"] /
 * [data-gbc~="gbp-stack-cinematic"] rules is a canon violation (css_lint DUP-1 flags it).
 *   --gbp-dur-reveal        per-element transition duration (default 350ms)
 *   --gbp-ease-reveal       easing curve (default the Gryzbek reveal bezier)
 *   --gbp-stagger-step      ladder step (default 40ms; bold verticals may
 *                           use 30ms; NEVER above 80ms — settle-time math)
 *   --gbp-reveal-distance   entry translateY (default 16px restrained;
 *                           bold register may use 24-28px)
 *
 * MARKUP CONTRACT:
 *   [data-gbc~="gbp-reveal"]                     single element fade-up (add .is-visible via JS)
 *   [data-gbc~="gbp-reveal"][data-delay="0|100|200"]  intra-section offset (≥200 clamps to 120ms)
 *   [data-gbc~="gbp-stack-cinematic"]            parent of a card grid; CHILDREN stagger
 * Animate only transform + opacity. No will-change (permanent compositor
 * layers are banned here — see ref 20 §6.1 for the one hover-zoom exception).
 * ========================================================================== */

/* ---- 1. Tokens (defaults — override per client in an earlier :root) ---- */
:root {
  --gbp-dur-reveal: 350ms;
  --gbp-ease-reveal: cubic-bezier(0.22, 0.9, 0.36, 1);
  --gbp-stagger-step: 40ms;
  --gbp-reveal-distance: 16px;
}

/* ---- 2. Visible-by-default base + transition ---- */
[data-gbc~="gbp-reveal"],
[data-topaba-surface] > header,
[data-topaba-surface] > section,
[data-gbc~="gbp-stack-cinematic"] > * {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--gbp-dur-reveal) var(--gbp-ease-reveal),
    transform var(--gbp-dur-reveal) var(--gbp-ease-reveal);
}

/* ---- 3. Hidden pre-reveal state — ONLY under html.js-ready ---- */
html.js-ready [data-gbc~="gbp-reveal"]:not(.is-visible),
html.js-ready [data-topaba-surface] > header:not(.is-visible),
html.js-ready [data-topaba-surface] > section:not(.is-visible) {
  opacity: 0;
  transform: translateY(var(--gbp-reveal-distance));
}
html.js-ready [data-gbc~="gbp-stack-cinematic"]:not(.is-visible) > * {
  opacity: 0;
  transform: translateY(var(--gbp-reveal-distance));
}

/* ---- 4. Revealed state ---- */
/* Plugin-rendered routes are named positionally here for the same reason they are in motion.js:
   they are PHP templates with no block attributes to carry data-gbc. The failure contract is
   unchanged and it is what makes hiding them safe - no JS, a thrown error, or reduced-motion all
   strip html.js-ready, and every one of these rules is scoped under it. */
[data-gbc~="gbp-reveal"].is-visible,
[data-topaba-surface] > header.is-visible,
[data-topaba-surface] > section.is-visible,
[data-gbc~="gbp-stack-cinematic"].is-visible > * {
  opacity: 1;
  transform: none;
}

/* ---- 5. Stagger ladder — monotonic, token-driven, 40ms/step ----
 * Delays apply on the REVEAL only (.is-visible), so the hide is instant.
 * :nth-child(n+9) caps the ladder — items 9+ share step 8 (settle-time
 * ceiling: 8 × 40ms + 350ms = 670ms < the 800ms bar). */
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(1) { transition-delay: calc(var(--gbp-stagger-step) * 0); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(2) { transition-delay: calc(var(--gbp-stagger-step) * 1); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(3) { transition-delay: calc(var(--gbp-stagger-step) * 2); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(4) { transition-delay: calc(var(--gbp-stagger-step) * 3); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(5) { transition-delay: calc(var(--gbp-stagger-step) * 4); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(6) { transition-delay: calc(var(--gbp-stagger-step) * 5); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(7) { transition-delay: calc(var(--gbp-stagger-step) * 6); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(8) { transition-delay: calc(var(--gbp-stagger-step) * 7); }
[data-gbc~="gbp-stack-cinematic"].is-visible > :nth-child(n+9) { transition-delay: calc(var(--gbp-stagger-step) * 8); }

/* ---- 6. data-delay hooks — clamped ladder (≥200 → 120ms, LOCKED) ----
 * Only 0 / 100 / 200 are author-valid; 300-800 exist so legacy markup
 * clamps instead of breaking. Long hero cascades read as broken. */
[data-gbc~="gbp-reveal"][data-delay="0"].is-visible   { transition-delay: 0ms; }
[data-gbc~="gbp-reveal"][data-delay="100"].is-visible { transition-delay: 100ms; }
[data-gbc~="gbp-reveal"][data-delay="200"].is-visible,
[data-gbc~="gbp-reveal"][data-delay="300"].is-visible,
[data-gbc~="gbp-reveal"][data-delay="400"].is-visible,
[data-gbc~="gbp-reveal"][data-delay="500"].is-visible,
[data-gbc~="gbp-reveal"][data-delay="600"].is-visible,
[data-gbc~="gbp-reveal"][data-delay="700"].is-visible,
[data-gbc~="gbp-reveal"][data-delay="800"].is-visible { transition-delay: 120ms; }

/* ---- 7. Editor defeat — 3-scope (REQUIRED; editor iframe runs no hook JS,
 * so without this the operator sees a blank page in Gutenberg) ---- */
.editor-styles-wrapper [data-gbc~="gbp-reveal"],
.editor-styles-wrapper [data-gbc~="gbp-stack-cinematic"] > *,
.block-editor-page [data-gbc~="gbp-reveal"],
.block-editor-page [data-gbc~="gbp-stack-cinematic"] > *,
body.wp-admin [data-gbc~="gbp-reveal"],
body.wp-admin [data-gbc~="gbp-stack-cinematic"] > * {
  opacity: 1 !important;
  transform: none !important;
  animation: none !important;
  transition: none !important;
}

/* ---- 8. Reduced motion — UNIVERSAL guard + scoped reveal restore ----
 * Universal `*` form so future motion classes can never escape the guard
 * (css_lint PRM-2). The restore forces reveal content visible even if the
 * hook JS already stamped js-ready before the media query flipped. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  html.js-ready [data-gbc~="gbp-reveal"],
  html.js-ready [data-gbc~="gbp-stack-cinematic"] > * {
    opacity: 1;
    transform: none;
  }
}
/* ====================== end canonical-motion-bundle.v1 ===================== */
