/* ============================================================
   LAYOUT, container, section rhythm, grids, scroll rail
   ============================================================ */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide { max-width: var(--container-wide); }
.container--text { max-width: var(--container-text); }

/* Section rhythm. One rule owns vertical padding so nothing fights it. */
.section {
  position: relative;
  padding-block: var(--section-y);
}
.section--tight { padding-block: var(--section-y-sm); }
.section--flush-top { padding-top: 0; }

.section--paper { background: var(--paper); }
.section--band  { background: var(--paper-2); }
.section--dark  { background: var(--ink); color: var(--on-dark); }
.section--dark h1, .section--dark h2, .section--dark h3, .section--dark h4 { color: var(--on-dark); }

/* Hairline divider that sits at the very top of a section */
.section--ruled { border-top: 1px solid var(--line); }
.section--dark.section--ruled { border-top-color: var(--line-dark); }

/* ---------- Section header block ---------- */
.s-head {
  display: grid;
  gap: clamp(1.25rem, 2.4vw, 2rem);
  margin-bottom: clamp(3rem, 6vw, 5.5rem);
}
.s-head__title { max-width: 20ch; }
.s-head--split {
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: end;
  column-gap: clamp(2rem, 6vw, 6rem);
}
@media (max-width: 900px) {
  .s-head--split { grid-template-columns: 1fr; align-items: start; }
}

/* ---------- Generic two-column split ---------- */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

/* ============================================================
   SIGNATURE, the connection rail
   A hairline down the left edge that fills as you scroll, with a
   node at every section. It is the site's one visual motif:
   separate parts, one connected line.
   ============================================================ */

.rail {
  position: fixed;
  top: 0;
  left: max(18px, calc((100vw - var(--container-wide)) / 2 + 18px));
  height: 100vh;
  width: 1px;
  z-index: 40;
  pointer-events: none;
  display: none;
}
.rail__track {
  position: absolute;
  inset: 0;
  background: var(--line);
  opacity: 0.9;
}
.rail__fill {
  position: absolute;
  top: 0; left: 0;
  width: 1px;
  height: 0;
  background: var(--bronze);
  transition: height 120ms linear;
}
.rail__nodes {
  position: absolute;
  inset: 0;
}
.rail__node {
  position: absolute;
  left: 50%;
  width: 5px; height: 5px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--line-strong);
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.rail__node.is-passed { background: var(--bronze); }
.rail__node.is-current { transform: scale(1.9); background: var(--bronze); }

/* Rail inverts over dark sections */
.rail.is-over-dark .rail__track { background: var(--line-dark-2); }
.rail.is-over-dark .rail__node  { background: rgba(255,255,255,0.22); }
.rail.is-over-dark .rail__fill,
.rail.is-over-dark .rail__node.is-passed,
.rail.is-over-dark .rail__node.is-current { background: var(--bronze-lite); }

@media (min-width: 1180px) {
  .rail { display: block; }
}

/* ---------- Scroll reveal (used by js/reveal.js) ---------- */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}
