/* =========================================================================
   THE PATH — one role pinned, one idea at a time.

   Each .role is a tall scroll track. Its .role__stage pins to the viewport
   while the beats inside cross-fade. The DOM is identical in every mode:
   when pinning is off (narrow screens, reduced motion, no JS) the same
   markup simply stacks and reads as a normal list.
   ========================================================================= */

.path { display: grid; }

.role {
  position: relative;
  /* One viewport of scroll per beat, plus one to read the last one. */
  /* Per-beat scroll cost. At 78vh the path was 16,000px — 61% of the whole
     page, and ~18 screens before the first case study. One sentence does not
     need three quarters of a screen to land. */
  min-height: calc((var(--beats, 3) + 0.35) * var(--beat-scroll, 46vh));
}

.role__stage {
  position: sticky;
  top: 0;
  /* A fixed height, not a minimum: the tallest beat must not push the stage
     past the viewport it is pinned to. */
  height: 100vh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: var(--s-6);
  padding-block: clamp(var(--s-6), 8vh, var(--s-8));
}

/* ---- The headline that does not move ---------------------------------- */
.role__head {
  display: grid;
  gap: var(--s-2);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--border-subtle);
}
.role__years { color: var(--accent-ink); }
.role__org {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 1.4rem + 4.4vw, 5.5rem);
  font-weight: 500;
  line-height: 0.98;
  letter-spacing: var(--tr-tight);
}
.role__title {
  font-family: var(--font-edit);
  font-style: italic;
  font-size: var(--t-lead);
  color: var(--ink-secondary);
}
.role__title .mono { font-style: normal; }

/* ---- Beats ------------------------------------------------------------ */
.role__beats { position: relative; display: grid; align-items: center; min-height: 0; }
.beat {
  grid-area: 1 / 1;
  display: grid;
  align-content: center;
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--d-enter) var(--e-out),
              transform var(--d-enter) var(--e-out);
  pointer-events: none;
}
.beat.is-active { opacity: 1; transform: none; pointer-events: auto; }

/* The type is the point of this section — it is allowed to be large. */
.beat__lead,
.beat__text {
  font-size: clamp(1.4rem, 0.95rem + 1.7vw, 2.35rem);
  line-height: 1.22;
  letter-spacing: -0.02em;
  max-width: 20ch;
  text-wrap: balance;
}
.beat__lead { max-width: 24ch; }

/* ---- Emphasis ----------------------------------------------------------
   Three steps, the same three the rest of the page uses. The sentence sits
   back in the secondary ink; <b> is the subject, in full ink; <em> is the
   turn, in the serif and the accent, at most one a beat. With the sentence
   and its <b> both in --ink (as they were) the bold was a weight change at
   display size and nothing else.

   The role's opening beat carries the pen mark (stage.css) under its turn,
   one a role. */
.beat__lead,
.beat__text { color: var(--ink-secondary); }
.beat__lead b,
.beat__text b { font-weight: 500; color: var(--ink); }
.beat__lead em,
.beat__text em {
  font-family: var(--font-edit);
  font-style: italic;
  font-weight: 400;
  font-size: 1.12em;      /* the serif's x-height meets the sans beside it */
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--accent-ink);
}

/* The highlights land after the sentence does: the beat fades up plain,
   then the subject brightens, then the turn takes its colour, then the pen
   draws. Unpinned, every beat is active from the start and none of this
   runs. */
.js .beat b  { transition: color 480ms var(--e-out) 240ms; }
.js .beat em { transition: color 480ms var(--e-out) 400ms; }
.js .beat:not(.is-active) b,
.js .beat:not(.is-active) em { color: var(--ink-secondary); transition-delay: 0ms; }
.js .beat .pen[data-reveal]::after { transition-delay: 620ms; }
.js .beat:not(.is-active) .pen[data-reveal]::after {
  clip-path: inset(0 100% 0 0);
  transition-delay: 0ms;
}
@media (prefers-reduced-motion: reduce) {
  .js .beat b, .js .beat em { transition: none; }
}

.beat__art {
  width: min(20rem, 100%);
  margin-bottom: var(--s-5);
  color: var(--ink-secondary);
}
.beat__art .gfx { width: 100%; height: auto; }

/* A rendered picture in place of a line drawing (summaryArt, or a point's
   `shot`). It
   is capped by height as well as width: the stage it sits in is pinned to
   one viewport. */
.beat__art--shot { width: min(26rem, 100%); }
.beat__art--shot img {
  display: block;
  width: 100%;
  height: auto;
  max-height: var(--shot-max, none);
  object-fit: contain;
}

/* An optional "go and look at the real thing" link under a beat. Evidence
   beats a claim, and it costs one line instead of a paragraph. */
.beat__link {
  grid-column: 1 / -1;
  justify-self: start;
  display: inline-flex; align-items: center; gap: var(--s-2);
  margin-top: var(--s-4);
  padding-bottom: 2px;
  color: var(--ink-secondary);
  border-bottom: 1px solid var(--border);
  transition: color var(--d-state) var(--e-soft),
              border-color var(--d-state) var(--e-soft);
}
.beat__link:hover,
.beat__link:focus-visible { color: var(--accent); border-bottom-color: var(--accent); }
.beat__link-arrow { color: var(--accent); font-size: 0.9em; line-height: 1; }

/* Side by side for the whole pinned range: stacking art above 3-line display
   type overflows a pinned 100vh stage. Keyed to 900px so it turns on exactly
   when pinning does, not 200px later. */
@media (min-width: 900px) {
  .beat {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
    /* Column gap only — a row gap this size strands the beat link far below
       the sentence it belongs to. */
    column-gap: clamp(var(--s-6), 4vw, var(--s-8));
    row-gap: 0;
    align-items: center;
  }
  .beat > .beat__art { margin-bottom: 0; width: 100%; }
  /* Sit under the text, not under the drawing. */
  .beat__art ~ .beat__link { grid-column: 2; }
  .beat__art + .beat__lead { grid-column: auto; }
  .beat__art--shot { --shot-max: 46vh; }
  .beat__lead,
  .beat__close,
  .beat__evidence { grid-column: 1 / -1; }
}

.beat__evidence { display: grid; gap: var(--s-5); }
@media (min-width: 900px) { .beat__evidence { grid-template-columns: repeat(3, 1fr); } }

/* ---- Closing beat ----------------------------------------------------- */
.beat__close { display: grid; gap: var(--s-5); align-content: center; min-height: 0; }
.beat__more {
  display: flex; align-items: center; gap: var(--s-3);
  padding-top: var(--s-5);
  border-top: 1px solid var(--border-subtle);
  color: var(--ink-meta);
}
.beat__more-arrow {
  width: 1px; height: 18px; background: var(--border);
  position: relative;
}
.beat__more-arrow::after {
  content: ""; position: absolute; left: -3px; bottom: 0;
  width: 7px; height: 7px;
  border-left: 1px solid var(--border); border-bottom: 1px solid var(--border);
  transform: rotate(-45deg); transform-origin: bottom left;
}

/* ---- Progress dots ---------------------------------------------------- */
.role__dots { display: flex; gap: var(--s-2); align-items: center; padding: 0; margin: 0; }
.role__dots li {
  width: 22px; height: 2px; border-radius: 2px;
  background: var(--border);
  transition: background var(--d-state) var(--e-soft);
}
.role__dots li.is-on { background: var(--accent); }

/* ---- Fallbacks --------------------------------------------------------
   No pinning on small screens (a sticky stage on a short viewport hides
   more than it shows), and none when motion is reduced. Same markup,
   read as a plain stacked list.                                          */
@media (max-width: 899px), (prefers-reduced-motion: reduce) {
  .role { min-height: 0; }
  .role__stage {
    position: static;
    /* The pinned stage is a fixed 100vh; unpinned it must grow with its
       beats, or every role overflows into the next one. */
    height: auto;
    min-height: 0;
    display: block;
    padding-block: var(--s-7) var(--s-8);
  }
  .role__beats { display: grid; gap: var(--s-6); }
  .beat {
    grid-area: auto;
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .beat__lead, .beat__text { font-size: var(--t-lead); max-width: 34ch; }
  .beat__art { width: min(16rem, 55%); margin-bottom: var(--s-4); }
  .beat__art--shot { width: min(26rem, 100%); }
  .role__dots { display: none; }
  .beat__more { margin-top: var(--s-4); }
}
