/* =============================================================
   Kingdom Combat Arts — kingdomcombatarts.com
   Vanilla CSS. No build step. Load order: tokens, base, blocks.
   ============================================================= */

/* ---------- tokens ---------- */
:root{
  --black:    #0A0806;   /* page base — warm, so scrims cannot pull cool */
  --graphite: #16110B;   /* warm — the page lifts brown, never grey */
  --steel:    #2A2118;
  --gold:     #D39726;
  --gold-lt:  #F3C55C;
  --gold-dk:  #8A5A14;
  --gold-deep:#4A3210;
  --bone:     #E9E5DD;
  --mute:     #8B8F96;
  --dim:      #7A7E85;   /* 4.89:1 on --black — passes AA at 11px */

  --display: 'Marcellus', 'Times New Roman', Times, serif;
  --body:    'Barlow', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
  --script:  'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;

  --pad:    clamp(86px, 13vh, 150px);
  --gutter: clamp(22px, 5vw, 84px);
  --maxw:   1240px;
}

/* ---------- base ---------- */
*, *::before, *::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
html{ background:var(--black); }
/* One gradient over the whole document rather than a band per section, so the
   page breathes lighter and darker as it scrolls with no seam where sections
   meet. Kept to a narrow range (8..22 of 255) so nothing reads as a step. */
body{
  margin:0;
  /* Noise tile over the gradient. Over 5000px this gradient holds the same
     8-bit value for dozens of rows then steps, which reads as faint horizontal
     banding; per-pixel dither breaks the staircase. */
  background-image:
    url("noise.png"),
    linear-gradient(180deg,
    #0A0806  0%,
    #0A0806 17%,   /* crown, and the top of Who we are, stay flat black */
    #0C0A07 25%,
    #1A1309 38%,
    #0B0907 50%,
    #1C150A 64%,
    #0B0907 78%,
    #171108 90%,
    #0A0806 100%);
  background-repeat:repeat, no-repeat;
  background-size:128px 128px, 100% 100%;
  color:var(--bone);
  font-family:var(--body);
  font-weight:300;
  font-size:clamp(16px, 1.35vw, 19px);
  line-height:2;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
h1,h2,h3{
  font-family:var(--display);
  font-weight:400;
  text-transform:uppercase;
  line-height:1.24;
  letter-spacing:0.09em;
  color:var(--bone);
  margin:0;
}
h1{ font-size:clamp(31px, 5.1vw, 62px); letter-spacing:0.1em; }
h2{ font-size:clamp(25px, 3.3vw, 40px); }
h3{ font-size:clamp(19px, 2vw, 24px); }
p{ margin:0; }
p + p{ margin-top:1.35em; }
ul{ margin:0; padding:0; list-style:none; }
a{ color:inherit; }
img{ max-width:100%; display:block; }

:focus-visible{
  outline:1px solid var(--gold-lt);
  outline-offset:4px;
}

.eyebrow{
  font-family:var(--body);
  font-weight:400;
  font-size:11px;
  letter-spacing:0.4em;
  line-height:1.8;
  text-transform:uppercase;
  color:var(--gold);
  margin:0 0 22px;
}
.lede{ color:var(--mute); }
.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--black); color:var(--bone);
  padding:14px 22px; font-size:11px; letter-spacing:0.26em; text-transform:uppercase;
  border:1px solid var(--gold);
}
.skip:focus{ left:var(--gutter); top:14px; }

/* ---------- layout ---------- */
.section{ padding:var(--pad) var(--gutter); }
.wrap{ max-width:var(--maxw); margin:0 auto; }
[id]{ scroll-margin-top:90px; }
/* Rides up under the crown rather than sitting a full section gap below it,
   and hands off to What to expect without a canyon between them. */
#who{
  position:relative;
  /* Needed: position:relative alone does not make a stacking context, so the
     z-index:-1 layer below would fall into the root context and paint UNDER
     body's gradient, which is opaque. isolate scopes it to this section. */
  isolation:isolate;
  padding-top:clamp(40px, 6vh, 76px);
  padding-bottom:clamp(64px, 9vh, 116px);
}
/* Line art in the left margin beside the copy — a single figure, so it is
   anchored left rather than run full width, which would leave the right half
   empty against centred text. It also mirrors the sparring pair sitting in the
   right margin of the section below. The source is already transparent apart
   from the strokes, so the page gradient reads straight through it. z-index -1
   keeps it under the copy but over the body gradient; the mask fades it at the
   section edges so the crop cannot draw a horizontal line. */
#who::before{
  content:"";
  position:absolute;
  /* Runs past the section's bottom edge so the artwork carries on down the page
     without the section itself having to grow that much. */
  inset:0 0 -80px 0;
  z-index:-1;
  pointer-events:none;
  /* Sized off the section's height and nudged past the left edge, so it sits in
     the margin beside the centred copy rather than behind it. */
  background:url("who-bg.webp") no-repeat left -38px bottom 0 / auto 98%;
  opacity:.62;
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 5%, #000 80%, transparent 100%);
          mask-image:linear-gradient(to bottom, transparent 0%, #000 5%, #000 80%, transparent 100%);
}
/* Below this the copy spans most of the viewport, so the figure can no longer
   sit beside it — it goes behind instead, dulled until the type clears it.
   #D39726 over the page background holds 4.5:1 against --mute up to 0.20
   opacity (composited in sRGB, which is what CSS opacity does); 0.18 leaves
   margin. Centred rather than left-anchored, since there is no margin left. */
@media (max-width: 1179px){
  #who::before{
    inset:0;
    /* Flat-gold variant. The full-colour art carries near-white highlight
       strokes that composite brighter than the gold and blow the contrast
       ceiling; one known colour makes the limit predictable. */
    background-image:url("who-bg-m.webp");
    background-position:center 24%;
    background-size:auto 84%;
    opacity:.17;
    -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 12%, #000 86%, transparent 100%);
            mask-image:linear-gradient(to bottom, transparent 0%, #000 12%, #000 86%, transparent 100%);
  }
}

/* ---------- crown mark (flat 2D) ---------- */
/* `fill` is an inherited property, so it reaches paths inside <use>'s shadow tree. */
.crown{ fill:var(--gold); display:block; }

/* ---------- nav ---------- */
.nav{
  position:absolute; top:0; left:0; right:0; z-index:20;
  display:flex; align-items:flex-start; justify-content:space-between; gap:24px;
  padding:clamp(20px, 3.2vh, 34px) var(--gutter);
}
/* Stacked lockup: crown over KINGDOM over COMBAT ARTS, centred on each other.
   Side by side, the crown sat next to two short lines and read as loose. */
.brand{
  display:flex; flex-direction:column; align-items:center; gap:7px;
  text-decoration:none;
}
.brand .crown{ width:38px; height:auto; flex:none; }
.brand-name{
  font-family:var(--display); text-transform:uppercase;
  letter-spacing:0.14em; font-size:16px; line-height:1.1; color:var(--bone);
  text-indent:0.14em;   /* trailing tracking would otherwise sit the word left */
}
.brand-sub{
  font-family:var(--body); font-weight:400; font-size:9px;
  letter-spacing:0.3em; line-height:1.5; text-transform:uppercase; color:var(--gold);
  text-indent:0.3em;
}
.nav-links{ display:flex; align-items:center; gap:clamp(20px, 2.6vw, 40px); }
.nav-links a{
  font-size:11px; font-weight:400; letter-spacing:0.26em; text-transform:uppercase;
  color:var(--mute); text-decoration:none; padding-bottom:5px;
  border-bottom:1px solid transparent;
  transition:color .25s ease, border-color .25s ease;
}
.nav-links a:hover{ color:var(--bone); border-bottom-color:var(--gold); }

.nav-toggle{
  display:none;
  background:none; border:1px solid rgba(233,229,221,.26); color:var(--bone);
  font-family:var(--body); font-size:10px; font-weight:400;
  letter-spacing:0.26em; text-transform:uppercase;
  padding:11px 16px; cursor:pointer;
  transition:border-color .25s ease;
}
.nav-toggle:hover{ border-color:var(--gold); }

.menu{
  position:fixed; inset:0; z-index:60;
  background:var(--black);
  display:none; flex-direction:column; align-items:center; justify-content:center; gap:6px;
}
.menu.is-open{ display:flex; }
.menu a{
  font-family:var(--display); text-transform:uppercase; letter-spacing:0.09em;
  font-size:clamp(21px, 6.2vw, 30px); color:var(--bone); text-decoration:none;
  padding:16px 10px; line-height:1.3;
}
.menu a:hover{ color:var(--gold); }
.menu-close{
  position:absolute; top:clamp(20px,3.2vh,34px); right:var(--gutter);
  background:none; border:1px solid rgba(233,229,221,.26); color:var(--bone);
  font-family:var(--body); font-size:10px; letter-spacing:0.26em; text-transform:uppercase;
  padding:11px 16px; cursor:pointer;
}

/* ---------- photo frames ---------- */
/* A photo slot. The colour is only what shows while the image loads — warm, so
   it does not flash a cool grey against the brown page. To add a slot, give the
   element .ph plus a class carrying its background-image. */
.ph{
  position:relative;
  background-color:#15100A;
  background-size:cover;
  background-position:center;
  background-repeat:no-repeat;
}

/* ---------- hero ---------- */
.hero{
  position:relative;
  min-height:78vh;
  display:flex; align-items:center;
  overflow:hidden;
}
/* The scrim fades out at both ends instead of butting against the sections
   above and below. Nothing paints a hard edge; the page gradient runs straight
   through. The text sits inside the opaque band, so contrast holds. */
.hero-scrim{
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 88%, transparent 100%);
          mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 88%, transparent 100%);
}
/* Bottom-left, so the dev caption does not sit on the sparring artwork. */
.hero-scrim::after{ left:24px; right:auto; bottom:24px; }
/* Two-layer scrim: near-solid black bottom-left, image opens toward top-right. */
.hero-scrim{
  position:absolute; inset:0; z-index:1;
  /* Centred copy needs a centred backing — the old left-to-right ramp put the
     text's right half on a lighter ground than its left. */
  background:
    linear-gradient(to top,
      rgba(10,8,6,.90) 0%, rgba(10,8,6,.78) 26%,
      rgba(10,8,6,.52) 62%, rgba(10,8,6,.24) 100%),
    radial-gradient(105% 78% at 50% 50%,
      rgba(10,8,6,.86) 0%, rgba(10,8,6,.52) 52%, rgba(10,8,6,.10) 100%);
}

/* Sparring pair in the bottom-right corner, the right man running off the page
   edge. Sized off the hero's height and pushed past the right edge so it sits in
   the margin beside the centred copy rather than behind it. z-index 1 puts it
   over the photo scrim; .hero-inner is z-index 2, so the type stays on top. */
.hero::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  pointer-events:none;
  background:url("spar.webp") no-repeat right -74px bottom 0 / auto 54%;
  opacity:.68;
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 92%, transparent 100%);
          mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 92%, transparent 100%);
}
/* Same treatment as the Who-we-are figure below 1180px: behind the copy rather
   than beside it, dulled to 0.18 so --mute still clears 4.5:1 over it. */
@media (max-width: 1179px){
  .hero::after{
    background-image:url("spar-m.webp");
    background-position:center bottom 4%;
    background-size:auto 56%;
    opacity:.17;
    -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 16%, #000 88%, transparent 100%);
            mask-image:linear-gradient(to bottom, transparent 0%, #000 16%, #000 88%, transparent 100%);
  }
}
.hero-inner{
  position:relative; z-index:2;
  width:100%;
  /* The gutter lives inside this box, so the cap has to include it or the hero
     copy sits one gutter further in than every .wrap section. */
  max-width:calc(var(--maxw) + 2 * var(--gutter));
  margin:0 auto;
  padding:clamp(66px,10vh,110px) var(--gutter);
}
/* Wide enough for the headline to hold two lines at its 62px ceiling. The body
   paragraph keeps its own 56ch measure, so only the h1 uses the extra width. */
.hero-copy{ max-width:820px; margin:0 auto; text-align:center; }
.hero-copy p:not(.eyebrow){ color:var(--mute); margin:26px auto 0; max-width:56ch; }
/* Sized for the headline that is actually there — a 14ch measure left "UP"
   stranded on a line of its own. Balance keeps the lines even at every width. */
.hero h1{ max-width:none; text-wrap:balance; }

/* ---------- what to expect (folded into the hero) ---------- */
.expect{
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:clamp(14px,2vh,20px) clamp(30px,4vw,58px);
  margin:clamp(28px,4.2vh,42px) auto 0;
  max-width:730px;
}
.expect-name{
  display:block;
  font-family:var(--display); text-transform:uppercase; letter-spacing:0.09em;
  font-size:clamp(14px,1.25vw,17px); line-height:1.35; color:var(--bone);
}
.expect-desc{
  display:block; margin-top:7px;
  font-size:13px; line-height:1.6; color:var(--mute);
}

/* ---------- buttons ---------- */
.btns{ display:flex; flex-wrap:wrap; gap:14px; margin-top:38px; }
.hero .btns{ justify-content:center; }
.btn{
  display:inline-block;
  padding:18px 40px;
  font-family:var(--body); font-weight:400; font-size:11px;
  letter-spacing:0.28em; line-height:1; text-transform:uppercase;
  text-decoration:none; border:1px solid; white-space:nowrap;
  transition:background-color .28s ease, color .28s ease, border-color .28s ease;
}
.btn-primary{ color:var(--gold); border-color:var(--gold); background:transparent; }
.btn-primary:hover{ background:var(--gold); color:var(--black); }
.btn-ghost{ color:var(--bone); border-color:rgba(233,229,221,.28); background:transparent; }
.btn-ghost:hover{ border-color:var(--bone); }

/* ---------- prose column ---------- */
/* Who we are and What to expect sit on the same left axis with the same
   measure, so the two read as a matched pair down the page. .hero-copy carries
   the identical 820px cap. */
.col-copy{ max-width:820px; margin:0 auto; text-align:center; }
.col-copy .col-body{
  margin:clamp(22px,3.4vh,34px) auto 0;
  color:var(--mute); max-width:56ch;
}

/* ---------- shield wall ---------- */
.divider{ padding:clamp(50px, 8vh, 96px) var(--gutter); }
.shieldwall{
  display:flex; align-items:center; gap:clamp(18px, 3vw, 44px);
  max-width:var(--maxw); margin:0 auto;
}
.sw-rank{
  height:20px; flex:1 1 0; min-width:0;
  background:repeating-linear-gradient(90deg, var(--gold-dk) 0 1px, transparent 1px 15px);
  opacity:.5;
}
.sw-rank.is-left{
  -webkit-mask-image:linear-gradient(90deg, transparent 0%, #000 78%);
          mask-image:linear-gradient(90deg, transparent 0%, #000 78%);
}
.sw-rank.is-right{
  -webkit-mask-image:linear-gradient(90deg, #000 22%, transparent 100%);
          mask-image:linear-gradient(90deg, #000 22%, transparent 100%);
}
.shieldwall .crown{ width:34px; height:auto; flex:none; opacity:.88; }

/* ---------- a monday ---------- */
.section-head{ max-width:62ch; }
.section-head .lede{ margin-top:22px; }
.steps{
  display:grid; grid-template-columns:repeat(3, 1fr);
  gap:clamp(30px, 4.2vw, 66px);
  margin-top:clamp(46px, 7.5vh, 82px);
}
.step{ border-top:1px solid var(--gold-dk); padding-top:26px; }
.step-num{
  font-family:var(--display); color:var(--gold);
  font-size:clamp(20px, 2.2vw, 26px); letter-spacing:0.14em; line-height:1;
}
.step h3{ margin:16px 0 14px; }
.step p{ font-size:16px; line-height:1.95; color:var(--mute); }

/* ---------- two doors ---------- */
.doors{
  display:grid; grid-template-columns:1fr 1fr;
  gap:clamp(22px, 3vw, 40px);
  margin-top:clamp(46px, 7.5vh, 82px);
}
.door{
  display:flex; flex-direction:column;
  border:1px solid rgba(138,90,20,.5);
  background:rgba(26,20,13,.5);
  transition:border-color .3s ease;
}
.door:hover{ border-color:var(--gold); }
.door .ph{ aspect-ratio:16 / 10; }
/* Real photography. One property swap, as the placeholders were built for. */
.ph-club{ background-image:url("club.webp"); }
.ph-academy{ background-image:url("academy.webp"); }
.door-body{ padding:clamp(26px, 3vw, 42px); display:flex; flex-direction:column; flex:1; }
.tag{
  font-family:var(--body); font-weight:400; font-size:10px;
  letter-spacing:0.34em; line-height:1.8; text-transform:uppercase; color:var(--gold);
  margin-bottom:16px;
}
.door h3{ margin-bottom:16px; }
.door p{ font-size:16px; line-height:1.95; color:var(--mute); }
/* Club copy runs well longer than the academy's, so pin both links to the
   bottom of their card instead of letting each float under its own paragraph. */
.door-body p{ margin-bottom:28px; }
.door-link{
  margin-top:auto; align-self:flex-start;
  font-size:11px; font-weight:400; letter-spacing:0.28em; text-transform:uppercase;
  color:var(--gold); text-decoration:none;
  padding-bottom:5px; border-bottom:1px solid var(--gold-deep);
  transition:color .25s ease, border-color .25s ease;
}
.door-link:hover{ color:var(--gold-lt); border-bottom-color:var(--gold-lt); }

/* ---------- scripture ---------- */
.scripture{ text-align:center; }
.scripture .wrap{ padding:clamp(20px, 5vh, 60px) 0; }
.scripture blockquote{
  margin:0 auto;
  text-wrap:balance;
  max-width:15em;
  font-family:var(--script); font-style:italic; font-weight:300;
  font-size:clamp(31px, 5vw, 62px);
  line-height:1.48; letter-spacing:0.005em;
  color:var(--bone);
}

/* ---------- 0. the opening screen ---------- */
.opening{
  position:relative;
  height:100vh;
  height:100svh;
  display:flex; flex-direction:column; justify-content:flex-end;
  overflow:hidden;
  /* No top padding — the crown runs to the very top of the viewport and the
     nav sits over it. */
  /* Fades to transparent, not to black, so it sits on the page gradient with
     no edge where the section ends. */
  background:radial-gradient(62% 62% at 50% 44%, rgba(34,25,14,.92) 0%, rgba(34,25,14,0) 78%);
}
/* Full bleed, edge to edge and behind the nav. The stage is taken out of flow
   and given the whole viewport so the crown is sized against the screen rather
   than against whatever the verse left over. Biased upward so the peaks run off
   the top and the bar clears the verse underneath. */
.crown-stage{
  position:absolute;
  left:0; right:0; top:0;
  height:100%;
  /* Portrait: the crown is width-bound and short, so there is already room
     under it and it barely needs lifting. */
  transform:translateY(-4%);
  z-index:1;
}
/* Landscape: the crown is nearly as tall as the viewport. Lift it only enough
   that the bar clears the verse, and no further — the tip sits just below the
   top edge so the whole crown is visible face-on. The nav sits over the peaks. */
@media (min-aspect-ratio: 1/1){
  .crown-stage{ transform:translateY(-18%); }
}
/* Keeps the nav legible where the metal runs underneath it. */
.opening::before{
  content:"";
  position:absolute; top:0; left:0; right:0;
  height:clamp(170px, 24vh, 280px);
  background:linear-gradient(to bottom,
    rgba(10,8,6,.96) 0%, rgba(10,8,6,.94) 46%, rgba(10,8,6,.62) 72%, rgba(10,8,6,0) 100%);
  z-index:5;
  pointer-events:none;
}
.opening-verse{ position:relative; z-index:5; margin-top:auto; }
/* Same job as the nav scrim, at the other end: keeps the verse readable if the
   bar swings down behind it mid-rotation. */
.opening::after{
  content:"";
  position:absolute; left:0; right:0; bottom:0;
  height:clamp(210px, 38vh, 420px);
  /* Zero at 0% — that is the section's bottom edge, and any value there paints
     a hard line against whatever the page gradient is doing just below it.
     Strong through the middle, where the bar swings behind the verse. */
  background:linear-gradient(to top,
    rgba(10,8,6,0)   0%,
    rgba(10,8,6,.62) 9%,
    rgba(10,8,6,.93) 26%,
    rgba(10,8,6,.93) 68%,
    rgba(10,8,6,.45) 88%,
    rgba(10,8,6,0)   100%);
  z-index:2;
  pointer-events:none;
}
/* The flat mark paints on first frame and holds the composition; the canvas
   crossfades over it once Three.js mounts, and stays hidden if it never does. */
.crown-flat{
  position:absolute; inset:0; margin:auto;
  width:80%; height:80%;
  transition:opacity .4s ease;
}
.crown-stage canvas{
  position:absolute; top:0; left:0;
  display:block;
  opacity:0;
  transition:opacity .4s ease;
  pointer-events:none;   /* nothing here may intercept a scroll */
}
.crown-stage.is-live canvas{ opacity:1; }
.crown-stage.is-live .crown-flat{ opacity:0; }

.opening-verse{
  flex:0 0 auto;
  text-align:center;
  padding:clamp(18px,3vh,32px) var(--gutter) clamp(38px, 6.5vh, 76px);
  opacity:0;
  transform:translateY(16px);
  transition:opacity .9s ease, transform .9s ease;
}
.opening-verse.is-in{ opacity:1; transform:none; }
.opening-verse blockquote{
  margin:0 auto;
  max-width:21em;
  text-wrap:balance;   /* keeps "war." off a line of its own on a phone */
  font-family:var(--script); font-style:italic; font-weight:300;
  font-size:clamp(23px, 3.2vw, 40px);
  line-height:1.45; color:var(--bone);
}
.opening-verse .eyebrow{ margin:clamp(14px,2.2vh,22px) 0 0; }

/* ---------- close ---------- */
.close{ text-align:center; }
.close p{ color:var(--mute); margin:26px auto 0; max-width:56ch; }
.close .btns{ justify-content:center; margin-top:40px; }
.close .capture,
.close .capture-done{ text-align:center; }
.close .capture label{ text-align:center; }

.capture{
  margin:clamp(30px,5vh,46px) auto 0;
  max-width:32em;
}
.capture label{
  display:block;
  font-family:var(--body); font-weight:400; font-size:11px;
  letter-spacing:0.3em; line-height:1.8; text-transform:uppercase;
  color:var(--mute);
  margin-bottom:16px;
}
.capture-row{ display:flex; align-items:stretch; gap:12px; }
.capture-input{
  flex:1 1 auto; min-width:0;
  background:transparent; color:var(--bone);
  /* --steel is 1.30:1 on --black; an empty field is identified only by its
     boundary, so it owes the 3:1 non-text minimum. --dim is 4.89:1. */
  border:1px solid var(--dim);
  padding:16px 20px;
  font-family:var(--body); font-weight:300; font-size:16px; line-height:1.4;
  transition:border-color .25s ease;
}
.capture-input::placeholder{ color:var(--dim); opacity:1; }
.capture-input:hover{ border-color:var(--gold); }
.capture-input:focus{ border-color:var(--gold); }
.capture-input[aria-invalid="true"]{ border-color:var(--gold-lt); }
/* The button is a flex item here, so stretch decides its height — centre the
   label rather than letting the shared 18px padding position it. */
.capture-row .btn{
  flex:0 0 auto;
  display:inline-flex; align-items:center; justify-content:center;
  padding-top:0; padding-bottom:0;
}
.capture-row .btn[disabled]{ opacity:.5; cursor:default; }
/* The honeypot. Taken out of the visual and accessibility trees both — moved
   off-screen rather than display:none, which some bots know to skip. */
.hp{
  position:absolute;
  width:1px; height:1px;
  overflow:hidden;
  clip:rect(0 0 0 0);
  clip-path:inset(50%);
  white-space:nowrap;
}
.capture-error{
  margin-top:14px;
  font-size:14px; line-height:1.7; color:var(--gold-lt);
  min-height:1.7em;              /* reserved, so an error causes no layout shift */
}
.capture-error:empty{ min-height:0; }
/* The not-wired notice, visually distinct from a user-facing validation error. */
.capture-error.is-note{
  font-size:11px; font-weight:400; letter-spacing:0.22em; text-transform:uppercase;
  color:var(--gold);
}
.capture-done{
  margin:clamp(30px,5vh,46px) auto 0;
  max-width:32em;
  font-family:var(--display); text-transform:uppercase; letter-spacing:0.09em;
  font-size:clamp(17px,1.8vw,22px); line-height:1.5; color:var(--bone);
}
.capture-done:focus-visible{ outline:1px solid var(--gold-lt); outline-offset:8px; }

/* ---------- footer ---------- */
.foot{ padding:clamp(30px, 5vh, 48px) var(--gutter); }
.foot-in{
  max-width:var(--maxw); margin:0 auto;
  display:flex; justify-content:space-between; align-items:center;
  flex-wrap:wrap; gap:12px 28px;
  font-size:11px; font-weight:400; letter-spacing:0.24em; line-height:2;
  text-transform:uppercase; color:var(--dim);
}
.foot-in a{
  color:var(--dim); text-decoration:none;
  padding-bottom:4px; border-bottom:1px solid transparent;
  transition:color .25s ease, border-color .25s ease;
}
.foot-in a:hover{ color:var(--gold); border-bottom-color:var(--gold); }

.foot-legal{
  max-width:var(--maxw); margin:clamp(24px,4vh,38px) auto 0;
  padding-top:clamp(26px,3.6vh,36px);
  display:flex; justify-content:space-between; align-items:center;
  flex-wrap:wrap; gap:10px 28px;
}
.foot-copy{
  font-size:11px; font-weight:400; letter-spacing:0.16em; line-height:1.9;
  text-transform:uppercase; color:var(--dim);
}
.foot-links{ display:flex; flex-wrap:wrap; gap:10px 24px; }
/* Marked placeholders — no pages behind them yet, so they are not dressed up
   as links that go nowhere. */
.foot-links span{
  font-size:11px; font-weight:400; letter-spacing:0.16em; line-height:1.9;
  text-transform:uppercase; color:var(--dim);
}

/* ---------- motion ---------- */
.reveal{
  opacity:0;
  transform:translateY(16px);
  transition:opacity .6s ease, transform .6s ease;
}
.reveal.is-in{ opacity:1; transform:none; }
.steps .reveal:nth-child(2){ transition-delay:.09s; }
.steps .reveal:nth-child(3){ transition-delay:.18s; }

/* =============================================================
   Breakpoints
   ============================================================= */

/* Staggered, not all at once: the prose pair breaks first, then the cards,
   then the three columns — each at the width where it actually stops working. */
@media (max-width: 900px){
  .doors{ grid-template-columns:1fr; }
}
@media (max-width: 820px){
  .steps{ grid-template-columns:1fr; gap:clamp(34px,5vh,46px); }
  .step p{ max-width:62ch; }
  .steps .reveal:nth-child(2),
  .steps .reveal:nth-child(3){ transition-delay:0s; }
}

@media (max-width: 880px){
  .nav-links{ display:none; }
  .nav-toggle{ display:inline-block; }
}


@media (max-width: 620px){
  .hero{ min-height:88vh; }
  .btns{ gap:12px; }
  .btn{ padding:17px 30px; letter-spacing:0.24em; }
  .scripture blockquote{ max-width:11em; }
  .foot-in{ flex-direction:column; align-items:flex-start; gap:6px; }
  .capture-row{ flex-direction:column; }
  .capture-row .btn{ width:100%; padding-top:18px; padding-bottom:18px; }
}

/* 360–440px: terms go single-file rather than squeezing to 2 columns. */
@media (max-width: 440px){
  .btn{ width:100%; text-align:center; }
  .hero-scrim::after{ left:16px; right:16px; bottom:16px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *, *::before, *::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  .reveal,
  .opening-verse{ opacity:1; transform:none; }
}
