/* Sentient-orb R4: Guardian Forge region styles. Every selector carries an .orb-forge-* hook.
   Loads after style.css and before the page's inline <style>, so hook selectors are written
   with enough specificity to beat the inline page rules they override. Palette: :root tokens
   (rgba forms of --ai-orange, --electric-purple, --ai-cyan, --ai-magenta, --deep-purple-bg). */

/* ---------- hero: one time-based full-viewport layer (the orb field) ---------- */
/* ---- the long hero -------------------------------------------------------------------------
   Giovanni: "do it like it's done on echorb and the home screen". Measured, what those two do that
   this page did not is HOLD the world on screen. echorb pins a 260vh header to a 100lvh stage and
   the index crossing does the same at 520vh. Guardian Forge slid its world past at page speed, and
   a monotonic slide at page speed reads as a flat picture moving, whatever the depth separation is.
   This page actually had MORE far-to-near separation than echorb, 204px against 97px, and still
   read worse, because echorb's reverses in the middle and this did not.

   Adding the turn alone was tried and rejected on measurement: unpinned, turn and parallax fight,
   and the near plane stalls through the first half of the pass, 488px to 482px, then rushes the
   second, 482px to 266px. echorb's gesture is clean only because pinning freezes the parallax and
   leaves the turn acting alone.

   Gated on HEIGHT more tightly than echorb, because this hero's content is 764px against echorb's
   612px and needs a taller frame to pin inside without clipping. Measured headroom: 230px at
   1920x1080, 136px at 1440x900, 100px at 1536x864, but MINUS 44px at 1280x720 and minus 4px at
   1200x760. The gate is 850px of viewport height; below it this page keeps the hero it had. */
/* Motion gate: html[data-motion]:not([data-motion="still"]).

   This was briefly `and (prefers-reduced-motion: no-preference)` on the media query, to spare a
   reduced-motion visitor the extra pinned scroll. It went too far. Most Windows machines ship with
   animations off for performance rather than by choice, which is exactly why data-motion defaults
   to full, and gating on the OS flag alone handed the flat hero to people whose site setting said
   full. Measured on such a machine on 2026-09-10: this hero was one viewport tall instead of 260vh.

   The attribute selector is the fix and it is stricter than the original gate on both sides.
   data-motion is only ever present once the script has run, so:
     JS + full   -> the long pinned hero
     JS + still  -> the single-screen hero, which is the case Giovanni reported as "stuck on the
                    hero section scrolling without moving"
     no JS       -> the single-screen hero, whatever the OS says, because without the script there
                    is no world moving through the span and 260vh would be scrolling past nothing.
   The reduced-motion visitor's accommodation is the Reduce motion button in the footer. */
@media (min-width: 1200px) and (min-height: 850px) {
  html[data-motion]:not([data-motion="still"]) .orb-forge-hero.forge-hero {
    min-height: 0;
    height: 260vh;
    /* block, not the centring flex it is by default: as a flex container it centred the stage in
       the 260vh span, so the stage started 757px down the header and sticky had already been
       passed before it could engage. The stage does its own centring instead. */
    display: block;
    /* The header's padding moves onto the STAGE rather than being dropped. Zeroing it here shifted
       the whole hero up 41px, measured: content top 129 to 88, first button 792 to 752. The stage
       reproduces the original box so the copy sits exactly where it always did. */
    padding-top: 0;
    padding-bottom: 0;
    /* Sideways clipping STAYS, and this is the distinction that matters: overflow hidden creates a
       scroll container and breaks a sticky descendant, but overflow CLIP does not. Setting this to
       visible let the world planes and the scrim spill and put a horizontal scrollbar on the page,
       scrollWidth 3741 against a 1440 frame. Clip on x keeps the page from scrolling sideways and
       still lets the stage pin. */
    overflow-x: clip;
    overflow-y: visible;
  }
  /* The copy handoff has to span the hero it is now in. orbForgeHandoff fades this hero's copy to
     0.2 across the first 100vh of scroll, which was the whole hero before. Pinned, the hero runs
     260vh, so the copy finished fading at 900px and then sat at 20% over a held world for another
     1440px, which is a screen and a half of ghost text. The range now matches the pinned travel,
     260vh less the 100vh the stage occupies, so the copy is still readable while the world turns
     and has handed off by the time the stage releases. */
  @supports (animation-timeline: scroll()) {
    html[data-motion]:not([data-motion="still"]) .orb-forge-hero .orb-forge-content {
      animation-range: 0 160vh;
    }
  }
  html[data-motion]:not([data-motion="still"]) .forge-hero-stage {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100lvh;
    overflow: clip;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding: calc(var(--orb-forge-nav) + 52px) 0 56px;
    width: 100%;
  }
}
/* Below the gate the wrapper is not in the box tree at all, so the layout is unchanged by
   construction rather than by matching declarations. */
.forge-hero-stage { display: contents; }

.orb-forge-hero.forge-hero {
  --orb-forge-nav: 77px;
  min-height: 100vh;
  min-height: 100svh;
  padding: calc(var(--orb-forge-nav) + 52px) 0 56px;
  isolation: isolate;
  overflow: hidden;
  overflow-x: clip;               /* clip sideways, let the held glow spill into the next section */
  overflow-y: visible;
  background:
    linear-gradient(180deg, rgba(10, 0, 21, 0) 55%, #0a0015 100%),
    radial-gradient(ellipse 80% 50% at 30% 20%, rgba(255, 107, 0, 0.15) 0%, transparent 50%),
    radial-gradient(ellipse 60% 40% at 70% 80%, rgba(153, 69, 255, 0.15) 0%, transparent 50%),
    radial-gradient(ellipse 50% 30% at 50% 50%, rgba(0, 212, 255, 0.1) 0%, transparent 50%),
    linear-gradient(135deg, #0a0015 0%, #1a0033 50%, #2a0845 100%);
}
/* forgeGlow held at its 33% frame (15s cycle, -5s): rotate(120deg) scale(1.1), opacity .8 */
.orb-forge-hero.forge-hero::before {
  animation-play-state: paused;
  animation-delay: -5s;
  z-index: 0;
}
.orb-forge-field {
  position: absolute;
  inset: 0 0 -18% 0;             /* the orb field runs 18% past the hero so the handoff has no hard edge */
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(#000 78%, transparent);
  mask-image: linear-gradient(#000 78%, transparent);
}
.orb-forge-bubble {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 50%;
}
.orb-forge-hero .orb-forge-content { z-index: 2; }
.orb-forge-title { position: relative; display: inline-block; }
/* the shared h1/h3 hover sweep (style.css:2067) would surface beside the hugged title and on the planes */
.orb-forge-title .forge-title::before,
.orb-forge-section h3::before { content: none; }
/* type scrim (layered-type-scrim): a dark ellipse behind the title so the orb field never sits
   directly under the glyphs. Item 11: the previous comment cited a 1.7:1 worst-glyph figure that no
   retained artifact supports; the controlled A/B measured 2.42:1 without the scrim and 2.46:1 with
   it, so the scrim is kept for the bubble-under-glyph case and no figure is claimed here. */
.orb-forge-title::before {
  content: '';
  position: absolute;
  inset: -14% -12%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(10, 0, 21, 0.78), rgba(10, 0, 21, 0) 78%);
}
/* crumbs sit at 88px inside the hero; content starts below them at every width.
   Item 9: the bound was 767px, so exactly 768 fell through to the flex-centred fallback and the
   shield sat 57.9px lower there than at 1024. 768px inclusive keeps the shield top continuous. */
@media (max-width: 768px) {
  .orb-forge-hero.forge-hero { padding-top: calc(var(--orb-forge-nav) + 64px); }
  .orb-forge-hero .forge-shield { width: 160px; height: 160px; margin-bottom: 1.5rem; }
}
/* off-screen: the hero's small keyframes pause under the same observer as the field */
.orb-forge-hero.is-away .forge-shield-icon,
.orb-forge-hero.is-away .forge-shield-ring,
.orb-forge-hero.is-away .status-dot { animation-play-state: paused; }
/* scroll handoff: content sinks and dims across the first viewport (scroll-linked, not time-based) */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .orb-forge-hero .orb-forge-content {
      animation: orbForgeHandoff linear both;
      animation-timeline: scroll(root);
      animation-range: 0 100vh;
    }
  }
}
@keyframes orbForgeHandoff {
  to { opacity: 0.2; transform: translateY(-8vh) scale(0.97); }
}

/* ---------- sections: transparent over the document gradient, one light pool each ---------- */
.orb-forge-section.forge-section {
  background: transparent;
  position: relative;
  isolation: isolate;
  overflow: clip;
  transform: none;                /* style.css:523 offsets every section by 30px; neutralised by hook */
  transition: none;
}
.orb-forge-section > .container { position: relative; z-index: 1; }
/* Item 10 (fix A, approved 2026-09-07): same lit-pool hard edge as the body sections. The box
   started above the section and was cut by the section clip, so the boundary fell through the
   bright part of the gradient. The box now sits inside the section and a vertical mask fades it out
   at both edges; ellipse centres move down ~10% to follow the box. */
.orb-forge-pool {
  position: absolute;
  inset: 0 -20% auto -20%;
  height: 70%;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 22%, #000 78%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 22%, #000 78%, transparent 100%);
  pointer-events: none;
  z-index: 0;
  --orb-forge-pool-x: 28%;
  background:
    radial-gradient(ellipse 55% 70% at var(--orb-forge-pool-x) 45%, rgba(255, 107, 0, 0.22), rgba(255, 107, 0, 0) 70%),
    radial-gradient(ellipse 40% 55% at calc(100% - var(--orb-forge-pool-x)) 75%, rgba(153, 69, 255, 0.16), rgba(153, 69, 255, 0) 70%);
  opacity: 0.35;
  transform: translateY(6%);
  transition: opacity 900ms ease, transform 900ms ease;
}
.orb-forge-section:nth-of-type(even) .orb-forge-pool { --orb-forge-pool-x: 72%; }
.orb-forge-section.is-lit .orb-forge-pool { opacity: 1; transform: none; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .orb-forge-pool {
      animation: orbForgePool linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 35%;
    }
  }
}
@keyframes orbForgePool {
  from { opacity: 0.35; transform: translateY(6%); }
  to { opacity: 1; transform: none; }
}
/* the workflow line rides above the planes so the four steps stay connected */
.orb-forge-section .workflow-line { z-index: 1; }
/* 320 defect: minmax(320px) overflowed a 296px container; the clip hid the cards' right edge */
.orb-forge-section .feature-grid { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* ---------- planes (foreground): tint .72 on the body gradient, cyan rim, orange heat on hover ---------- */
.orb-forge-section .orb-forge-plane {
  position: relative;
  isolation: isolate;
  background: rgba(10, 0, 21, var(--orb-forge-tint, 0.72));
  border: 1px solid rgba(0, 212, 255, 0.25);
  border-radius: 20px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(255, 0, 255, 0.06) inset;
  transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), border-color 0.3s ease, box-shadow 0.4s ease;
}
.orb-forge-section .orb-forge-plane.workflow-step { padding: 2rem 1rem 1.5rem; height: 100%; }
.orb-forge-section .orb-forge-plane.forge-faq-item { --orb-forge-tint: 0.75; border-radius: 16px; }
.orb-forge-section .orb-forge-shot { padding: 0; overflow: hidden; border-radius: 15px; }
.orb-forge-section .orb-forge-shot img { width: 100%; height: auto; display: block; }
.orb-forge-section .orb-forge-plane:hover {
  transform: none;
  border-color: rgba(255, 107, 0, 0.55);
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.45), 0 0 40px rgba(255, 107, 0, 0.12), 0 0 0 1px rgba(255, 0, 255, 0.06) inset;
}
@media (hover: hover) and (pointer: fine) {
  .orb-forge-section .orb-forge-plane:hover { transform: translateY(-4px); }
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .orb-forge-section .orb-forge-plane.is-glass {
    -webkit-backdrop-filter: blur(16px) saturate(1.3);
    backdrop-filter: blur(16px) saturate(1.3);
  }
}
@media (max-width: 767px) {
  .orb-forge-section .orb-forge-plane.is-glass { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ---------- reveal choreography: hidden only when JS ran and motion is on ---------- */
html[data-motion-js]:not([data-motion="still"]) .orb-forge-section:not(.is-in) .orb-forge-reveal { opacity: 0; }
.orb-forge-section.is-in .orb-forge-reveal {
  animation: orbForgeReveal 0.6s ease backwards;
  animation-delay: calc(var(--i, 0) * 90ms);
}
@keyframes orbForgeReveal {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}
/* off-screen sections pause their own infinite keyframes (avatar ring, get-started glow) */
html[data-motion-js] .orb-forge-section:not(.is-visible) .agent-avatar::after,
html[data-motion-js] .orb-forge-section:not(.is-visible) .get-started-card::before { animation-play-state: paused; }

/* ---------- still composition: identical declarations under the media query and the attribute ---------- */
@media (prefers-reduced-motion: reduce) {
  .orb-forge-hero .forge-shield-icon,
  .orb-forge-hero .forge-shield-ring { animation-play-state: paused; animation-delay: 0s; }
  .orb-forge-hero .status-dot { animation-play-state: paused; animation-delay: -1s; }
  .orb-forge-hero .orb-forge-content { animation: none; }
  .orb-forge-section .orb-forge-pool,
  .orb-forge-section.is-lit .orb-forge-pool { animation: none; opacity: 1; transform: none; transition: none; }
  html[data-motion-js]:not([data-motion="still"]) .orb-forge-section:not(.is-in) .orb-forge-reveal,
  .orb-forge-section.is-in .orb-forge-reveal { animation: none; opacity: 1; }
  .orb-forge-section .orb-forge-plane:hover { transform: none; }
  .orb-forge-section .agent-avatar::after,
  .orb-forge-section .get-started-card::before { animation-play-state: paused; }
}
html[data-motion="still"] .orb-forge-hero .forge-shield-icon,
html[data-motion="still"] .orb-forge-hero .forge-shield-ring { animation-play-state: paused; animation-delay: 0s; }
html[data-motion="still"] .orb-forge-hero .status-dot { animation-play-state: paused; animation-delay: -1s; }
html[data-motion="still"] .orb-forge-hero .orb-forge-content { animation: none; }
html[data-motion="still"] .orb-forge-section .orb-forge-pool,
html[data-motion="still"] .orb-forge-section.is-lit .orb-forge-pool { animation: none; opacity: 1; transform: none; transition: none; }
html[data-motion="still"] .orb-forge-section:not(.is-in) .orb-forge-reveal,
html[data-motion="still"] .orb-forge-section.is-in .orb-forge-reveal { animation: none; opacity: 1; }
html[data-motion="still"] .orb-forge-section .orb-forge-plane:hover { transform: none; }
html[data-motion="still"] .orb-forge-section .agent-avatar::after,
html[data-motion="still"] .orb-forge-section .get-started-card::before { animation-play-state: paused; }
