Rule handbook metadata

Rule
DET.AMBIENT.Z_INDEX · lane deterministic
Page status
stale
page_version
c85b9d27a8f29b758a41bb53c76bfb4ec754f10bf5d2ec9e8eafeebd799ea335
generated_at
2026-05-19T18:30:00.000Z
registry_fingerprint
6773fda516344e110b5a7b1435e655e1264e773825ca8bbe62194189891c42ba

How this rule is fixed

Pilot deterministic fixer: handbook_after · harness mode standalone · verify expect_rule_clean.

  • Harness: apply-harness-fixture-remediation.py copies the After example HTML from this handbook page onto the defect fixture, then invoke-det-ruleset-remediation-verify.sh re-audits and expects zero findings for this rule.
  • Production sites: run-website-ux-remediation-loop.sh runs handbook_html_patch (HTML patches in lib/ux-deterministic-fixers/fixers/patches/) before invoking the Cursor agent when the quality gate still fails.

Detection module: docs/design/ux-audit/deterministic-design-rules.md#det-ambient-z-index. Scroll down for Before / After examples and Evidence and remediation steps.

Purpose

Kitchen Sink ships two ambient systems that share a stacking contract:

  • Forge ambient.forge-ambient with .forge-ambient-bg, optional .forge-ambient-scrim, and .forge-ambient-content (css/forge-ambient.css).
  • Animated backgrounds.ks-has-ambient-bg with .ks-ambient-bg, .ks-ambient-bg-overlay, and .ks-content (css/ks-animated-backgrounds.css).
  • Living background#ks-living-scene / .ks-living-scene and section-local .ks-living-section bands (css/ks-living-background.css).

The contract is bg at z-index 0, scrim/overlay at z-index 1, foreground content at z-index 2, and pointer-events: none on every decorative plane. Ambient layers must never intercept clicks, cover CTAs, or stack above prose and controls.

This deterministic rule samples computed styles in Playwright and flags stack inversions, elevated ambient z-index, and interactive canvases inside ambient containers.

Plan: Identify pages with ambient markup on the first screen. Do: Use KS slot classes and avoid inline z-index overrides on bg/canvas layers. Check: Run the auditor metrics phase or inspect computed z-index and pointer-events in DevTools. Adjust: Move drawing surfaces into the bg slot and wrap interactive UI in .forge-ambient-content or .ks-content.

Passing signals

  • .forge-ambient-bg / .ks-ambient-bg (including .ks-section-bg.ks-ambient-bg and .ks-living-scene__global.ks-ambient-bg) report z-index 0–1 and pointer-events: none.
  • Foreground copy and controls live in .forge-ambient-content or .ks-content with z-index ≥ 2 (or .container / .container-fluid direct children of .ks-living-section at z-index 1 when the section bg is 0).
  • Optional scrims use .forge-ambient-scrim or .ks-ambient-bg-overlay at z-index 1, also with pointer-events: none.
  • #ks-living-scene / .ks-living-scene stays at z-index 0 with pointer-events: none so the global parallax field never blocks the page.
  • <canvas> elements inside .forge-ambient, .ks-has-ambient-bg, or .ks-living-scene sit in the bg slot at z-index 0 with pointer-events: none, or are omitted in favor of SVG loaded via data-ks-bg-src.

Failing signals

  • Ambient bg/canvas z-index > 1 (for example inline style="z-index: 5" on .forge-ambient-bg).
  • pointer-events: auto (or unset on an absolutely positioned canvas/SVG) on a decorative layer that overlaps buttons or links.
  • Stack inversion: ambient layer z-index ≥ content wrapper z-index inside the same .forge-ambient / .ks-has-ambient-bg / .ks-living-section container.
  • Hero markup places headings and CTAs in a bare <div> while a canvas or bg layer sits above them in paint order.
  • .ks-living-scene with z-index > 0 or pointer-events other than none, blocking interaction with the document below.

Before example

Before (failing example)

Governed agent delivery

Clicks may hit the canvas or SVG instead of the button below.

Failing KS markup: canvas and ambient bg elevated above prose; no content wrapper; pointer events enabled on decorative layers.

After example

After (passing example)

Governed agent delivery

Ambient stays behind scrim and content; controls remain clickable.

Passing KS markup: canonical Forge ambient slots — bg 0, scrim 1, content 2 — with no pointer capture on decorative planes.

Alternative passing pattern for asset-gallery sections:

<section class="forge-section ks-has-ambient-bg ks-bg-overlay--soft">
  <div class="ks-ambient-bg" data-ks-bg-src="assets/svg/bg/mesh-soft.svg" aria-hidden="true"></div>
  <div class="ks-ambient-bg-overlay" aria-hidden="true"></div>
  <div class="ks-content container py-5">
    <h2 class="h3 mb-3">Section with animated background</h2>
    <a class="btn btn-outline-primary" href="#next">Continue</a>
  </div>
</section>

Evidence and remediation

Evidence: Auditor report fields ambientZIndexReport.violations[] with kinds pointer-events, z-index-high, stack-inversion, or canvas-layer. Each finding includes the offending class, computed z-index, and page URL. In DevTools, select .forge-ambient-bg / .ks-ambient-bg and confirm z-index: 0 and pointer-events: none.

Remediate (in order):

  1. Remove inline or custom CSS that raises ambient bg/canvas above z-index 1.
  2. Set pointer-events: none on every decorative SVG, canvas, and global living-scene root.
  3. Wrap interactive UI in .forge-ambient-content or .ks-content; add .forge-ambient-scrim or .ks-ambient-bg-overlay when readability needs separation (see AI.AMBIENT.READABILITY_CONFLICT).
  4. For particle/canvas effects, mount the canvas inside the bg slot (sibling before content wrapper), not as a sibling above prose.
  5. Re-run analyze-website-ux.mjs metrics on first-screen URLs; stack inversions often co-occur with unreadable hero bands.