/* ==========================================================================
   ORO — LUX LAYER  (layer 13)
   Loaded LAST. Namespace `orolux-`. Nothing here edits an existing file.

   REMOVABLE IN ONE LINE: every rule is scoped under `html.orolux`, and that
   class is added by oro-lux.js. Delete the <link> + <script> from index.html,
   or just stop adding the class, and the page returns to exactly its previous
   state. No existing selector is widened to reach a new element.

   WHY THIS LAYER EXISTS
   ---------------------------------------------------------------
   Four verified defects (§0) plus a visual-weight pass on the six sections
   that were reading flat. It follows the house rules rather than fighting
   them:
     · Law 1 is respected — gold marks meaning, it is not sprinkled around.
       New gold appears only on live/complete state, never on planned state.
     · No new runtime dependency, no canvas, no particle engine. The page is
       already carrying Three.js + Lottie; this adds CSS and ~7 KB of JS.
     · Authored in px / clamp(px,vw,px), never rem — 1rem == 1vw on this
       build (see the rem trap: 1rem == 1vw on this build).
   ========================================================================== */

.orolux {
  /* Light-section ramp. Warm ivory, never pure white — pure white next to
     #080808 strobes, and the brand is warm. */
  --orolux-paper:      #F7F4ED;
  --orolux-paper-deep: #EDE7DB;
  --orolux-ink:        #14110C;
  --orolux-ink-2:      #4A423A;
  --orolux-dim:        #6B6459;   /* 5.6:1 on paper — AA body           */
  --orolux-bronze:     #8C6743;   /* 5.2:1 on paper — AA accent text    */
  --orolux-gold:       #C9A46A;   /* fills and dots only, never text-on-light */
  --orolux-line:       rgb(20 17 12 / .13);
  --orolux-line-soft:  rgb(20 17 12 / .07);
  --orolux-ease:       cubic-bezier(.19, 1, .22, 1);
  --orolux-spring:     cubic-bezier(.22, 1.4, .36, 1);
}


/* ==========================================================================
   0 · DEFECT FIXES
   Four things that were verifiably wrong, not matters of taste.
   ========================================================================== */

/* ── 0.1 · The ORO text band carried a full section's padding ──────────────
   The section padding was NOT the cause — oro-sections.css already trims it
   to `padding-block: clamp(8px,1vw,20px)`. The space is inside the SVG.

   createTextLoop emits `viewBox="0 0 1200 520"` with no width/height, so the
   SVG scales to the container width and takes its height from the viewBox
   ratio: 1310px wide -> 568px tall. But the wave path only oscillates between
   y=202.8 and y=317.2, so with the glyphs sitting on it the ink occupies
   roughly the middle 125px. The other ~440px is empty viewBox. Measured, not
   assumed.

   Fixed without touching the generator: clip the host to the ink band and
   centre the full-size SVG inside it. The path is centred on y=260 of 520 —
   exactly the middle — so centring shows the whole wave and crops only the
   emptiness above and below it. */
.orolux .orox-divider {
  position: relative;
  height: clamp(120px, 13vw, 180px);
  overflow: hidden;
}
.orolux .orox-divider > svg {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: auto;
  transform: translateY(-50%);
}
/* The bloom was sized for a full section; on a thin band it just fogs it. */
.orolux .orox-divider-sc::before { display: none; }


/* ── 0.2 · Possibilities Wall was 1280px inside a 1600px page ──────────────
   `.oropw__in { width: min(1280px, 92vw) }` while `.orox__container` runs to
   1600px, so on a wide screen the wall floated narrow with dead margins on
   both sides and squeezed six cards into ~195px each. Matching the page
   container removes the dead space and lets the cards breathe. */
.orolux .oropw__in { width: min(1600px, 92vw); }

/* With the extra width the cards can carry real presence: more padding, a
   proper material, and a lift that reads as physical rather than as a colour
   change. */
.orolux .oropw__card {
  padding: clamp(20px, 1.9vw, 32px) clamp(18px, 1.7vw, 28px);
  gap: clamp(10px, 1vw, 16px);
  background:
    linear-gradient(180deg, rgb(245 242 236 / .062), rgb(245 242 236 / .015) 55%, rgb(245 242 236 / .008));
  box-shadow:
    inset 0 1px 0 rgb(245 242 236 / .10),
    0 1px 2px rgb(0 0 0 / .3);
  transition:
    border-color .45s var(--orolux-ease),
    transform    .55s var(--orolux-ease),
    box-shadow   .55s var(--orolux-ease);
}
.orolux .oropw__card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(120% 80% at 50% 0%, rgb(201 164 106 / .16), transparent 62%);
  opacity: 0;
  transition: opacity .5s var(--orolux-ease);
}
.orolux .oropw__card:hover {
  transform: translateY(-6px);
  border-color: rgb(201 164 106 / .42);
  box-shadow:
    inset 0 1px 0 rgb(245 242 236 / .16),
    0 18px 40px -18px rgb(0 0 0 / .85);
}
.orolux .oropw__card:hover::after { opacity: 1; }

/* The icon was a flat outline in a flat well. Give it the same treatment the
   rest of the page gives a live element. */
.orolux .oropw__i {
  transition: transform .55s var(--orolux-spring), border-color .45s var(--orolux-ease);
}
.orolux .oropw__card:hover .oropw__i {
  transform: translateY(-2px) scale(1.06);
  border-color: rgb(201 164 106 / .5);
}


/* ── 0.3 · The dithered field was reading as a moiré over the copy ─────────
   oro-sections.js mounts PixelBlast on `.orox-bento-sc` at patternDensity .72
   / pixelSize 5. Its own header says: "If one of them is the first thing you
   notice in its section, it is turned up too far." It was. Rather than edit
   that file (it belongs to another lane) the effect is damped here and masked
   away from the middle of the section, where the text lives.

   The canvas is not a direct child: oro-sections.js wraps it in a
   `<div class="orox-fx">` inserted as the section's first child, so that
   wrapper is what has to be damped. The authored value is
   `.orox-bento-sc .orox-fx.is-on { opacity: .42 }` — same specificity as the
   selector below, so this wins only because oro-lux.css loads later. Keep it
   last in the <head>. */
/* Mask on the wrapper regardless of state; opacity only on `.is-on`, so the
   authored 1.2s fade-in still happens — it just fades in to less. */
.orolux .orox-bento-sc > .orox-fx {
  -webkit-mask-image: radial-gradient(125% 78% at 50% 50%, transparent 14%, #000 76%);
          mask-image: radial-gradient(125% 78% at 50% 50%, transparent 14%, #000 76%);
}
.orolux .orox-bento-sc > .orox-fx.is-on { opacity: .32; }


/* ── 0.4 · Reduced motion broke the footer's wide card ─────────────────────
   oro-magic.css gives `.orox-marquee { flex-wrap: wrap }` under reduced
   motion. Its groups are `min-width:100%`, so the original and the looping
   clone wrap onto two rows. `.orob__bg` is absolutely positioned and
   bottom-anchored with `align-items:flex-end`, so a two-row marquee grows
   UPWARD out of its reserved band and lands on top of the link list.
   Verified: default-motion path is unaffected — this is the a11y path only.
   Fix: keep it one row and let the overflow clip, which is what the animated
   version does anyway. */
@media (prefers-reduced-motion: reduce) {
  .orolux .orob__bg .orox-marquee { flex-wrap: nowrap; overflow: hidden; }
  /* Only the first group is needed when nothing scrolls; the clone exists
     purely to make the loop seamless. */
  .orolux .orob__bg .orox-marquee__g ~ .orox-marquee__g { display: none; }
}


/* ==========================================================================
   1 · BREATHING SECTIONS — white + gold
   Thirteen consecutive black sections is a lot of black. Three sections are
   lifted onto warm paper so the page has a rhythm:

     dark … LIGHT (#token-unlocks) … dark … LIGHT (#tokenomics) … dark …
     LIGHT (#faq) … dark (#closing, #footer)

   These three were chosen because they are the page's *documents* — the spec,
   the allocation and the answers. A document reading as printed matter is
   both prettier and more honest than the same text glowing in the dark. The
   class is applied by oro-lux.js.

   Most of this comes free: oro-sections.css is authored against custom
   properties, so re-declaring the ramp on the section flips almost everything.
   What follows the token block is the handful of rules that hardcoded a
   paper-white rgba and cannot inherit.
   ========================================================================== */

.orolux .orolux-light {
  --orox-ink: var(--orolux-paper);
  --orox-paper: var(--orolux-ink);
  --orox-dim: var(--orolux-dim);
  --orox-line: var(--orolux-line);
  --orox-line-strong: rgb(20 17 12 / .24);
  --orox-turq: var(--orolux-bronze);
  --orox-sky: var(--orolux-bronze);
  --orox-blue: var(--orolux-bronze);
  --orox-light: #A8822F;
  --orox-spec: #7A5A34;
  --orox-glass:
    linear-gradient(180deg, rgb(255 255 255 / .72), rgb(255 255 255 / .30) 48%, rgb(255 255 255 / .16));
  --orox-glass-hi: inset 0 1px 0 rgb(255 255 255 / .9);

  color: var(--orolux-ink);
  background-color: var(--orolux-paper);
  background-image:
    linear-gradient(180deg, var(--orolux-paper) 0%, var(--orolux-paper-deep) 100%);
}

/* Paper needs a seam at both edges or it looks like a rendering error where it
   meets the black. A hairline plus a short gradient does it. */
.orolux .orolux-light::after {
  content: "";
  position: absolute;
  z-index: 0;
  left: 0;
  right: 0;
  height: clamp(40px, 4vw, 72px);
  pointer-events: none;
}
.orolux .orolux-light::after { top: 0; background: linear-gradient(180deg, rgb(8 8 8 / .17), transparent); }
.orolux .orolux-light > * { position: relative; z-index: 1; }

/* The section bloom is a gold radial tuned for black. On paper it reads as a
   stain, so it becomes a soft warm light instead. */
.orolux .orolux-light::before {
  background: radial-gradient(
    ellipse at 50% 50%,
    rgb(201 164 106 / .20) 0%,
    rgb(201 164 106 / .07) 36%,
    transparent 70%);
}

/* Titles are a light-to-mid ramp clipped to the text; inverted for paper. */
.orolux .orolux-light .orox__title,
.orolux .orolux-light .orox-core__title {
  background-image: linear-gradient(180deg, var(--orolux-ink), var(--orolux-ink-2));
}

/* Hardcoded paper-white alphas that cannot inherit the token flip. */
.orolux .orolux-light .orox-alloc__label { color: var(--orolux-ink-2); }
.orolux .orolux-light .orox-alloc__i:hover { background: rgb(20 17 12 / .045); }
.orolux .orolux-light .orox-donut__wrap::after {
  background: radial-gradient(circle, rgb(201 164 106 / .30), transparent 66%);
}
.orolux .orolux-light .orox-donut > circle:first-child { stroke: rgb(20 17 12 / .08); }

/* Cards and wells inside a light section. Only `.orox-stat` (tokenomics)
   actually occurs in the three light sections today — the `.orox-unlock__*`
   rules that used to sit here were removed after #token-unlocks stayed dark,
   because a stylesheet full of selectors that match nothing is a trap for
   whoever reads it next. Verified with a dead-selector audit against the live
   DOM, not by inspection. */
.orolux .orolux-light .orox-stat {
  border-color: var(--orolux-line);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .9),
    0 1px 2px rgb(20 17 12 / .05),
    0 12px 28px -20px rgb(20 17 12 / .3);
}

/* Forward guard, deliberately kept: if a section carrying status chips is
   ever added to the light list, `planned` must stay quiet on paper too, or
   the page starts looking like it claims things it has not shipped. */
.orolux .orolux-light [class*="planned"] { color: var(--orolux-dim); }

/* The dithered shader is a dark-section texture. On paper it is grit.
   (No light section currently carries one — this is a guard for if one ever
   does, since the FX mount list and this list are edited independently.) */
.orolux .orolux-light > .orox-fx { display: none; }


/* ── 1.1 · #ledger — the white→gold section ────────────────────────────────
   The ecosystem register is the page's centrepiece list, so it gets the
   fullest version of the light treatment: a warm white that ripens into gold
   toward the foot, a gold horizon line, and a slow specular drift across the
   top. Everything still resolves to AA — the type sits on the white end of
   the wash, never on the saturated end. */
/* NOTE ON GEOMETRY: this section is ~2340px tall because ScrollTrigger pins
   it — the content sits near the TOP and the rest is scroll runway. A wash
   measured in percentages therefore puts its richest gold 1500px below
   anything the eye ever rests on, and the visible window reads as flat cream.
   So the gold is placed in absolute px, anchored to the top where the content
   actually is, and the runway below is left pale. */
/* The wash itself is declared in §11, where the ember layers join it — a
   single background-image stack has to be written in one place. */

/* Horizon: a gold rule at the foot of the section so it lands rather than
   just stopping. */
.orolux .orolux-light--gold::after {
  top: auto;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(140 103 67 / .45) 22%, rgb(140 103 67 / .45) 78%, transparent);
}

/* Slow specular drift. 26s, very low contrast — it should read as light
   moving over a metal surface, not as an animation playing. */
.orolux .orolux-light--gold::before {
  background: linear-gradient(104deg,
    transparent 34%,
    rgb(255 255 255 / .55) 48%,
    rgb(255 246 224 / .30) 55%,
    transparent 70%);
  animation: orolux-wash 26s ease-in-out infinite;
  mix-blend-mode: soft-light;
}
@keyframes orolux-wash {
  0%, 100% { transform: translate3d(-8%, 0, 0); }
  50%      { transform: translate3d(8%, 0, 0); }
}

/* On the gold wash the ring needs a darker track and a bronze arc to hold
   its shape — the authored white-on-black values vanish here. */
.orolux .orolux-light--gold .orox-tally__track { stroke: rgb(20 17 12 / .10); }
.orolux .orolux-light--gold .orox-tally__ring::after {
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    rgb(140 103 67 / .22) 60deg,
    rgb(201 164 106 / .34) 110deg,
    rgb(140 103 67 / .14) 170deg,
    transparent 260deg);
}
/* Row hover inverts: dark tint on light, not light tint on dark. */
.orolux .orolux-light--gold .orox-mod:hover { background: rgb(20 17 12 / .05); }
.orolux .orolux-light--gold .orox-mod:hover .orox-mod__tick {
  border-color: rgb(140 103 67 / .7);
  box-shadow: 0 0 14px -3px rgb(140 103 67 / .55);
}
/* The big tally numeral was near-white; it needs to be ink here. */
.orolux .orolux-light--gold .orox-tally__v { color: var(--orolux-ink); }


/* ==========================================================================
   2 · ROADMAP → MISSION CONTROL
   The brief asked for a horizontal timeline. The content will not take one:
   four milestones with a paragraph each become unreadable side by side, and
   the section already reads top-to-bottom with the rest of the page. What it
   was actually missing was STATE — live and planned looked nearly identical,
   and the rail was an inert grey line. So the axis stays vertical and the
   energy, hierarchy and material arrive instead.
   ========================================================================== */

/* The rail becomes a conduit: warm and lit down to the last live phase, inert
   below it. The gradient stop is the honest bit — it stops where the work
   stops. */
.orolux .orox-road { position: relative; }
.orolux .orox-road__rail {
  background: linear-gradient(
    180deg,
    rgb(201 164 106 / .85) 0%,
    rgb(201 164 106 / .55) 38%,
    rgb(140 103 67 / .30) 52%,
    rgb(245 242 236 / .10) 62%,
    rgb(245 242 236 / .07) 100%);
}

/* A pulse that travels the lit part of the rail. 9s, low contrast — it should
   register as "this is running", not as a light show. */
.orolux .orox-road::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 22%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, rgb(255 242 169 / .95), transparent);
  filter: blur(.5px);
  animation: orolux-rail 9s var(--orolux-ease) infinite;
}
@keyframes orolux-rail {
  0%   { transform: translateY(-24%); opacity: 0; }
  14%  { opacity: 1; }
  48%  { opacity: 1; }
  62%  { transform: translateY(230%); opacity: 0; }
  100% { transform: translateY(230%); opacity: 0; }
}

/* Phase cards get a real material and a hover that expands rather than just
   tints. */
.orolux .orox-phase {
  transition:
    transform   .55s var(--orolux-ease),
    border-color .45s var(--orolux-ease),
    box-shadow  .55s var(--orolux-ease),
    background  .45s var(--orolux-ease);
}
.orolux .orox-phase:hover {
  transform: translateX(6px);
  border-color: rgb(201 164 106 / .38);
  box-shadow: 0 22px 48px -26px rgb(0 0 0 / .9);
}

/* LIVE — lit dot with a slow halo, brighter edge, warm inner glow. */
.orolux .orox-phase--live .orox-phase__dot {
  background: radial-gradient(circle at 40% 35%, #FFF2A9, #C9A46A 55%, #8C6743);
  box-shadow:
    0 0 0 1px rgb(201 164 106 / .5),
    0 0 14px 2px rgb(201 164 106 / .45);
}
.orolux .orox-phase--live .orox-phase__dot::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  border: 1px solid rgb(201 164 106 / .45);
  animation: orolux-ping 3.4s var(--orolux-ease) infinite;
}
@keyframes orolux-ping {
  0%   { transform: scale(.72); opacity: .85; }
  70%  { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}
.orolux .orox-phase--live {
  background-image: linear-gradient(100deg, rgb(201 164 106 / .07), transparent 46%);
}
.orolux .orox-phase--live .orox-phase__tag {
  color: #EAD795;
  border-color: rgb(201 164 106 / .42);
}

/* PLANNED — recessed by MATERIAL, never by opacity.
   An earlier revision of this file dimmed these cards to .78, which quietly
   re-created a bug oro-sections.css had already found and fixed: its "VISUAL
   PASS" note records that `.orox-phase--todo{opacity:.72}` was dropping
   #737373 body text to roughly 3:1 and that opacity was restored to 1 so the
   text returns to AAA. Dimming a whole card is the cheap way to say "not
   done" and it costs contrast on the copy. The recession here is carried by
   the border, the dot and the absence of the live wash instead — none of
   which touch the text. */
.orolux .orox-phase--todo {
  border-color: rgb(245 242 236 / .07);
  background-image: none;
}
.orolux .orox-phase--todo .orox-phase__dot {
  background: rgb(245 242 236 / .13);
  box-shadow: inset 0 0 0 1px rgb(245 242 236 / .22);
}

/* The progress bar reads as an instrument rather than a div. */
.orolux .orox-prog__track {
  box-shadow: inset 0 0 0 1px rgb(245 242 236 / .09);
  overflow: hidden;
}
.orolux .orox-prog__fill {
  background: linear-gradient(90deg, #8C6743, #C9A46A 45%, #EAD795);
  box-shadow: 0 0 18px -2px rgb(201 164 106 / .7);
  position: relative;
}
.orolux .orox-prog__fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(255 242 169 / .55), transparent);
  animation: orolux-sheen 3.6s linear infinite;
}
@keyframes orolux-sheen {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(200%); }
}


/* ==========================================================================
   3 · DISTRIBUTION → interactive radial
   The chart and its legend were two separate objects that happened to share a
   section. Now they are one instrument: hovering a row isolates its segment,
   and the centre readout becomes that row. That is the whole "make the pie
   feel connected" ask, and it is a genuine reading aid rather than a finish.
   Classes are toggled by oro-lux.js.
   ========================================================================== */

.orolux .orox-donut__seg {
  transition:
    stroke-width .45s var(--orolux-ease),
    opacity      .35s var(--orolux-ease),
    filter       .35s var(--orolux-ease);
}
.orolux .orox-donut.is-linked .orox-donut__seg { opacity: .22; }
.orolux .orox-donut__seg.orolux-hot {
  opacity: 1;
  stroke-width: 34;
  filter: drop-shadow(0 0 12px rgb(201 164 106 / .65));
}

/* Legend rows become targets: a gold spine slides in on the active row. */
.orolux .orox-alloc__i {
  position: relative;
  cursor: default;
}

/* ── touch ────────────────────────────────────────────────────────────────
   On a coarse pointer the rows are TAPPABLE (oro-lux.js switches the input
   model on `(hover: none)`), so they have to look it — an affordance that
   only exists on hover is no affordance at all on a phone. A hairline
   chevron, and a tap highlight suppressed so the browser's grey flash does
   not fight the gold state.

   `(hover: none)` rather than a width query: a narrow window on a desktop
   still has a mouse, and a touchscreen laptop has both. */
@media (hover: none) {
  .orolux .orox-alloc__i {
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    padding-right: clamp(22px, 5vw, 30px);
  }
  .orolux .orox-alloc__i::after {
    content: "";
    position: absolute;
    right: clamp(4px, 1.4vw, 10px);
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -3px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    opacity: .32;
    transition: opacity .3s var(--orolux-ease), transform .3s var(--orolux-spring);
  }
  /* selected: the chevron turns down, so the row reads as "open" */
  .orolux .orox-alloc__i.orolux-hot::after {
    opacity: .9;
    transform: rotate(45deg);
  }
  /* The cursor-tracked light is pointer-only; on touch it would sit wherever
     the last tap landed and read as a smudge. */
  .orolux .orox-donut__wrap::before { display: none; }
}
.orolux .orox-alloc__i::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12%;
  bottom: 12%;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, #EAD795, #8C6743);
  transform: scaleY(0);
  transform-origin: 50% 50%;
  transition: transform .4s var(--orolux-spring);
}
.orolux .orox-alloc__i.orolux-hot::before { transform: scaleY(1); }
.orolux .orox-alloc__i.orolux-hot .orox-alloc__pct { color: #EAD795; }
.orolux .orolux-light .orox-alloc__i.orolux-hot .orox-alloc__pct { color: var(--orolux-bronze); }
.orolux .orox-alloc__dot {
  transition: transform .4s var(--orolux-spring), box-shadow .4s var(--orolux-ease);
}
.orolux .orox-alloc__i.orolux-hot .orox-alloc__dot {
  transform: scale(1.7);
  box-shadow: 0 0 10px 1px currentColor;
}

/* Centre readout swaps with a short cross-fade instead of snapping. */
.orolux .orox-donut__center { transition: opacity .22s var(--orolux-ease); }
.orolux .orox-donut__center.orolux-swap { opacity: 0; }

/* A cursor-tracked warm light behind the ring. --lx/--ly are written by
   oro-lux.js; the fallback keeps it centred before the first pointer event
   and on touch, where they are never set. */
.orolux .orox-donut__wrap::before {
  content: "";
  position: absolute;
  inset: -12%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(
    260px circle at var(--lx, 50%) var(--ly, 50%),
    rgb(201 164 106 / .20), transparent 68%);
  opacity: 0;
  transition: opacity .5s var(--orolux-ease);
  pointer-events: none;
}
.orolux .orox-donut__wrap:hover::before { opacity: 1; }


/* ==========================================================================
   4 · FAQ → luxury accordion
   Was six hairline rows and 35% dead column. Now: glass panels, a spring
   open, an icon that morphs + → ×, and the dead column carries the answer
   text on wide screens so the eye has somewhere to go.
   ========================================================================== */

.orolux .orox-faq { max-width: 1100px; }

.orolux .orox-faq__i {
  border: 1px solid var(--orox-line);
  border-radius: clamp(12px, 1.1vw, 18px);
  margin-bottom: clamp(8px, .8vw, 14px);
  background: var(--orox-glass);
  box-shadow: var(--orox-glass-hi);
  transition:
    border-color .45s var(--orolux-ease),
    background   .45s var(--orolux-ease),
    box-shadow   .45s var(--orolux-ease),
    transform    .45s var(--orolux-ease);
}
.orolux .orox-faq__i:last-child { border-bottom: 1px solid var(--orox-line); }
.orolux .orox-faq__i:hover {
  border-color: rgb(201 164 106 / .34);
  transform: translateY(-2px);
}
.orolux .orox-faq__i[open] {
  border-color: rgb(201 164 106 / .40);
  box-shadow: 0 24px 54px -30px rgb(0 0 0 / .95);
}
.orolux .orolux-light .orox-faq__i[open] {
  box-shadow: 0 20px 44px -26px rgb(20 17 12 / .45);
}

.orolux .orox-faq__i summary { padding: clamp(18px, 1.7vw, 28px) clamp(18px, 1.6vw, 28px); }
.orolux .orox-faq__i .orox-faq__a { padding: 0 clamp(18px, 1.6vw, 28px) clamp(20px, 1.8vw, 30px); }

/* Open answer springs in rather than appearing. */
.orolux .orox-faq__i[open] .orox-faq__a { animation: orolux-answer .5s var(--orolux-ease) both; }
@keyframes orolux-answer {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

/* THE SIGN IS DELIBERATELY NOT TOUCHED.
   An earlier revision of this file rebuilt it as a + that rotates to a ×.
   That was wrong: oro-sections.css already authors this control properly —
   on open it becomes a graduated gold seal that turns over, and its own
   comment explains the choice ("a flat swatch spinning reads as nothing, a
   graduated one reads as a seal turning over"). It also ships a
   reduced-motion variant that drops the rotation and re-authors the gradient
   the right way up, and a forced-colors variant using Highlight/CanvasText.

   Overriding it replaced a solid gold seal with a 12%-alpha wash, and the
   inherited `::after { transform: scaleY(0) }` combined with an added 135°
   rotation to render a single diagonal slash instead of any legible glyph.
   The panels below are this layer's contribution; the control is theirs. */

/* Only the spacing changes, because the summary padding above moved. */
.orolux .orox-faq__i summary .orox-faq__sign { margin-left: auto; }

/* Wide screens: the answer takes the column that was empty, so an open row
   reads as question | answer rather than a tall stack. */
@media (min-width: 1100px) {
  .orolux .orox-faq__i summary { padding-right: clamp(56px, 5vw, 84px); }
  .orolux .orox-faq__i .orox-faq__a {
    max-width: 68ch;
    margin-left: clamp(0px, 3vw, 54px);
  }
}


/* ==========================================================================
   5 · FOOTER → ambient
   The footer's content was already rich; it just sat perfectly still. This
   adds depth behind it — a perspective floor and a slow warm beam — plus a
   coin that drifts. All pseudo-elements, all behind the content, none of it
   interactive.
   ========================================================================== */

.orolux .orof { position: relative; }

/* Grid floor running to a horizon. z-index -1 for the same reason the dust
   host uses it: a positioned element at 0 would paint over the copy. */
.orolux .orof::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: -25%;
  right: -25%;
  bottom: 0;
  height: clamp(240px, 26vw, 460px);
  pointer-events: none;
  background-image:
    linear-gradient(rgb(201 164 106 / .34) 1px, transparent 1px),
    linear-gradient(90deg, rgb(201 164 106 / .34) 1px, transparent 1px);
  background-size: 72px 72px;
  transform: perspective(300px) rotateX(64deg);
  transform-origin: 50% 100%;
  /* Fade in from the horizon so the grid emerges rather than starting flat. */
  -webkit-mask-image: linear-gradient(180deg, transparent 4%, #000 55%, #000);
          mask-image: linear-gradient(180deg, transparent 4%, #000 55%, #000);
  opacity: .75;
}

/* A warm glow sitting on the horizon line, so the floor reads as lit rather
   than as a wireframe pasted on. */
.orolux .orof::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 0;
  bottom: clamp(150px, 17vw, 300px);
  height: clamp(120px, 13vw, 220px);
  pointer-events: none;
  background: radial-gradient(60% 100% at 50% 100%, rgb(201 164 106 / .16), transparent 72%);
  filter: blur(18px);
}

/* A slow warm beam across the top of the footer. 24s, barely there. */
.orolux .orof__wm { overflow: hidden; }
.orolux .orof__wm::after {
  content: "";
  position: absolute;
  top: -30%;
  left: -40%;
  width: 45%;
  height: 160%;
  pointer-events: none;
  background: linear-gradient(100deg, transparent, rgb(201 164 106 / .10), transparent);
  filter: blur(28px);
  animation: orolux-beam 24s linear infinite;
}
@keyframes orolux-beam {
  0%   { transform: translateX(0) skewX(-14deg); }
  100% { transform: translateX(320%) skewX(-14deg); }
}

/* The hero coin drifts instead of hanging, and its halo breathes out of phase
   with it so the two do not read as one rigid object. (`.orof__hero img` was
   in this list and matched nothing — the real classes are `.orof__coin` and
   `.orof__coin-halo`. Caught by the dead-selector audit.) */
.orolux .orof__coin {
  animation: orolux-float 11s ease-in-out infinite;
  will-change: transform;
}
.orolux .orof__coin-halo {
  animation: orolux-halo 7.5s ease-in-out infinite;
}
@keyframes orolux-halo {
  0%, 100% { opacity: .72; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.06); }
}
@keyframes orolux-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-14px) rotate(-1.6deg); }
}

/* ── the one real hit-target failure on the page ──────────────────────────
   Measured across every interactive element at 1440 and 390: exactly ONE
   control is under WCAG 2.5.8 AA's 24x24 — the "Full build order" link in the
   footer's build-status block, at 119x20. Four pixels short on height.

   (28 others sit at 24px tall. Those PASS AA and are only under the 44px
   Apple/Material guideline, which is ordinary for a footer text link, so they
   are left alone — inflating a whole column of text links to 44px would wreck
   the footer's density for no conformance gain. oro-qa.css already lifted the
   controls where 44px genuinely matters: the PWA prompts and the toast close.)

   min-height rather than height, so a longer label grows the link instead of
   overflowing it. */
.orolux .orof__status-link {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
}

/* Footer link columns pick up the same lift as the rest of the page. */
.orolux .orob__card { transition: border-color .5s var(--orolux-ease), transform .5s var(--orolux-ease), box-shadow .5s var(--orolux-ease); }
.orolux .orob__card:hover { box-shadow: 0 20px 44px -26px rgb(0 0 0 / .9); }


/* ==========================================================================
   6 · ECOSYSTEM — the two sections that carry it
   #core is already the page's best frame (the coin on the board). Its only
   weak element was the node row underneath, which was six labels on a rule.
   #ledger is the actual ecosystem list; its rows now read as a connected
   spine rather than six unrelated lines.
   ========================================================================== */

/* ── #core · the node row becomes a connected run ───────────────────────── */
.orolux .orox-core__nodes {
  position: relative;
  padding-top: clamp(16px, 1.5vw, 26px);
}
.orolux .orox-core__nodes::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent,
    rgb(201 164 106 / .5) 12%,
    rgb(201 164 106 / .5) 88%,
    transparent);
}
.orolux .orox-core__node {
  position: relative;
  padding-top: clamp(14px, 1.2vw, 20px);
  transition: color .4s var(--orolux-ease), transform .5s var(--orolux-ease);
}
/* Each node hangs a stem and a dot off the run above it. */
.orolux .orox-core__node::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: clamp(9px, .8vw, 13px);
  background: rgb(201 164 106 / .55);
}
.orolux .orox-core__node::after {
  content: "";
  position: absolute;
  top: clamp(8px, .75vw, 12px);
  left: -2.5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #FFF2A9, #C9A46A 60%, #8C6743);
  box-shadow: 0 0 10px 1px rgb(201 164 106 / .5);
}
.orolux .orox-core__node:hover { color: #EAD795; transform: translateY(-2px); }

/* ── #ledger · rows become a spine ──────────────────────────────────────── */
.orolux .orox-mods { position: relative; }
.orolux .orox-mod {
  position: relative;
  transition: background .4s var(--orolux-ease), transform .45s var(--orolux-ease);
  border-radius: 10px;
}
.orolux .orox-mod:hover {
  background: rgb(245 242 236 / .035);
  transform: translateX(4px);
}
/* The tick reads as a filled node once the row is in. (The state class here
   is `.is-done`, not `.is-in` — an earlier version of this rule listed the
   latter and matched nothing.) */
.orolux .orox-mod .orox-mod__tick {
  transition: border-color .5s var(--orolux-ease), box-shadow .5s var(--orolux-ease);
}
.orolux .orox-mod:hover .orox-mod__tick {
  border-color: rgb(201 164 106 / .6);
  box-shadow: 0 0 14px -2px rgb(201 164 106 / .65);
}

/* The tally ring gets a metallic sweep so it stops reading as a grey donut. */
.orolux .orox-tally__ring { position: relative; }
.orolux .orox-tally__ring::after {
  content: "";
  position: absolute;
  inset: -6%;
  z-index: -1;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    rgb(201 164 106 / .22) 60deg,
    rgb(255 242 169 / .30) 110deg,
    rgb(201 164 106 / .14) 170deg,
    transparent 260deg);
  filter: blur(16px);
  animation: orolux-spin 18s linear infinite;
}
@keyframes orolux-spin { to { transform: rotate(360deg); } }


/* ==========================================================================
   7 · THE TOKEN — the three statement cards
   They were correct but weightless. Same material language as everything
   above, plus the ghost numeral coming forward on hover.
   ========================================================================== */

.orolux .orox-step {
  transition:
    transform    .55s var(--orolux-ease),
    border-color .45s var(--orolux-ease),
    box-shadow   .55s var(--orolux-ease);
}
.orolux .orox-step:hover {
  transform: translateY(-6px);
  border-color: rgb(201 164 106 / .38);
  box-shadow: 0 26px 56px -30px rgb(0 0 0 / .95);
}
.orolux .orox-step__ghost { transition: opacity .5s var(--orolux-ease), transform .6s var(--orolux-ease); }
.orolux .orox-step:hover .orox-step__ghost { opacity: .18; transform: translateY(-4px) scale(1.04); }


/* ==========================================================================
   9 · LIGHT-SECTION TEXT REPAIRS
   oro-sections.css sets a literal near-white on four elements, which cannot
   inherit the token flip in §1 and so vanished on paper. Found by sweeping
   every `color:` in that file for a luminance above .62 — these are the three
   that land inside a light section. (The fourth, `.orox-foot__chip`, is in
   the footer, which stays dark.)
   ========================================================================== */

.orolux .orolux-light .orox-mod__name   { color: var(--orolux-ink); }        /* was #dfe4ea */
.orolux .orolux-light .orox-faq__a      { color: var(--orolux-ink-2); }
.orolux .orolux-light .orox-faq__a strong { color: var(--orolux-ink); }      /* was #e8edf2 */

/* State colour on paper: in-progress earns bronze, planned stays neutral.
   Same rule as everywhere else — gold marks meaning. */
.orolux .orolux-light .orox-mod.is-done .orox-mod__amt { color: var(--orolux-bronze); }
.orolux .orolux-light .orox-mod__amt { color: var(--orolux-dim); }
.orolux .orolux-light .orox-mod.is-done {
  background: rgb(255 255 255 / .55);
  border-color: rgb(20 17 12 / .10);
  box-shadow: 0 1px 2px rgb(20 17 12 / .04);
}
.orolux .orolux-light .orox-mod__tick { border-color: rgb(20 17 12 / .22); }

/* The un-lit resting state is `opacity:.42`, authored for light-on-dark. Dark
   ink on paper loses far more at the same alpha — .42 puts these rows near
   2.5:1 while the scroll is still mid-way through the pin. Raised to .58 for
   the light section only: still clearly recessive against the lit rows, but
   readable at every point of the reveal.
   (Not a permanent-state fix — oro-sections.js adds `.is-done` to every row
   up front under reduced motion or without GSAP, so that path was already
   fine. This is about the transit.) */
.orolux .orolux-light .orox-mod { opacity: .58; }
.orolux .orolux-light .orox-mod.is-done { opacity: 1; }
.orolux .orolux-light .orox-mod.is-done .orox-mod__tick {
  background: var(--orolux-gold);
  border-color: var(--orolux-gold);
  box-shadow: 0 0 0 5px rgb(201 164 106 / .18);
}
.orolux .orolux-light .orox-mod__tick svg { stroke: #FFFDF8; }

/* The sign geometry is inherited untouched — see §4. These two rules only
   retint the PANEL edge for paper; the control itself is left alone. */
.orolux .orolux-light .orox-faq__i:hover { border-color: rgb(140 103 67 / .38); }
.orolux .orolux-light .orox-faq__i[open] { border-color: rgb(140 103 67 / .45); }


/* ==========================================================================
   10 · ACCESS TIERS — the aperture, the rail, the ledger
   This is where governance actually lives on the page (tier 04, "Govern —
   decide what changes"), and it was the flattest of the dark sections: a
   near-invisible dotted dial, four text rows on hairlines, and a ledger of
   dark-on-dark rows.

   The honesty of it is preserved exactly — the threshold still reads "not
   set", planned still reads planned, and no state is upgraded. What changes
   is that the instrument now looks like an instrument.
   ========================================================================== */

/* ── the aperture ─────────────────────────────────────────────────────────
   A bloom behind the dial and a slow bezel sweep, so the ring reads as
   machined rather than as a faint dotted outline. */
.orolux .orox-at-figure { position: relative; }
.orolux .orox-at-figure::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: clamp(120px, 13vw, 210px);
  width: clamp(300px, 30vw, 460px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgb(201 164 106 / .16), rgb(201 164 106 / .05) 42%, transparent 70%);
  filter: blur(20px);
  pointer-events: none;
}
.orolux .orox-at-figure::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: clamp(120px, 13vw, 210px);
  width: clamp(230px, 23vw, 350px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0deg,
    rgb(201 164 106 / .30) 42deg,
    rgb(255 242 169 / .40) 82deg,
    rgb(201 164 106 / .16) 128deg,
    transparent 220deg);
  filter: blur(10px);
  animation: orolux-spin 22s linear infinite;
  pointer-events: none;
}

/* The threshold statement carries the section. Give it the weight it earns —
   and keep "not set" honest by rendering it as an unset instrument reading,
   not as a value. */
.orolux .orox-at-thr-v {
  font-weight: 300;
  letter-spacing: -.02em;
  background-image: linear-gradient(180deg, #F5F2EC, #A39D92);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}
.orolux .orox-at-thr-r {
  width: clamp(52px, 5vw, 78px);
  background: linear-gradient(90deg, var(--orox-turq), transparent);
}

/* ── the tier rail ────────────────────────────────────────────────────────
   The drawn portion of the rail was flat white at .5 alpha. It becomes the
   same gold conduit the roadmap uses, so "how far down the tiers you are"
   reads at a glance. */
.orolux .orox-at-lbl::after {
  background: linear-gradient(180deg, rgb(234 215 149 / .95), rgb(201 164 106 / .75));
  box-shadow: 0 0 10px -1px rgb(201 164 106 / .6);
}
.orolux .orox-at-mark {
  border-radius: 50%;
  box-shadow: 0 0 12px 2px rgb(201 164 106 / .6);
}
.orolux .orox-at-lbl {
  border-radius: 10px;
  transition: background-color .35s var(--orolux-ease), transform .45s var(--orolux-ease);
}
.orolux .orox-at-lbl:hover { transform: translateX(3px); }

/* The selected tier gets a warm wash so the choice is legible without
   reading the numbers. */
.orolux .orox-access-sc #orox-at-1:checked ~ .orox-at-side .orox-at-lbl[data-t="1"],
.orolux .orox-access-sc #orox-at-2:checked ~ .orox-at-side .orox-at-lbl[data-t="2"],
.orolux .orox-access-sc #orox-at-3:checked ~ .orox-at-side .orox-at-lbl[data-t="3"],
.orolux .orox-access-sc #orox-at-4:checked ~ .orox-at-side .orox-at-lbl[data-t="4"] {
  background-image: linear-gradient(90deg, rgb(201 164 106 / .10), transparent 62%);
}

/* ── the ledger rows ──────────────────────────────────────────────────────
   Were hairline-separated rows on flat black. Now cards with the same glass
   the rest of the page uses, and a hover that lifts. */
.orolux .orox-at-row {
  border-top: 0;
  margin-bottom: clamp(6px, .6vw, 10px);
  border-radius: clamp(10px, .9vw, 14px);
  background: linear-gradient(180deg, rgb(245 242 236 / .045), rgb(245 242 236 / .012));
  box-shadow: inset 0 1px 0 rgb(245 242 236 / .07);
  padding-right: clamp(14px, 1.4vw, 22px);
  transition:
    opacity   200ms linear,
    transform 200ms var(--orox-ease),
    background .4s var(--orolux-ease),
    box-shadow .4s var(--orolux-ease);
}
.orolux .orox-at-row:hover {
  background: linear-gradient(180deg, rgb(245 242 236 / .075), rgb(245 242 236 / .02));
  box-shadow:
    inset 0 1px 0 rgb(245 242 236 / .12),
    0 16px 34px -22px rgb(0 0 0 / .9);
}

/* The build-state spine: lit for work underway, inert for work that is not.
   The `i` bars are authored flat; this is the only place state is added. */
.orolux .orox-at-spine i {
  border-radius: 2px;
  transition: background .4s var(--orolux-ease), box-shadow .4s var(--orolux-ease);
}
.orolux .orox-at-row:hover .orox-at-spine i {
  background: linear-gradient(180deg, rgb(234 215 149 / .8), rgb(201 164 106 / .5));
  box-shadow: 0 0 8px -2px rgb(201 164 106 / .7);
}

/* Panel title picks up the same clipped ramp as every other section title,
   so the tier heading stops looking like body copy. */
.orolux .orox-at-pttl {
  background-image: linear-gradient(180deg, #F5F2EC, #B4AEA3);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}


/* ==========================================================================
   13 · THE DRIFT WALL — a warm grade over cool artwork
   MEASURED, not eyeballed: each scene plate was decoded to a canvas and its
   mean channel values read. Seven of the nine come back cool —

     chip -17 · ring -17 · works -13 · portal -14 · facade -15 · slab -10
     (library +8 warm, vault -2 neutral)

   — on a site whose entire palette is a gold ramp. The blue is in the artwork
   itself, which is why no CSS or hex sweep has ever found it.

   WHY A FILTER AND NOT NEW ARTWORK
   `assets/**` belongs to the visuals lane, and the third hard rule of this build is
   that two lanes must never edit it at once — that collision has already cost
   this repo a `.webp` set. A render-time grade fixes what the visitor sees
   without touching a byte of image data, costs one GPU composite, and is
   deleted in one line the day gold plates ship.

   The grade is a duotone rather than a tint: dropping saturation first means
   the cool cast has nothing left to show, and the sepia then puts every plate
   in the same warm family. Nine mismatched renders become one deliberate
   wall, which is a better result than nine correctly-coloured mismatched
   renders would have been.
   ========================================================================== */

.orolux .drift-wall__inner img,
.orolux .drift-wall__tile img {
  filter:
    saturate(.34)      /* strip the cyan — it has no equivalent in the ramp */
    sepia(.5)          /* re-tint into the gold family                       */
    hue-rotate(-8deg)  /* nudge sepia's brown toward the ramp's bronze       */
    brightness(1.05)
    contrast(1.04);
  transition: filter .6s var(--orolux-ease);
}
/* On hover the plate comes back toward its own colour, so the grade reads as
   a resting state rather than as damage. */
.orolux .drift-wall__tile:hover img {
  filter: saturate(.62) sepia(.24) brightness(1.06) contrast(1.03);
}

@media (prefers-reduced-motion: reduce) {
  .orolux .drift-wall__inner img,
  .orolux .drift-wall__tile img { transition: none; }
}
/* Forced colours: never fight the user's palette with a filter. */
@media (forced-colors: active) {
  .orolux .drift-wall__inner img,
  .orolux .drift-wall__tile img,
  .orolux .drift-wall__tile:hover img { filter: none; }
}


/* ==========================================================================
   12 · TOKEN UTILITY — the material pass
   The brief called these cards flat and it was right: the statement floated
   on nothing, the issuance slots rendered as bare outlines, and the surface
   list was six hairline rows. This gives the section the same material the
   rest of the page now has, without changing a word of it or upgrading any
   state — "no figure published" still publishes no figure.
   ========================================================================== */

/* ── the claim ────────────────────────────────────────────────────────────
   "A key, not a holding." is the section's thesis and had no more presence
   than body copy. A gold spine and a little air is enough — a card around it
   would make it look like an aside, which is the opposite of what it is. */
.orolux .orox-unlock__claim {
  position: relative;
  padding-left: clamp(16px, 1.5vw, 26px);
}
.orolux .orox-unlock__claim::before {
  content: "";
  position: absolute;
  left: 0;
  top: .18em;
  bottom: .18em;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--orox-light), var(--orox-turq) 55%, transparent);
}

/* ── the eight issuance slots ─────────────────────────────────────────────
   These are the honest centrepiece of the section — eight slots deliberately
   left empty because no issuance parameter is fixed. As flat outlines they
   read like unstyled inputs. As recessed wells with a faint hatch they read
   as "nothing has been put here yet", which is exactly the claim. */
.orolux .orox-unlock__slots i {
  position: relative;
  border-color: rgb(245 242 236 / .16);
  background-color: rgb(0 0 0 / .28);
  background-image: repeating-linear-gradient(
    -45deg,
    rgb(245 242 236 / .05) 0 1px,
    transparent 1px 7px);
  box-shadow:
    inset 0 1px 3px rgb(0 0 0 / .6),
    inset 0 -1px 0 rgb(245 242 236 / .05);
  overflow: hidden;
}
/* A slow sweep along the row makes the emptiness feel like a live register
   waiting on a value, rather than a static graphic. */
.orolux .orox-unlock__slots i::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(201 164 106 / .22), transparent);
  transform: translateX(-100%);
  animation: orolux-slot 7s var(--orolux-ease) infinite;
}
.orolux .orox-unlock__slots i:nth-child(2)::after { animation-delay: .18s; }
.orolux .orox-unlock__slots i:nth-child(3)::after { animation-delay: .36s; }
.orolux .orox-unlock__slots i:nth-child(4)::after { animation-delay: .54s; }
.orolux .orox-unlock__slots i:nth-child(5)::after { animation-delay: .72s; }
.orolux .orox-unlock__slots i:nth-child(6)::after { animation-delay: .90s; }
.orolux .orox-unlock__slots i:nth-child(7)::after { animation-delay: 1.08s; }
.orolux .orox-unlock__slots i:nth-child(8)::after { animation-delay: 1.26s; }
@keyframes orolux-slot {
  0%       { transform: translateX(-100%); }
  22%, 100% { transform: translateX(100%); }
}

/* ── the surface list ─────────────────────────────────────────────────────
   Six hairline rows become the same glass rows used in #access-tiers, so the
   two lists that describe the same six surfaces finally look related. */
.orolux .orox-unlock__item {
  border-radius: clamp(10px, .9vw, 14px);
  padding-left: clamp(12px, 1.1vw, 18px);
  padding-right: clamp(12px, 1.1vw, 18px);
  transition:
    background .4s var(--orolux-ease),
    box-shadow .4s var(--orolux-ease),
    transform  .4s var(--orolux-ease);
}
.orolux .orox-unlock__item:hover {
  background: linear-gradient(180deg, rgb(245 242 236 / .055), rgb(245 242 236 / .015));
  box-shadow:
    inset 0 1px 0 rgb(245 242 236 / .10),
    0 14px 30px -22px rgb(0 0 0 / .9);
  transform: translateX(4px);
}

/* ── the route diagram ────────────────────────────────────────────────────
   The four-step check already has a card. Its rail gets the same gold
   conduit language as the roadmap so the two read as one system, and the
   entry node is marked as the live one. */
.orolux .orox-unlock__rail {
  background: linear-gradient(
    180deg,
    rgb(201 164 106 / .55) 0%,
    rgb(201 164 106 / .28) 55%,
    rgb(245 242 236 / .10) 100%);
}
.orolux .orox-unlock__node { transition: box-shadow .4s var(--orolux-ease); }
.orolux .orox-unlock__node--entry {
  box-shadow: 0 0 12px 1px rgb(201 164 106 / .5);
}
.orolux .orox-unlock__stop { transition: transform .4s var(--orolux-ease); }
.orolux .orox-unlock__stop:hover { transform: translateX(3px); }

/* ── the boundaries list ("What it is not") ───────────────────────────────
   These are the strongest sentences on the page. They should not be the
   quietest thing in the section. */
.orolux .orox-unlock__no {
  border-radius: clamp(10px, .9vw, 14px);
  padding: clamp(10px, .95vw, 15px) clamp(12px, 1.1vw, 18px);
  transition: background .4s var(--orolux-ease);
}
.orolux .orox-unlock__no:hover { background: rgb(245 242 236 / .035); }
.orolux .orox-unlock__x {
  transition: color .4s var(--orolux-ease), transform .4s var(--orolux-spring);
}
.orolux .orox-unlock__no:hover .orox-unlock__x { transform: scale(1.12); }


/* ==========================================================================
   11 · LIVING BACKGROUNDS
   Two techniques, chosen per surface rather than one applied everywhere.

   DARK sections reuse `bg-particles.js`, the canvas engine already on the
   page — hosts are injected by oro-lux.js. It is IntersectionObserver-gated,
   so only the section on screen is running. Its particles are authored white;
   at these opacities over a gold-bloomed black that reads as fine luminous
   dust, which is what the section wants.

   LIGHT sections get a CSS-only ember field instead — no canvas, no JS, no
   per-frame cost — because white particles are invisible on paper and the
   colour has to be gold there anyway.
   ========================================================================== */

/* ── dark: the canvas host ────────────────────────────────────────────────
   z-index -1 is load-bearing. A positioned element at z-index 0 paints ABOVE
   non-positioned block content, which would put dust on top of the copy;
   -1 puts it under the text and over the section background. `.orox` already
   sets `isolation: isolate`, so -1 cannot escape the section. */
.orolux .orolux-dust {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .5;
  /* Fade it out of the corners so it never reads as a rectangle of dots. */
  -webkit-mask-image: radial-gradient(ellipse 78% 68% at 50% 50%, #000 24%, transparent 82%);
          mask-image: radial-gradient(ellipse 78% 68% at 50% 50%, #000 24%, transparent 82%);
}
.orolux .orolux-dust canvas { display: block; }

/* ── light: the CSS ember field ───────────────────────────────────────────
   Two gradient layers drifting at different rates, which reads as depth. No
   DOM, no canvas — the whole field is two background-images on one
   pseudo-element. */
.orolux .orolux-light--gold {
  background-image:
    /* ── near embers, larger and warmer ── */
    radial-gradient(2px 2px at 12% 18%, rgb(140 103 67 / .34), transparent 60%),
    radial-gradient(1.6px 1.6px at 34% 42%, rgb(140 103 67 / .28), transparent 60%),
    radial-gradient(2.2px 2.2px at 58% 12%, rgb(160 119 74 / .30), transparent 60%),
    radial-gradient(1.4px 1.4px at 72% 34%, rgb(140 103 67 / .26), transparent 60%),
    radial-gradient(2px 2px at 88% 22%, rgb(160 119 74 / .24), transparent 60%),
    radial-gradient(1.6px 1.6px at 22% 58%, rgb(140 103 67 / .22), transparent 60%),
    radial-gradient(1.8px 1.8px at 64% 62%, rgb(140 103 67 / .20), transparent 60%),
    /* ── the wash from §1.1 ── */
    /* The gold pool — deeper, with a tighter core inside it so the falloff is
       not one flat ramp.

       SIZES ARE min(px, vw), POSITIONS ARE px. That split is the whole trick:
       the VERTICAL anchor has to stay absolute because ScrollTrigger pins this
       section to ~2340px and a percentage would drop the gold below anything
       the eye rests on — but the pool's WIDTH has to track the viewport, or a
       figure tuned at 1440 covers a 768 screen entirely. That is exactly what
       happened: at 768 the wash swamped the section and left white in one
       corner. Scaling the width fixes 700-1100 without another breakpoint. */
    radial-gradient(min(420px, 30vw) min(380px, 34vw) at 76% 290px, rgb(196 152 84 / .40) 0%, transparent 66%),
    radial-gradient(min(820px, 57vw) min(680px, 50vw) at 78% 310px, rgb(201 164 106 / .72) 0%, rgb(201 164 106 / .26) 42%, transparent 74%),
    radial-gradient(min(700px, 49vw) min(520px, 38vw) at 2% 60px, rgb(255 255 255 / .95), transparent 62%),
    linear-gradient(180deg, transparent 74%, rgb(190 148 84 / .44) 100%),
    linear-gradient(180deg, #FFFDF8 0px, #FDF9F1 420px, #F8F0DE 900px, #F1E4C6 100%);
  /* These three lists are POSITIONAL — one entry per background-image layer,
     in the same order. 12 layers: 7 ember tiles, then 3 washes and 2 ramps
     that must not tile or move. Adding an image without extending all three
     silently mis-assigns every layer after it. */
  background-repeat: repeat, repeat, repeat, repeat, repeat, repeat, repeat,
                     no-repeat, no-repeat, no-repeat, no-repeat, no-repeat;
  background-size: 340px 300px, 340px 300px, 340px 300px, 340px 300px,
                   520px 460px, 520px 460px, 520px 460px,
                   auto, auto, auto, auto, auto;
}

/* THE EMBERS DO NOT DRIFT — and that is a deliberate reversal.
   An earlier revision animated `background-position` across all 12 layers to
   give the field a slow parallax. It was measured with a devtools trace, on
   screen, 3-second window, animation on vs off:

     Paint       79.2ms -> 21.4ms   (-73%)
     RasterTask  23.2ms ->  0.4ms   (-98%)
     painted area roughly 7x lower

   background-position is not a compositor-friendly property, so every frame
   repainted a ~1424x2340 element. That is about 27ms of main-thread work per
   second, continuously, while this section is visible — on a page already
   carrying a 3310ms TBT — to move specks 5px per second, which nobody can
   perceive. The field is static now and looks identical.

   The section still moves: the specular wash on ::before animates `transform`,
   which the compositor handles for free. Motion here has to earn its paint. */

/* ── the wash on a phone ──────────────────────────────────────────────────
   The pools above are sized in ABSOLUTE px because the section is pinned and
   a percentage puts the gold below anything the eye rests on (see the note on
   the background-image stack). That tuning is for a ~1440px viewport: an
   820px-wide pool covers a 390px screen twice over, so on a phone the whole
   section rendered as saturated gold instead of white ripening into gold.

   Re-tuned rather than disabled — the gold is the point, it just has to be
   proportional to the viewport. Verified at 390x844. */
@media (max-width: 700px) {
  .orolux .orolux-light--gold {
    background-image:
      radial-gradient(2px 2px at 12% 18%, rgb(140 103 67 / .30), transparent 60%),
      radial-gradient(1.6px 1.6px at 34% 42%, rgb(140 103 67 / .24), transparent 60%),
      radial-gradient(2.2px 2.2px at 58% 12%, rgb(160 119 74 / .26), transparent 60%),
      radial-gradient(1.4px 1.4px at 72% 34%, rgb(140 103 67 / .22), transparent 60%),
      radial-gradient(2px 2px at 88% 22%, rgb(160 119 74 / .20), transparent 60%),
      radial-gradient(1.6px 1.6px at 22% 58%, rgb(140 103 67 / .18), transparent 60%),
      radial-gradient(1.8px 1.8px at 64% 62%, rgb(140 103 67 / .16), transparent 60%),
      /* one pool, sized to the screen, sitting low so the heading keeps white
         behind it */
      radial-gradient(300px 300px at 88% 620px, rgb(201 164 106 / .40) 0%, rgb(201 164 106 / .12) 46%, transparent 74%),
      radial-gradient(300px 240px at 0% 40px, rgb(255 255 255 / .95), transparent 66%),
      linear-gradient(180deg, transparent 82%, rgb(190 148 84 / .26) 100%),
      linear-gradient(180deg, #FFFDF8 0px, #FDFAF3 340px, #FAF4E8 760px, #F6EEDD 100%);
    background-size: 220px 200px, 220px 200px, 220px 200px, 220px 200px,
                     320px 300px, 320px 300px, 320px 300px,
                     auto, auto, auto, auto;
  }
  /* 11 layers here, not 12 — the inner gold core is dropped on small screens
     because at this scale it only deepens an area already covered by the main
     pool. background-size above matches that count.
     (The matching @keyframes override went with the drift itself — see the
     trace note beside the desktop rule.) */
}

/* The ring needs a darker track and a bronze arc to hold its shape on paper —
   the authored white-on-black values all but vanish here. */
.orolux .orolux-light--gold .orox-tally__track { stroke: rgb(20 17 12 / .13); }
.orolux .orolux-light--gold .orox-tally__arc { stroke: url(#oroxGrad); }
.orolux .orolux-light--gold .orox-tally__ring::before {
  content: "";
  position: absolute;
  inset: -4%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(255 255 255 / .85), rgb(255 255 255 / .35) 58%, transparent 74%);
}

/* The aperture bloom in §10 was slightly hot and sat a touch right of the
   drawn rings. Tightened and softened — it should read as light falling on
   the instrument, not as a lamp behind it. */
.orolux .orox-at-figure::before {
  width: clamp(250px, 25vw, 390px);
  background: radial-gradient(circle, rgb(201 164 106 / .13), rgb(201 164 106 / .04) 44%, transparent 72%);
}
.orolux .orox-at-figure::after {
  width: clamp(200px, 20vw, 300px);
  filter: blur(14px);
  opacity: .8;
}


/* ==========================================================================
   8 · REDUCED MOTION
   Same layout, same colours, nothing moves. Every animation introduced above
   is switched off here — the static end-state of each is already the correct
   design, which is why none of them animate layout.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .orolux .orox-road::before,
  .orolux .orox-phase--live .orox-phase__dot::after,
  .orolux .orox-prog__fill::after,
  .orolux .orof__wm::after,
  .orolux .orof__coin,
  .orolux .orof__coin-halo,
  .orolux .orox-tally__ring::after,
  .orolux .orolux-light--gold,
  .orolux .orolux-light--gold::before,
  .orolux .orox-at-figure::after,
  .orolux .orox-unlock__slots i::after {
    animation: none;
  }
  /* The slot sweep is the only thing that moves in §12; the recessed wells
     are the design and they stay. */
  .orolux .orox-unlock__slots i::after { display: none; }
  .orolux .orox-unlock__item:hover,
  .orolux .orox-unlock__stop:hover { transform: none; }
  .orolux .orox-faq__i[open] .orox-faq__a { animation: none; }
  /* The dust hosts are never created under reduced motion (oro-lux.js skips
     them entirely), so there is nothing to switch off here. */
  .orolux .oropw__card:hover,
  .orolux .orox-step:hover,
  .orolux .orox-phase:hover,
  .orolux .orox-mod:hover,
  .orolux .orox-faq__i:hover { transform: none; }
}

/* Forced colours: keep every new affordance visible as an outline. */
@media (forced-colors: active) {
  .orolux .orox-faq__i,
  .orolux .orox-faq__sign { border: 1px solid CanvasText; }
  .orolux .orox-road::before,
  .orolux .orof::after,
  .orolux .orox-tally__ring::after { display: none; }
}
