/* =============================================================================
 * homepage-fields.css  -  Synqa homepage ambient chapter fields (v10.3)
 * -----------------------------------------------------------------------------
 * Pairs with homepage-fields.js. Styles the per-chapter ambient field layer and
 * carries the eight `af*` keyframes the nine fields use. HOME-ONLY (index.html).
 *
 * Architecture: the sub-page fields (synqa-backgrounds.*) use ONE fixed
 * z-index:-1 layer behind transparent Bone sections + opaque cards. The homepage
 * is full-bleed editorial (no cards) and has two Ink chapters (ch-04, ch-08)
 * whose light fields must sit ABOVE their own Ink fill -> so each chapter mounts
 * its OWN field layer between its background and its content. The sub-page card
 * model is deliberately NOT ported (the homepage stays full-bleed). Honors
 * dec-no-reduced-motion: NO prefers-reduced-motion gate (full motion for all).
 * ========================================================================== */

/* ---- the eight ambient keyframes (af* namespace; never collide with the sub-
 * page sq* set, and the two systems never co-load anyway). Compositor-only:
 * transform / opacity only (afDash / stroke-dashoffset removed in v11). ---- */
@keyframes afSpin  { to { transform: rotate(360deg); } }
@keyframes afDrift { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(16px, -13px); } }
@keyframes afFlow  { from { transform: translateX(0); } to { transform: translateX(-524px); } }
@keyframes afFloat { 0% { opacity: 0; transform: translateY(28px); } 16% { opacity: .5; } 84% { opacity: .5; } 100% { opacity: 0; transform: translateY(-92px); } }
@keyframes afDawn  { 0%, 100% { opacity: .08; } 50% { opacity: .44; } }
@keyframes afGrind { 0%, 100% { opacity: .85; } 50% { opacity: .55; } }
@keyframes afUp    { to { transform: translateY(-720px); } }
@keyframes afDown  { to { transform: translateY(720px); } }

/* ---- ch-06 "the proof" THREE per-panel fields (c6* namespace). Compositor-only
 * (transform / opacity), one per the exploded-schematic / metrics-burst / growth-chart
 * ports in homepage-fields.js. The rotations reuse afSpin above. ---- */
@keyframes c6Settle  { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(6px, -4px); } }  /* schematic plate drift */
@keyframes c6Breathe { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(0, -9px); } }     /* schematic stack lift */
@keyframes c6Grind   { 0%, 100% { opacity: .85; } 50% { opacity: .5; } }                                      /* schematic Clay-dial pulse */
@keyframes c6Dawn    { 0%, 100% { opacity: .10; } 50% { opacity: .30; } }                                     /* schematic floor-grid sweep */
@keyframes c6Grow    { 0%, 100% { transform: scaleY(.60); } 50% { transform: scaleY(1); } }                   /* growth bars rise (about own base) */
@keyframes c6Trend   { 0%, 100% { transform: translateY(4px); opacity: .55; } 50% { transform: translateY(-4px); opacity: 1; } }  /* trend lines drift */
@keyframes c6Rise    { 0% { opacity: 0; transform: translateY(14px); } 18% { opacity: .5; } 82% { opacity: .5; } 100% { opacity: 0; transform: translateY(-30px); } }  /* rising particles */
@keyframes c6Sweep   { 0%, 100% { opacity: .10; } 50% { opacity: .30; } }                                     /* growth node-marker sweep */
@keyframes c6Tick    { 0%, 100% { transform: scaleX(.7); opacity: .5; } 50% { transform: scaleX(1); opacity: 1; } }  /* growth Clay-line tick fans */

/* ---- ch-07 "Theta." HARMONIC WEAVE (c7Harm* namespace) -- RETIRED 2026-06-26.
 * harmonicWeave() is no longer wired into BUILDERS; these keyframes are kept
 * (referenced only by the retired generator) so they do not create missing-ref
 * noise; they cost nothing when unused. ---- */
@keyframes c7Harm      { to { transform: rotate(360deg); } }                                                          /* (retired) curve precession about the shared centre */
@keyframes c7HarmPulse { 0%, 100% { opacity: .5; transform: scale(.7); } 50% { opacity: 1; transform: scale(1.25); } }  /* (retired) node-marker pulse */

/* ---- ch-07 Isometric Blueprint Machine (c7r4* namespace). Compositor-only
 * (transform / opacity / offset-distance), for blueprintMachine() in
 * homepage-fields.js. Each animation drives a small LOCAL element; there is
 * NO single large group carrying will-change:transform over the whole field. ---- */
@keyframes c7r4spin  { to { transform: rotate(360deg); } }                                                     /* hub pointer rotation */
@keyframes c7r4grow  { 0%, 100% { transform: scaleY(.55); } 50% { transform: scaleY(1); } }                    /* bar chart bar rise (own fill-box origin) */
@keyframes c7r4blink { 0%, 100% { opacity: .25; } 50% { opacity: .9; } }                                       /* leader-line dot blink */
@keyframes c7r4dawn  { 0%, 100% { opacity: .16; } 50% { opacity: .5; } }                                       /* crosshair marker fade */
@keyframes c7r4glide { from { offset-distance: 0%; } to { offset-distance: 100%; } }                           /* tracer dot along rail path */

/* ---- the per-chapter field layer. homepage-fields.js injects one of these into
 * each in-view chapter (skipping ch-02) and FILLS its host (position:absolute;
 * inset:0). z-index:-1 sits it above the host's own surface fill but below all
 * content - which ONLY works because the JS forces the host to a stacking context
 * with `isolation: isolate` on mount (a bare `position:relative` section is NOT a
 * stacking context, so a z-index:-1 child would otherwise paint behind the opaque
 * Bone/Ink fill and be invisible). ---- */
.ch-ambient-field {
  position: fixed;     /* TRULY viewport-pinned: the field stays in the same screen
                        * spot and follows the user. homepage-fields.js then sets a
                        * scroll-linked clip-path so each field shows ONLY within its
                        * chapter's visible band -> hard cutoff exactly at the moving
                        * transition line (owner: "cut off halfway"). */
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  opacity: 1;
  /* Paint/layout containment: each field is a self-contained layer, so a field's repaint (the
   * ch-03 orrery spin, the ch-06 per-panel schematic/burst/chart motion, the dot sweeps) must NOT
   * invalidate the rest of the page. This bounds each field's invalidation rect to its OWN box -
   * the main lever against the ch-03/ch-06 jank that only surfaces in production under network/font
   * main-thread contention. It ALSO clips each field to its own box, which is what lets the three
   * `centered` (position:absolute) ch-06 panel fields stay inside their sub-panel without the case
   * panels needing overflow:hidden (that would clip the M28 sheet pull). Visually identical (the
   * fixed fields also clip via overflow:hidden + the scroll-linked clip-path). */
  contain: layout paint;
}
.ch-ambient-field.is-on { opacity: 1; }
.ch-ambient-field svg { width: 100%; height: 100%; display: block; }

/* ch-06 per-panel fields: the three fields that are NOT viewport-fixed. Each is mounted
 * position:absolute filling its M08-track sub-panel (case 1 = exploded schematic, the
 * .wipe-panel INTERLUDE = metrics burst, case 2 = growth chart) so it sits CENTERED ON
 * ITS PANEL and rides with it as the track scrubs (owner: centered on the page, not
 * following the viewer). `contain:paint` on .ch-ambient-field clips each field to its
 * own panel box, so it never radiates into the neighbouring panel - no clip-path, no
 * counter-transform, and the case panels keep NO overflow:hidden (so the M28 sheet pulls
 * off the top freely). */
.ch-ambient-field--pin { position: absolute; }

/* PERF (measured under 6x CPU throttle = the weak-device scenario; perflab3 2026-06-26;
 * pixel-compliant - will-change is a compositing hint only, NO pixel change). Promote to a single
 * SVG-root GPU layer ONLY the fields that actually gain UNDER LOAD. (An UNthrottled A/B was
 * misleading: ch-07 looked like +13fps unthrottled but is NEUTRAL under throttle (+0.1) - its
 * ~2644-node texture re-raster cancels the paint offload, the classic oversized-layer trap.)
 * Confirmed throttled wins: ch-01 draftField (286 opacity groups) 12.8 -> 28.2 fps (+15.4, the big
 * one); ch-08 daylightRoll +1.8. Everything else gains nothing or regresses (ch-03/04/05/07/09) so
 * stays un-promoted; ch-06 is panel-scoped (nested-ancestor) and needs an approval-gated element
 * trim, not a layer. */
#ch-01 .ch-ambient-field svg { will-change: transform; }
#ch-08 .ch-ambient-field svg { will-change: transform; }

/* The transparent ch-06 case panels exposed .ch-06-bg's M17 repeating vertical
 * hairlines (they used to hide behind the opaque panels). Hide them on home. */
#ch-06 .ch-06-bg { display: none; }

/* The case-metrics column carries a vertical border-left separator that clashes
 * with the pinned field; drop it on the homepage cases. */
#ch-06 .case-metrics { border-left: none; }

/* ch-08 (INK, "two continents"): the daylightRoll field mounts as #ch-08's first
 * child (isolated stacking context) at z-index:-1, so it sits above the section
 * Ink fill but BEHIND the map content (.ch-08-inner, z-index:2) - the world map +
 * land read ON TOP of the dots. The OLD static dot-grid is removed: the new denser
 * daylightRoll (sp 36) replaces it. */
#ch-08 .ch-08-grid { display: none; }

/* OBSOLETE EDGE-FADE (the "fade-out from way back"). pass3.css paints #ch-08::before /
 * ::after as tall ink->transparent gradients at the section's top & bottom edges to fade
 * the OLD .ch-08-grid into the Ink. That grid is gone (replaced by the daylightRoll field),
 * and those gradients sit at z-index:1 - ABOVE the daylightRoll dots (z-index:-1) - so they
 * dimmed the top/bottom edge rows of dots (the persistent "darker rows" at the wipe edges).
 * Kill them on the homepage: the dot field + the wipe transitions handle the edges now. */
#ch-08::before, #ch-08::after { display: none; }

/* ch-08 "land blocks the dots": the SHARED world map (`.synqa-map-coastline`,
 * also used by /about) is authored stroke-only (`fill: none`), so the daylightRoll
 * dots showed straight through the continents. On the HOMEPAGE ch-08 only, fill the
 * continents with the chapter Ink so they opaquely MASK the dots beneath - dotted
 * ocean, dot-free land, Stone coastline on top. (Scoped to #ch-08 so the /about map
 * stays outline-only.) */
#ch-08 .synqa-map-coastline path { fill: var(--ink); }

/* Owner: drop the subtle equator/meridian dashed reference CROSS on the ch-08 map
   (.synqa-map-bg-line: 3 parallels + 1 meridian) - no longer needed now the dot
   field + coastline carry the map. Scoped to #ch-08 (home-only file anyway), so any
   /about map reference lines are untouched. */
#ch-08 .synqa-map-bg-line { display: none; }

/* ch-06 per-panel fields: each case panel paints an opaque Bone fill that would cover
 * its own field. Make them transparent (home-only) so each panel's field (the exploded
 * schematic / growth chart, mounted as the panel's isolated z-index:-1 first child)
 * reads behind the case copy. The .ch-06-pin itself is Bone, so the revealed surface is
 * unchanged; the M28 Ink sheet (.case-title-card) is a separate opaque element and still
 * pulls as before. (The .wipe-panel INTERLUDE stays Ink - its burst is light strokes.) */
#ch-06 .case-panel { background: transparent; }

/* ch-04 (INK) mounts inside .ch-04-unified (already a z-index:1 stacking context),
 * so the field reads on that Ink panel. ch-05 / ch-06 mount inside their sticky
 * pins (isolated on mount), so the field is a viewport-sized static backdrop
 * through the pinned scrub. */

/* MOBILE composition (gated). On mobile the sticky pins unpin and the chapters
 * STACK (content-driven height), so the desktop position:fixed + scroll-linked
 * clip-path model can't run. Instead homepage-fields.js mounts ONE field per
 * chapter as `centered` -> .ch-ambient-field--pin = position:absolute; inset:0,
 * filling its position:relative chapter box, with isolation:isolate forcing the
 * host stacking context so the z-index:-1 field paints ABOVE the chapter's own
 * Bone/Ink fill but BELOW content. Each field fills + scrolls WITH its chapter
 * (no pin, no clip), mirroring the sub-page synqa-bg pattern adapted per-chapter.
 * Breakpoint matches the site's mobile breakpoint (where the pins unpin) and the
 * JS MOBILE flag. The desktop rules above are untouched. */
@media (max-width: 1023px), (pointer: coarse) {
  /* `centered` (--pin) mobile fields (ch-04's section + .ch-04-unified panel, and
   * any generic fallback) bind to the HOST chapter box: position:absolute + inset:0
   * fills the position:relative chapter. Scoped to --pin ONLY so the FIXED mobile
   * fields (ch-01 / ch-05 / ch-06 / ch-07 - viewport-sized + scroll-clipped by
   * updateClips, so the 1360x720 slice art keeps a sane ~viewport aspect instead of
   * distorting to the tall stacked runway) keep their base position:fixed and get
   * clipped to their chapter band rather than being forced absolute+inset over the
   * whole tall section. (The JS also adds --pin via `centered`; this re-asserts it so
   * the field stays host-bound even if a stale cache serves older JS.) */
  .ch-ambient-field--pin {
    position: absolute;
    inset: 0;
  }
  .ch-ambient-field {
    /* Quiet ambient texture behind the stacked content: the mobile layout is
     * tighter than the full-bleed desktop editorial, so the field is gentled to
     * read as subtle texture (not a foreground show) while staying well above the
     * harness floor (opacity > 0.02). Content sits above it (z-index:-1 + the host
     * stacking context), and pointer-events:none keeps it out of touch/scroll. */
    opacity: 0.6;
    /* Heavy fields are GPU-promoted on desktop (#ch-01 / #ch-08 svg will-change).
     * On mobile a full-chapter promoted layer is wasteful; the owner handles
     * background performance separately, so leave promotion as-is and do not add
     * any here. */
  }
  /* ch-04 unified-panel theTurn field: the Ink panel carries LIGHT Bone body copy
   * ("We've been the client.") directly over the bars, so the panel field is
   * gentled below the 0.6 chapter default to a whisper so the bars read as quiet
   * texture WITHOUT competing with the copy for legibility. The section-level
   * ch-04 field (in the runway / boundary band, no copy over it) keeps 0.6.
   * Lifted 0.32 -> 0.38 -> 0.5 (the re-check found the panel still read as
   * "almost pure flat Ink, only two faint bars"; the owner wants the theTurn
   * bars clearly PRESENT on the revealed Ink panel, not a whisper). 0.5 reads
   * as a clear-but-quiet Stone bar field that stays under the light Bone body
   * copy without competing with it for legibility. */
  .ch-04-unified > .ch-ambient-field { opacity: 0.5; }
  /* The desktop GPU-promotion hint is desktop-only intent; it is harmless on
   * mobile (still just a compositing hint) so it is left in place. */
}

/* Print: nothing animates on paper; hide the layer so it never muddies a print. */
@media print { .ch-ambient-field { display: none; } }
