/* ══════════════════════════════════════════════════════════════════════
   age-gate.css — the age gate's checkboxes are LIGHT, and you can see them.

   THE DEFECT (owner, 2026-08-26): "the checkboxes on the age gate are too
   dark - make them more light so you can see them."

   MEASURED ON THE LIVE SITE (iPhone 390x844, corechainresearch.com, before
   this sheet). The visible control is not the <input> — that is
   `.lag-cb{opacity:0;width:0;height:0}` — it is the sibling
   `<span class="lag-box">`, and its unchecked state resolved to:

       modal surface  rgb(20, 34, 53)   #142235   (--sf-elevated)
       box fill       rgb(20, 34, 53)   #142235   →  1.00:1 against it
       box border     rgba(166,186,203,.20) over that ground
                      = rgb(49, 64, 83)           →  1.52:1

   A fill at 1.00:1 is not "hard to see", it is the same colour as the thing
   it sits on: the control was one 1.5px hairline at 1.52:1, well under the
   3:1 WCAG 1.4.11 floor for a non-text UI control. It is not a mistake in
   the gate either — `.lag-box` paints `var(--lag-surface, var(--sf-elevated,
   #ffffff))`, which is deliberately THE SAME TOKEN AS THE MODAL so that on a
   light client you get the familiar white box on a white card, read by its
   grey outline. On a dark client that identity is the bug.

   WHY THE FIX IS NOT `--lag-surface`. That custom property is the gate's own
   designed escape hatch and it is the wrong lever here, because ONE token
   paints three things: `.lag-modal` background, `.lag-box` background and the
   disabled `.lag-btn-primary` mix. Re-pointing it to a light value would
   repaint the whole modal. The box needs its own colour, so the box gets its
   own rule.

   THE CASCADE TRAP, and it is the whole difficulty of this lane. None of the
   gate's CSS is in a stylesheet. age-gate.js BUILDS IT AS A STRING and appends
   `<style id="lag-style">` to <head> AT RUNTIME — measured live: 10,283
   characters, and the only <style> on the page containing `.lag-box`. A
   runtime-appended sheet lands after every <link>, including this one, so an
   equal-specificity rule here LOSES on source order no matter what the lane
   number is.

   The route out is SPECIFICITY, not a bang-important override, and it is the
   route sf-refresh.css §6a already takes for the gate logo: every selector
   carries `#lag-root` (1,1,0+), and one id outranks any number of classes.
   PROVEN LIVE, worst case: these rules injected as the FIRST child of <head>
   — before theme.css, before everything — still won against the runtime
   sheet appended last. Nothing below needs a bang-important override and
   nothing below carries one — that is an asserted property of this file.

   WHERE THIS SHEET ACTUALLY SITS, because an earlier draft of this comment
   said "linked last" and that is FALSE. lib.linkCss() appends each lane's
   sheet at </head> as the lane runs, so the order is LANE ORDER: this sheet
   lands after every engine sheet (theme.css, sf-base.css, sf-refresh.css) and
   after lanes 01–17, but BEFORE every higher-numbered lane — measured in the
   built gate.html, /sf-final-age-gate.css at line 373 with six lane sheets
   after it (homepage, pdp, catalog, chrome, hero-minimal, shipping-claim).
   So nothing below may rely on being last. Every selector here carries its
   own weight: an id, or `html body` in front of the class form.

   THE SECOND HALF OF THE TRAP. `#lag-root .lag-box` (1,1,0) also outranks the
   gate's own `.lag-cb:checked+.lag-box` (0,2,0) and `.lag-check:hover
   .lag-box` (0,2,0) — so overriding the resting state silently kills the
   CHECKED state and the hover, which is a far worse defect than the one being
   fixed (a gate whose boxes never appear to tick). Both are therefore
   RESTATED below at matching specificity. Verified live by clicking the real
   label: checked fill still rgb(63,182,201), tick opacity still 1. Guard B in
   18-age-gate.mjs reads THIS FILE back and throws if either restatement is
   ever edited away, so the pair cannot be lost quietly.

   AFTER, measured the same way, this sheet injected as the first child of
   <head> on the live gate:

       box fill    rgb(240,246,250)  #F0F6FA  → 14.71:1 against the modal
       box border  rgb(143,166,184)  #8FA6B8  →  6.35:1
       checked     rgb(63,182,201)   #3FB6C9  →  6.68:1 (unchanged, the brand
                                                 accent — not redesigned here)
       tick ink    rgb(4,20,26)      #04141A  →  7.81:1 inside the checked box,
                                                 opacity 0 → 1 on :checked

   The fill is the client's own ink token, so it is whatever --sf-text holds:
   #F0F6FA on the deployed build measured above (14.71:1), #E9F3F8 in the
   theme.css currently on disk (14.23:1). Either clears the 3:1 control floor
   many times over, and so does the edge at 6.35:1. The state change is
   carried by the tick at 7.81:1 plus a full hue swing from near-white to
   accent; the two FILLS sit ~2.2:1 apart, which is the ordinary
   white-box→brand-box pattern and is not a ratio WCAG asks for.

   SCOPE. Colour only. Not one word of the gate's copy, neither
   acknowledgement statement, no layout, no logo, no button, no size, no
   border WIDTH (the border shorthand is left alone and only `border-color` is
   restated), and no behaviour. The focus ring of the RUNTIME gate is its own
   `.lag-cb:focus-visible+.lag-box{outline:…}` and is deliberately untouched;
   the native controls in rule 4 get an explicitly solved ring, see there.

   The face and edge are exposed as --lag-check-face / --lag-check-edge so a
   later palette move is one line rather than a hunt. The face defaults
   THROUGH --sf-text so it tracks the palette rather than freezing a hex.

   THE RESIDUAL RISK, stated correctly this time. An earlier draft said "a
   future palette that flipped this client to a light ground would put a
   near-white box on a near-white card". That cannot happen and it was the
   wrong risk: the face is --sf-text and the card is --sf-elevated, and a
   light-ground flip moves BOTH — sf-refresh.css does exactly that in its own
   plate scope (line 1785ff: --sf-elevated → --cc-plate, --sf-text →
   --cc-plate-ink), and the chip stays a dark chip on a light plate. The real
   failure mode is the two tokens DRIFTING TOWARD each other — a mid-grey ink,
   or a client pinning --lag-surface light on a dark client — and it is no
   longer narrative: 18-age-gate.mjs resolves --sf-text, --sf-elevated,
   --sf-accent and --sf-accent-text out of the built stylesheets, computes the
   three ratios this file depends on, and THROWS below 3:1.
   ══════════════════════════════════════════════════════════════════════ */

/* ── 1. The resting box is a light chip, not the modal wearing a hairline ──
   `border-color` only: the gate's own `border:1.5px solid …` keeps the weight
   it was designed with. */
#lag-root .lag-box {
  background: var(--lag-check-face, var(--sf-text, #E9F3F8));
  border-color: var(--lag-check-edge, #8FA6B8);
}

/* ── 2. Hover, restated. Rule 1 outranks the gate's own (0,2,0) hover, so
   without this line the affordance disappears. ─────────────────────────── */
#lag-root .lag-check:hover .lag-box {
  border-color: var(--lag-accent, var(--sf-accent, #3FB6C9));
}

/* ── 3. Checked, restated. Same reason: rule 1 outranks (0,2,0).
   These are the gate's own two declarations and ONLY those two
   (age-gate.js:573 sets `background` and `border-color`, nothing else).
   The tick ink is NOT restated here on purpose: it comes from the BASE
   `.lag-box` rule (age-gate.js:568, `color:var(--lag-accent-text,
   var(--sf-accent-text, #ffffff))`), which rule 1 does not disturb because
   rule 1 sets no `color`. An earlier draft added a `color` line here with a
   #04141A literal and called the rule "byte-for-byte the gate's own answer";
   it was neither — it would have painted a near-black tick where the gate
   paints white if --sf-accent-text ever went missing. ─────────────────── */
#lag-root .lag-cb:checked + .lag-box {
  background: var(--lag-accent, var(--sf-accent, #3FB6C9));
  border-color: var(--lag-accent, var(--sf-accent, #3FB6C9));
}

/* ══════════════════════════════════════════════════════════════════════
   4. THE SAME DEFECT ON THE NATIVE CONTROLS — gate.html AND checkout.html

   The runtime `.lag-*` gate above covers the interstitial. It is not the only
   place this client asks a buyer to tick a compliance box, and the other two
   surfaces do not use it at all:

     gate.html      the hand-authored account-access page — no #lag-root on it
                    anywhere. Three attestations, `#compliance-row
                    .compliance-check > input[type=checkbox]` (lines 483–494).
     checkout.html  five: #attest-age / #attest-research-use / #attest-terms
                    in #attest-block (856/860/864), #create-account-check
                    (596) and #use-store-credit (912).

   All eight are NATIVE `<input type=checkbox>`, styled inline only by
   `accent-color`. `accent-color` paints the CHECKED fill and nothing else, so
   the resting box is whatever the user agent paints — and the UA paints it
   from `color-scheme`, which final/css/app-surfaces.css (lane 04) sets to
   `dark` on `body.cc-app`. All four of these pages carry `cc-app`. Result:
   eight near-black squares on a navy card. The owner's complaint, twice over,
   in the purchase flow.

   ── WHY THIS IS A CHIP AND NOT `color-scheme: light` ──────────────────────
   REPORTED, because it is a decision against a sibling lane's stated one.
   final/css/app-surfaces.css line 41 sets `body.cc-app { color-scheme: dark }`
   and its comment gives the reason in so many words: without it these very
   boxes "are white browser squares on a navy card — the single loudest
   off-brand element on the whole flow". An earlier draft of THIS file put
   `color-scheme: light` on gate.html's three, which reversed that decision
   for three of the eight and left the other five dark — half a flow fixed and
   a silent disagreement between two lanes.

   Lane 04's decision STANDS and is not touched: `color-scheme` stays `dark`,
   so selects, scrollbars, autofill and every other native control on these
   pages keep the dark scheme they were solved for. What changes is that these
   eight controls stop being UA-painted at all — `appearance:none` and the
   chip below, painted from the SAME two tokens as `#lag-root .lag-box` in
   rule 1 (--lag-check-face and --lag-check-edge) and the same accent on
   :checked, so the two gates resolve to one set of colours by construction
   rather than by two people typing the same hex. Rule 4 carries more
   declarations than rule 1 does, because the native control has to be told to
   stop painting itself and then given the tick the `.lag-box` span gets as
   inline SVG — the COLOURS are the shared part, not the declaration list.
   Two things come out of that which `color-scheme` cannot give:

     · both gates now look identical, which is what the owner is comparing;
     · the colour is a real value in the CSSOM. `color-scheme:light` hands the
       control to Chrome's #FFFFFF/#767676 constants — those are what the
       16.03:1 / 3.53:1 figures in the earlier draft were computed from, and
       they are not iOS Safari's numbers, on the device the defect came from.
       A chip is measured, not assumed, and 18-age-gate.mjs gates it.

   MEASURED, computed style, Chrome 390x844 against the sandbox in
   factory/output/_probe/ (and the same values are what any engine reports,
   because they are declared here rather than chosen by the UA):

       resting fill   #F0F6FA  → 14.71:1 on the #142235 gate card
                               → 16.52:1 on the #0C1726 attest block
       resting edge   #8FA6B8  →  6.35:1 / 7.13:1 on the same two
       checked fill   #3FB6C9  →  6.68:1 / 7.50:1   (the brand accent)
       tick           #04141A  →  7.81:1 inside the checked chip
       store credit   #059669  →  4.78:1, tick 4.98:1 — see the last rule
       focus ring     #3FB6C9  →  6.68:1 on the gate card, 2px solid at lane
                                  04's 3px offset — read off :focus-visible,
                                  not assumed (rule 4d)

   Read back off `getComputedStyle` on all eight controls, resting and checked,
   at 390x844: `appearance` computes `none`, `color-scheme` still computes
   `dark` (lane 04 intact), the box is 22x22 under the mobile bump, and the
   tick background-image is absent when unchecked and present when checked.
   The 8 dark squares in the before crops are gone.

   SIZE, WEIGHT AND HIT TARGET ARE NOT TOUCHED. Four of the eight carry an
   inline `width/height` (15–17px) and 02-mobile.mjs's sheet bumps every
   checkbox to 22px under 860px with `!important`; `box-sizing:border-box`
   below keeps the 1.5px border inside whatever size wins, and nothing here
   sets width, height, margin or flex.

   THE TICK IS A BACKGROUND IMAGE, NOT A PSEUDO-ELEMENT. `::after` on an
   `<input>` is a replaced-element edge case that renders in today's engines
   but is not something to bet a compliance control on, and this defect was
   reported from a phone. A background-image on the input itself is the
   ordinary, portable technique. Its cost is one frozen literal: the SVG
   stroke cannot read a custom property, so the tick ink is written as
   `%2304141A` = #04141A = this client's --sf-accent-text. That literal is NOT
   left to drift — 18-age-gate.mjs resolves --sf-accent-text out of the built
   stylesheets and throws if it stops matching. The path, viewBox and
   stroke-width are byte-identical to CHECK_SVG in age-gate.js:481.
   ══════════════════════════════════════════════════════════════════════ */

/* 4a. The resting chip. Selector twice over on purpose: the id-scoped form is
   the one that beats gate.html's inline <style> rule at line 152 (0,1,1), and
   the `html body` form is the rename-proof fallback — it carries (0,2,3),
   which beats that inline rule AND lane 04's `body.cc-app input[type=
   "checkbox"]` (0,2,1) on WEIGHT, not on source order, because this sheet is
   not last (see the header). Only gate.html carries `.compliance-check`
   (grepped across all 26 built pages), so nothing else can be caught. */
#compliance-row .compliance-check input[type="checkbox"],
html body .compliance-check input[type="checkbox"],
#attest-age,
#attest-research-use,
#attest-terms,
#create-account-check,
#use-store-credit {
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
  background-color: var(--lag-check-face, var(--sf-text, #E9F3F8));
  background-image: none;
  background-repeat: no-repeat;
  background-position: center;
  background-origin: border-box;
  background-size: 62% 62%;
  border: 1.5px solid var(--lag-check-edge, #8FA6B8);
  border-radius: var(--lag-check-radius, var(--sf-check-radius, var(--sf-radius, 4px)));
  transition: border-color .15s ease, background-color .15s ease;
}

/* 4b. Checked — the brand accent behind the gate's own checkmark. */
#compliance-row .compliance-check input[type="checkbox"]:checked,
html body .compliance-check input[type="checkbox"]:checked,
#attest-age:checked,
#attest-research-use:checked,
#attest-terms:checked,
#create-account-check:checked {
  background-color: var(--lag-accent, var(--sf-accent, #3FB6C9));
  border-color: var(--lag-accent, var(--sf-accent, #3FB6C9));
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2304141A' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E");
}

/* 4c. Hover, restated for the same reason rule 2 exists: 4a outranks the
   pages' own hover styling of these controls, and the affordance would go
   quiet without it. The label is the hover target — the cursor is over the
   words, not the 16px box — so it is the wrapper that carries `:hover`. */
#compliance-row .compliance-check:hover input[type="checkbox"],
html body .compliance-check:hover input[type="checkbox"],
#attest-block label:hover > input[type="checkbox"],
#sc-toggle-wrap:hover > #use-store-credit {
  border-color: var(--lag-accent, var(--sf-accent, #3FB6C9));
}

/* 4d. The focus ring is SOLVED, not a UA constant. `color-scheme` also drives
   the default ring, and lane 04 leaves it to the UA (it sets only
   `outline-offset:3px !important` on body.cc-app checkboxes) — so a
   compliance control on a #142235 card was drawing a ring nobody had
   measured. #3FB6C9 is 6.68:1 on that card and 7.50:1 on the attest block.
   `outline-offset` is deliberately NOT set here: lane 04's `!important` owns
   it and one offset across every control on the page is the right answer. */
#compliance-row .compliance-check input[type="checkbox"]:focus-visible,
html body .compliance-check input[type="checkbox"]:focus-visible,
#attest-age:focus-visible,
#attest-research-use:focus-visible,
#attest-terms:focus-visible,
#create-account-check:focus-visible,
#use-store-credit:focus-visible {
  outline: 2px solid var(--lag-accent, var(--sf-accent, #3FB6C9));
}

/* 4e. Store credit keeps its GREEN checked fill. #use-store-credit is a
   payment instrument, not a compliance box: it sits in a green-tinted block
   and its inline `accent-color:#059669` was a deliberate money signal, so
   this restates that signal rather than repainting it brand-cyan — only the
   RESTING state (4a) changes, which is the reported defect. #059669 is
   4.78:1 on #0C1726 and the same #04141A tick reads 4.98:1 on it. */
#use-store-credit:checked {
  background-color: #059669;
  border-color: #059669;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2304141A' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E");
}
