/* ============================================================
   JWRC — landing page
   Loaded ONLY by index.html. Tokens, type and shared components
   come from style.css unchanged; everything here is scoped to
   this page so the founder's portfolio cannot be affected.
   ============================================================ */

/* ---------- chapter marker (shared idiom, page-local copy) ---------- */
.chapter { display: flex; align-items: baseline; gap: 22px; margin-bottom: 44px; }
.chapter .no { font-family: var(--display); font-size: clamp(36px,4.4vw,62px); font-weight: 600;
  line-height: .82; color: var(--acc); letter-spacing: -.04em; }
.chapter .lbl { font: 600 11px/1 var(--body); letter-spacing: .3em; text-transform: uppercase;
  color: var(--ink-faint); }
.dark .chapter .lbl, .deep .chapter .lbl { color: rgba(252,248,240,.62); }
.chapter .rule { flex: 1; height: 1px; background: var(--line); align-self: center; }
.dark .chapter .rule, .deep .chapter .rule { background: var(--line-lt); }

/* ---------- the crowd hero ----------
   A field of points that arrives scattered and finds its formation. The
   canvas sits behind the type at low opacity so the headline never has to
   fight it, and the whole layer is skipped entirely for anyone who has
   asked for reduced motion. */
.hero-c {
  position: relative; overflow: hidden; color: var(--ivory);
  background:
    radial-gradient(130% 100% at 18% 0%, rgba(35,64,107,.62), transparent 60%),
    radial-gradient(100% 90% at 88% 8%, rgba(232,70,28,.30), transparent 58%),
    var(--band-2);
  min-height: min(94svh, 940px);
  display: flex; align-items: center;
  padding-block: clamp(96px,11vw,150px) clamp(70px,8vw,110px);
}
.hero-c-bg { position: absolute; inset: 0; z-index: 1; }
.hero-c-bg canvas { width: 100%; height: 100%; display: block; opacity: .5; }
.hero-c-in { position: relative; z-index: 2; }
.hero-c h1 { color: var(--ivory); max-width: 17ch; }
.hero-c-lede { max-width: 56ch; color: rgba(252,248,240,.80); }
.hero-c-note {
  margin-top: clamp(44px,6vw,84px); max-width: 34ch;
  font-family: var(--display); font-style: italic; font-size: clamp(17px,1.5vw,21px);
  line-height: 1.45; color: var(--acc-gold);
}

/* ---------- values ---------- */
.values { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(24px,3vw,48px); }
.value { padding-top: 26px; border-top: 2px solid var(--line); }
.value h3 { font-size: clamp(20px,1.8vw,25px); margin: 20px 0 10px; }
.value p { font-size: 15px; line-height: 1.62; color: var(--ink-soft); margin: 0; }
.v-glyph { width: 46px; height: 46px; overflow: visible; }
.v-glyph .dr { fill: none; stroke: var(--flame); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round; }

/* ---------- full-bleed photographic band ----------
   Breaks a long reading passage with the thing being described. Height is
   fixed in vh rather than by the image, so nothing reflows when it loads,
   and the picture is oversized inside its frame to leave room for the
   parallax to travel without ever exposing an edge. */
.bleed {
  position: relative; margin: clamp(48px,6vw,88px) 0 0; padding: 0;
  height: clamp(320px, 52vh, 560px); overflow: hidden;
  background: var(--band-2);
}
.bleed img {
  position: absolute; inset: -12% 0; width: 100%; height: 124%;
  object-fit: cover; will-change: transform;
}
.bleed::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(18,24,40,.15) 0%, rgba(18,24,40,.72) 78%);
}
.bleed figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: clamp(24px,4vw,52px) var(--gut);
}
.bleed figcaption span {
  display: block; max-width: 22ch;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(21px,2.4vw,36px); line-height: 1.18; letter-spacing: -.02em;
  color: var(--ivory); text-wrap: balance;
}

/* ---------- the mosaic ----------
   Five frames of the same idea at different sizes. An explicit grid means
   the row heights exist before the photographs arrive. */
/* Four tiles, four different events. It was five, but the fifth was a
   panoramic band showing the same crowd as the full-bleed image a screen
   above it — the page looked like it was repeating itself. Four columns by
   two rows is eight cells: 4 + 2 + 1 + 1. */
.mosaic-strip {
  display: grid; gap: 10px;
  grid-template-columns: repeat(4, minmax(0,1fr));
  grid-template-rows: repeat(2, clamp(130px, 15vw, 210px));
}
.ms { margin: 0; overflow: hidden; border-radius: 3px; background: var(--bg-3); }
.ms img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .9s var(--ease-out), filter .6s var(--ease); filter: saturate(.92); }
.ms:hover img { transform: scale(1.045); filter: saturate(1.05); }
.ms.a { grid-column: span 2; grid-row: span 2; }   /* the anchor frame */
.ms.b { grid-column: span 2; }
.ms.c { grid-column: span 1; }
.ms.d { grid-column: span 1; }

/* ---------- why records ---------- */
.symbols { list-style: none; margin: 0 0 clamp(40px,5vw,70px); padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 1px;
  background: var(--line-lt); }
.symbols li { background: var(--band); padding: clamp(26px,3vw,40px);
  display: flex; gap: 22px; align-items: flex-start; }
.s-n { font-family: var(--display); font-size: 26px; font-weight: 600; color: var(--acc-gold);
  line-height: 1; flex: none; font-variant-numeric: tabular-nums; }
.symbols p { margin: 0; font-size: 16px; line-height: 1.6; color: rgba(252,248,240,.84); }

/* the line, and the two pictures it is comparing */
.receipt {
  display: grid; gap: clamp(24px,3vw,56px);
  grid-template-columns: minmax(0,.85fr) minmax(0,1.15fr);
  align-items: center;
}
.pullline {
  font-family: var(--display); font-size: clamp(22px,2.4vw,36px); line-height: 1.26;
  letter-spacing: -.02em; color: var(--ivory); margin: 0;
}

/* The stack composes the pair as one object. The crowd sets the height;
   the certificate is laid on its lower-left corner and given a mount and a
   shadow so it reads as a physical print resting on top, rather than as a
   second image that happens to be smaller. */
.stack { position: relative; padding-bottom: clamp(30px,3.4vw,52px); }
.stack figure { margin: 0; }
.stack img {
  /* height:auto is load-bearing: the width/height attributes reserve space
     before load, but a used height also beats aspect-ratio, which only
     applies when a dimension is auto. */
  width: 100%; height: auto; display: block; border-radius: 3px;
  background: var(--band);
}
.rc-large img { aspect-ratio: 3/2; object-fit: cover; }
.rc-large figcaption {
  position: absolute; right: 0; bottom: 0;
  font: 600 11px/1 var(--body); letter-spacing: .2em; text-transform: uppercase;
  color: var(--acc-gold);
}
.rc-small {
  position: absolute; left: clamp(-14px, -1.4vw, -6px); bottom: 0;
  width: clamp(116px, 26%, 210px); z-index: 2;
}
.rc-small img {
  aspect-ratio: 4/3; object-fit: cover; object-position: 50% 36%;
  border: 5px solid var(--bg); border-radius: 2px;
  box-shadow: 0 18px 40px -14px rgba(0,0,0,.75);
  transition: transform .7s var(--ease-out);
}
.rc-small figcaption {
  margin-top: 9px; font: 600 10.5px/1 var(--body); letter-spacing: .18em;
  text-transform: uppercase; color: rgba(252,248,240,.66);
}
.stack:hover .rc-small img { transform: translateY(-5px) rotate(-1.2deg); }

/* ---------- the record reel ----------
   A horizontal band of the real records. It scrolls with the finger on
   touch and is nudged by scroll position on a pointer device. */
.reel-wrap { margin-top: clamp(56px,7vw,110px); }
.reel-head h3 { font-size: clamp(21px,2vw,28px); color: var(--ivory); margin-bottom: 8px; }
.reel-head p { font-size: 15px; color: rgba(252,248,240,.68); margin: 0 0 30px; max-width: 58ch; }
.reel {
  display: flex; gap: 20px; overflow-x: auto; scroll-snap-type: x proximity;
  padding: 4px var(--gut) 28px; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.reel::-webkit-scrollbar { display: none; }
/* Snapping fights the drift: the browser keeps pulling scrollLeft back to
   the nearest card, so a slow nudge either stutters or is cancelled. Snap
   is suspended while the reel is carrying itself and restored the moment
   the reader takes hold of it. */
.reel.is-drifting { scroll-snap-type: none; }
.rcard {
  flex: none; width: clamp(260px, 30vw, 380px); scroll-snap-align: start;
  border: 1px solid var(--line-lt); border-radius: 4px; overflow: hidden;
  background: var(--band); position: relative;
  padding: clamp(24px,2.4vw,34px);
  transition: border-color .45s var(--ease), transform .55s var(--ease-out);
}
/* the record's own photograph, held back so the words lead */
.rcard::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: var(--shot); background-size: cover; background-position: center;
  opacity: .16; transition: opacity .6s var(--ease), transform 1.1s var(--ease-out);
  transform: scale(1.06);
}
.rcard::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(18,24,40,.55), rgba(18,24,40,.94));
}
.rcard > * { position: relative; z-index: 2; }
.rcard:hover, .rcard:focus-within { border-color: rgba(217,164,65,.55); transform: translateY(-4px); }
.rcard:hover::before, .rcard:focus-within::before { opacity: .34; transform: scale(1); }
.rc-fig { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.rc-n { font-family: var(--display); font-weight: 600; font-size: clamp(32px,3.4vw,50px);
  line-height: 1; letter-spacing: -.035em; color: var(--acc-gold); font-variant-numeric: tabular-nums; }
.rc-u { font: 600 11px/1 var(--body); letter-spacing: .18em; text-transform: uppercase;
  color: rgba(252,248,240,.66); }
.rcard h4 { font-family: var(--display); font-weight: 600; font-size: 19px; line-height: 1.3;
  margin: 0 0 10px; color: var(--ivory); }
.rcard p { margin: 0; font-size: 14px; line-height: 1.6; color: rgba(252,248,240,.72); }
.reel-more { margin-top: 6px; }

/* ---------- what we build ---------- */
.kinds { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 1px; background: var(--line); }
.kinds li { background: var(--bg); padding: 0 0 clamp(24px,2.4vw,32px); overflow: hidden; }
.k-shot { display: block; aspect-ratio: 5/4; overflow: hidden; background: var(--bg-3);
  margin-bottom: clamp(18px,2vw,26px); }
.k-shot img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .9s var(--ease-out); filter: saturate(.92); }
.kinds li:hover .k-shot img { transform: scale(1.05); }
.kinds h3 { font-size: 19px; margin-bottom: 10px; padding-inline: clamp(20px,2vw,28px); }
.kinds p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft);
  padding-inline: clamp(20px,2vw,28px); }

/* the six steps, threaded on a rule that fills as you read down it */
.method { position: relative; }
.method-h { font-size: clamp(21px,2vw,28px); margin-bottom: 36px; }
.steps { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: clamp(24px,3vw,44px); }
.steps li { position: relative; padding-top: 30px; }
.steps li::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--line);
}
.steps li::after {
  content: ""; position: absolute; top: 0; left: 0; height: 2px; width: 100%;
  background: linear-gradient(90deg, var(--flame), var(--gold));
  transform: scaleX(0); transform-origin: left;
  transition: transform .8s var(--ease-out);
}
.steps li.is-in::after { transform: scaleX(1); }
.st-n { font-family: var(--display); font-size: 15px; font-weight: 600; color: var(--acc-sm);
  letter-spacing: .1em; }
.steps h4 { font-family: var(--display); font-weight: 600; font-size: 18px; margin: 8px 0 8px; }
.steps p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }

.partners { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.partners span {
  display: inline-flex; align-items: center; min-height: max(38px, var(--tap-min));
  padding: 0 18px; border: 1px solid var(--line); border-radius: 999px;
  font: 600 12.5px/1 var(--body); color: var(--ink-soft);
  transition: border-color .35s var(--ease), color .35s var(--ease);
}
.partners span:hover { border-color: var(--flame-deep); color: var(--acc-sm); }

/* ---------- take part, over the crowd ---------- */
.join-c { position: relative; overflow: hidden; }
.join-bg { position: absolute; inset: 0; z-index: 0; }
.join-bg img { width: 100%; height: 100%; object-fit: cover; opacity: .22; }
.join-c::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: radial-gradient(80% 70% at 50% 50%, rgba(11,16,27,.55), rgba(11,16,27,.94));
}
.join-in { position: relative; z-index: 2; }

/* ---------- responsive ---------- */
@media (max-width: 1024px) {
  body .values { grid-template-columns: 1fr 1fr; }
  body .kinds { grid-template-columns: 1fr 1fr; }
  body .steps { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 1024px) {
  body .mosaic-strip { grid-template-rows: repeat(2, clamp(112px, 17vw, 180px)); }
}
@media (max-width: 760px) {
  body .values { grid-template-columns: 1fr; }
  body .receipt { grid-template-columns: 1fr; }
  body .rc-small { width: clamp(104px, 30%, 150px); left: 0; }
  /* the mosaic collapses to two even columns rather than trying to keep a
     feature tile that would be barely larger than the others */
  /* two columns, four rows: 2 + 1 + 1 + 2 + 2 */
  body .mosaic-strip { grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(3, clamp(104px, 26vw, 155px)); }
  body .ms.a { grid-column: 1 / -1; grid-row: span 1; }
  body .ms.b { grid-column: 1 / -1; }
  body .kinds { grid-template-columns: 1fr; }
  body .steps { grid-template-columns: 1fr; }
  body .symbols { grid-template-columns: 1fr; }
  body .hero-c { min-height: auto; }
  body .reel { scroll-snap-type: none; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .rcard, .rcard::before, .steps li::after,
  .ms img, .k-shot img, .receipt img { transition: none; }
  .bleed img { transform: none !important; }
  .hero-c-bg canvas { opacity: .3; }
}

/* Photographs uncover rather than fade: the image slides up from behind
   its own frame and settles from a slight scale.

   This was written with clip-path first, which was a mistake twice over.
   Animating clip-path repaints rather than composites — on full-bleed
   images it cost about 30fps of scrolling — and Chrome's
   IntersectionObserver counts clip-path as visibility, so an element
   hidden that way never reports as intersecting and never triggers the
   reveal that would have shown it. Transform and opacity have neither
   problem: the container clips, the image only ever moves. */
[data-reveal] { overflow: hidden; }
[data-reveal] img {
  transform: translateY(14%) scale(1.06);
  opacity: 0;
  will-change: transform, opacity;
}
[data-reveal].is-shown img {
  transform: translateY(0) scale(1);
  opacity: 1;
  transition: transform 1.05s var(--ease-out), opacity .75s var(--ease);
}
/* released once it has played, so nothing keeps a layer it no longer needs */
[data-reveal].is-done img { will-change: auto; }

/* ---------- the reel, made legible as a track ----------
   A horizontal scroller needs to say how far along you are, or people do
   not know there is more. */
.reel-rail {
  margin: 4px var(--gut) 0; height: 2px; background: var(--line-lt);
  position: relative; border-radius: 2px; overflow: hidden;
}
.reel-rail i {
  position: absolute; inset: 0 auto 0 0; width: 30%;
  background: linear-gradient(90deg, var(--flame), var(--gold));
  border-radius: 2px; transform-origin: left;
}
.reel-nav { display: flex; gap: 10px; margin: 18px var(--gut) 0; }
.reel-nav button {
  width: var(--tap); height: var(--tap); border-radius: 50%;
  border: 1px solid var(--line-lt); background: transparent; color: var(--ivory);
  display: grid; place-items: center;
  transition: border-color .3s var(--ease), background-color .3s var(--ease),
              transform .3s var(--ease-out);
}
.reel-nav button:hover:not(:disabled) { border-color: var(--gold); background: rgba(217,164,65,.12); }
.reel-nav button:active:not(:disabled) { transform: scale(.93); }
.reel-nav button:disabled { opacity: .32; cursor: not-allowed; }

/* ---------- pointer-reactive cards ----------
   The 3D transform is applied only while the pointer is actually over a
   card. Leaving it on every card permanently put all thirteen of them into
   their own 3D rendering contexts, which cost about 30fps of scrolling for
   an effect nobody was looking at. */
.rcard.is-tilting, .kinds li.is-tilting, .value.is-tilting {
  transform: perspective(900px)
             rotateX(calc(var(--ry, 0) * -1deg))
             rotateY(calc(var(--rx, 0) * 1deg))
             translateY(-3px);
  transition: transform .35s var(--ease-out);
  will-change: transform;
}
.rcard, .kinds li, .value { transition: transform .5s var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] img { transform: none; opacity: 1; transition: none; }
  .is-tilting { transform: none !important; }
}
@media (hover: none) {
  .is-tilting { transform: none !important; }
}
