/* ── THE HIDDEN ATTRIBUTE MUST ACTUALLY HIDE (2026-09-06) ─────────────────────────────────────
   THE THIRD TIME THIS EXACT DEFECT LANDED, so it is fixed at the sheet rather than on the element.
   `hidden` is only a UA rule of `display: none`, so ANY explicit display beats it — and every one
   of these pages is built from flex rows. The receipts, all the same bug:
     · .ref-input on the landing page (its own rule, added when it bit).
     · .ref-toggle beside it, 2026-08-12 — the comment there says it plainly: "the lesson was
       already learned for .ref-input; its sibling never got the same line."
     · /access's own two-step form tonight, where `.field { display: flex }` left the email field
       AND the code field on screen together. Caught by looking at the rendered page; invisible to
       every test in the suite, all of which were green.
   One rule ends the class for every element on every page that reads this sheet. */
[hidden] { display: none !important; }

/* -- velealor.com | the marketing shell -----------------------------------------
   ONE source of truth for the editorial pages: /velea /why /system /gate /access
   /confirmed. Until 2026-07-20 it was pasted into all six, 72-100% identical: every
   change cost six edits, and drift went unseen.

   WHAT IS NOT IN HERE, AND WHY. A selector lives here only if every page that declares
   it declares it IDENTICALLY. Where pages genuinely disagree, the whole rule stays with
   its page -- a partial override would silently inherit this file's other properties.
   Not hypothetical: text-transform:uppercase leaked into /access's display h1 the first
   time this was split. The divergent ones:
     - .cta  (2 variants across 12 pages)
     - .p1hero  (2 variants across 6 pages)
     - .slot  (2 variants across 7 pages)
     - :root  (2 variants across 6 pages)
     - body  (2 variants across 7 pages)
     - h1  (2 variants across 6 pages)
     - p  (2 variants across 6 pages)
   Each is a decision someone made. None of them is hidden any more.

   A page's <style> loads after this file, so its rules win. Fonts and art use absolute
   paths, so this file is position-independent.
   ------------------------------------------------------------------------------- */

/* Playfair Display's two faces came out with the type swap (site audit, 2026-08-30): every page
   downloaded them and nothing set them any more. Didot is a system face on Apple devices and
   falls back to Georgia elsewhere — the same trade the landing page has made since 2026-08-10. */
@font-face { font-family: "Inter"; src: url("/marketing/fonts/inter-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/marketing/fonts/inter-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/marketing/fonts/inter-600.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/marketing/fonts/inter-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Hanuman"; src: url("/marketing/fonts/Hanuman.ttf") format("truetype"); font-weight: 400; font-display: swap; }
/* MOUL — the Khmer DISPLAY face (David, 2026-08-31: "Use Moul though. I like the sensual
   contrast"). Hanuman is the text Khmer and stays the footer word mark's face; Moul is heavy and
   rounded, and set against Didot's hairline contrast it is the pairing he means. OFL, self-hosted
   beside the others so no page reaches out to Google for it. */
@font-face { font-family: "Moul"; src: url("/marketing/fonts/Moul.ttf") format("truetype"); font-weight: 400; font-display: swap; }
* { box-sizing: border-box; margin: 0; }
/* iOS SAFARI INFLATES UNADJUSTED TEXT (2026-08-30, his phone screenshots: "Too big. Too
   condensed" on type that measured to spec in desktop Chrome). Without this, Mobile Safari
   scales paragraphs up on its own judgment and every size below is a lie on the one device
   he actually tests. 100%, not none — none also kills the user's own zoom. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
a { color: var(--champ); text-decoration: none; }
/* z-index 30, not auto (2026-08-30, his screenshot of the open menu with the page bleeding
   through it). The night pass gave nav/main/footer a shared z-index:1 to sit above the film
   grain — which put the burger dropdown (z-20 INSIDE nav's stacking context) in the same
   layer as main, and main, later in the DOM, painted over the open menu. The nav must
   outrank the content it drops over, on every page. */
.nav { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem var(--pad); border-bottom: 1px solid var(--gold-line); position: relative; z-index: 30; }
/* baseline, not centre — see landing.html; the gate stands on the line the word stands on */
.brand { display: inline-flex; align-items: baseline; gap: 0.5rem; }
/* THE ARCH, NOT THE ARC (his ruling, 2026-08-27: "Only arches please"). This nav wore
   velea-mark.svg — the sweeping arc SYSTEM_MAP calls "VeleaMark = the app" — while the
   landing page and the app icon moved to the gate at v1468/v1469, so the site showed two
   different marks one click apart. Now his own /gate-mark.png as a mask with a flat gold
   fill; square box + contain so the drawing is never distorted (the GateMark.tsx pattern).
   28px, not 22: the gate is a PORTRAIT mark (316:500 of content in a square canvas), so an
   equal box renders it smaller than the shape it replaces — his note, "The ones you are
   using are also too small". The arc is untouched everywhere else; it is still the loader. */
.vmark { display: inline-block; width: 21px; height: 21px; background: var(--gold);
    -webkit-mask: url("/gate-mark.png") center / contain no-repeat; mask: url("/gate-mark.png") center / contain no-repeat; }
.bname { font-family: var(--serif); font-size: 1.2rem; color: var(--champ); }
.links { display: flex; align-items: baseline; gap: 1.4rem; }
.links a.item { font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft); white-space: nowrap; }
.links a.item:hover { color: var(--champ); }
.links a.item.on { color: var(--champ); border-bottom: 1px solid var(--gold-line); padding-bottom: 2px; }
.burger { display: none; background: none; border: none; cursor: pointer; padding: 6px; }
.burger span { display: block; width: 20px; height: 2px; background: var(--gold); margin: 4px 0; border-radius: 2px; }
@media (max-width: 760px) {
    .burger { display: block; }
    .links { display: none; position: absolute; top: 100%; left: 0; right: 0; z-index: 20;
      flex-direction: column; align-items: flex-start; gap: 0; background: var(--plum-deep);
      border-bottom: 1px solid var(--gold-line); }
    .nav.open .links { display: flex; }
    .links a.item { padding: 0.95rem var(--pad); width: 100%; border-top: 1px solid rgba(212,175,55,0.14); }
    .links a.item.on { border-bottom: none; }
  }
/* THE COLUMN FOLLOWS THE WINDOW (2026-07-20). It was pinned at 58rem and anchored
     left, so a wide screen got a 433px empty right gutter at 1440 and 712px at 1728 —
     measured. It now grows with the viewport up to 100rem, keeping the same left
     anchor, and the PROSE keeps its own 44rem measure below so reading width is
     unchanged: only figures, beats and rules take the extra room. */
/* THE PHONE GOT THE DESKTOP'S GUTTER AND NONE OF ITS MARGIN (David, 2026-08-31, on /portrait:
   "it doesn't fill up the whole screen's width"). The max-width above subtracts TWO gutters so the
   column can sit inset on a wide screen — but the matching `margin-left` that balances them only
   exists from 900px up, and `clamp(2.5rem, 5.5vw, 5.5rem)` bottoms out at its 2.5rem MINIMUM on a
   phone (5.5vw of 440px is 24px, under the 40px floor). So a 440px phone reserved 80px, spent none
   of it on the left, and left a dead 80px strip down the right of every marketing page — measured
   at 307px of content in a 440px viewport. The inset is a wide-screen idea; it now lives entirely
   in the wide-screen branch, where its own margin is. */
main { max-width: 100%; margin: 0; padding: clamp(3rem, 8vw, 5rem) var(--pad) 4rem; }
/* Reading measure, independent of how wide the column gets. */
main > p, main > ul, main > .big, main > .lede, main > h2.sub, main > .label, main > h1,
  .say > p, .say > .big { max-width: var(--maxw); }
@media (min-width: 900px) {
  main { max-width: min(108rem, calc(100vw - 2 * clamp(2.5rem, 5.5vw, 5.5rem)));
         margin-left: clamp(2.5rem, 5.5vw, 5.5rem); }
}
.kicker { font-size: 0.92rem; letter-spacing: 0.34em; text-transform: uppercase; color: var(--champ); font-weight: 600; }
.kicker .km { font-family: var(--khmer); letter-spacing: normal; text-transform: none; font-size: 1rem; }
h2.sub { font-family: var(--serif); font-weight: 500; font-size: clamp(1.45rem, 4.8vw, 1.95rem); line-height: 1.38; color: var(--ink); margin: 1.6rem 0 0; text-wrap: balance; }
.lede { font-size: clamp(1.05rem, 2.6vw, 1.2rem); line-height: 1.7; color: var(--ink-dim); margin: 1.6rem 0 0; }
/* SECTION HEADS ARE SERIF, AND THEY OUTRANK THE LINE BELOW THEM (David, 2026-07-20).
     They were letterspaced uppercase sans at 0.92rem — smaller than the serif sentence
     they introduced, which read as a caption rather than a heading. Now: serif, larger
     than .big at every viewport (1.8-2.5rem against 1.45-1.95rem), gold, sentence case
     as written in the markup. */
.label { font-family: var(--serif); font-size: clamp(1.8rem, 5.6vw, 2.5rem); line-height: 1.18;
           letter-spacing: normal; text-transform: none; color: var(--champ); font-weight: 500;
           margin: 0 0 1.1rem; text-wrap: balance; }
.rule { border: none; height: 1px; background: var(--gold-line); margin: clamp(2.6rem, 7vw, 4rem) 0; width: 100%; }
@media (min-width: 900px) { .rule { width: calc(100vw - 2 * clamp(2.5rem, 5.5vw, 5.5rem) - 2 * var(--pad)); max-width: none; } }
strong { color: var(--ink); font-weight: 600; }
ul { padding-left: 1.15rem; margin: 0 0 1.1rem; }
li { font-size: 1.02rem; line-height: 1.7; color: var(--ink-dim); margin-bottom: 0.45rem; }
.big { font-family: var(--serif); font-weight: 500; font-size: clamp(1.45rem, 4.8vw, 1.95rem); line-height: 1.38; color: var(--ink); margin: 0 0 1.1rem; text-wrap: balance; }
.cta:hover { color: #E0C169; border-bottom-color: var(--gold); } /* was a button's lift + brightness; the door is a label on a rule now (2026-08-31) */
.ctaRow { text-align: left; margin-top: clamp(2.5rem, 7vw, 4rem); }
figure { margin: clamp(2.4rem, 7vw, 3.6rem) 0; }
figure.bleed { width: 100vw; margin-left: calc(50% - 50vw); }
figure.bleed img { width: 100%; display: block; }
@media (min-width: 900px) { figure.bleed { margin-left: calc(-1 * clamp(2.5rem, 5.5vw, 5.5rem) - var(--pad)); width: 100vw; } }
figcaption { font-size: 0.85rem; color: var(--ink-soft); margin-top: 0.7rem; text-align: center; letter-spacing: 0.02em; }
.p1hero::before { content: ""; position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(20,10,26,0.42) 0%, rgba(20,10,26,0.05) 40%, rgba(20,10,26,0.55) 100%); }
/* .p1hero .inner moved to access.html 2026-08-30 — the one page that renders a hero
   diverged on it (nav overlay + hero padding), and the shell law says a selector the
   pages disagree about lives wholly with its page. */
.p1hero .kicker { color: #fff; text-shadow: 0 1px 10px rgba(0,0,0,0.4); }
.p1hero .kicker .km { color: #fff; }
.p1hero h1 { color: #fff; text-shadow: 0 2px 18px rgba(0,0,0,0.45); }
.p1hero h2.sub { color: rgba(255,255,255,0.94); text-shadow: 0 1px 12px rgba(0,0,0,0.45); }
.p1hero .lede { color: rgba(255,255,255,0.88); text-shadow: 0 1px 10px rgba(0,0,0,0.4); }
.moons { display: flex; justify-content: space-between; gap: 0.4rem; padding: 0.6rem 0.2rem; }
.moon { width: clamp(26px, 8vw, 44px); height: clamp(26px, 8vw, 44px); border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 10px rgba(212,175,55,0.25); }
dl dt { font-family: var(--serif); font-size: 1.15rem; color: var(--ink); margin-top: 1.3rem; }
dl dd { margin: 0.3rem 0 0; font-size: 1rem; line-height: 1.7; color: var(--ink-dim); }
.field { display: flex; gap: 0.5rem; margin: 1.8rem 0 0.8rem; max-width: 30rem; }
/* STACKED ON PHONES (2026-08-30, his note: "the email bubble is not long enough"). The row
   starved the input to a stub beside the button; a whole address must fit. */
@media (max-width: 560px) { .field { flex-direction: column; gap: 0.7rem; } .field input, .field button { width: 100%; } }
.field input { flex: 1; min-width: 0; padding: 0.85rem 1.15rem; border-radius: 999px; border: 1px solid var(--gold-line); background: rgba(58,49,40,0.05); color: var(--ink); font-size: 1rem; }
.field input:focus { outline: none; border-color: var(--gold); }
.field button { flex-shrink: 0; border: none; cursor: pointer; padding: 0.85rem 1.4rem; border-radius: 999px; background: var(--gold); color: #2a180f; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
/* A STEP THAT STACKS ON EVERY WIDTH (2026-09-07), for the one form that holds more than a single
   input. `.field` is a flex ROW built for input+button, and it already stacks under 560px; with an
   optional second input in it, the row arrangement puts the SUBMIT between two fields at every
   width above that — seen rendered, and wrong at any size. The gold button is a stopping point,
   and nothing after a stopping point gets filled. */
.field-stack { flex-direction: column; gap: 0.7rem; }
.field-stack input, .field-stack button { width: 100%; }
.note { font-size: 0.85rem; color: var(--ink-soft); }
footer { border-top: 1px solid var(--gold-line); padding: 0.85rem var(--pad); display: flex; justify-content: center; gap: 0.7rem; align-items: baseline; font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft); white-space: nowrap; }
footer .fm { font-family: var(--serif); font-size: 0.95rem; color: var(--champ); text-transform: none; letter-spacing: 0.02em; }
footer .km { font-family: var(--khmer); text-transform: none; letter-spacing: normal; }
@media (max-width: 560px) { .nav { gap: 0.35rem 0.9rem; } .nav a.item { font-size: 0.6rem; letter-spacing: 0.08em; } }
/* PHONE TYPE FLOORS (2026-08-30, his screenshots against his seven type cards: "Too big.
   Too condensed"). The display sizes ease down and the leading opens at phone width —
   hierarchy holds (label > big > body), leading lands inside the 120–150% band. */
@media (max-width: 760px) {
  .big, h2.sub { font-size: 1.32rem; line-height: 1.5; }
  .label { font-size: 1.6rem; }
}
/* ── The story (mobile tap-through; engine in /marketing/story.js) ──────────────
   Shared by /why /system /gate. Ground and fade are vars so the gate's black page
   keeps its own night. Grammar is ManifestoIntro's — see story.js header. */
.story { position: fixed; left: 0; right: 0; bottom: 0; z-index: 10; display: flex; flex-direction: column;
    background: var(--story-bg, radial-gradient(120% 90% at 50% 12%, #241333 0%, #10081a 62%)); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.story-beat { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; width: 100%; max-width: 40rem;
    margin: 0 auto; padding: 1.4rem var(--pad) 1rem; display: flex; flex-direction: column; justify-content: center; }
.story-beat > div { animation: story-rise 0.7s ease both; }
.story-beat img { max-height: 62svh; width: auto; max-width: 100%; margin: 0 auto; display: block; }
.story-beat figure { margin: 0; }
/* A cloned full-bleed figure keeps its 100vw scroll-page geometry and runs off the beat —
   inside the story it takes the beat's own width. */
.story-beat figure.bleed { width: 100%; margin-left: 0; }
.story-beat figure.bleed img { width: 100%; }
@keyframes story-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.story-foot { position: relative; flex: 0 0 auto; width: 100%; max-width: 40rem; margin: 0 auto;
    padding: 0 var(--pad) calc(env(safe-area-inset-bottom, 0px) + 1.3rem); }
.story-fade { position: absolute; left: 0; right: 0; top: -3rem; height: 3rem; pointer-events: none;
    background: var(--story-fade, linear-gradient(to bottom, rgba(16,8,26,0), #10081a)); }
.story-track { display: flex; gap: 5px; margin-bottom: 1rem; }
.story-track span { flex: 1; height: 2px; border-radius: 999px; background: rgba(242,229,210,0.16); overflow: hidden; }
.story-track span i { display: block; height: 100%; border-radius: 999px; background: var(--gold); }
.story-track span.on i { animation: story-fill 0.75s ease both; }
@keyframes story-fill { from { width: 0; } to { width: 100%; } }
.story-cues { display: flex; align-items: center; justify-content: space-between; min-height: 22px; }
/* BACK (his 8/31 note: "this tapping ahead feature should have a back tap too… I keep wanting to
   go back to look at things and am unable to"). Same weight as Skip, opposite end; the left
   quarter of the screen walks back too, for anyone who already knows the gesture. */
.story-back { background: none; border: none; font-family: var(--sans); color: rgba(242,229,210,0.45);
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; padding: 0.2rem 0.1rem; cursor: pointer; }
/* THE DOOR, as a thing you press — his ruling on the last screen's cue. */
.story-door { margin-top: clamp(1.6rem, 5vw, 2.4rem); }
.story-door .cta { margin-top: 0; }
.story-cue { font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(242,229,210,0.38); transition: opacity 0.4s; }
.story-skip { background: none; border: none; font-family: var(--sans); color: rgba(242,229,210,0.45);
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer; padding: 0.35rem 0 0.35rem 1rem; }
body.storying { overflow: hidden; }
/* Section heads: serif, larger than the line they introduce (see system.html). */
