/* ═══════════════════════════════════════════════════════════════════════════
   ARC · arc-experience.css — THE EXPRESSIVE LAYER
   8 September 2026 · arc-frontend · branch arcverse-frontend-gate

   WHY THIS FILE EXISTS, MEASURED, NOT ASSERTED.
   The first frontend programme shipped 11 pages onto arc-shell.css and Darren
   said the site looked substantially unchanged. He was right. Measured against
   design-prototypes/*.html the shipped pages carried:

       display type      0        (the token --arcs-display existed; NOTHING
                                   in the estate consumed it — there was no
                                   .arcs-display CLASS. A token nobody applies
                                   is not a design decision, it is a comment.)
       depth shadows     0-1
       motion rules      0-8
       full-bleed stage  0-7

   Four of the five qualities the 6 Sep ruling demanded scored zero, and only
   ONE of them (photography) needs an asset we do not own. Display type, depth,
   motion and editorial composition are free. This file is those four.

   🔒 LOAD ORDER IS FIXED AND THIS FILE IS LAST:
        arc-tokens.css  →  arc-shell.css  →  arc-experience.css
      It EXTENDS the shell. It redefines no --arcs-* or --s3-* token, overrides
      no shell class, and owns no chrome. Every colour here resolves through a
      shell or estate token.

   🚨 IT DOES NOT OWN THE FOCUS RING. arc-tokens.css sets an estate-wide
      :focus-visible ring with !important because 20+ pages carry outline:none.
      A :focus-visible rule written here would read correct in the source and
      do nothing on the page — that exact defect was measured on the MATCH
      prototype. Dark surfaces created here RETINT via --focus-ring only.

   🚨 THERE IS NO CARD-GRID HELPER IN THIS FILE, DELIBERATELY. A wall of
      equal rounded cards is the skeleton the ruling rejected. Nothing here
      makes one easy to build. .arcx-split is unequal BY CONSTRUCTION.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   0 · THE CLASS CONTRACT.  READ THIS BEFORE WRITING A PAGE.
       Every class this file publishes, what it does, and the markup it expects.
       If it is not in this list it is not part of the contract and may change.

   HEAD OF EVERY PAGE — the order is not negotiable:
       <link rel="stylesheet" href="arc-tokens.css">
       <link rel="stylesheet" href="arc-shell.css">
       <link rel="stylesheet" href="arc-experience.css">
   END OF BODY:
       <script src="arc-shell.js" defer></script>
       <script src="arc-experience.js" defer></script>

   ── TYPE ──────────────────────────────────────────────────────────────────
   .arcx-display        The page's opening headline. ONE per page, on the <h1>.
                        clamp(2.35rem,4.3vw,3.65rem). Modifiers: --tight (short
                        headlines, -0.038em), --wide (26ch instead of 19ch).
   .arcx-h2             A band's heading. clamp(1.75rem,3.2vw,2.75rem).
   .arcx-h3             A sub-heading inside a band.
   .arcx-lede           THE ONE paragraph under a display or h2. One only.
   .arcx-eyebrow        Sentence-case kicker with a fading gold rule. Interchangeable
                        with the shell's .arcs-eyebrow — pick one spelling per page.

   ── DEPTH ─────────────────────────────────────────────────────────────────
   .arcx-plate          A LIGHT panel carrying a live read. Any element.
      __k __claim __why __src   key · the claim · the reason · the provenance.
                        Children must be display:block elements or <span>s.
      --gold            2px gold hairline across the top.
      --hang            Hangs out of its band into the band below. THE signature
                        move. Requires: the plate is a grid item, and the NEXT
                        band's wrap carries the shell's .arcs-wrap--underhang.
   .arcx-lift           Add to any surface that should answer a hand: lifts 2px
                        with a deeper shadow on hover and on :focus-within.

   ── THE STAGE ─────────────────────────────────────────────────────────────
   .arcx-stage          A MODIFIER. Always written  class="arcs-stage arcx-stage".
                        Changes the shell stage's inner grid to 1fr / 400px.
   .arcx-stage__bg      OPTIONAL washed ground for an OWNED image. Add this
                        element ONLY when you have one; set the image with
                        style="--arcx-stage-img:url('img/x.jpg')".
   (the words column is the SHELL's .arcs-words — there is no .arcx-words)

   ── COMPOSITION ───────────────────────────────────────────────────────────
   .arcx-split          Two UNEQUAL columns, 1.32fr / 1fr. There is no equal
                        option. Modifiers: --wide (1.55/1) · --flip (1/1.32) ·
                        --rail (1fr/400px) · --key (190px/1fr) · --end · --mid.
                        Collapses to one column at 1080px.
   .arcx-run            Container for a list of entries. One hairline each.
   .arcx-row            One entry. An <a> or a <button>. Children MUST be <span>.
      __k __t __b __m   kicker · title · body · meta line.
      --marked          THE EXCEPTION ONLY: a 3px accent rule for a row that
                        genuinely differs. Set the colour with --arcx-rule on
                        that row. 🚨 If every row is marked, none of them is.
   .arcx-feature        The ONE large entry a band leads with.
      __img __tag __t __b        the image zooms slowly on hover.
   .arcx-reveal         A link whose underline completes on the PARENT's hover.
                        Put it last inside a .arcx-row or .arcx-feature.
   .arcx-quiet          The trailing note that closes a run.

   ── MOTION (opt-in, see §6) ───────────────────────────────────────────────
   data-arcx-enter              reveal this element when it scrolls into view.
   data-arcx-enter="stagger"    reveal its DIRECT CHILDREN in sequence (max 7).
   data-arcx-enter="fade|plate|settle"   the other three keyframes.
   window.arcxObserve()         call after injecting marked markup from arcApi.

   ── A COMPLETE BAND, COPY THIS ────────────────────────────────────────────

     <section class="arcs-stage arcx-stage">
       <div class="arcs-stage__inner">
         <div class="arcs-words">
           <p class="arcx-eyebrow">Your week in ARC</p>
           <h1 class="arcx-display">Three people are waiting to hear from you.</h1>
           <p class="arcx-lede">Kemi matched you on Tuesday and has not had a reply.</p>
           <div style="margin-top:30px;display:flex;gap:12px;flex-wrap:wrap">
             <a class="arcs-btn arcs-btn--gold" href="/matches">Open my matches</a>
             <a class="arcs-btn arcs-btn--ghost" href="#later">Not this week</a>
           </div>
         </div>
         <figure class="arcx-plate arcx-plate--gold arcx-plate--hang arcx-lift">
           <span class="arcx-plate__k">Why you are seeing this</span>
           <span class="arcx-plate__claim">Kemi asked for someone who has closed a first hire.</span>
           <span class="arcx-plate__why">You told her in August that you had just done that.</span>
           <span class="arcx-plate__src">Facilitator note · 22 August 2026</span>
         </figure>
       </div>
     </section>

     <section class="arcs-band arcs-band--paper">
       <div class="arcs-wrap arcs-wrap--underhang">   <!-- clears the hang -->
         <div class="arcx-split">
           <div>
             <p class="arcx-eyebrow">This Thursday</p>
             <h2 class="arcx-h2">The room in Brighton has four seats left.</h2>
             <p class="arcx-lede">Six people confirmed.</p>
             <a class="arcx-reveal" href="/events">Take a seat</a>
           </div>
           <div data-arcx-enter="stagger">
             <div class="arcx-run">
               <a class="arcx-row arcx-row--marked" href="/m/1"
                  style="--arcx-rule: var(--s3-arena-1)">
                 <span class="arcx-row__k">Needs an answer</span>
                 <span class="arcx-row__t">Kemi asked you a question</span>
                 <span class="arcx-row__b">About the first hire you made in July.</span>
                 <span class="arcx-row__m">Tuesday · unanswered for 3 days</span>
               </a>
               <a class="arcx-row" href="/m/2">
                 <span class="arcx-row__k">Work opportunity</span>
                 <span class="arcx-row__t">Casual barista, 15–20 hours a week</span>
               </a>
             </div>
             <p class="arcx-quiet">Nothing else is waiting.</p>
           </div>
         </div>
       </div>
     </section>

   ── THINGS THIS FILE DELIBERATELY DOES NOT PUBLISH ────────────────────────
   No card grid · no score, meter, percentage or star · no focus-ring rule
   (arc-tokens.css owns it estate-wide with !important) · no chrome, dock,
   sheet or journey strip (arc-shell.css owns those) · no colour outside an
   --s3- or --arcs- token · no external image host.

   ⚠ THE LINE ABOVE ONCE READ "--s3-*[slash]--arcs-* token" AND THAT GLOB
     CLOSED THIS COMMENT SIX LINES EARLY. The stray comment terminator turned
     the rest of the contract into garbage declarations, and the next comment
     opener then ran on and SWALLOWED THE WHOLE :root TOKEN BLOCK. Every
     --arcx-* custom property vanished, so `font-size: var(--arcx-display)`
     became invalid and the page opened at 16px body text — the exact failure
     this file exists to fix, reintroduced by a comment.
     🚨 It survived a brace-balance check, because the checker stripped
        comments with the same naive rule the CSS parser uses and therefore
        reproduced the bug instead of catching it. ONLY THE BROWSER'S CSSOM
        FOUND IT: `[...sheet.cssRules][0].selectorText` was `.arcx-display`
        when it had to be `:root`.
     🔒 NEVER WRITE A `*` IMMEDIATELY BEFORE A `/` IN A COMMENT HERE, and
        verify structure against a real parser, never a regex.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
   1 · TOKENS.  Additive only. Prefix --arcx-. Nothing below redefines a
       shell token; where the shell already carries a value, this file uses
       the shell's (--arcs-band-y, --arcs-wash-read, --arcs-z-plate, ...).
   ═══════════════════════════════════════════════════════════════════════════ */
:root {
  /* ── TYPE. Size is the instrument. The scale is ARC_EXPERIENCE_BASELINE §3.1
        verbatim. A 1.4rem heading is not display type; if a page opens at body
        size it has failed the ruling regardless of what else it does. ─────── */
  --arcx-display    : clamp(2.35rem, 4.3vw, 3.65rem);
  --arcx-h2         : clamp(1.75rem, 3.2vw, 2.75rem);
  --arcx-lede       : clamp(1.125rem, 1.7vw, 1.375rem);
  --arcx-h3         : clamp(1.1875rem, 1.9vw, 1.5rem);

  /* letter-spacing tightens as size grows; line-height loosens as it shrinks. */
  --arcx-display-ls : -0.032em;
  --arcx-display-lh : 1.06;
  --arcx-h2-ls      : -0.02em;
  --arcx-h2-lh      : 1.1;

  /* ── DEPTH. Baseline §3.2 verbatim. Two shadows, not a scale of six: the
        plate (an object that hangs between two bands) and the lift (a surface
        that answers a hand). Both are shadow colour, not content colour —
        there is no hex and no text pairing in either. ────────────────────── */
  --arcx-shadow-plate : 0 34px 64px -22px rgb(3 10 24 / .78), 0 4px 14px rgb(3 10 24 / .4);
  --arcx-shadow-lift  : 0 16px 40px -14px rgb(0 0 0 / .7);

  /* ── MOTION. Two curves only: entrance decelerates hard, a hand-response
        is short and nearly linear at the end. ───────────────────────────── */
  --arcx-ease       : cubic-bezier(.16, .8, .28, 1);
  --arcx-ease-hand  : cubic-bezier(.2, .7, .3, 1);
  --arcx-in-dur     : .72s;
  --arcx-in-step    : 70ms;

  /* ── HANG. How far a plate drops out of its band into the band below.
        🔒 THIS IS THE SHELL'S --arcs-hang VALUE, DELIBERATELY IDENTICAL. The
           clearance the next band reserves is the shell's .arcs-wrap--underhang
           (band-y + clamp(0px,6vw,96px)), which was tuned against exactly this
           number. Round 1 used 5vw/88px "because it looked fine" and left 130px
           of dead air under the plate at 1553px — the two values are a matched
           pair and drifting one silently loosens the composition. ────────── */
  --arcx-hang       : clamp(0px, 6vw, 104px);

  /* the gap between the two halves of an unequal split. */
  --arcx-gutter     : clamp(24px, 3.4vw, 52px);

  /* ── TEXT ON THE AI BAND, AND THIS IS A MEASURED FIX, NOT A PREFERENCE.
        The shell's --arcs-on-navy family was calibrated on --s3-navy. The AI
        band is NOT navy: its gradient opens on
        color-mix(--s3-purple-strong 78%, --s3-navy) = rgb(99 52 198), which is
        far lighter. Measured 8 Sep with the estate audit's own resolver
        (self-control 21.00 / 1.00 / (128,128,128); anti-control --s3-gold on
        --arcs-w = 2.10:1, so the instrument can report a failure):

            --arcs-on-navy-3 on that ground  2.67:1   FAIL
            --arcs-on-navy   on that ground  4.26:1   under the 4.5 body floor
            --s3-gold        on that ground  3.52:1   under the 4.5 body floor

        So gold is NOT a safe text colour on the AI band even though it is
        7.84:1 on navy, and the shell's secondary ink is unreadable there. A
        purple-tinted white is the honest answer — grey on a purple field reads
        as a rendering fault, and it fails anyway. Remeasured: 6.37:1 and
        5.14:1 on the same worst-case stop. ──────────────────────────────── */
  --arcx-on-ai      : color-mix(in srgb, var(--arcs-w) 90%, var(--s3-purple-strong));
  --arcx-on-ai-3    : color-mix(in srgb, var(--arcs-w) 76%, var(--s3-purple-strong));
}


/* ═══════════════════════════════════════════════════════════════════════════
   2 · DISPLAY TYPE.  The largest single visual change available, and the one
       that scored a hard zero.
   ═══════════════════════════════════════════════════════════════════════════ */

/* .arcx-display — a page opens on this ONCE. It is an <h1> in almost every
   case. Explicit weight/spacing/height so the class works on a <p> or a <span>
   too, not only on a heading the shell reset already touched. */
.arcx-display.arcx-display {
  font-size: var(--arcx-display);
  font-weight: 600;
  line-height: var(--arcx-display-lh);
  letter-spacing: var(--arcx-display-ls);
  max-width: 19ch;
  text-wrap: balance;
}
/* the prototypes go one step tighter on the very largest setting. Opt in when
   the headline is short and set at the clamp ceiling. */
/* 🚨 THE DOUBLED CLASS IS A BUG FIX. DO NOT TIDY IT TO ONE CLASS.
   Found 9 Sep 2026 by the chat lane, verified and quantified by the Foreman.
   arc-shell.css:222 `.arcs-page h1, .arcs-page h2, .arcs-page h3` and :226
   `.arcs-page p, ul, ol` are (0,1,1). Every rule below was (0,1,0).
   SPECIFICITY BEATS SOURCE ORDER, so the resets won and these components'
   own line-height, letter-spacing and margins NEVER APPLIED.
   Measured across the 20 shell pages: 71 .arcx-h2 + 20 .arcx-h3 rendering at
   DISPLAY tracking (-0.032em) and 1.06 leading instead of 1.1/1.2 and
   -0.02/-0.024em; 85 .arcx-lede, 83 .arcx-eyebrow and 18 .arcx-quiet unable
   to set their own margin. 298 elements.
   🔒 IT WAS INVISIBLE ON THE ONE ELEMENT EVERYONE CHECKS FIRST: .arcx-display
   asks for exactly the reset's values, so the headline looked correct while
   the whole h2/h3 tier of the ruled type scale silently did not render.
   Corroboration, not theory: hubs.html:213 carries a PAGE-LEVEL PATCH,
   `.arcs-page p.arcx-eyebrow { margin-bottom: 20px }`, above a comment
   reading "declared 20px -> computed 0px". A builder hit this, worked around
   it on one page, and nineteen others kept the defect. That is exactly what
   the baseline means by "A PAGE-LEVEL PATCH WOULD HAVE HIDDEN ALL THIRTY-FOUR".
   Same idiom as .arcx-plate--hang and .arcs-stick.arcs-stick. */
.arcx-display--tight.arcx-display--tight { letter-spacing: -0.038em; }
/* a headline that has to hold a long name or a whole sentence. */
.arcx-display--wide  { max-width: 26ch; }


.arcx-h2.arcx-h2 {
  font-size: var(--arcx-h2);
  font-weight: 600;
  line-height: var(--arcx-h2-lh);
  letter-spacing: var(--arcx-h2-ls);
  max-width: 19ch;
  text-wrap: balance;
}

.arcx-h3.arcx-h3 {
  font-size: var(--arcx-h3);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.024em;
  max-width: 24ch;
}

/* THE ONE paragraph under a display headline. One. A lede followed by three
   more paragraphs is body copy with a large first line. */
.arcx-lede.arcx-lede {
  /* 24px, not 18. Measured by looking: display line-height is 1.06, so the
     headline's last line has almost no descender space beneath it and 18px
     read as ~12px on screen — tighter than the 30px between the lede and the
     actions below it, which inverted the rhythm. */
  margin-top: 24px;
  font-size: var(--arcx-lede);
  line-height: 1.5;
  letter-spacing: -0.012em;
  max-width: 44ch;
  color: var(--s3-ink-mid);
}

/* ── colour by band. The shell's bands set their own text colour; display type
      inherits it correctly on light bands, but the LEDE needs lifting on navy
      or it reads as the shell's muted default against a dark ground. ────── */
.arcs-band--navy .arcx-display, .arcs-band--ai .arcx-display,
.arcs-band--deep .arcx-display, .arcx-stage .arcx-display,
.arcs-stage .arcx-display,
.arcs-band--navy .arcx-h2, .arcs-band--ai .arcx-h2,
.arcs-band--deep .arcx-h2, .arcx-stage .arcx-h2,
.arcs-stage .arcx-h2,
.arcs-band--navy .arcx-h3, .arcs-band--ai .arcx-h3,
.arcs-band--deep .arcx-h3, .arcx-stage .arcx-h3,
.arcs-stage .arcx-h3 {
  color: var(--arcs-w);
}

.arcs-band--navy .arcx-lede, .arcs-band--ai .arcx-lede,
.arcs-band--deep .arcx-lede, .arcx-stage .arcx-lede,
.arcs-stage .arcx-lede {
  color: var(--arcs-on-navy);
}

/* .arcx-eyebrow — sentence case with a fading gold rule, NOT tracked-out
   all-caps, which is the commonest tell on a generated page.
   ⚠ GOLD IS 2.10:1 ON WHITE AND MUST NEVER BE TEXT THERE. On light bands the
     word is ink-mid and the RULE carries the gold instead. This is the same
     rule the shell applies to .arcs-eyebrow; the two are interchangeable in
     appearance and either may be used. Prefer one spelling per page. */
.arcx-eyebrow.arcx-eyebrow {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 20px;
  font-size: var(--arcs-small);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--s3-ink-mid);
}

.arcx-eyebrow::after {
  content: ""; height: 1px; flex: 1; max-width: 170px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--s3-gold) 70%, var(--s3-ink-mid)), transparent);
}

.arcs-band--navy .arcx-eyebrow, .arcs-band--ai .arcx-eyebrow,
.arcs-band--deep .arcx-eyebrow, .arcx-stage .arcx-eyebrow,
.arcs-stage .arcx-eyebrow {
  color: var(--s3-gold);            /* 6.3:1 on --s3-navy — safe as text HERE only */
}

.arcs-band--navy .arcx-eyebrow::after, .arcs-band--ai .arcx-eyebrow::after,
.arcs-band--deep .arcx-eyebrow::after, .arcx-stage .arcx-eyebrow::after,
.arcs-stage .arcx-eyebrow::after {
  background: linear-gradient(90deg, var(--s3-gold), transparent);
}


/* ═══════════════════════════════════════════════════════════════════════════
   3 · DEPTH.  Layering and overlap. Not a flat card with a 1px border.
   ═══════════════════════════════════════════════════════════════════════════ */

/* .arcx-plate — THE SIGNATURE MOVE, and the thing a card grid cannot do.
   A LIGHT panel carrying a live read, sitting on a navy band and HANGING OUT
   of it into the band below. The overlap is what makes it depth; without the
   overlap it is a card with a bigger shadow.

   Printed, not carded: 2px radius, one deep shadow, NO border. A border plus a
   shadow is a card pretending to be an object.

   🔒 The shell's .arcs-plate is the NAVY plate (a photograph or a dark object
      on the stage). This is the LIGHT one. They are different components and a
      page uses whichever separates from the surface underneath it. Do not
      stack the two class names on one element. */
.arcx-plate {
  position: relative;
  z-index: var(--arcs-z-plate);
  border-radius: 2px;
  background: var(--arcs-w);
  color: var(--s3-ink);
  box-shadow: var(--arcx-shadow-plate);
  padding: clamp(24px, 2.6vw, 36px);
}
/* a plate on a WHITE band needs the paper tone to separate from its ground;
   white on white is an invisible object with an expensive shadow. */
.arcs-band--white .arcx-plate {
  background: var(--arcs-paper);
  color: var(--s3-ink);
}

/* the gold hairline across the top. A claim the member is meant to read first. */
.arcx-plate--gold::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--s3-gold);
}

/* ── THE HANG. Clear the band's OWN bottom padding first, then hang by
      --arcx-hang. Getting this wrong does not look broken — it looks like
      slightly worse spacing, which is why it has to be arithmetic and not an
      eye. The band BELOW must reserve the clearance with the shell's
      .arcs-wrap--underhang or the plate lands on its heading. ───────────── */
/* 🚨 `.arcx-plate.arcx-plate--hang` — THE DOUBLED CLASS IS A BUG FIX AND MUST
   NOT BE "TIDIED" TO ONE CLASS. Measured in the browser, 8 Sep: the plate's
   computed margin-bottom was 0px and it sat 80px ABOVE the stage's bottom
   edge — the exact inverse of hanging — while the source read as correct and
   the calc() itself resolved fine when tested on a bare element.

   The cause is a specificity collision with the shell's own trap-fix:
       .arcs-page figure, .arcs-page blockquote, ...  { margin: 0 }   (0,1,1)
       .arcx-plate--hang                              { margin-bottom }(0,1,0)
   The shell added that rule to kill the UA's `margin: 1em 40px` on <figure>,
   and it now beats any single-class margin on a <figure> — which is the
   natural element for a plate carrying a claim and a source line. Doubling the
   class to (0,2,0) wins on every element, so the component works whether a
   page author reaches for <figure>, <aside> or <div>.
   ⚠ Getting this wrong does not look broken. It looks like a plate with
     slightly generous spacing, which is why it survived a source read. */
.arcx-plate.arcx-plate--hang {
  --arcx-pad-b: var(--arcs-band-y);
  align-self: end;
  margin-bottom: calc(-1 * (var(--arcx-pad-b) + var(--arcx-hang)));
}
/* inside a stage the band's bottom padding is a different token. */
.arcx-stage .arcx-plate.arcx-plate--hang,
.arcs-stage .arcx-plate.arcx-plate--hang { --arcx-pad-b: var(--arcs-stage-b); }

/* plate internals. A live read carries a CLAIM, a REASON and its PROVENANCE.
   🚨 No score, no percentage, no star, no completeness meter. Ruled. */
.arcx-plate__k {
  display: block;
  font-size: var(--arcs-micro);
  font-weight: 500;
  color: var(--s3-ink-mid);
}

.arcx-plate__claim {
  display: block;
  margin-top: 10px;
  font-size: var(--arcx-h3);
  font-weight: 600;
  line-height: 1.24;
  letter-spacing: -0.024em;
  color: var(--s3-ink);
  max-width: 24ch;
}

.arcx-plate__why {
  display: block;
  margin-top: 12px;
  color: var(--s3-ink-mid);
  font-size: var(--arcs-small);
  line-height: 1.6;
  max-width: 40ch;
}

.arcx-plate__src {
  display: block;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--s3-border);
  font-size: var(--arcs-micro);
  color: var(--s3-ink-mid);
}

/* .arcx-lift — a surface that answers a hand. Transform AND shadow together;
   a shadow change alone reads as a rendering artefact rather than a lift.
   :focus-within so a keyboard reaching a control inside gets the same answer —
   this is NOT a focus ring and does not touch --focus-ring. */
.arcx-lift {
  transition: transform .2s var(--arcx-ease-hand), box-shadow .2s var(--arcx-ease-hand);
}

.arcx-lift:hover,
.arcx-lift:focus-within {
  transform: translateY(-2px);
  box-shadow: var(--arcx-shadow-lift);
}


/* ═══════════════════════════════════════════════════════════════════════════
   4 · THE STAGE.  The full-bleed opening. Navy ground for a WHOLE section,
       not a sidebar sliver — that is the ruling, quoted.

   🚨 .arcx-stage IS A MODIFIER OF THE SHELL'S .arcs-stage, NOT A RIVAL TO IT.
      IT IS ALWAYS WRITTEN AS  class="arcs-stage arcx-stage".

      Round 1 of this file built .arcx-stage as a self-contained section that
      redeclared the navy gradient, the padding, the min-height and the focus
      retint. It rendered, and it looked almost right — which is why this had
      to be caught by SCREENSHOT and not by reading the diff. What the render
      showed: the "Not this week" ghost button was INVISIBLE, dark-on-dark.

      The cause is structural, not cosmetic. SIX rule-groups in arc-shell.css
      are keyed on the literal selector `.arcs-stage`:
          --focus-ring / --focus-halo retint     (line 286)
          .arcs-stage .arcs-h2                   (line 619)
          .arcs-stage .arcs-btn--ghost           (lines 783, 787)
          .arcs-stage .arcs-state                (lines 881, 886)
          .arcs-stage .arcs-repflag              (line 899)
      A new class cannot inherit any of them. Bridging all six here would work
      today and drift the moment the shell adds a seventh — and the seventh
      would fail the same silent way.

   🔒 SO THIS FILE CHANGES ONLY WHAT DIFFERS: the inner grid ratio, and the
      image mechanism. Everything else stays the shell's, for ever.

        .arcs-stage alone        53fr / 47fr, a masked photograph dissolving in
                                 from the right. Use when there IS a photograph.
        + .arcx-stage            1fr / 400px, an optional washed owned asset as
                                 a full ground. Use when there is not — which is
                                 nearly always, because ARC owns one photograph.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── THE GROUND IMAGE. Optional, and OWNED ONLY. Never an external host:
      site/ is a public URL.
        <div class="arcx-stage__bg" style="--arcx-stage-img:url('img/x.jpg')"></div>
      The transmittance system is arithmetic, not judgement: --arcs-wash-open
      (.42) is a FLAT floor that may only darken, laid under a composition
      gradient that reaches --arcs-wash-read (.78) where the words are. Text
      contrast therefore does not depend on which parts of the picture happen
      to be light. 🚨 NEVER PUT TEXT ON AN UNWASHED IMAGE.

   🚨 ADD THIS ELEMENT ONLY WHEN YOU ACTUALLY HAVE AN IMAGE. With no
      --arcx-stage-img the wash still paints, so an empty .arcx-stage__bg is a
      sheet of darkening over the stage's own gradient — decoration that costs
      contrast and gives nothing. Caught in the first render: the left third of
      an imageless stage was visibly muddier than the right for no reason. ── */
.arcx-stage__bg {
  position: absolute; inset: 0;
  z-index: var(--arcs-z-photo);
  overflow: hidden;
  background-image: var(--arcx-stage-img, none);
  background-size: cover;
  background-position: 58% 42%;
}
/* 🔒 THE FLOOR IS ARITHMETIC AND HERE IS THE ARITHMETIC, SO NOBODY HAS TO
      RE-DERIVE IT BEFORE CHANGING A STOP. The two layers ALWAYS composite —
      the flat --arcs-wash-open (.42) paints over the composition gradient at
      every x — so the effective alpha at any point is

          a = 1 - (1 - a_composition) * (1 - 0.42)

      and white text needs a >= 0.58 to clear 4.5:1 over the worst case, a pure
      WHITE pixel of the photograph. Solving: 🚨 NO COMPOSITION STOP MAY EVER
      GO BELOW 28%. The stops below are 78 / 58 / 34, measured over a white
      pixel at 13.11:1 / 8.68:1 / 5.22:1 — so the guarantee holds across the
      WHOLE band, not merely where the words happen to be. That distinction is
      the point: a wash tuned to where the text sits today falls out of
      registration the first time the column rewraps.
   ⚠ A round of this file measured the .42 layer ALONE and reported 2.76:1 — a
     false failure, because that ground exists nowhere on the element. Model
     the composite or do not model it. */
.arcx-stage__bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(0deg, var(--arcs-wash-open), var(--arcs-wash-open)),
    linear-gradient(96deg,
      var(--arcs-wash-read) 0%,
      color-mix(in srgb, var(--arcs-ink) 58%, transparent) 52%,
      color-mix(in srgb, var(--arcs-ink) 34%, transparent) 100%);
}

/* ── THE ASYMMETRIC INNER SPLIT. 1fr / 400px — deliberately unequal, and the
      400px side is a FIXED measure so it reads as a column of record rather
      than half of a two-up grid.
   🚨 THE ROW MUST FILL THE SECTION OR align-self:end MEANS NOTHING. Measured
      on the profile prototype: "end" put a plate at the bottom of a 500px
      CONTENT row floating inside a 900px section — 115px ABOVE the section's
      own bottom edge, the exact opposite of hanging. Only a render showed it. */
/* THE ONLY LAYOUT LINE THIS FILE OWNS ON THE STAGE. Everything else about
   .arcs-stage__inner — position, z-index, max-width, the min-height that makes
   align-self:end mean anything, the row template, the gap, min-width:0 on the
   children — is already correct in the shell and is NOT repeated here. */
.arcx-stage .arcs-stage__inner {
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
}

/* 🔒 THERE IS NO .arcx-words. The stage's words column is the shell's
      .arcs-words, and it must be, because the shell already staggers its
      direct children on page load (.arcs-words > *:nth-child(1..7)). A second
      class here would have produced a words column that does not animate while
      looking, in the source, exactly like one that does. */


/* ═══════════════════════════════════════════════════════════════════════════
   5 · EDITORIAL COMPOSITION.  Unequal by construction.
   🚨 There is no .arcx-grid, no .arcx-cards and no auto-fill repeat() in this
      file. If a page needs a wall of equal rounded cards it is rebuilding the
      rejected skeleton and should start again.
   ═══════════════════════════════════════════════════════════════════════════ */

/* .arcx-split — two columns that are NEVER equal. The default 1.32/1 is the
   match prototype's; the modifiers are the other ratios the three prototypes
   actually used. There is no 1fr/1fr option, deliberately. */
.arcx-split {
  display: grid;
  grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr);
  gap: var(--arcx-gutter);
  align-items: start;
}

.arcx-split > * { min-width: 0; }

.arcx-split--wide { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); }

.arcx-split--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 1.32fr); }
/* the reading column plus a fixed column of record. Same measure as the stage. */
.arcx-split--rail { grid-template-columns: minmax(0, 1fr) minmax(0, 400px); }
/* a narrow left kicker column against a wide body — used for dated runs. */
.arcx-split--key  { grid-template-columns: minmax(0, 190px) minmax(0, 1fr); }

.arcx-split--end  { align-items: end; }

.arcx-split--mid  { align-items: center; }

/* ── HAIRLINE RUNS. A list of real entries separated by one hairline, not by a
      gap and a border-radius. This is what replaces the card grid.
   ⚠ NAME COLLISION, STATED SO NOBODY TRIPS ON IT: the shell already ships
     .arcs-run / .arcs-row, which is a STATIC key/value definition row. These
     are the INTERACTIVE entry rows — an <a> or a <button> the member clicks.
     Different components, deliberately different prefixes. Do not mix the two
     sets of part names: .arcs-row__k and .arcx-row__k are not the same thing. */
.arcx-run { border-top: 1px solid var(--s3-border); }

.arcs-band--navy .arcx-run, .arcs-band--ai .arcx-run,
.arcs-band--deep .arcx-run, .arcx-stage .arcx-run { border-top-color: var(--arcs-hair); }


.arcx-row {
  display: block; width: 100%;
  text-align: left; text-decoration: none; color: inherit;
  border: 0;
  border-bottom: 1px solid var(--s3-border);
  background: transparent;
  cursor: pointer;
  padding: 20px 18px 22px 18px;
  /* background only. THE MOVEMENT IS ON THE CHILDREN — see below. */
  transition: background .24s ease;
}

/* ── THE HOVER REVEAL: the row steps toward the reader's hand.
   🚨 THE MECHANISM IS A TRANSFORM ON THE CONTENT, NOT padding-left ON THE ROW,
      AND THAT IS A PERFORMANCE FIX, NOT A STYLE PREFERENCE. Round 1 of this
      file animated the row's own padding-left. padding is a LAYOUT property:
      every frame of that transition reflows the row and everything after it.
      .arcx-row is the primitive a whole page is built from, so a run of 20
      entries meant 20 elements thrashing layout under one pointer. Caught by
      the design hook before it shipped. `transform` on the children is
      compositor-only, looks identical, and costs nothing.
   🔒 THE CHILDREN, NOT THE ROW. A transform on .arcx-row itself would create a
      containing block for its own descendants and move the hover target under
      the pointer. Moving what is INSIDE the row is the visual effect anyway. */
.arcx-row > * { transition: transform .24s var(--arcx-ease-hand); }

.arcx-row:hover > * { transform: translateX(6px); }


.arcx-row:hover { background: var(--arcs-w); }

.arcs-band--white .arcx-row:hover { background: var(--s3-grey); }

.arcs-band--navy .arcx-row, .arcs-band--ai .arcx-row,
.arcs-band--deep .arcx-row, .arcx-stage .arcx-row { border-bottom-color: var(--arcs-hair); }

.arcs-band--navy .arcx-row:hover, .arcs-band--ai .arcx-row:hover,
.arcs-band--deep .arcx-row:hover, .arcx-stage .arcx-row:hover {
  background: var(--arcs-hair);
}
/* the last row closes the run rather than trailing a hairline into whitespace. */
.arcx-row:last-child { border-bottom: 0; }

/* ── .arcx-row--marked — THE ACCENT RULE, AND IT IS THE EXCEPTION, NOT THE
      DEFAULT. Round 1 put a 3px coloured left border on EVERY row, which is
      the chunky side-tab that reads as generic AI-generated UI the moment a
      page sets --arcx-rule to an arena colour on all twenty entries.
   🔒 A plain run is defined by its hairlines and nothing else. The accent goes
      only on a row that GENUINELY DIFFERS from the ones around it — the live
      one, the one that needs an answer, the one a Facilitator flagged — and
      the arena or state colour goes in --arcx-rule on that row alone. If every
      row in a run is marked, none of them is, and it is a side-tab again. */
.arcx-row--marked {
  border-left: 3px solid var(--arcx-rule, var(--s3-border));
  padding-left: 22px;
}

.arcs-band--navy .arcx-row--marked, .arcs-band--ai .arcx-row--marked,
.arcs-band--deep .arcx-row--marked, .arcx-stage .arcx-row--marked {
  border-left-color: var(--arcx-rule, var(--arcs-hair-2));
}

/* 🚨 display:block ON THE PARTS IS LOAD-BEARING, NOT TIDINESS. A row is an <a>
   or a <button>, so its children must be <span> (an <a> may not contain a <p>).
   A span is inline by default, and without these the whole entry renders as one
   run-on line. Measured on the match prototype; invisible in the source. */
.arcx-row__k {
  display: block;
  font-size: var(--arcs-micro);
  font-weight: 500;
  color: var(--s3-ink-mid);
}

.arcx-row__t {
  display: block;
  margin-top: 7px;
  font-size: 1.1875rem;
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.025em;
  color: var(--s3-ink);
}

.arcx-row__b {
  display: block;
  margin-top: 9px;
  font-size: var(--arcs-small);
  line-height: 1.6;
  color: var(--s3-ink-mid);
  max-width: 46ch;
}

.arcx-row__m {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px;
  font-size: var(--arcs-micro);
  color: var(--s3-ink-mid);
}

.arcx-row__m svg { width: 14px; height: 14px; flex: none; }

.arcs-band--navy .arcx-row__k, .arcs-band--ai .arcx-row__k,
.arcs-band--deep .arcx-row__k, .arcx-stage .arcx-row__k,
.arcs-band--navy .arcx-row__m, .arcs-band--ai .arcx-row__m,
.arcs-band--deep .arcx-row__m, .arcx-stage .arcx-row__m { color: var(--arcs-on-navy-3); }

.arcs-band--navy .arcx-row__t, .arcs-band--ai .arcx-row__t,
.arcs-band--deep .arcx-row__t, .arcx-stage .arcx-row__t { color: var(--arcs-w); }

.arcs-band--navy .arcx-row__b, .arcs-band--ai .arcx-row__b,
.arcs-band--deep .arcx-row__b, .arcx-stage .arcx-row__b { color: var(--arcs-on-navy); }

/* 🚨 THE KICKER MUST BE LIFTED ON HOVER, AND THIS IS A MEASURED DEFECT FIX.
   The hover state paints --arcs-hair (white 13%) over the navy, which lightens
   the ground — so --arcs-on-navy-3 drops from 5.96:1 at rest to 4.04:1 under
   the pointer. The row became LESS readable the moment a member reached for
   it, which is the exact inverse of what a hover state is for, and it is
   invisible to the eye because both states look "grey on navy". Lifted to
   --arcs-on-navy on hover, it measures 7.31:1. Found by measuring the hover
   ground, not the resting one — a contrast sweep that only checks resting
   states will never see this class of defect. */
.arcs-band--navy .arcx-row:hover .arcx-row__k,
.arcs-band--navy .arcx-row:hover .arcx-row__m,
.arcs-band--deep .arcx-row:hover .arcx-row__k,
.arcs-band--deep .arcx-row:hover .arcx-row__m,
.arcx-stage .arcx-row:hover .arcx-row__k,
.arcx-stage .arcx-row:hover .arcx-row__m { color: var(--arcs-on-navy); }

/* .arcx-reveal — a link whose underline completes under the hand. Put it as the
   last child of a .arcx-row or .arcx-feature; it reacts to the PARENT's hover,
   so the whole entry is the target and the underline is only the signal. */
.arcx-reveal.arcx-reveal {
  display: inline-block;
  margin-top: 20px;
  font-weight: 500;
  color: var(--s3-blue-ink);
  padding-bottom: 2px;
  border-bottom: 1px solid color-mix(in srgb, var(--s3-blue-ink) 34%, transparent);
  transition: border-color .2s ease;
}

.arcx-row:hover .arcx-reveal,
.arcx-feature:hover .arcx-reveal,
.arcx-row:focus-visible .arcx-reveal,
.arcx-feature:focus-visible .arcx-reveal { border-bottom-color: var(--s3-blue-ink); }

.arcs-band--navy .arcx-reveal, .arcs-band--ai .arcx-reveal,
.arcs-band--deep .arcx-reveal, .arcx-stage .arcx-reveal {
  color: var(--s3-gold);
  border-bottom-color: color-mix(in srgb, var(--s3-gold) 40%, transparent);
}
.arcs-band--navy .arcx-row:hover .arcx-reveal, .arcs-band--deep .arcx-row:hover .arcx-reveal,
.arcs-band--ai .arcx-row:hover .arcx-reveal, .arcx-stage .arcx-row:hover .arcx-reveal { border-bottom-color: var(--s3-gold); }

/* .arcx-feature — the ONE large entry a band leads with, against the run of
   small ones beside it. That is the asymmetry: one thing at size, several
   things at scale, never six things the same size. */
.arcx-feature {
  position: relative; display: block;
  text-decoration: none; color: inherit;
}

.arcx-feature__img {
  display: block; position: relative; overflow: hidden;
  border-radius: 2px; aspect-ratio: 16 / 11;
  background: var(--s3-grey-2);
}

.arcx-feature__img img {
  width: 100%; height: 100%; object-fit: cover;
  /* a long, slow scale. Fast is a jump; .8s is the picture breathing. */
  transition: transform .8s var(--arcx-ease-hand);
}

.arcx-feature:hover .arcx-feature__img img { transform: scale(1.045); }

.arcx-feature__tag {
  position: absolute; left: 16px; top: 16px; z-index: 2;
  padding: 6px 12px; border-radius: 2px;
  background: var(--s3-gold-tint); color: var(--gold-ink);
  font-size: var(--arcs-micro); font-weight: 500; white-space: nowrap;
}

.arcx-feature__t {
  display: block; margin-top: 22px;
  font-size: var(--arcx-h3); font-weight: 600;
  line-height: 1.18; letter-spacing: -0.03em;
  max-width: 20ch; color: var(--s3-ink);
}

.arcx-feature__b {
  display: block; margin-top: 12px;
  color: var(--s3-ink-mid); max-width: 44ch; line-height: 1.6;
}

.arcs-band--navy .arcx-feature__t, .arcs-band--deep .arcx-feature__t, .arcx-stage .arcx-feature__t { color: var(--arcs-w); }

.arcs-band--navy .arcx-feature__b, .arcs-band--deep .arcx-feature__b, .arcx-stage .arcx-feature__b { color: var(--arcs-on-navy); }

/* the trailing note that closes a run without becoming another entry. */
.arcx-quiet.arcx-quiet {
  margin-top: 26px; padding-top: 22px;
  border-top: 1px solid var(--s3-border);
  font-size: var(--arcs-small); color: var(--s3-ink-mid);
  max-width: 44ch;
}
.arcs-band--navy .arcx-quiet, .arcs-band--deep .arcx-quiet,
.arcs-band--ai .arcx-quiet, .arcx-stage .arcx-quiet { border-top-color: var(--arcs-hair); color: var(--arcs-on-navy); }


/* ═══════════════════════════════════════════════════════════════════════════
   5b · THE AI BAND. LAST IN THE FILE'S CASCADE ORDER, AND THAT PLACEMENT IS
        THE WHOLE POINT.

   🚨 EVERY RULE HERE IS (0,2,0) — EXACTLY THE SAME SPECIFICITY AS THE
      .arcs-band--navy RULES ABOVE, WHICH ALSO MATCH .arcs-band--ai. Written
      anywhere earlier in this file they would be silently overridden by
      last-wins and the AI band would keep the failing colours while the source
      read as if it had been fixed. That was round 1 of this section and it was
      caught by re-reading the cascade, not by looking at the page — on a navy
      band the two colours are close enough that the failure is invisible.
      🔒 IF ANOTHER .arcs-band--ai RULE IS EVER ADDED TO THIS FILE, IT GOES
         HERE, BELOW THIS LINE. Never above.

   The measured reason: on the AI gradient's lightest stop, rgb(99 52 198),
   --s3-gold is 3.52:1 and --arcs-on-navy is 4.26:1, both under the 4.5 body
   floor, and --arcs-on-navy-3 is 2.67:1. Only the WORD changes: the eyebrow's
   rule and the reveal's underline keep their gold, because a fill carries no
   contrast requirement.
   ═══════════════════════════════════════════════════════════════════════════ */
.arcs-band--ai .arcx-eyebrow,
.arcs-band--ai .arcx-lede,
.arcs-band--ai .arcx-row__b,
.arcs-band--ai .arcx-feature__b,
.arcs-band--ai .arcx-quiet,
.arcs-band--ai .arcx-reveal   { color: var(--arcx-on-ai); }

.arcs-band--ai .arcx-row__k,
.arcs-band--ai .arcx-row__m   { color: var(--arcx-on-ai-3); }


/* ═══════════════════════════════════════════════════════════════════════════
   6 · MOTION.  Four keyframes, staggered, reduced-motion honoured.

   🔒 THE DIVISION OF LABOUR WITH THE SHELL, SO THE TWO NEVER FIGHT:
        arc-shell.css  owns the PAGE-LOAD moment  (.arcs-words, .arcs-plate,
                       .arcs-stage__photo, the dock). Untouched here.
        this file      owns the SCROLL entrance for what is below the fold,
                       and every hover reveal.

   🚨 SCROLL ENTRANCE IS OPT-IN AND MUST STAY RARE. The shell's own note is
      right: "a fade-and-rise on every section as you scroll past it is the
      loudest generated-page tell there is." Nothing animates unless a page
      author writes data-arcx-enter on it. Budget: AT MOST ONE marked group
      per band, and not in every band. If a reviewer can see the pattern, it
      is being used too much.

   🔒 CONTENT IS NEVER HIDDEN BY DEFAULT. The opacity:0 rules are scoped to
      html.arcx-motion, a class only arc-experience.js adds — and it adds it
      only when the script runs AND motion is allowed. If the script 404s,
      throws, or the reader prefers reduced motion, every marked element is
      simply visible. A page whose content depends on a script having run is
      broken, not animated.
   ═══════════════════════════════════════════════════════════════════════════ */
@keyframes arcx-fade   { from { opacity: 0 }                              to { opacity: 1 } }

@keyframes arcx-rise   { from { opacity: 0; transform: translateY(18px) }  to { opacity: 1; transform: none } }

@keyframes arcx-plate  { from { opacity: 0; transform: translateY(38px) }  to { opacity: 1; transform: none } }

@keyframes arcx-settle { from { opacity: 0; transform: scale(1.05) }       to { opacity: 1; transform: none } }


html.arcx-motion [data-arcx-enter] { opacity: 0; }

html.arcx-motion [data-arcx-enter].is-in {
  animation: arcx-rise var(--arcx-in-dur) var(--arcx-ease) both;
}

html.arcx-motion [data-arcx-enter="fade"].is-in   { animation-name: arcx-fade; }

html.arcx-motion [data-arcx-enter="plate"].is-in  { animation-name: arcx-plate;  animation-duration: .9s; }

html.arcx-motion [data-arcx-enter="settle"].is-in { animation-name: arcx-settle; animation-duration: 1.1s; }

/* the stagger. The GROUP is marked; its direct children arrive in sequence.
   The group itself stays fully opaque — hiding both would double the fade. */
html.arcx-motion [data-arcx-enter="stagger"] { opacity: 1; }

html.arcx-motion [data-arcx-enter="stagger"] > * { opacity: 0; }

html.arcx-motion [data-arcx-enter="stagger"].is-in > * {
  animation: arcx-rise var(--arcx-in-dur) var(--arcx-ease) both;
}

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(1) { animation-delay: calc(0 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(2) { animation-delay: calc(1 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(3) { animation-delay: calc(2 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(4) { animation-delay: calc(3 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(5) { animation-delay: calc(4 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(6) { animation-delay: calc(5 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(7) { animation-delay: calc(6 * var(--arcx-in-step)) }

html.arcx-motion [data-arcx-enter="stagger"].is-in > *:nth-child(n+8) { animation-delay: calc(7 * var(--arcx-in-step)) }

/* ── THE FLOOR. Belt and braces: the shell already neutralises animation and
      transition duration under reduce, but this file must be safe on its own —
      it can be loaded on a page that has not yet been migrated. Here the
      TRANSFORMS and DELAYS are removed outright rather than compressed to
      0.001ms, because a compressed transform still creates a stacking context
      and a 0.001ms translate is still a translate. ─────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html [data-arcx-enter],
  html [data-arcx-enter] > *,
  html [data-arcx-enter="stagger"] > * {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    animation-delay: 0s !important;
  }

  .arcx-lift, .arcx-reveal,
  .arcx-row, .arcx-row > *,
  .arcx-feature__img img { transition: none !important; }

  .arcx-lift:hover, .arcx-lift:focus-within { transform: none !important; }
  /* the row still ANSWERS the hand — it changes background — it just does not
     move. Removing the state as well as the motion is not an accessibility
     win, it is a lost affordance. */
  .arcx-row:hover > * { transform: none !important; }

  .arcx-feature:hover .arcx-feature__img img { transform: none !important; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   7 · RESPONSIVE.  Down to 390px, no horizontal scroll. Every grid child
       already carries min-width:0 above; this is the collapse.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  /* the plate stops hanging. Stacked, it drops onto the heading below it, and
     a plate sitting on a sentence is not a bold move. The band below then
     stops owing the clearance, which .arcs-wrap--underhang already handles. */
  /* same doubled class as the desktop rule — a single class here would be
     beaten by .arcs-page figure (0,1,1) and the plate would keep hanging onto
     the heading below it on a phone, which is the worst place for it to. */
  .arcx-plate.arcx-plate--hang { margin-bottom: 0; align-self: start; justify-self: start; }

  /* 🚨 THIS OVERRIDE IS MANDATORY AND ITS SPECIFICITY IS THE REASON. The shell
     already collapses `.arcs-stage__inner` to 1fr here, but that rule is
     (0,1,0) and the desktop rule above is (0,2,0). SPECIFICITY BEATS MEDIA
     QUERY ORDER — without this line the 400px rail would survive to 390px and
     force a horizontal scroll, while the shell's source reads as if it had
     already handled it. */
  .arcx-stage .arcs-stage__inner {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
    min-height: 0;
    gap: 34px;
  }
  /* the ground's horizontal composition gradient assumed a wide frame. Stacked,
     the words sit over the middle of the picture, so the gradient turns. */
  .arcx-stage__bg::after {
    background:
      linear-gradient(0deg, var(--arcs-wash-open), var(--arcs-wash-open)),
      linear-gradient(180deg,
        color-mix(in srgb, var(--arcs-ink) 60%, transparent) 0%,
        var(--arcs-wash-read) 46%,
        var(--arcs-navy-deep) 100%);
  }


  .arcx-split,
  .arcx-split--wide,
  .arcx-split--flip,
  .arcx-split--rail,
  .arcx-split--key { grid-template-columns: minmax(0, 1fr); }
}


@media (max-width: 620px) {
  /* the display clamp already floors at 2.35rem; what needs relaxing at phone
     width is the MEASURE, not the size — 19ch of 2.35rem is two words a line. */
  .arcx-display { max-width: none; }

  .arcx-h2      { max-width: none; }

  .arcx-lede    { max-width: none; }

  .arcx-row     { padding: 18px 14px 20px 14px; }

  .arcx-row--marked { padding-left: 18px; }
  /* 4px of step, not 6: at 390px a 6px shove of every child inside a 14px
     inset reads as the row wobbling rather than answering. */
  .arcx-row:hover > * { transform: translateX(4px); }

  .arcx-plate   { padding: 22px 20px; }

  .arcx-feature__t { max-width: none; }
}


@media (max-width: 400px) {
  /* 🚨 --arcs-band-x floors at 20px a side, and a 400px fixed rail plus 40px of
     padding cannot fit 390px. The rail already collapses to 1fr at 1080px, so
     this only guards a page that sets its own grid — but a guard that fires
     only on someone else's mistake is exactly the guard worth having. */
  .arcx-stage .arcs-stage__inner,
  .arcx-split--rail { grid-template-columns: minmax(0, 1fr); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   9 · AVR-009 WEIGHT CEILING OVER THE LEGACY STYLESHEET
   ═══════════════════════════════════════════════════════════════════════════
   🚨 A DEFECT THAT EXISTS IN NEITHER FILE, ONLY IN THEIR COMBINATION. Measured
   8 Sep 2026 on the served staging pages.

   member-home, founder-home and student-home were rebuilt onto this design
   system and load Inter at `wght@400;500;600` — the AVR-009 ceiling. They also
   still load arc-ui.css for 46 legacy classes each, and arc-ui.css declares
   `font-weight: 700` or `800` in 77 places.

   🔒 SO THOSE PAGES WERE ASKING FOR A FACE THEY DO NOT LOAD, and the browser
      was SYNTHESISING bold — smeared, mechanically-obliqued glyphs — on the
      exact pages whose brief demands "strong, large, confident typography as a
      visual element in its own right". Faux bold is the one thing that reads as
      cheap at display size.

   ⚠ THIS IS WHY IT WAS INVISIBLE TO EVERY CHECK WE HAD. arc-ui.css is correct
     on its own terms: the OTHER 30 pages that load it DO request a 700 face, so
     their weights resolve to a real font. The three rebuilt homes are the only
     ones where the stylesheet and the font link disagree. Neither file is wrong.
     The pairing is. Same shape as every contrast defect this estate has shipped.

   🔒 SCOPED TO `.arcs-page` AND ENUMERATED, NOT BLANKET-CAPPED. A rule like
      `.arcs-page [class*="arc-"] { font-weight: 600 }` would flatten legitimate
      400 and 500 text across 46 classes to fix 8 selectors. These are exactly
      the eight arc-ui selectors that both declare a weight above 600 AND match
      markup on the three homes, measured rather than guessed. arc-experience.css
      loads at line 107 and arc-ui.css at line 97, so later origin plus the added
      `.arcs-page` class wins in every case without !important.

   ⚠ VERIFIED STATICALLY (specificity + load order + selector census), NOT YET BY
     RENDER — this session's browser injection is unavailable. Treat the computed
     result as DERIVED until a rendering lane confirms no element resolves >600. */
.arcs-page .arc-btn,
.arcs-page .arc-pill,
.arcs-page .arc-av,
.arcs-page .arc-match,
.arcs-page .arc-cardhd h2,
.arcs-page .arc-ring > i,
.arcs-page .arc-faces .more,
.arcs-page .arc-prio .top span { font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   ARC HIERARCHY EXPRESSION + HONEST CAPABILITY SLOTS
   Added 9 September 2026, Foreman, Masterpiece Pass part 2.

   Two jobs, both required by the Architect and neither previously built:

   1. THE HIERARCHY MUST BE VISIBLE. Arena -> Hub -> Program is ruled ARC
      structure; until now it had no visual expression beyond a hashed swatch.
      These primitives consume the derived families in arc-tokens.css, so an
      arena recolour propagates everywhere and no component holds a hex.

   2. CAPABILITY SLOTS. Darren, 9 Sep 2026: "Do not visually promise
      functionality that doesn't exist, but design ARCverse so new
      capabilities can progressively arrive without another visual rebuild."
      🔒 THOSE ARE TWO REQUIREMENTS AND MOST DESIGN SYSTEMS SATISFY ONLY ONE.
      A greyed-out button with a tooltip fails the first: it promises. A page
      that simply omits the region fails the second: the capability arrives
      and the layout has to be rebuilt around it.
      The slot holds the SPACE and states the ABSENCE as fact.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── ARENA MARK. The dot/tile that says which arena something belongs to. ───
   Never a coloured NAME — arc-tokens.css: "arena NAMES are never coloured
   text on these." The mark carries the colour; the label stays in ink. */
.arc-mark {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: var(--arcs-small); font-weight: 500; letter-spacing: -0.01em;
  color: var(--s3-ink);
}
.arc-mark::before {
  content: ""; flex: none; width: 10px; height: 10px; border-radius: 2px;
  background: var(--arc-arena, var(--s3-ink-mid));
}
/* On a dark band the FILL is not safe (7 of 15 fall under 3:1 on navy) —
   the lift is. Same component, correct value, no page override needed. */
.arcs-band--navy .arc-mark, .arcs-band--deep .arc-mark, .arcs-stage .arc-mark,
.arcs-band--ai .arc-mark {
  color: var(--arcs-on-navy);
}
.arcs-band--navy .arc-mark::before, .arcs-band--deep .arc-mark::before,
.arcs-stage .arc-mark::before, .arcs-band--ai .arc-mark::before { background: var(--arc-arena-lift, var(--s3-gold)); }

/* ── ARENA RULE. A hairline that inherits the arena. The estate's answer to
   the "side-tab" AI-tell that Impeccable caught three times in the profile
   proof: a 3px coloured bar down a card's left edge is the single most
   recognisable generated-interface signature. This is a 1px rule under a
   kicker, not a slab beside a card. */
.arc-rule { border: 0; height: 1px; margin: 0 0 18px;
  background: color-mix(in srgb, var(--arc-arena, var(--s3-border)) 42%, transparent); }

/* ── HUB PILL. A hub belongs to its arena and stays individually legible.
   Tint + arena ink, measured worst case 7.85:1. The hairline is REQUIRED:
   the tint is 1.17:1 against paper and is a surface, not a contrast device. */
.arc-hubpill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px; border-radius: 2px;
  background: var(--arc-hub-pill, var(--s3-grey));
  border: 1px solid color-mix(in srgb, var(--arc-arena, var(--s3-border)) 26%, transparent);
  color: var(--arc-hub-ink, var(--s3-ink));
  font-size: var(--arcs-small); font-weight: 500; line-height: 1.2;
}

/* ── HUB TILE. The small icon fill. Darkens along the ladder so a white
   glyph only ever gets safer — worst case 4.60:1 across 15 arenas x 12 hubs. */
.arc-hubtile {
  width: 38px; height: 38px; border-radius: 3px; flex: none;
  display: grid; place-items: center;
  background: var(--arc-hub-tile, var(--s3-ink-mid)); color: #fff;
}
.arc-hubtile svg { width: 18px; height: 18px; }

/* ═══ THE CAPABILITY SLOT ═══════════════════════════════════════════════════
   🚨 READ THIS BEFORE USING IT, AND BEFORE "IMPROVING" IT.

   A slot is used where a capability is GENUINELY NOT BUILT. It must:
     · state plainly that the thing is not here yet, as FACT, not apology;
     · never render a control that looks operable;
     · hold its place in the composition so arrival is a content change,
       not a redesign.

   🔒 IT MUST NOT: carry a disabled button, a "coming soon" badge, a progress
   bar, a percentage, a countdown, or a waitlist field. The baseline forbids
   meters and scores outright; and a disabled control is a promise wearing a
   grey coat. The pattern is the stated-absence line from the Profile proof —
   "Nothing recorded outside hospitality" — presented as plain fact, because
   a surface that can only say good things is marketing, not evidence.

   WHEN THE CAPABILITY ARRIVES: replace the slot's children with the real
   component. The band, the rhythm and the surrounding composition do not
   move. That is the whole design requirement. */
.arc-slot {
  border: 1px dashed color-mix(in srgb, var(--s3-border) 100%, transparent);
  border-radius: 3px;
  padding: clamp(20px, 2.4vw, 30px);
  background: color-mix(in srgb, var(--s3-grey) 55%, transparent);
}
.arc-slot__k {
  display: block; font-size: var(--arcs-small); font-weight: 500;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--s3-ink-mid); margin-bottom: 8px;
}
.arc-slot__what {
  display: block; font-size: 1.0625rem; font-weight: 500; line-height: 1.45;
  color: var(--s3-ink); max-width: 48ch;
}
.arc-slot__why {
  display: block; margin-top: 10px; font-size: var(--arcs-small);
  line-height: 1.6; color: var(--s3-ink-mid); max-width: 56ch;
}
/* On dark bands the slot is a hairline on the ground, not a grey box. */
.arcs-band--navy .arc-slot, .arcs-band--deep .arc-slot, .arcs-stage .arc-slot,
.arcs-band--ai .arc-slot {
  background: color-mix(in srgb, #fff 5%, transparent);
  border-color: color-mix(in srgb, #fff 16%, transparent);
}
.arcs-band--navy .arc-slot__what, .arcs-band--deep .arc-slot__what,
.arcs-stage .arc-slot__what, .arcs-band--ai .arc-slot__what { color: var(--arcs-w); }
.arcs-band--navy .arc-slot__k,  .arcs-band--deep .arc-slot__k,
.arcs-stage .arc-slot__k,
.arcs-band--navy .arc-slot__why, .arcs-band--deep .arc-slot__why,
.arcs-stage .arc-slot__why { color: var(--arcs-on-navy); }

/* 🚨 THE AI BAND IS A DARK GROUND AND WAS IN NONE OF THE FOUR LISTS ABOVE.
   Found 9 Sep 2026 by the entry-surface lane, confirmed by me: --s3-ink-mid
   on the AI band gradient measures 1.36:1 and 2.14:1. The one honest sentence
   on a page about a capability that does not exist would have been its least
   readable text.
   🔒 AND THE INSTRUMENT BUILT TO CATCH THIS CANNOT SEE IT: ground-coverage.py
   reports "dark grounds discovered: 2 - .arcs-band--deep, .arcs-band--navy".
   .arcs-band--ai is a dark ground with its own --arcs-on-ai inks and is
   invisible to the sweep. That is why this class of defect survives here.
   The same gap was fixed in the same pass for .arcs-state, .arcs-repflag
   and .arc-mark. */
.arcs-band--ai .arc-slot__k, .arcs-band--ai .arc-slot__why { color: var(--arcs-on-ai); }
