:root{
  --navy: #0B0E1A;
  --bone: #F7F3EA;
  --charcoal: #2B2620;
  --rust: #8A3A22;
  --slate: #5C6355;
  --muted: rgba(247,243,234,0.55);
  --muted-soft: rgba(247,243,234,0.32);
  --font-display: 'Fraunces', serif;
  --font-body: 'Jost', sans-serif;
}
*{box-sizing:border-box; margin:0; padding:0;}
html{scroll-behavior:smooth;}
body{
  background:var(--navy); color:var(--bone);
  font-family:var(--font-body); overflow-x:hidden;
}
a{color:inherit; text-decoration:none;}

/* ---------- NAV ---------- */
/* Transparent over the pinned hero (nothing to separate from — the
   logo itself is hidden there). Once you scroll past it, the nav
   becomes a solid, opaque banner — navy over dark sections, bone over
   the light zone — matching whichever section is passing underneath
   exactly, via the existing .on-light toggle. Solid on purpose: no
   translucency means no risk of it ever overlapping page copy in a
   way that's hard to read. */
nav{
  position:fixed; top:0; left:0; right:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between;
  padding:28px 56px;
  background:rgba(11,14,26,0);
  transition:background 0.25s ease;
}
nav.scrolled{
  background:var(--navy);
}
nav.scrolled.on-light{
  background:var(--bone);
}
.logo-mark{
  height:22px; width:auto; display:block;
  opacity:0; filter:none;
  transition:opacity 0.25s ease, filter 0.4s ease;
}
nav.on-light .logo-mark{ filter:invert(1); }

.navlinks a{
  font-size:12px; letter-spacing:0.06em; color:var(--bone);
  text-transform:uppercase; transition:color 0.4s ease;
}
nav.on-light .navlinks a{ color:var(--charcoal); }

/* One brief flicker of grain exactly where navy cuts to bone — a nod
   to the name itself, signal cutting through noise. Triggered in JS
   whenever the light zone's top edge crosses the nav line. */
.grain-flash{
  position:fixed; inset:0; z-index:40; pointer-events:none;
  opacity:0; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  transition:opacity 0.5s ease;
}
.grain-flash.flash{ opacity:0.15; transition:opacity 0.07s ease; }

/* ==================================================================
   PINNED INTRO STAGE
   .stage sets the scroll "budget" for the whole sequence — increase
   or decrease its height to make the hold slower or faster. .stage-inner
   is sticky, so it stays fixed in the viewport for that entire budget;
   once you scroll past it, it releases and the page moves on to
   .light-zone with a hard cut (no gradient — see .light-zone background).
   ================================================================== */
.stage{
  position:relative;
  height:520vh;
  background:var(--navy);
}
.stage-inner{
  position:sticky; top:0;
  height:100svh; overflow:hidden;
  display:flex; align-items:flex-end; justify-content:center;
  background:var(--navy);
  will-change:transform;
  transform:translateZ(0);
  cursor:default;
}

/* Ghost wordmark, sized in JS (js/main.js) so it always spans exactly
   65% of viewport width regardless of screen size. "Signal" lives here,
   bottom-anchored so 90% of it shows above the fold; "North" is its
   twin down in .light-zone, top-anchored, so the two halves of the
   name sit almost flush against the hard-cut line, only ever this
   faint. */
.ghost-wordmark{
  position:absolute; left:0;
  width:65%;
  font-family:var(--font-body); font-weight:600;
  letter-spacing:-0.01em; text-transform:uppercase;
  font-size:clamp(140px, 24vw, 460px);
  line-height:0.8;
  white-space:nowrap; user-select:none; pointer-events:none;
}
#ghostWordmark{
  bottom:0;
  color:rgba(255,255,255,0.02);
  transform:translateY(10%);
  transition:transform 2.6s cubic-bezier(0.19,1,0.22,1), color 2.6s ease;
}
/* One slow, one-time breath once the hold phase is reached — not a
   loop, just a single settle, like a photo finishing its exposure. */
#ghostWordmark.settle{
  transform:translateY(8%);
  color:rgba(255,255,255,0.04);
}
/* Quick brighten right as the seam crosses, then a slow fade back to
   resting — matched to .flash on #northWordmark below. */
#ghostWordmark.flash{
  color:rgba(255,255,255,0.22);
  transition:color 0.12s ease;
}
/* Grain "flashlight" — the same noise texture as .grain-flash, but
   masked to a soft circle that follows the cursor, dark hero only.
   Signal cutting through noise, literally: nothing to see until you
   move, and only right where you are. Experimental — may not keep it. */
.hero-grain{
  position:absolute; inset:0;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay;
  opacity:0;
  pointer-events:none;
  z-index:5;
  -webkit-mask-image:radial-gradient(circle 200px at var(--mx, 50%) var(--my, 50%), rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 100%);
  mask-image:radial-gradient(circle 200px at var(--mx, 50%) var(--my, 50%), rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 100%);
  transition:opacity 0.4s ease;
}

.scroll-cue{
  position:absolute; bottom:40px; left:50%;
  transform:translateX(-50%);
  animation:bob 2.6s ease-in-out infinite;
  transition:opacity 0.3s ease;
}
.scroll-cue svg{ display:block; opacity:0.85; }
@keyframes bob{
  0%,100%{ transform:translate(-50%,0); }
  50%{ transform:translate(-50%,8px); }
}

/* Both lines sit dead-center, stacked on top of each other, and are
   driven entirely by JS (opacity + scale) tied to scroll progress
   through .stage — see js/main.js. Font-size for .build is also set
   in JS so it always spans ~90% of viewport width at full size. */
.stage-text{
  position:absolute; top:50%; left:50%;
  width:100%; padding:0 24px;
  text-align:center; box-sizing:border-box;
  opacity:0; transform:translate(-50%,-50%) scale(0.5);
  will-change:opacity, transform;
}
.stage-text.build{
  z-index:2;
  font-family:var(--font-display); font-weight:600;
  line-height:1.05;
  color:var(--bone);
}
.build-line{ display:block; width:fit-content; margin:0 auto; white-space:nowrap; }
.stage-text.wedo{
  z-index:1;
  font-family:var(--font-display); font-weight:300; font-style:italic;
  font-size:clamp(16px, 1.6vw, 22px);
  color:var(--muted);
}

/* ---------- LIGHT ZONE (About + pull quote) ----------
   Background lives on this full-width wrapper, not on the inner text
   columns, so it runs edge to edge. Sits directly under .stage with
   nothing between them — the moment the pin releases, navy cuts hard
   to bone. */
.light-zone{
  position:relative;
  width:100%;
  background:var(--bone); color:var(--charcoal);
}
/* "North" — the other half of the wordmark, top-anchored so the
   visible 90% sits directly under where "Signal" cuts off above the
   line. Sits behind the copy; at this opacity it never competes with
   it. */
.north-wordmark-wrap{
  position:absolute; top:0; left:0; width:100%;
  height:clamp(160px, 26vw, 420px);
  overflow:hidden; pointer-events:none;
}
#northWordmark{
  top:0;
  color:rgba(43,38,32,0.045);
  transform:translateY(-10%);
  transition:color 1.8s ease;
}
#northWordmark.flash{
  color:rgba(43,38,32,0.24);
  transition:color 0.12s ease;
}
.about-copy{
  padding:180px 56px 0; max-width:760px; margin:0 auto;
}
.about-copy .about-title{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(26px, 3vw, 40px); line-height:1.15;
  margin:0 0 40px;
}
.about-copy p{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(19px, 1.9vw, 24px); line-height:1.65;
  margin:0 0 40px;
}
.fade-up{
  opacity:0; transform:translateY(18px);
  transition:opacity 0.9s ease, transform 0.9s ease;
}
.fade-up.in-view{ opacity:1; transform:translateY(0); }

/* Five words carrying the thesis — heart, feel, believe, change, heart —
   warm from ink to rust, same device as the hero's "heart." One per
   line, never two in the same sentence, so it reads as emphasis rather
   than a pattern. Triggered separately from the fade-up itself (see
   keyWordObserver in main.js) on a deeper scroll threshold, so the
   color lands after the line has already settled on screen rather
   than arriving at the same moment as the text. */
.key-word{ transition:color 1s ease; }
.key-word.key-word-active{ color:#AC482A; }
/* Pull-quote's stagger-word reveal and the key-word color transition
   need to coexist on the same span -- spelled out together so neither
   set of transitions clobbers the other. */
.stagger-word.key-word{ transition:opacity 0.6s ease, transform 0.6s ease, color 1s ease; }

.signature{
  font-family:var(--font-body); font-size:14px; color:var(--slate);
  letter-spacing:0.02em; margin-top:-8px;
}

.pull{
  padding:0 56px 160px; max-width:760px; margin:0 auto;
}
.pull-quote{
  margin:0; padding-left:32px; border-left:1px solid rgba(43,38,32,0.25);
  font-family:var(--font-display); font-style:italic; font-weight:300;
  font-size:clamp(24px, 3vw, 36px); line-height:1.4; color:var(--charcoal);
}
/* Each word starts invisible; JS gives every span its own
   transition-delay so the line arrives slowly, word by word. */
.stagger-word{
  display:inline-block; opacity:0; transform:translateY(10px);
  transition:opacity 0.6s ease, transform 0.6s ease;
}
.pull-quote.in-view .stagger-word{ opacity:1; transform:translateY(0); }

/* ---------- CONTACT ---------- */
.contact{
  background:var(--navy); color:var(--bone);
  padding:160px 56px 120px;
}
.contact-inner{ max-width:560px; margin:0 auto; text-align:left; }
.contact h2{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(38px, 5vw, 44px); margin:0 0 22px;
}
.contact p{
  font-size:16px; line-height:1.6; color:var(--muted);
  max-width:560px; white-space:nowrap; margin:0 0 48px;
}

.contact-form .field{ margin-bottom:28px; }
.contact-form label{
  display:block; font-size:11px; letter-spacing:0.08em;
  text-transform:uppercase; color:var(--muted); margin-bottom:8px;
}
.contact-form input,
.contact-form textarea{
  width:100%; background:transparent;
  border:none; border-bottom:1px solid rgba(247,243,234,0.25);
  color:var(--bone); font-family:var(--font-body); font-size:16px;
  padding:8px 0; outline:none; resize:vertical;
  transition:border-color 0.3s ease;
}
.contact-form textarea{ min-height:100px; }
.contact-form input:focus,
.contact-form textarea:focus{ border-bottom-color:var(--bone); }

.cta-btn{
  display:inline-flex; align-items:center; gap:10px;
  background:var(--bone); color:var(--navy); border:none;
  font-family:var(--font-body); font-weight:500; font-size:15px;
  padding:16px 30px; border-radius:2px; cursor:pointer;
  margin-top:8px;
  transition:transform 0.2s ease-out, background 0.25s ease;
}
.cta-btn:hover{ background:#fff; }
.cta-btn:disabled{ opacity:0.6; cursor:default; transform:none; }

footer{
  background:var(--navy); padding:32px 56px 44px;
  display:flex; justify-content:space-between; flex-wrap:wrap; gap:8px;
  font-size:11px; letter-spacing:0.04em; color:var(--muted-soft);
  border-top:1px solid rgba(247,243,234,0.08);
}

/* ---------- THANK YOU (post-submit landing page) ---------- */
.thanks{
  min-height:100vh; background:var(--navy); color:var(--bone);
  display:flex; flex-direction:column; align-items:flex-start; justify-content:center;
  padding:160px 56px 120px; max-width:560px; margin:0 auto;
}
.thanks h1{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(38px, 5vw, 44px); margin:0 0 22px;
}
.thanks p{
  font-size:16px; line-height:1.6; color:var(--muted);
  max-width:480px; margin:0 0 40px;
}

@media (max-width:820px){
  nav{ padding:22px 24px; }
  .navlinks{ display:none; }
  .logo-mark{ height:16px; }
  .about-copy, .pull, .contact, .thanks{ padding-left:28px; padding-right:28px; }
  .stage{ height:340vh; }
  /* Desktop's clamp floor (24px) is still too big for the <br>-forced
     line break at phone widths — each half wraps again on its own,
     turning the intended two lines into four. Sized down so each half
     holds its own line. */
  .pull-quote{ font-size:clamp(15px, 4.2vw, 19px); }
  /* The desktop nowrap on .contact p would force it edge-to-edge off
     screen on a phone -- hand it back to normal wrapping here. */
  .contact p{ white-space:normal; font-size:15px; max-width:100%; }
}
