/* ============================================================
   CloudSprint — aesthetic-full-concept stylesheet
   Concept C, "The Lantern on the Headland" (11-immersive-concept.md §2),
   attempted with REAL WebGL glass, not a CSS/SVG mood mockup.
   Scope of this pass: chapter 01 (Arrival) is a real three.js scene.
   Chapters 02-09 are deliberately plain, light HTML — same token
   system, no scene machinery — so it's obvious what's "real" here
   and what's still a placeholder for the other 8 of the 50-80
   specialist dev-days 11 §2 estimates for the full concept.
   ============================================================ */

:root {
  --ink:        #0D2A34;
  --ink-lift:   #143842;
  --porcelain:  #F1F5F5;
  --paper:      #FBFDFD;
  --amber:      #EC9A2E;
  --amber-deep: #B26A12;
  --aqua:       #9EC7CB;
  --slate:      #27373C;
  --slate-soft: #566269;
  --hair:       #D7E0E1;
  --hair-ink:   rgba(158,199,203,.22);

  /* 3D-only tonal ramp (11 §6.1/§6.2), used inside the hero scene only */
  --ramp-1: #1E4450;
  --ramp-2: #4F6F77;
  --ramp-3: #8FA9AD;
  --ramp-4: #C9D7D8;
  --dawn:   #F3E6D3;

  --serif: "Fraunces", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --sans:  "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono:  "Space Mono", ui-monospace, "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --measure: 65ch;
  --pad-x: clamp(20px, 5vw, 40px);
  --shadow-card: 0 1px 2px rgba(13,42,52,.06), 0 14px 40px rgba(13,42,52,.08);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ink); /* the scene no longer covers the whole page (see .webgl-layer) */
  color: var(--slate);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg { max-width: 100%; display: block; }
a { color: inherit; }

h1, h2, h3, .promise { font-family: var(--serif); font-weight: 400; color: var(--ink);
  letter-spacing: -.01em; line-height: 1.08; text-wrap: balance; font-optical-sizing: auto; }

.eyebrow {
  font-family: var(--mono); font-size: 15px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--slate-soft); margin: 0 0 16px;
}
.on-dark { color: var(--aqua) !important; }

.wrap { max-width: 1080px; margin: 0 auto; padding-inline: var(--pad-x); }
.section { padding-block: clamp(52px, 8vw, 96px); }
.lede { font-size: clamp(18px, 2.2vw, 21px); color: var(--slate); max-width: 60ch; }
.prose p { max-width: var(--measure); }
.hair { border: 0; border-top: 1px solid var(--hair); margin: 0; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: #fff; padding: 10px 16px;
  font-family: var(--mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
}
.skip:focus { left: 8px; top: 8px; }

/* ---- Lockup / nav (identical contract to the other two builds) ---- */
.lockup { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; }
.mark { width: 32px; height: 32px; flex: none; background: var(--ink-lift); border-radius: 6px;
  display: grid; align-content: center; gap: 3px; padding: 8px 7px; }
.mark i { display: block; height: 3px; border-radius: 2px; background: var(--amber); }
.mark i:nth-child(1) { width: 55%; opacity: .55; }
.mark i:nth-child(2) { width: 78%; opacity: .78; }
.mark i:nth-child(3) { width: 100%; }
.wm { font-family: var(--sans); font-size: 20px; color: var(--ink); letter-spacing: -.01em; }
.wm .l { font-weight: 400; } .wm .b { font-weight: 700; }
.wm.on-dark { color: #fff !important; }

.nav { position: sticky; top: 0; z-index: 100; background: rgba(251,253,253,.9);
  backdrop-filter: saturate(140%) blur(8px); border-bottom: 1px solid var(--hair); }
.nav.on-dark { background: rgba(13,42,52,.72); border-bottom-color: var(--hair-ink); }
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  max-width: 1080px; margin: 0 auto; padding: 14px var(--pad-x); }
.nav__links { display: flex; align-items: center; gap: 26px; }
.nav__links a { font-size: 15px; font-weight: 500; color: var(--slate); text-decoration: none; padding: 4px 0; }
.nav.on-dark .nav__links a { color: var(--aqua); }
.nav__links a:hover { color: var(--ink); }
.nav.on-dark .nav__links a:hover { color: #fff; }
.nav__toggle { display: none; background: none; border: 1px solid var(--hair); border-radius: 8px;
  width: 42px; height: 40px; cursor: pointer; align-items: center; justify-content: center; }
.nav__toggle span, .nav__toggle span::before, .nav__toggle span::after {
  content: ""; display: block; width: 18px; height: 2px; background: var(--ink); position: relative; }
.nav.on-dark .nav__toggle span, .nav.on-dark .nav__toggle span::before, .nav.on-dark .nav__toggle span::after { background: #fff; }
.nav__toggle span::before { position: absolute; top: -6px; }
.nav__toggle span::after { position: absolute; top: 6px; }
@media (max-width: 760px) {
  .nav__toggle { display: inline-flex; }
  .nav__links { display: none; position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: flex-start; gap: 4px;
    background: var(--paper); border-bottom: 1px solid var(--hair); padding: 12px var(--pad-x) 20px; }
  .nav.on-dark .nav__links { background: var(--ink-lift); }
  .nav__links.is-open { display: flex; }
  .nav__links a { padding: 10px 0; width: 100%; font-size: 16px; }
}

/* ---- Buttons ---- */
.btn { display: inline-flex; align-items: center; gap: 8px; font-family: var(--sans);
  font-size: 15px; font-weight: 600; padding: 13px 22px; border-radius: 10px;
  text-decoration: none; cursor: pointer; border: 1px solid transparent;
  transition: transform .15s ease, background .2s ease, border-color .2s ease; }
.btn--primary { background: var(--ink); color: #fff; }
.btn--primary:hover { background: var(--ink-lift); transform: translateY(-1px); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--hair); }
.btn--ghost:hover { border-color: var(--ink); }
.btn--on-dark { background: var(--amber); color: var(--ink); }
.btn--on-dark:hover { background: #f6ad4d; transform: translateY(-1px); }
.btn--ghost-on-dark { background: transparent; color: #fff; border-color: var(--hair-ink); }
.btn--ghost-on-dark:hover { border-color: #fff; }
.btn__arrow { font-weight: 700; }
.text-link { color: var(--ink); font-weight: 600; text-decoration: none; border-bottom: 2px solid var(--amber); }
.text-link:hover { color: var(--ink-lift); }

/* ============================================================
   The scene — now a FIXED, full-viewport layer behind the whole
   page, not just the hero. Follow-up from Lorenzo after seeing the
   first pass: "a flowing version of [the hero] into all page
   sections". The canvas renders continuously as you scroll; every
   section's copy sits in a .panel card on top of it so text never
   sits directly on the render (11 §6.2 / 03 §3 rule 1).
   ============================================================ */
.webgl-layer {
  /* SPLIT LAYOUT: the scene owns the right half, content scrolls in the
     left half (main is 50% wide below), so the portal is never behind a
     text card. Narrow screens restack — see the max-width: 900px block. */
  position: fixed; top: 0; right: 0; bottom: 0; width: 50%; z-index: -1;
  background: linear-gradient(180deg, var(--ink) 0%, var(--ramp-1) 55%, var(--ramp-2) 100%);
}
/* Soft seam: the scene fades in from the content column's ink instead of
   meeting it at a hard 50/50 edge. */
.webgl-layer::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 26%; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg, var(--ink) 0%, rgba(13,42,52,.7) 35%, rgba(13,42,52,0) 100%);
}
/* ---- Portal spill across the seam (see assets/spill-config.js) ---- */
/* Lens spill: the canvas is wider than its half; its left edge fades in from
   nothing, is only dimly present at the seam (--spill-a, driven per frame by
   lens-scene.js so it grows with the portal), and reaches full strength a
   little way into the right half. Replaces the ::before ink fade. */
html[data-spill-lens="on"] .webgl-layer::before { display: none; }
/* The layer's own opaque backdrop would end in a hard edge at the seam (the
   dimly spilled scene to its left has nothing behind it but the page ink), so
   once the scene is running the canvas' sky is the only backdrop. */
html.scene-active[data-spill-lens="on"] .webgl-layer { background: none; }
html[data-spill-lens="on"] #lens-canvas {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, rgba(0,0,0,var(--spill-a, .2)) var(--spill-lens-px), #000 calc(var(--spill-lens-px) + 14%));
  mask-image: linear-gradient(90deg, transparent 0, rgba(0,0,0,var(--spill-a, .2)) var(--spill-lens-px), #000 calc(var(--spill-lens-px) + 14%));
}
/* Glow spill: a warm radial light centred on the seam, screen-blended so it
   brightens both the ink column and the scene edge continuously. Reach and
   opacity are set per frame from the portal's brightness. */
.spill-glow {
  display: none; position: fixed; top: 0; bottom: 0;
  left: calc(50% - var(--spill-reach-px, 0px));
  width: calc(var(--spill-reach-px, 0px) * 2); /* symmetric about the seam so the gradient never meets a clipped box edge */
  z-index: -1; pointer-events: none; opacity: 0;
  transform-origin: 50% 50%; mix-blend-mode: screen;
  background: radial-gradient(ellipse 50% 58% at 50% 42%, rgba(255,196,120,.6) 0%, rgba(236,154,46,.3) 38%, rgba(236,154,46,0) 100%);
}
html[data-spill-glow="on"] .spill-glow { display: block; }
@media (max-width: 900px) { .spill-glow { display: none !important; } }

/* Tuning panel */
.spill-toggle {
  position: fixed; right: 16px; bottom: 16px; z-index: 200;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  background: rgba(13,42,52,.9); color: var(--ramp-4); border: 1px solid var(--hair-ink);
  border-radius: 999px; padding: 8px 14px; cursor: pointer; backdrop-filter: blur(6px);
}
.spill-toggle:hover, .spill-toggle[aria-expanded="true"] { border-color: var(--amber); color: #fff; }
.spill-panel {
  position: fixed; right: 16px; bottom: 60px; z-index: 200; width: min(320px, calc(100vw - 32px));
  background: rgba(13,42,52,.95); color: var(--ramp-4); border: 1px solid var(--hair-ink);
  border-radius: 14px; padding: 16px; backdrop-filter: blur(8px); box-shadow: 0 20px 60px rgba(0,0,0,.4);
  font-size: 13px; line-height: 1.45;
}
.spill-panel[hidden] { display: none; }
.spill-panel__title { margin: 0 0 12px; font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: #fff; }
.spill-panel__group { border: 0; margin: 0 0 12px; padding: 0; }
.spill-panel__legend { display: block; padding: 0; margin-bottom: 6px; font-size: 12px; color: var(--aqua); }
.spill-panel__row { display: flex; flex-wrap: wrap; gap: 6px; }
.spill-panel__opt, .spill-panel__reset {
  font: inherit; font-size: 12px; color: var(--ramp-4); background: transparent;
  border: 1px solid var(--hair-ink); border-radius: 8px; padding: 6px 10px; cursor: pointer;
}
.spill-panel__opt:hover, .spill-panel__reset:hover { border-color: var(--aqua); color: #fff; }
.spill-panel__opt[aria-pressed="true"] { background: var(--amber); border-color: var(--amber); color: var(--ink); font-weight: 600; }
.spill-panel__out { color: #fff; font-family: var(--mono); }
.spill-panel__slider { width: 100%; accent-color: var(--amber); }
.spill-panel__note { margin: 12px 0 0; font-size: 11.5px; color: var(--ramp-3); }

main { width: 50%; }
#lens-canvas {
  /* Normally exactly the layer; with lens spill on, --spill-lens-px (set by
     assets/spill-config.js) widens it leftward past the seam. The camera in
     lens-scene.js is offset by half that so the portal stays centred on the
     right half. */
  position: absolute; top: 0; bottom: 0;
  left: calc(-1 * var(--spill-lens-px, 0px));
  width: calc(100% + var(--spill-lens-px, 0px));
  height: 100%; display: block;
  opacity: 0; transition: opacity 1.1s ease;
}
#lens-canvas.is-ready { opacity: 1; }

/* Poster: shown until (and unless) the real scene takes over, and
   permanently for reduced-motion / no-WebGL2 visitors. Same
   information content as the canvas (i.e. none — it's decorative). */
.hero__poster {
  position: absolute; inset: 0; display: grid; place-items: center;
  transition: opacity .6s ease;
}
.hero__poster svg { width: min(70%, 480px); height: auto; }
html.scene-active .hero__poster { opacity: 0; pointer-events: none; }

.hero-webgl, .section { background: transparent; }
.hero-webgl {
  position: relative; /* anchors .hero__caption below */
  min-height: 100vh;
  min-height: 100svh;
  color: var(--porcelain);
}

.hero__panel {
  position: relative; z-index: 2;
  max-width: 640px;
  margin: 0 auto;
  padding: clamp(96px, 16vw, 160px) var(--pad-x) clamp(64px, 10vw, 96px);
}

/* Generic dark panel for every non-hero chapter, now that the scene
   shows through everywhere instead of stopping after the hero. Ties back
   to the portal: a soft amber-tinted glow on the edge nearest the viewer,
   as if lit by the light you just travelled through, plus a settle-in
   reveal timed to the same scroll that drives the camera (assets/reveal.js)
   so the content feels delivered by the tunnel, not just laid over it. */
.panel {
  position: relative; z-index: 2;
  background: rgba(13,42,52,.86);
  border: 1px solid var(--hair-ink);
  border-radius: 18px;
  padding: clamp(28px, 4vw, 44px);
  backdrop-filter: blur(2px);
  color: var(--ramp-4);
  box-shadow: 0 30px 80px rgba(0,0,0,.35);
}
/* Hidden-then-revealed state only applies once reveal.js confirms it's
   running (progressive enhancement — see the comment there). Without JS,
   .panel keeps the plain visible styling above. */
.js-reveal .panel {
  opacity: 0;
  transform: scale(.94) translateY(28px);
  transition: opacity .8s ease, transform .8s cubic-bezier(.16,.8,.3,1), box-shadow 1s ease;
}
.js-reveal .panel.is-visible {
  opacity: 1;
  transform: none;
  box-shadow: 0 0 60px rgba(236,154,46,.08), 0 30px 80px rgba(0,0,0,.35);
}
.panel h2, .panel h3 { color: #fff; }
.panel strong { color: #fff; }
.panel .eyebrow, .panel .lede { color: var(--aqua); }
.panel .confirm { background: rgba(236,154,46,.24); color: #ffd9a0; }
.panel .not-built { background: rgba(255,255,255,.08); color: var(--ramp-4); }
.panel .text-link { color: #fff; border-bottom-color: var(--amber); }
.panel .disclosure { background: rgba(255,255,255,.05); border-color: var(--hair-ink); }
.panel .disclosure__btn:hover { background: rgba(255,255,255,.08); }
.panel .disclosure__label { color: #fff; }
.panel .disclosure__teaser { color: var(--ramp-4); }
.panel .lane__stage { border-color: var(--hair-ink); }
.panel .lane__time { color: #fff; }
.panel .grid-2 h3 { color: #fff; }
.panel a { color: inherit; }
/* Status tags were tuned for light cards; on the dark .panel background
   they need their own contrast, not the light-mode versions above. */
.panel .tag--belief { background: rgba(158,199,203,.22); color: var(--ramp-4); }
.panel .tag--hypothesis { background: rgba(255,255,255,.12); color: var(--ramp-4); }
.panel .tag--how-we-work { background: rgba(236,154,46,.22); color: #ffd9a0; }
.panel .tag--our-practice { background: rgba(158,199,203,.16); color: #fff; }
.hero__panel-inner {
  background: rgba(13,42,52,.86);
  border: 1px solid var(--hair-ink);
  border-radius: 18px;
  padding: clamp(28px, 4vw, 40px);
  backdrop-filter: blur(2px);
}
.hero__promise { color: #fff; font-size: clamp(38px, 6.5vw, 66px); margin: 0 0 20px; max-width: 15ch; }
.hero__sub { color: var(--aqua); font-size: clamp(17px, 2vw, 20px); max-width: 52ch; margin: 0 0 28px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
.hero__micro { color: var(--ramp-4); font-size: 14px; margin: 0 0 20px; }

.motion-toggle {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  background: transparent; color: var(--ramp-4); border: 1px solid var(--hair-ink);
  border-radius: 999px; padding: 7px 14px; cursor: pointer;
}
.motion-toggle:hover { border-color: var(--aqua); color: #fff; }
.scroll-hint {
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ramp-4); margin: 22px 0 0;
}
.scroll-hint::after { content: ""; display: block; width: 1px; height: 22px; margin-top: 8px;
  background: linear-gradient(var(--aqua), transparent); }
@media (prefers-reduced-motion: reduce) { .scroll-hint::after { display: none; } }

.hero__caption {
  position: absolute; left: var(--pad-x); bottom: 18px; z-index: 2;
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  color: var(--ramp-4); opacity: .75; max-width: 46ch;
}

/* ============================================================
   Plain content below the hero — same light system as flat/
   ============================================================ */
.band-ink { background: var(--ink); color: var(--porcelain); }
.band-ink h2, .band-ink h3 { color: #fff; }
.band-ink p { color: var(--aqua); }

.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
@media (max-width: 720px) { .grid-2 { grid-template-columns: 1fr; } }

.fit-list { margin: 0; padding-left: 22px; }
.fit-list li { margin-bottom: 8px; }

.lane { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }
.lane__stage { border-top: 1px solid var(--hair); padding: 20px 0; display: grid; grid-template-columns: 200px 1fr; gap: 20px; }
.lane__stage:last-child { border-bottom: 1px solid var(--hair); }
.lane__time { font-family: var(--serif); font-size: 20px; color: var(--ink); }
.lane__verb { display: block; font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--amber-deep); margin-top: 4px; }
.lane__body p { margin: 0; max-width: 50ch; }
@media (max-width: 640px) { .lane__stage { grid-template-columns: 1fr; } }

/* Disclosure (thesis objects) — plain, no 3D here by design */
.disclosure { border: 1px solid var(--hair); border-radius: 12px; margin-bottom: 12px; overflow: hidden; background: var(--paper); }
.disclosure__btn { width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  padding: 16px 18px; display: flex; flex-direction: column; gap: 6px; font: inherit; color: inherit; }
.disclosure__btn:hover { background: var(--porcelain); }
.tag { display: inline-block; font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; padding: 3px 9px; border-radius: 999px; width: max-content; }
.tag--belief { background: rgba(158,199,203,.28); color: var(--ink-lift); }
.tag--hypothesis { background: rgba(39,55,60,.10); color: var(--slate); }
.tag--how-we-work { background: rgba(236,154,46,.16); color: var(--amber-deep); }
.tag--our-practice { background: rgba(13,42,52,.10); color: var(--ink); }
.disclosure__label { font-family: var(--serif); font-size: 19px; color: var(--ink); }
.disclosure__teaser { font-size: 14.5px; color: var(--slate-soft); }
.disclosure__panel { padding: 0 18px 20px; }
.disclosure__panel p { margin: 0; max-width: var(--measure); }

.confirm {
  font-family: var(--mono); font-size: .82em; letter-spacing: .04em;
  background: rgba(236,154,46,.16); color: #8a5209; padding: 1px 6px; border-radius: 4px; /* wraps: long [confirm: ...] tags overflowed the half-width column */
}
.not-built { font-family: var(--mono); font-size: .78em; letter-spacing: .04em;
  background: rgba(39,55,60,.08); color: var(--slate-soft); padding: 1px 6px; border-radius: 4px; }

.footer { background: var(--ink); color: var(--aqua); }
.footer__inner { max-width: 1080px; margin: 0 auto; padding: 48px var(--pad-x); }
.footer__tagline { font-family: var(--serif); font-size: 20px; color: #fff; max-width: 40ch; margin: 0 0 30px; }
.footer__groups { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; }
@media (max-width: 860px) { .footer__groups { grid-template-columns: repeat(2, 1fr); } }
.footer__group h4 { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ramp-4); margin: 0 0 12px; font-weight: 400; }
.footer__group ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.footer__group a { color: var(--aqua); text-decoration: none; font-size: 14.5px; }
.footer__group a:hover { color: #fff; }
.footer__location { font-size: 14.5px; margin: 0 0 12px; }
.footer__location strong { display: block; color: #fff; font-size: 12px; text-transform: uppercase;
  letter-spacing: .08em; font-family: var(--mono); margin-bottom: 4px; }
.footer__meta { margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--hair-ink);
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  display: flex; flex-wrap: wrap; gap: 12px 24px; justify-content: space-between; color: var(--aqua); }

a:focus-visible, button:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* ============================================================
   Split-layout adjustments. The content column is now half the
   viewport, so two-column inner grids collapse earlier than their
   viewport-based breakpoints would.
   ============================================================ */
@media (min-width: 901px) {
  .grid-2 { grid-template-columns: 1fr; }
  .lane__stage { grid-template-columns: 1fr; }
}
@media (min-width: 1500px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .lane__stage { grid-template-columns: 200px 1fr; }
}

/* ---- Narrow screens: scene becomes a sticky strip under the nav, content
   scrolls beneath it (the strip has to sit ABOVE content here, so it gets
   a real z-index and an opaque background instead of z-index: -1). ---- */
@media (max-width: 900px) {
  :root { --nav-h: 68px; --strip-h: 40svh; }
  html { scroll-padding-top: calc(var(--nav-h) + var(--strip-h) + 12px); }
  .webgl-layer {
    top: var(--nav-h); left: 0; right: 0; bottom: auto; width: auto; height: var(--strip-h);
    z-index: 5; border-bottom: 1px solid var(--hair-ink);
  }
  .webgl-layer::before { display: none; }
  main { width: auto; margin-top: var(--strip-h); }
}
