/* ==========================================================================
 * 2 · Why we record sleep: a week of sleep, stacked (js/rhythm/)
 * --------------------------------------------------------------------------
 * Static by default: the four captions in order beside a still of the week
 * stack (no JS, no WebGL, reduced motion). rhythm.js adds .is-live before
 * anyone scrolls (a tall track, a sticky stage, one caption at a time) and
 * .is-ready once the 3D has drawn. Colour and type come from tokens.css and
 * home.css; this file lays the section out and sets the labels' micro type.
 * ========================================================================== */

.rhythm {
  position: relative;
  /* The page's content edge (.wrap), used to line the captions up with it. */
  --rhythm-edge: max(var(--gutter), calc((100% - var(--wrap)) / 2 + var(--gutter)));
}
.rhythm__track,
.rhythm__stage {
  position: relative;
}
.rhythm__canvas,
.rhythm__labels {
  display: none;
}

.rhythm__caption .eyebrow {
  margin-bottom: 18px;
}
.rhythm__caption .h2,
.rhythm__caption .h3 {
  margin-bottom: 16px;
}
.rhythm__caption p:not(.eyebrow) {
  max-width: 30em;
  font-size: clamp(17px, 1.4vw, 19px);
  line-height: 1.6;
  color: var(--text-2);
}
.rhythm__static img {
  width: 100%;
  height: auto;
}
/* "Sample week", in the hero's caption style: the data is illustrative. */
.rhythm__sample {
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--text-2);
}

/* ---- Static: the still, then the story in four steps ----------------------- */
.rhythm:not(.is-live) .rhythm__stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 36px;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: var(--section) var(--gutter);
}
.rhythm:not(.is-live) .rhythm__captions {
  display: contents;
}
/* Narrow: the first caption, the still, then the other three. */
.rhythm:not(.is-live) .rhythm__static {
  order: 1;
  margin: 0 -2%;
}
.rhythm:not(.is-live) .rhythm__caption:not(:first-child) {
  order: 2;
}
.rhythm:not(.is-live) .rhythm__sample {
  order: 1;
  justify-self: end;
  margin-top: -20px;
}
@media (min-width: 940px) {
  .rhythm:not(.is-live) .rhythm__stage {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 56px clamp(28px, 4vw, 56px);
    align-items: start;
  }
  .rhythm:not(.is-live) .rhythm__caption:first-child {
    grid-column: 1;
    grid-row: 1;
    align-self: center;
  }
  .rhythm:not(.is-live) .rhythm__static {
    grid-column: 2 / 4;
    grid-row: 1;
    margin: 0;
  }
  .rhythm:not(.is-live) .rhythm__caption:not(:first-child) {
    grid-row: 2;
    padding-top: 28px;
    border-top: 1px solid var(--hairline);
  }
  .rhythm:not(.is-live) .rhythm__sample {
    grid-column: 2 / 4;
    grid-row: 1;
    align-self: end;
    margin: 0;
  }
}

/* ---- Live: a tall track, a sticky stage, one caption at a time ------------- */
.rhythm.is-live .rhythm__track {
  height: 320vh;
}
.rhythm.is-live .rhythm__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.rhythm.is-live .rhythm__canvas {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.8s var(--ease-out);
}
.rhythm.is-ready .rhythm__canvas {
  opacity: 1;
}
.rhythm.is-live .rhythm__labels {
  display: block;
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
/* While three.js loads, the still stands in where the stack will be. */
.rhythm.is-live .rhythm__static {
  position: absolute;
  top: 50%;
  right: var(--rhythm-edge);
  width: min(56%, 880px);
  margin: 0;
  transform: translateY(-46%);
  transition:
    opacity 0.8s var(--ease-out),
    visibility 0s linear 0.8s;
}
.rhythm.is-ready .rhythm__static {
  opacity: 0;
  visibility: hidden;
}
.rhythm.is-live .rhythm__captions {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.rhythm.is-live .rhythm__caption {
  position: absolute;
  left: var(--rhythm-edge);
  /* Centred in what the sticky nav leaves free. */
  top: calc(50% + 34px);
  width: min(440px, 32vw);
  opacity: 0;
  transform: translateY(calc(-50% + 18px));
  transition:
    opacity 0.5s var(--ease-out),
    transform 0.7s var(--ease-out);
}
.rhythm.is-live .rhythm__caption.is-on {
  opacity: 1;
  transform: translateY(-50%);
}
.rhythm.is-live .rhythm__caption .h2,
.rhythm.is-live .rhythm__caption .h3 {
  font-size: clamp(34px, 3.7vw, 54px);
  line-height: 1.04;
  letter-spacing: -0.035em;
  font-weight: 680;
}
/* Under the stack, on the content edge; rhythm.js keeps the 3D above it. */
.rhythm.is-live .rhythm__sample {
  position: absolute;
  right: var(--rhythm-edge);
  bottom: 28px;
}

/* ---- Labels on the 3D (positioned by rhythm.js) ----------------------------
 * The hero's micro type (css/orrery.css), so the two rings read as one
 * instrument. The next window's label gets a chip: on the stack it sits over
 * lines, not sky. */
.rhythm__label {
  position: absolute;
  left: 0;
  top: 0;
  font-size: 10.5px;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
  white-space: nowrap;
  opacity: 0;
  will-change: transform, opacity;
}
.rhythm__label--hour {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
}
.rhythm__label--today,
.rhythm__label--next {
  color: var(--accent-bright);
}
.rhythm__label--next {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55em;
  padding: 6px 10px 5px;
  border: 1px solid color-mix(in srgb, var(--accent-bright) 30%, transparent);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--background) 84%, transparent);
}
.rhythm__label--next b {
  font-weight: 650;
  letter-spacing: 0.04em;
}

/* Landscape phones keep the caption beside the stack, with less room for both. */
@media (max-height: 520px) and (orientation: landscape) {
  .rhythm.is-live .rhythm__caption .h2,
  .rhythm.is-live .rhythm__caption .h3 {
    font-size: clamp(26px, 4vw, 34px);
  }
  .rhythm.is-live .rhythm__caption p:not(.eyebrow) {
    font-size: 15px;
    line-height: 1.5;
  }
  .rhythm__label--next {
    padding: 5px 8px 4px;
    font-size: 10px;
  }
}

/* ---- Narrow portrait: the stack above, the caption below -------------------- */
@media (max-width: 939px) and (orientation: portrait) {
  .rhythm.is-live .rhythm__track {
    height: 280vh;
  }
  /* Centred in the space above the caption, where the stack will draw. */
  .rhythm.is-live .rhythm__static {
    top: 40%;
    left: var(--gutter);
    right: var(--gutter);
    width: auto;
    transform: translateY(-50%);
  }
  .rhythm.is-live .rhythm__caption {
    top: auto;
    bottom: max(28px, env(safe-area-inset-bottom));
    left: var(--gutter);
    right: var(--gutter);
    width: auto;
    max-width: 34em;
    transform: translateY(18px);
  }
  .rhythm.is-live .rhythm__caption.is-on {
    transform: none;
  }
  /* The caption owns the bottom here, so the note sits under the nav. */
  .rhythm.is-live .rhythm__sample {
    top: 81px;
    right: auto;
    bottom: auto;
    left: var(--gutter);
  }
  .rhythm.is-live .rhythm__caption .eyebrow {
    margin-bottom: 12px;
  }
  .rhythm.is-live .rhythm__caption .h2,
  .rhythm.is-live .rhythm__caption .h3 {
    margin-bottom: 12px;
    font-size: clamp(28px, 7.4vw, 40px);
  }
  .rhythm.is-live .rhythm__caption p:not(.eyebrow) {
    font-size: 16px;
    line-height: 1.55;
  }
  .rhythm__label--next {
    padding: 5px 8px 4px;
    font-size: 10px;
  }
}
