/* Homepage journey (build.py JOURNEY flag). Text on the left; one sticky stage on the right,
   on the same paper as the text: no border, no background, no divider.
   Classes on <html> come from the boot script: hero-gl (draw live), hero-pin (motion allowed),
   no-webgl (still image), gl-ready (canvas running), journey-scrolled (cue hidden). */

.journey { position: relative; }
.journey-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; }
.journey-text { min-width: 0; }
.journey-stage-col { position: relative; min-width: 0; }
.journey-stage {
  position: sticky; top: var(--header-h);
  height: calc(100vh - var(--header-h)); height: calc(100svh - var(--header-h));
  display: flex; align-items: center; justify-content: center;
}
/* the canvas is sized in JS to the column plus the bleed to the viewport's right edge (the engine reads large) */
.journey-stage canvas { position: absolute; left: 0; top: 0; display: block; pointer-events: none; }
/* soft left edge so nothing on the canvas (the floor grid) ends in a hard line at the column edge */
.journey-stage canvas { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 3.5%); mask-image: linear-gradient(to right, transparent 0, #000 3.5%); }
.journey-stage .hero-fallback, .journey-stage .hero-noscript { width: 100%; height: auto; }
.journey-stage .hero-fallback { display: none; }
.no-webgl .journey-stage .hero-fallback { display: block; }
.no-webgl .journey-stage canvas { display: none; }

/* The ending: the assembled engine in side elevation with one line of text centred above it, the only text in the
   drawing. journey.js places and fades it (left/top in stage px); with no WebGL the end still and the line take over
   from the fallback image once the last card has passed (journey-end on the stage). */
.journey-end { position: absolute; inset: 0; pointer-events: none; }
.journey-tagline {
  position: absolute; left: 50%; top: 36%; margin: 0; transform: translate(-50%, -100%);   /* no-WebGL default; journey.js sets px */
  font-family: var(--font); font-weight: 600; font-size: 36px; line-height: 1.15; letter-spacing: -0.01em;
  color: var(--ink); white-space: nowrap; opacity: 0;
}
@media (min-width: 1400px) { .journey-tagline { font-size: 44px; } }
.journey-end-still { display: none; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.no-webgl .journey-stage .journey-end-still { display: block; opacity: 0; transition: opacity .4s ease; }
.no-webgl .journey-stage .hero-fallback { transition: opacity .4s ease; }
.no-webgl .journey-stage.journey-at-end .journey-end-still { opacity: 1; }
.no-webgl .journey-stage.journey-at-end .hero-fallback { opacity: 0; }
.no-webgl .journey-stage .journey-tagline { transition: opacity .4s ease; }
.no-webgl .journey-stage.journey-at-end .journey-tagline { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .no-webgl .journey-stage .journey-end-still, .no-webgl .journey-stage .hero-fallback, .no-webgl .journey-stage .journey-tagline { transition: none; } }

/* Hero: the H1 alone, vertically centred in the first screen, the scroll cue at its foot. */
.journey-hero {
  position: relative; display: flex; flex-direction: column; justify-content: center;
  min-height: calc(100vh - var(--header-h)); min-height: calc(100svh - var(--header-h));
  padding: 48px 0 112px;
}
.journey-hero h1 { font-size: clamp(45px, 5.45vw, 79px); margin: 0; max-width: 12ch; will-change: opacity; }
@media (min-width: 1400px) { .journey-hero h1 { font-size: clamp(60px, 4.9vw, 98px); } }

/* ?wash=1: a very soft accent-tint wash behind the headline (about 12 percent accent over paper at the centre,
   nothing at the edge), under the text and under the canvas; journey.js sets the centre and size from the headline */
.journey-wash .journey-hero::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: var(--wash-x, 40%); top: var(--wash-y, 45%); width: var(--wash-w, 900px); height: var(--wash-h, 600px); transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(227,239,252,1) 0%, rgba(227,239,252,.86) 18%, rgba(227,239,252,.58) 40%, rgba(227,239,252,.28) 64%, rgba(227,239,252,.08) 86%, rgba(227,239,252,0) 100%);
}

.scroll-cue {
  position: absolute; left: 0; bottom: 40px; margin: 0;
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 12px; line-height: 1.4; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--grey); transition: opacity .4s ease;
}
.scroll-cue-tick { display: block; width: 2px; height: 28px; background: var(--accent); border-radius: 1px; }
.journey-scrolled .scroll-cue { opacity: 0; }

/* What we do: one screen, paragraph centred against the side elevation. */
/* No full-screen min-height: the scroll between the headline leaving and the paragraph centring is the
   explosion, so the gap is sized to that (about a third of a screen of lead-in), not to blank paper. */
.journey-what { padding: 16vh 0 6vh; }
.journey-what p { font-size: 19px; line-height: 1.6; }

/* Expertise: one card per beat. With motion allowed each card gets most of a screen of scroll. */
.journey-expertise { padding: 24px 0 0; }
.journey-cards { margin: 24px 0 0; display: grid; gap: 16px; }
.journey-card { max-width: 460px; }
.journey-card p { margin: 0; }
.hero-pin .journey-cards { display: block; padding: 4vh 0 0; }
.hero-pin .journey-card { margin: 0 0 30vh; }
.hero-pin .journey-card:last-of-type { margin-bottom: 0; }
.hero-pin .journey-text { padding-bottom: 130vh; }   /* room for the hammer test's hold, the reassembly, the closing housing and the tagline */

/* Phone stills: only under 900 px, where the stage is hidden and the text flows normally. */
.journey-still { display: none; }
@media (max-width: 899.98px) {
  .journey-grid { display: block; }
  .journey-stage-col { display: none; }
  .journey-still { display: block; width: 100%; height: auto; margin: 24px 0 8px; }
  .journey-hero { min-height: 0; padding: 40px 0 72px; }
  .journey-hero .scroll-cue { display: none; }   /* no pinned journey on phones: nothing to scroll through */
  .journey-what { min-height: 0; padding: 32px 0; }
  .hero-pin .journey-cards { display: grid; padding: 0; }
  .hero-pin .journey-card { margin: 0; }
  .journey-cards .journey-still { margin: 0 0 24px; }
  .hero-pin .journey-text { padding-bottom: 48px; }
}

/* Owner 2026-11-05: Expertise beat cards much larger, no underline on the title, title turns blue on hover. */
.journey-card { max-width: 560px; padding: 32px 36px; }
.journey-card h3 { font-size: 30px; line-height: 1.15; margin: 0 0 14px; }
.journey-card h3 a { text-decoration: none; color: var(--ink); transition: color .15s ease; }
.journey-card h3 a:hover, .journey-card h3 a:focus-visible { color: #2F6FBF; text-decoration: none; }
.journey-card p { font-size: 20px; line-height: 1.5; }
@media (min-width: 1800px) {
  .journey-card { max-width: 640px; padding: 36px 40px; }
  .journey-card h3 { font-size: 36px; }
  .journey-card p { font-size: 23px; }
}
