/* ==========================================================================
   PROCESS — loaded only by /process and /es/process.
   ========================================================================== */
/* --------------------------------------------------------------------------
   Process (.prch, .prcl, .clk, .prf, .prcc)

   Two clocks, one instrument. .clk is rendered twice at timescales orders of
   magnitude apart — seconds for a lead, days for a build — and that repetition
   IS the page's thesis, so the two instances share every rule and differ only
   in their data.

   This page is the loud one. Services is a quiet register and About is
   long-form prose; Process earns a moving part because its whole subject is
   elapsed time. The playhead is the only thing on the site that tracks scroll
   position, and brand blue is reserved for it here.
   -------------------------------------------------------------------------- */

.prch,
.prcl,
.prf,
.prcc {
  position: relative;
  padding-block: var(--section-y);
  /* Every section carrying an .aurora needs this. The layer sits at inset:-10px
     and so bleeds 10px past its section on each side; unclipped, that widened
     the document by 10px and produced a horizontal scrollbar at every width.
     `clip` rather than `hidden` because hidden creates a scroll container and
     would break position:sticky on .clk__dial. */
  overflow-x: clip;
}

/* The contract promises the first dial is visible below the h1 on first
   viewport. It was not: 120px section padding + h1 + standfirst + a 40px hero
   tail + another 120px + a 48px head margin put the ring's top at ~815px, below
   the fold on any laptop. The hero tail and the first clock's top padding are
   tightened so the ring breaks the fold at 900px viewport height. Only the
   FIRST clock needs this — .prcl--alt keeps the full rhythm. */
.prch { background: var(--surface-0); padding-bottom: 8px; }
.prcl:not(.prcl--alt) { padding-top: 64px; }
.prcl:not(.prcl--alt) .prcl__head { margin-bottom: 32px; }
.prcl { background: var(--surface-0); }
.prcl--alt { background: var(--surface-50); }
.prf { background: var(--surface-0); }

/* INERT, and left in place deliberately rather than deleted. These name the
   colour each section would ramp TO, but the shared band rule in base.css
   selects only .why/.feat/.vid/.ct/.svc/.svcf::after, so no ::after is ever
   generated here and nothing reads these. Process therefore has hard section
   cuts, not bands — true before the stylesheet split and unchanged by it.
   Adding .prcl/.prcl--alt/.prf to that selector list is all it would take, but
   that is a visual change and needs a ruling, not a refactor. */
.prcl { --fade-rgb: 247, 248, 250; }        /* -> .prcl--alt */
.prcl--alt { --fade-rgb: 255, 255, 255; }   /* -> .prf */
.prf { --fade-rgb: 7, 12, 22; }             /* -> .prcc */

/* --- Page head ----------------------------------------------------------- */
.prch__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h1);
  line-height: 1.04;
  letter-spacing: -0.02em;
  word-spacing: 0.03em;
  color: var(--ink-950);
  text-wrap: balance;
}

.prch__sub {
  margin-top: 22px;
  max-width: 36em;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ink-700);
}

/* --- Section heads ------------------------------------------------------- */
.prcl__head { max-width: 40em; margin-bottom: 48px; }

.prcl__mark {
  display: block;
  width: 4px;
  height: 26px;
  margin-bottom: 20px;
  background: var(--blue-brand);
  border-radius: 1px;
  transform: skewX(-18deg);
}

.prcl__h {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1.1;
  letter-spacing: -0.02em;
  word-spacing: 0.03em;
  color: var(--ink-950);
}

.prcl__p {
  margin-top: 14px;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ink-500);
}

.prcl__foot {
  margin-top: 48px;
  max-width: 40em;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ink-500);
}

/* --- The clock ----------------------------------------------------------- */
.clk { display: grid; gap: 40px; }

/* Base first, media query after. Declared the other way round, this rule's
   `position: relative` won on source order at equal specificity and silently
   cancelled the sticky below — the dial scrolled away from the readout it was
   reporting, which is the one thing it exists not to do. */
/* Below 900px the dial stacks above the rail, and it used to be `position:
   relative` — so it scrolled off at roughly the second event and the visitor
   went on driving a playhead they could no longer see. That is the exact
   failure the desktop sticky exists to prevent, so mobile gets it too, in a
   compact form: a smaller ring pinned under the header, on an opaque ground so
   the rail passes BEHIND it rather than showing through. */
/* The pinned band must span the FULL column width. A dial only as wide as its
   own ring leaves the rail's text visibly sliding past to the right of it —
   the ring occludes its own box and nothing else, which reads as a rendering
   fault rather than a pinned instrument. Full width + an opaque ground + a
   closing hairline makes it a header the rail passes cleanly behind. */
.clk__dial {
  position: sticky;
  top: var(--nav-h);
  z-index: 2;
  width: 100%;
  padding: 10px 0;
  background: var(--clk-ground, var(--surface-0));
  border-bottom: 1px solid var(--border);
}
.prcl--alt .clk { --clk-ground: var(--surface-50); }

@media (min-width: 900px) {
  /* Dial left and sticky, rail right — the dial has to stay on screen while the
     rail scrolls past it, or the readout it is reporting is off-screen at the
     exact moment it changes. */
  .clk { grid-template-columns: 15rem minmax(0, 1fr); gap: 64px; align-items: start; }
  /* Desktop puts the dial in its own column, so it needs none of the mobile
     band's scaffolding — no ground, no hairline, no pinned readout box. */
  .clk__dial {
    top: calc(var(--nav-h) + 48px);
    width: 15rem;
    padding: 0;
    background: none;
    border-bottom: 0;
  }
}

.clk__svg { display: block; width: 100%; height: auto; transform: rotate(-90deg); }

.clk__track {
  fill: none;
  stroke: var(--border);
  stroke-width: 3;
}

.clk__arc {
  fill: none;
  stroke: var(--blue-brand);
  stroke-width: 3;
  stroke-linecap: round;
  /* 2*pi*54, rounded. --clk-p is written by initClocks() as 0..1. Defaults to 1
     so a no-JS visitor sees a complete arc rather than an empty ring. */
  stroke-dasharray: 339.3;
  stroke-dashoffset: calc(339.3 - (339.3 * var(--clk-p, 1)));
  /* 120ms LINEAR is for the scroll case only: the arc is reporting a position
     the visitor is themselves controlling, so it must not lag or ease — a clock
     hand that decelerates misreports time. The duration only smooths the
     rAF-quantised steps. */
  transition: stroke-dashoffset 120ms linear;
}

/* A CLICKED event is a different motion problem with a different answer. There
   the visitor commands a jump rather than scrubbing continuously, the arc can
   travel the entire dial (0:00 -> 0:52) in one move, and at 120ms linear that
   full sweep reads as a snap with no arrival. A commanded move should settle:
   ease-out decelerates onto the target, and the duration is scaled for the
   distance (~1.6x the page's 260ms row fade for a near-full-dial travel).
   The class is added on click and removed by the next scroll-driven paint, so
   the scroll case never inherits it. */
.clk.is-scrub .clk__arc { transition: stroke-dashoffset var(--clk-dur, 420ms) var(--ease-out); }

.clk__read {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 2px;
  text-align: center;
}

.clk__num {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-readout);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink-950);
  /* The readout changes character by character as the playhead moves; without
     tabular figures the whole string jitters horizontally on every tick. */
  font-variant-numeric: tabular-nums;
}

.clk__unit {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--ink-500);
}

.clk__tag {
  margin-top: 14px;
  text-align: center;
  /* px floor, same reason as every other example label on the site. */
  font-size: max(12px, var(--fs-xs));
  line-height: 1.4;
  color: var(--ink-500);
}

/* The mobile pinned band. This block MUST sit after the base .clk__svg and
   .clk__read rules above: a media query adds no specificity, so declared before
   them these lose on source order and the ring renders at full column width —
   which is exactly what happened on the first attempt. */
@media (max-width: 899px) {
  .clk__svg { width: 5.5rem; margin: 0 auto; }
  /* .clk__read centres absolutely on the dial box; the box is now a full-width
     band with a tag beneath, so centring on the whole box would drop the number
     below the ring's middle. Pin it to the ring's own square instead. */
  .clk__read { inset: 10px auto auto 0; width: 5.5rem; height: 5.5rem; left: 50%; transform: translateX(-50%); }
  .clk__num { font-size: 1.5rem; }
  /* The unit sits INSIDE the ring, so it is bounded by the ring's inner chord,
     not by the band. "transcurrido" is half again as long as "elapsed" and at
     the desktop size it crosses the stroke — the ES string is the constraint
     here, not the EN one. */
  .clk__unit { font-size: 10px; letter-spacing: 0.02em; }
  .clk__tag { margin-top: 6px; }
}

/* --- The event rail ------------------------------------------------------ */
.clk__events { list-style: none; margin: 0; padding: 0; }

.clk__ev { position: relative; }

.clk__btn {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px 20px;
  width: 100%;
  padding: 18px 0 18px 30px;
  border: 0;
  border-top: 1px solid var(--border);
  background: none;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}
.clk__ev:first-child .clk__btn { border-top: 0; }

@media (min-width: 640px) {
  .clk__btn { grid-template-columns: 5rem minmax(0, 1fr); align-items: baseline; }
  .clk__d { grid-column: 2; }
}

/* The rail and its nodes. Pseudo-elements so the first and last segments stop
   at their own node instead of running past the ends of the sequence. */
.clk__ev::before {
  content: "";
  position: absolute;
  left: 5px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border);
}
.clk__ev:first-child::before { top: 26px; }
.clk__ev:last-child::before { bottom: auto; height: 26px; }

.clk__ev::after {
  content: "";
  position: absolute;
  left: 0;
  top: 22px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--surface-0);
  border: 1px solid var(--ink-300);
  /* Corporate personality: short, decisive, no overshoot. */
  transition: background-color 200ms var(--ease-out),
              border-color 200ms var(--ease-out),
              transform 200ms var(--ease-out);
}
.prcl--alt .clk__ev::after { background: var(--surface-50); }

/* Reached — the playhead has passed this moment. */
.clk__ev.is-reached::after {
  background: var(--blue-brand);
  border-color: var(--blue-brand);
}
/* Current — the playhead is ON this moment. One node at a time, per the 1/3
   rule: only the single active element carries motion. */
.clk__ev.is-current::after { transform: scale(1.45); }

.clk__t {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink-500);
  font-variant-numeric: tabular-nums;
  transition: color 200ms var(--ease-out);
}
.clk__ev.is-reached .clk__t { color: var(--blue-brand); }

.clk__w {
  font-size: var(--fs-body);
  font-weight: 500;
  color: var(--ink-950);
  transition: color 200ms var(--ease-out);
}

.clk__d {
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink-500);
  /* The rail column runs ~690px at desktop; uncapped, clock 2's step paragraphs
     hit ~95 characters a line. Matches .prf__a's measure discipline. */
  max-width: 64ch;
}

/* Unreached rows must stay READABLE. The intent below was always "content is
   never hidden", but the mechanism contradicted it: opacity .55 composites
   --ink-500 to 2.34:1 on --surface-0 and 2.28:1 on --surface-50, both far under
   4.5:1 — and `is-reached` is set ONLY by initClocks(), so a visitor whose JS
   never runs got the whole rail stuck at .55 permanently, with a complete arc
   above unreadable text. Progress is carried by the node and the timestamp,
   which change COLOUR rather than fade, so nothing has to dim to show state and
   every row clears 4.5:1 in both states. Do not reintroduce a row-level
   opacity here — it dims the text along with the state. */
.clk__ev { opacity: 1; }
.clk__d { transition: color 260ms var(--ease-out); }
.clk__ev.is-reached .clk__d { color: var(--ink-700); }

.clk__btn:focus-visible {
  outline: 2px solid var(--blue-brand);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}
.clk__btn:hover .clk__w { color: var(--blue-brand); }

/* --- FAQ ----------------------------------------------------------------- */
.prf__h,
.prcc__h {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1.1;
  letter-spacing: -0.02em;
  word-spacing: 0.03em;
  text-wrap: balance;
}
.prf__h { color: var(--ink-950); margin-bottom: 40px; max-width: 20ch; }

.prf__row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px 48px;
  padding-block: 24px;
  border-top: 1px solid var(--border);
}
@media (min-width: 900px) {
  .prf__row { grid-template-columns: 22rem minmax(0, 1fr); align-items: start; }
}

.prf__q {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1.125rem;
  line-height: 1.35;
  color: var(--ink-950);
}

.prf__a {
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--ink-500);
  max-width: 62ch;
}

/* --- Close --------------------------------------------------------------- */
.prcc {
  background: var(--surface-deep);
  color: #fff;
  --glass-border: rgba(255, 255, 255, 0.16);
  --glass-hi: rgba(255, 255, 255, 0.14);
  --glass-fill: rgba(255, 255, 255, 0.08);
  --glass-fill-hover: rgba(255, 255, 255, 0.14);
  --shadow-rgb: 0, 0, 0;
  --shadow-a1: 0.30;
  --shadow-a2: 0.38;
  --shadow-a3: 0.46;
  /* The --ui-* set has to be re-inked too, or .ui-btn--outline draws --ink-950
     on --surface-deep and the phone CTA becomes an unreadable dark pill. Same
     swap .hdr--over-dark and .svcc perform. */
  --ui-fg: #fff;
  --ui-muted-fg: rgba(255, 255, 255, 0.72);
  --ui-border: rgba(255, 255, 255, 0.22);
  --ui-input: rgba(255, 255, 255, 0.32);
  --ui-accent: rgba(255, 255, 255, 0.12);
  --ui-bg: transparent;
  --ui-ring: #fff;
}

.prcc__h { color: #fff; max-width: 18ch; }
.prcc__p {
  margin-top: 18px;
  max-width: 34em;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ink-on-deep);
}
.prcc__actions { margin-top: 32px; display: flex; flex-wrap: wrap; gap: 12px; }

/* --- Reduced motion ------------------------------------------------------ */
/* The global rule already forces [data-reveal] visible and collapses durations.
   The clock needs its own statement: with reduced motion the playhead is not
   animated at all, every moment reads as reached, and the arc sits complete.
   initClocks() also returns early, so no scroll listener is ever attached. */
@media (prefers-reduced-motion: reduce) {
  .clk__arc,
  .clk.is-scrub .clk__arc { transition: none; --clk-p: 1; }
  .clk__ev { opacity: 1; }
  .clk__d { color: var(--ink-700); transition: none; }
  .clk__ev::after { background: var(--blue-brand); border-color: var(--blue-brand); transform: none; }
  .clk__t { color: var(--blue-brand); }
}
