/* =========================================================================
   SECTIONS — layout only. All colour, type and motion values come from
   tokens.css; all repeated visual treatments come from components.css.
   ========================================================================= */

/* ---- 00 · Nav ---------------------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-nav);
  background: color-mix(in oklab, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: border-color var(--d-state) var(--e-soft),
              background-color var(--d-state) var(--e-soft);
}
.nav.is-stuck { border-bottom-color: var(--border-subtle); }
.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  height: 60px;
}
.nav__mark {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-2);
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: var(--tr-tight);
  color: var(--ink);
  text-decoration: none;
}
.nav__mark span { color: var(--accent-ink); }
.nav__links { display: none; gap: var(--s-5); }
@media (min-width: 860px) { .nav__links { display: flex; } }
.nav__link {
  position: relative;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: var(--ink-meta);
  text-decoration: none;
  padding: var(--s-2) 0;
  transition: color var(--d-micro) var(--e-soft);
}
.nav__link:hover, .nav__link[aria-current="true"] { color: var(--ink); }
.nav__link[aria-current="true"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--accent);
}
.nav__actions { display: flex; align-items: center; gap: var(--s-3); }
.nav__progress {
  position: absolute;
  left: 0; bottom: -1px;
  height: 1px;
  width: 100%;
  transform-origin: left;
  transform: scaleX(var(--scroll-progress, 0));
  background: var(--accent);
}
/* Where the browser supports it, the progress bar runs entirely on the
   compositor off a scroll timeline — no scroll handler, no main-thread work,
   no frame the JS can drop. The JS custom property above stays as the
   fallback, so nothing is lost on older engines. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .nav__progress {
      transform: scaleX(0);
      animation: nav-progress linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes nav-progress { to { transform: scaleX(1); } }
  }
}
.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 44px; height: 44px;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  color: var(--ink-secondary);
  cursor: pointer;
  transition: color var(--d-micro) var(--e-soft),
              border-color var(--d-micro) var(--e-soft);
}
.icon-btn:hover { color: var(--ink); border-color: var(--border-subtle); }
.icon-btn svg { width: 17px; height: 17px; }

/* ---- 01 · Hero --------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: 100px;
  padding-bottom: var(--s-7);
  border-top: 0;
}
.hero__eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: clamp(var(--s-5), 4vw, var(--s-8));
}
.hero__title {
  font-family: var(--font-display);
  font-size: var(--t-hero);
  font-weight: 500;
  line-height: var(--lh-tight);
  letter-spacing: -0.045em;
  margin-bottom: clamp(var(--s-5), 4vw, var(--s-7));
}
.hero__title em {
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink-secondary);
}
.hero__title .dot { color: var(--accent-ink); }

/* Below 700px each phrase deliberately breaks after the noun, so the mask
   lines still map to visual lines instead of wrapping mid-phrase. */
@media (max-width: 700px) {
  .hero__title { font-size: clamp(2rem, 1rem + 6vw, 3rem); letter-spacing: -0.035em; line-height: 1.02; }
  .hero__title em { display: block; }
  .line { padding-bottom: 0.16em; margin-bottom: -0.16em; }
}

/* Line mask: each line rides up from behind its own clipping box.
   padding/margin pair keeps descenders from being sheared. */
.line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}
.line__inner { display: block; }
.js .line__inner {
  transform: translateY(105%);
  opacity: 0;
  transition: transform 900ms var(--e-out), opacity 700ms var(--e-out);
  transition-delay: var(--line-delay, 0ms);
}
.js .is-lit .line__inner { transform: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .js .line__inner { transform: none; opacity: 1; }
}

.hero__lead {
  max-width: 54ch;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--ink-secondary);
}
.hero__lead b { color: var(--ink); font-weight: 500; }
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
}
.hero__stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5) var(--s-4);
  margin-top: clamp(var(--s-7), 7vw, var(--s-9));
  padding-top: var(--s-5);
  border-top: 1px solid var(--border-subtle);
}
@media (min-width: 760px) {
  .hero__stats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5); }
}
.hero__scroll {
  display: none;
  position: absolute;
  right: var(--gutter);
  bottom: var(--s-6);
  align-items: center;
  gap: var(--s-3);
  writing-mode: vertical-rl;
}
@media (min-width: 1100px) { .hero__scroll { display: flex; } }
.hero__scroll::after {
  content: "";
  width: 1px; height: 56px;
  background: linear-gradient(var(--accent), transparent);
}

/* ---- 02 · Pillars ------------------------------------------------------
   A night plate. The stage carries .plate-night, so every token inside it
   is the dark set in both themes; in the light theme it reads as a dark
   band across the page, by design — the sky is a night sky.

   The sky image has its darks graded onto --n-000 at build time (BUILD.md),
   so its field IS the page colour and the masked edges have nothing to
   seam against. Change the page colour and that grade has to be redone. */
.value { padding-block: 0; }
.value__stage {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-block: var(--section-y) clamp(var(--s-8), 6vw, var(--s-10));
  background: var(--bg);
  color: var(--ink);
}
.value__sky {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: 72% 0%;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 78%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 78%, transparent);
}
/* On a phone the stage is four cards tall. `cover` would blow the sky up to
   fit that height, so the sky goes back to its own proportions, pinned
   top-right, and the planet sits beside the heading instead. */
@media (max-width: 719px) {
  .value__sky {
    inset: 0 0 auto auto;
    width: 230%;
    height: auto;
    aspect-ratio: 1752 / 898;
    object-fit: fill;
    translate: 22% -2%;
    opacity: 0.85;
    -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 92%);
            mask-image: linear-gradient(to bottom, #000 40%, transparent 92%);
  }
}

.value__head { margin-bottom: clamp(var(--s-6), 4vw, var(--s-8)); }
.value__title { max-width: none; }
.value__title em {
  display: block;
  font-weight: 400;
  letter-spacing: -0.01em;
  /* The serif's italic sits visually smaller than Inter Tight at the same
     size; this brings its x-height up to meet the line above. */
  font-size: 1.12em;
  line-height: 1;
}

.pillars {
  display: grid;
  gap: var(--s-4);
}
@media (min-width: 640px)  { .pillars { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .pillars { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* The lit card. With no pointer on the grid the first one is lit, so the
   row has a point of entry; once the pointer is on any card, that card
   takes the light and the first lets it go. Touch keeps the first. */
.pillar {
  --lit: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  min-width: 0;
  padding: clamp(var(--s-5), 2.2vw, var(--s-6));
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-3);
  background:
    radial-gradient(90% 60% at 0% 100%, color-mix(in srgb, var(--accent) calc(var(--lit) * 12%), transparent), transparent 70%),
    linear-gradient(to bottom, color-mix(in srgb, var(--ink) 3%, transparent), transparent 40%),
    color-mix(in srgb, var(--bg-raised) 82%, transparent);
  transition: border-color var(--d-state) var(--e-soft), box-shadow var(--d-state) var(--e-soft);
}
.pillars:not(:has(.pillar:hover)) .pillar:first-child,
.pillar:hover,
.pillar:focus-within {
  --lit: 1;
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent),
              0 24px 60px -30px color-mix(in srgb, var(--accent) 45%, transparent);
}
/* --lit is a number, not a colour, so it can't transition — the radial
   glow swaps. It is 12% of the accent in one corner; the border carries
   the motion. */

.pillar__art {
  position: absolute;
  top: var(--s-3);
  right: var(--s-3);
  z-index: 0;
  width: auto;
  height: clamp(6.5rem, 9vw, 8.25rem);
  pointer-events: none;
  translate: 0 0;
  transition: translate var(--d-enter) var(--e-expo), scale var(--d-enter) var(--e-expo);
}
.pillar:hover .pillar__art { translate: 0 -6px; scale: 1.04; }

.pillar__head,
.pillar__title,
.pillar__body,
.pillar__proof { position: relative; z-index: 1; }

.pillar__head {
  display: grid;
  gap: var(--s-4);
  justify-items: start;
  /* Reserves the tile's height so the title always starts below the glass. */
  min-height: clamp(6rem, 8vw, 7.25rem);
  align-content: start;
}
.pillar__num {
  font-size: var(--t-small);
  letter-spacing: 0.08em;
  color: var(--ink-meta);
  transition: color var(--d-state) var(--e-soft);
}
.pillars:not(:has(.pillar:hover)) .pillar:first-child .pillar__num,
.pillar:hover .pillar__num { color: var(--accent-ink); }

.pillar__title {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: 500;
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-tight);
  text-wrap: balance;
}
.pillar__body {
  color: var(--ink-secondary);
  font-size: var(--t-small);
  line-height: 1.6;
  text-wrap: pretty;
}
.pillar__proof {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: auto;
  padding-top: var(--s-5);
  border-top: 1px solid var(--border-subtle);
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
.pillar__proof span { text-wrap: balance; }
.pillar__proof b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {
  .pillar__art { transition: none; }
  .pillar:hover .pillar__art { translate: none; scale: none; }
}

/* A visible, deliberate gap marker for content still to be supplied. */
.todo-note {
  margin-top: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border: 1px dashed var(--accent-line);
  border-radius: var(--r-2);
  background: var(--accent-soft);
  color: var(--ink-secondary);
  font-size: var(--t-small);
  max-width: 62ch;
}

/* ---- 09 · About -------------------------------------------------------- */
.about { display: grid; gap: clamp(var(--s-6), 4vw, var(--s-8)); }
@media (min-width: 900px) { .about { grid-template-columns: 0.8fr 1.2fr; } }
/* The illustration carries its own circular edge, so the slot adds no frame
   of its own — a card behind a circle would read as two competing shapes. */
.about__portrait {
  margin: 0;
  aspect-ratio: 1;
  align-self: start;
  position: sticky;
  top: 96px;
}
.about__portrait img {
  width: 100%;
  height: auto;
  border-radius: 50%;
}
@media (max-width: 899px) { .about__portrait { position: static; max-width: 300px; } }
.about__copy { display: grid; gap: var(--s-5); max-width: var(--measure); }
.about__copy p { color: var(--ink-secondary); }
.about__copy p b { color: var(--ink); font-weight: 500; }

/* ---- 10 · Contact ------------------------------------------------------ */
.contact { text-align: left; }
.contact__big {
  display: inline-block;
  font-family: var(--font-display);
  font-size: clamp(1.85rem, 0.6rem + 6.2vw, 6rem);
  font-weight: 500;
  letter-spacing: -0.045em;
  line-height: 1.05;
  color: var(--ink);
  text-decoration: none;
  word-break: break-word;
  transition: color var(--d-state) var(--e-soft);
}
.contact__big:hover { color: var(--accent-ink); }
/* Magnetic wrapper: pointer-driven translate, capped at 10px. */
.magnetic { display: inline-block; will-change: transform; }
.contact__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: clamp(var(--s-6), 4vw, var(--s-8));
}

/* ---- Footer ------------------------------------------------------------ */
.footer {
  border-top: 1px solid var(--border-subtle);
  padding-block: var(--s-6);
}
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  align-items: center;
}

