@import url("./tokens.css");
@import url("./base.css");
@import url("./pieces-tokens.css");
@import url("./pieces.css");

@font-face { font-family: "Rethink Sans"; src: url("./RethinkSans_600SemiBold.ttf") format("truetype"); font-weight: 600; font-display: swap; }

body { font-size: 1.0625rem; }
h1, h2 { letter-spacing: -0.03em; }
.wm { display: inline-flex; align-items: center; gap: var(--space-xs); font: 600 1.375rem/1 var(--font-display); letter-spacing: -0.02em; color: var(--color-ink-dark); text-decoration: none; }
.wm img { width: 34px; height: auto; }
.wm b { font-weight: 600; }
.wm span { color: color-mix(in oklab, var(--color-ink-dark) 74%, transparent); }
.wm--light { color: var(--color-ink); }
.wm--light span { color: color-mix(in oklab, var(--color-ink) 74%, transparent); }

/* nav: floating pill */
.nav { position: absolute; z-index: var(--z-sticky-nav); top: var(--space-lg); left: 0; right: 0; width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); display: flex; align-items: center; justify-content: space-between; gap: var(--space-lg); }
.nav__links { display: flex; align-items: center; gap: var(--space-xs); }
.nav a.link { padding: 0 var(--space-sm); font-size: var(--text-sm); color: var(--color-ink-2); text-decoration: none; white-space: nowrap; min-height: 44px; display: inline-flex; align-items: center; border-radius: var(--radius-pill); transition: background-color var(--dur-short) var(--ease-out); }
.nav a.link:hover { color: var(--color-ink); }
.nav a.link--join { background: var(--color-accent); color: var(--color-accent-ink); font-weight: 600; padding: 0 var(--space-lg); }
.nav a.link--join:hover { background: var(--color-ink-2); color: var(--color-accent-ink); }
.nav a:focus-visible, .nav .wm:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.wm:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* controls */
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 var(--space-lg); border: 1px solid var(--color-accent); border-radius: var(--radius-pill); background: var(--color-accent); color: var(--color-accent-ink); font: 600 1.0625rem/1 var(--font-body); white-space: nowrap; cursor: pointer; transition: background-color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out); }
.btn:hover { background: var(--color-ink-2); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 3px; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.signup { width: 100%; max-width: 30rem; }
.signup label { display: block; margin-bottom: var(--space-xs); font-size: var(--text-sm); color: var(--color-ink-2); }
.signup__row { display: flex; gap: var(--space-xs); }
.signup input { flex: 1; min-width: 0; min-height: 52px; padding: 0 var(--space-lg); border: 1px solid color-mix(in oklab, var(--color-ink) 42%, transparent); border-radius: var(--radius-pill); background: color-mix(in oklab, var(--color-paper) 55%, transparent); color: var(--color-ink); font-size: 1.0625rem; outline: 2px solid transparent; outline-offset: -3px; }
.signup input::placeholder { color: var(--color-muted); }
.signup input:hover { border-color: var(--color-ink-2); }
.signup input:focus-visible { outline-color: var(--color-focus); }
.signup input[aria-invalid] { border-color: var(--color-error); }
.signup input:disabled { opacity: 0.55; cursor: not-allowed; }
.signup__help { min-height: 1lh; margin-top: var(--space-xs); font-size: var(--text-sm); color: var(--color-ink-2); }

/* real app screens: frameless, rounded like the glass, lit from below */
.screen { margin: 0; border-radius: var(--radius-screen); overflow: hidden; box-shadow: var(--shadow-screen); outline: 1px solid var(--color-edge); outline-offset: -1px; background: var(--color-surface); }
.story--reflect .screen { aspect-ratio: 1170 / 2532; }
/* The Journal keeps the frame of the screen it replaced (406 by 1028 board points), so its fade sits where it did. */
.hero__float { margin: 0; aspect-ratio: 406 / 1028; background: none; overflow: hidden; }
.story--stoke .tile { aspect-ratio: 390 / 452; }
.noticed { position: relative; min-height: 640px; }
.noticed__photo { position: absolute; inset: 0 var(--space-3xl) 0 0; margin: 0; border-radius: var(--radius-card); overflow: hidden; }
.noticed__photo > picture > img { object-position: 58% 50%; }
.piece { position: absolute; z-index: 2; margin: 0; width: 400px; }
.piece--1 { top: var(--space-xl); right: 0; }
.piece--2 { top: 42%; left: calc(-1 * var(--space-lg)); }
.piece--3 { bottom: var(--space-xl); right: var(--space-lg); }
.story--spots .tile { border-radius: 31px; }
.story .tile.tile--invert { background: var(--color-paper); box-shadow: none; outline: 0; }
.msgs { margin: 0; background: none; }
.tile { margin: 0; border-radius: var(--radius-card); overflow: hidden; box-shadow: var(--shadow-screen); background: var(--color-surface); }

/* hero: Poster, the Journal rising out of the photo */
.hero { position: relative; height: clamp(720px, 100svh, 920px); overflow: hidden; isolation: isolate; }
.hero__photo { position: absolute; inset: 0; z-index: 0; margin: 0; }
.hero__photo > picture > img { object-position: 44% 62%; }
.hero__scrim { position: absolute; inset: 0; z-index: 2; background: linear-gradient(180deg, var(--color-scrim) 0%, var(--color-scrim-0) 16%), linear-gradient(180deg, var(--color-scrim-0) 30%, var(--color-scrim) 100%), linear-gradient(90deg, var(--color-scrim) 0%, var(--color-scrim-0) 55%); pointer-events: none; }
.hero__inner { position: relative; z-index: 3; height: 100%; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap-columns); }
.hero__text { grid-column: 1 / 7; align-self: end; padding-bottom: var(--space-3xl); display: grid; gap: var(--space-lg); justify-items: start; }
/* The minimum is capped in vw (equal to 2.75rem at 320px), so a doubled root font can't push the headline off a phone. */
.hero h1 { max-width: 15ch; font-size: clamp(min(2.75rem, 13.75vw), 3.6vw + 1rem, 4.5rem); line-height: 1.02; }
.hero .lead { color: var(--color-ink); font-size: var(--text-lead); }
.hero .signup { margin-top: var(--space-sm); }
/* The Journal: its own column at the container's right edge, running off the hero's foot, and it scrolls (wheel, touch,
   keyboard). Fades at the foot, and at the head once scrolled (.is-scrolled, reveal.ts). */
.hero__screen { position: absolute; top: calc(var(--space-3xl) + var(--space-md)); bottom: 0; right: var(--gutter); width: 372px; aspect-ratio: auto; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; border-radius: var(--radius-card) var(--radius-card) 0 0; --fade-top: var(--mask-on); -webkit-mask-image: linear-gradient(180deg, var(--fade-top) 0, var(--mask-on) var(--space-xl), var(--mask-on) calc(100% - var(--space-3xl) - var(--space-xl)), var(--mask-off) 100%); mask-image: linear-gradient(180deg, var(--fade-top) 0, var(--mask-on) var(--space-xl), var(--mask-on) calc(100% - var(--space-3xl) - var(--space-xl)), var(--mask-off) 100%); }
.hero__screen.is-scrolled { --fade-top: var(--mask-off); }
.hero__screen::-webkit-scrollbar { display: none; }
.hero__screen:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 4px; }
.hero__screen .feed { margin: 0 0 calc(var(--space-3xl) + var(--space-xl)) auto; }
/* The surfer sits halfway between the headline and the Journal. */
.hero__photo > picture > img { transform: scale(1.06); transform-origin: 100% 60%; }

/* stories */
.story { position: relative; padding-block: var(--section-gap-s); }
.story__inner { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap-columns); align-items: center; }
.story__text { display: grid; gap: var(--space-lg); }
.story__text p { font-size: var(--text-lead); line-height: 1.5; color: var(--color-ink-2); max-width: 45ch; }
.story h2 { max-width: 13ch; font-size: clamp(2.25rem, 2.6vw + 1rem, 3.75rem); line-height: 1.04; }

.story--stoke .story__inner { justify-items: center; text-align: center; row-gap: var(--space-2xl); }
.story--stoke .story__text { grid-column: 3 / 11; justify-items: center; }
.story--stoke .story__text p { margin-inline: auto; }
.story--stoke h2 { margin-inline: auto; max-width: none; }
.story--stoke .story__media { grid-column: 4 / 10; justify-self: center; }
.rec { display: grid; justify-items: center; padding-block: var(--space-xl); }
.rec__time { display: inline-flex; align-items: center; gap: var(--space-sm); font: 600 clamp(2.5rem, 2vw + 1.5rem, 3.5rem)/1 var(--font-display); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--color-ink); }
.rec__dot { width: 14px; height: 14px; border-radius: var(--radius-pill); background: var(--color-alert); }
.rec__ring { width: 260px; height: 260px; }
.rec__track { stroke: color-mix(in oklab, var(--color-ink) 18%, transparent); }
.rec__arc { stroke: var(--color-ink); stroke-dasharray: 100; stroke-dashoffset: 95.3; }
.rec__pulse { transform-box: fill-box; transform-origin: center; }
@keyframes rec-pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(0.93); opacity: 0.72; } }
@keyframes rec-blink { 50% { opacity: 0.35; } }
.rec__soft { stroke: color-mix(in oklab, var(--color-ink) 28%, transparent); }
.rec__btn { stroke: color-mix(in oklab, var(--color-ink) 85%, transparent); }
.rec__stop { fill: var(--color-ink); }
.rec__hint { font-size: var(--text-lead); color: var(--color-ink-2); }

.story--notice { padding-top: var(--section-gap-s); }
.story--notice .story__media { grid-column: 1 / 8; }
.story--notice .story__text { grid-column: 8 / 13; }
.story--notice .tile { width: 520px; max-width: 100%; }

.story--reflect { padding-block: 0; background: var(--color-band); color: var(--color-ink-dark); overflow: hidden; }
.story--reflect .reflect__photo { position: absolute; inset: 0; margin: 0; z-index: 0; }
.story--reflect .reflect__photo > picture > img { object-position: 45% 70%; }
.story--reflect .reflect__photo::after { content: ""; position: absolute; inset: 0; z-index: 2; background: linear-gradient(90deg, var(--color-band) 0%, var(--color-band-0) 60%); }
.story--reflect .story__inner { position: relative; z-index: 2; min-height: 860px; }
.story--reflect .story__text { grid-column: 1 / 6; padding-block: var(--space-3xl); }
.story--reflect .story__text p { color: var(--color-ink-dark); }
.story--reflect .story__media { grid-column: 9 / 13; justify-self: end; width: 420px; max-width: 100%; }

.story--spots .story__media { grid-column: 7 / 12; justify-self: center; width: 460px; max-width: 100%; }
.spots { display: grid; gap: var(--space-lg); }
.lived { display: grid; gap: var(--space-xs); padding-inline: var(--space-lg); }
.lived__meta { font-size: var(--text-sm); color: var(--color-ink-2); }
.lived__title { font: 600 clamp(1.5rem, 1vw + 1rem, 2rem)/1.2 var(--font-display); letter-spacing: -0.02em; color: var(--color-ink); text-wrap: balance; }
.story--spots .story__text { grid-column: 1 / 6; grid-row: 1; }

/* close */
.close { padding-block: var(--section-gap-s) var(--section-gap); border-top: var(--rule-hair) solid var(--color-rule); }
.close__inner { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap-columns); align-items: end; row-gap: var(--space-xl); }
.close h2 { grid-column: 1 / 8; max-width: 16ch; font-size: clamp(min(2.5rem, 12.5vw), 3.4vw + 1rem, 4.5rem); line-height: 1.02; }
.close__form { grid-column: 8 / 13; display: grid; gap: var(--space-lg); }
.close__form p { color: var(--color-ink-2); }
/* Text columns never grow past their track (an email input's intrinsic width would, at a large root font). */
.hero__text, .close__form { grid-template-columns: minmax(0, 1fr); }
.hero__text > *, .close__form > * { min-width: 0; max-width: 100%; }

/* footer: colophon block */
.foot { padding-block: var(--space-2xl); border-top: var(--rule-hair) solid var(--color-rule); }
.foot__inner { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--gap-columns); align-items: start; }
.foot p { font-size: var(--text-sm); color: var(--color-ink-2); max-width: 60ch; }
.foot p + p { margin-top: var(--space-sm); }
.foot a { color: var(--color-ink); }

/* dusk: every story over its own late-evening photograph */
.dusk .story--photo { position: relative; overflow: hidden; isolation: isolate; }
.dusk .story--photo .bg { position: absolute; inset: 0; margin: 0; z-index: 0; }
.dusk .story--photo .bg::after { content: ""; position: absolute; inset: 0; z-index: 2; background: linear-gradient(90deg, var(--color-scrim) 0%, var(--color-scrim) 30%, var(--color-scrim-0) 66%); }
.dusk .close .bg > picture > img { transform: scaleX(-1); }
.dusk .story--stoke .bg::after { background: linear-gradient(270deg, color-mix(in oklab, var(--color-surface) 72%, transparent) 0%, color-mix(in oklab, var(--color-surface) 40%, transparent) 42%, color-mix(in oklab, var(--color-surface) 0%, transparent) 62%); }
.dusk .close h2, .dusk .close .close__form { grid-column: 1 / 7; }
.dusk .close .close__inner { align-content: center; }
.dusk .story--photo .story__inner { position: relative; z-index: 3; min-height: 720px; }
.dusk .close.story--photo { padding-block: var(--section-gap); border-top: 0; }
.dusk .close .close__inner { position: relative; z-index: 3; min-height: 520px; }

@media (max-width: 60rem) {
  .nav a.link:not(.link--join) { display: none; }
  .hero { height: auto; min-height: 860px; }
  .hero__inner, .story__inner, .close__inner, .foot__inner { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-2xl); }
  .hero__text { grid-column: 1 / -1; padding-top: calc(var(--space-3xl) + var(--space-lg)); padding-bottom: 0; align-self: start; }
  .hero__screen { position: relative; top: auto; right: auto; bottom: auto; grid-column: 1 / -1; width: min(100%, 320px); height: 560px; overflow: hidden; margin-bottom: 0; border-radius: 0; }
  .story__text, .story__media, .close h2, .close__form,
  .story--stoke .story__text, .story--stoke .story__media, .story--notice .story__media, .story--notice .story__text,
  .story--reflect .story__text, .story--reflect .story__media, .story--spots .story__media, .story--spots .story__text { grid-column: 1 / -1; grid-row: auto; width: auto; justify-self: stretch; }
  .story--reflect .story__media { width: min(100%, 360px); justify-self: center; }
  .story--stoke .story__media { justify-self: center; }
  .rec__ring { width: 208px; height: 208px; }
  .story--notice .story__text { grid-row: 1; }
  .noticed { min-height: 0; display: grid; gap: var(--space-md); }
  .noticed__photo { position: relative; inset: auto; aspect-ratio: 4 / 3; }
  .piece { position: relative; inset: auto; width: min(100%, 360px); }
  .hero__screen { justify-self: center; margin-top: 0; }
  .story--reflect .story__text { padding-bottom: 0; }
  .story--reflect .reflect__photo::after { content: ""; position: absolute; inset: 0; z-index: 2; background: color-mix(in oklab, var(--color-band) 45%, transparent); }
}
@media (max-width: 40rem) {
  .nav a.link:not(.link--join) { display: none; }
  .nav .wm { font-size: 1.125rem; gap: var(--space-2xs); }
  .nav .wm img { width: 26px; }
  .nav a.link--join { padding: 0 var(--space-sm); font-size: 0.875rem; }
  .signup__row { flex-direction: column; }
  .signup .btn { white-space: normal; text-align: center; padding-block: var(--space-xs); }
}
@media (prefers-reduced-motion: reduce) {
  .btn, .nav a.link { transition: background-color var(--dur-short) linear; }
  .btn:active { transform: none; }
}
@media (max-width: 22.5rem) { .nav .wm b { display: none; } }
.story figure.piece { background: none; overflow: visible; }

.story--bleed .story__inner { min-height: 900px; justify-items: start; text-align: left; row-gap: var(--space-xl); align-content: center; }
.story--bleed .story__text { grid-column: 1 / 6; justify-items: start; }
.story--bleed .story__text p { margin-inline: 0; }
.story--bleed h2 { margin-inline: 0; }
.story--bleed .story__media { grid-column: 1 / 6; justify-self: start; justify-items: center; padding-block: 0; }
@media (max-width: 60rem) {
  .story--bleed .story__inner { min-height: 0; }
  .story--bleed .story__text, .story--bleed .story__media { grid-column: 1 / -1; }
}
.dusk .story--bleed .bg::after { background: linear-gradient(90deg, var(--color-scrim) 0%, var(--color-scrim) 34%, var(--color-scrim-0) 62%); }
.dusk .story--bleed .bg > picture > img { object-position: 78% 60%; }
@media (max-width: 60rem) {
  .dusk .story--bleed .bg::after { background: linear-gradient(180deg, var(--color-scrim) 0%, var(--color-scrim) 55%, var(--color-scrim-0) 100%); }
  .dusk .story--bleed .bg > picture > img { object-position: 70% 60%; }
}

/* layout pass, 2026-11-04 */
/* stoke: text and recorder share one centre axis, so the timer and Tap to stop no longer hang off the ring; the scrim fades in steps, no seam */
.story--bleed .story__inner { min-height: 820px; }
.story--bleed .story__text, .story--bleed .story__media { grid-column: 1 / 6; justify-self: stretch; justify-items: center; text-align: center; }
.story--bleed .story__text p { margin-inline: auto; }
.story--bleed .story__media { margin-top: var(--space-lg); }
.dusk .story--bleed .bg::after { background: linear-gradient(90deg, var(--color-scrim) 0%, var(--color-scrim) 26%, color-mix(in oklab, var(--color-scrim) 72%, transparent) 40%, color-mix(in oklab, var(--color-scrim) 34%, transparent) 52%, var(--color-scrim-0) 64%); }

/* noticed: one photo, three cards that never touch each other or the surfer; two hang over the photo's edges */
.noticed { height: 640px; min-height: 0; }
.noticed__photo { inset: 0 120px 0 0; }
.noticed__photo > picture > img { object-position: 100% 50%; }
.piece { width: 360px; }
.piece--1 { top: -28px; right: 0; left: auto; bottom: auto; }
.piece--2 { top: 220px; right: var(--space-lg); left: auto; bottom: auto; }
.piece--3 { top: auto; bottom: -36px; right: 0; left: auto; }

@media (max-width: 60rem) {
  .story--bleed { display: flex; flex-direction: column; padding-bottom: 0; }
  .story--bleed .story__inner { order: 1; }
  .story--bleed .story__text, .story--bleed .story__media { grid-column: 1 / -1; }
  .dusk .story--bleed .bg { order: 2; position: relative; inset: auto; aspect-ratio: 4 / 3; margin-top: 0; }
  .dusk .story--bleed .bg::after { background: linear-gradient(180deg, var(--color-paper) 0%, var(--color-scrim-0) 40%); }
  .dusk .story--bleed .bg > picture > img { object-position: 68% 60%; }
  .noticed { height: auto; gap: 0; }
  .noticed__photo { inset: auto; }
  .noticed__photo > picture > img { object-position: 62% 50%; }
  .piece, .piece--1, .piece--2, .piece--3 { inset: auto; width: 100%; max-width: 380px; justify-self: center; }
  .piece--1 { margin-top: calc(-1 * var(--space-2xl)); }
  .piece--2, .piece--3 { margin-top: calc(-1 * var(--space-md)); }
}
@media (max-width: 60rem) { .story--reflect .story__inner { padding-bottom: var(--space-2xl); } }
.story--reflect .story__inner { padding-block: var(--space-2xl); }
.story h2.h2-fixed { max-width: 100%; }
.story h2.h2-notice { width: min(521px, 100%); }
.story h2.h2-reflect { width: min(502px, 100%); }
@media (max-width: 60rem) { .story h2.h2-fixed { width: auto !important; } }
@media (max-width: 60rem) {
  .story--spots .story__text { grid-row: 1; }
  .story--spots .story__media { grid-row: 2; }
  .story--spots .lived { padding-inline: 0; }
  .story--reflect .story__text { padding-block: 0; }
  .dusk .close .bg::after { background: linear-gradient(180deg, var(--color-scrim) 0%, var(--color-scrim) 55%, color-mix(in oklab, var(--color-scrim) 55%, transparent) 100%); }
}

/* phone polish: each heading sits close to its picture, sections sit apart, photos are shown, not buried */
@media (max-width: 60rem) {
  .story { padding-block: var(--space-3xl); }
  .story__inner { row-gap: var(--space-xl); }
  .story__text { gap: var(--space-md); }

  .dusk .story--bleed .bg { aspect-ratio: 1 / 1; }
  .dusk .story--bleed .bg > picture > img { object-position: 70% 62%; }

  .noticed__photo { aspect-ratio: 1 / 1; }
  .noticed__photo > picture > img { object-position: 60% 50%; }
  .piece--1 { margin-top: calc(-1 * var(--space-xl)); }

  .story--reflect { display: flex; flex-direction: column; padding-block: 0 var(--space-3xl); }
  .story--reflect .reflect__photo { position: relative; inset: auto; aspect-ratio: 4 / 3; }
  .story--reflect .reflect__photo::after { background: linear-gradient(180deg, var(--color-band-0) 45%, var(--color-band) 100%); }
  .story--reflect .story__inner { min-height: 0; padding-block: 0; margin-top: calc(-1 * var(--space-xl)); }

  .dusk .close.story--photo { display: flex; flex-direction: column; padding-block: 0 var(--space-3xl); }
  .dusk .close .bg { position: relative; inset: auto; aspect-ratio: 4 / 3; }
  .dusk .close .bg::after { background: linear-gradient(180deg, var(--color-scrim-0) 40%, var(--color-paper) 100%); }
  .dusk .close .close__inner { min-height: 0; margin-top: calc(-1 * var(--space-xl)); }
}
@media (max-width: 60rem) { .story--bleed { padding-bottom: 0; } }
@media (max-width: 60rem) {
  .story--bleed .rec { padding-bottom: 0; }
  .dusk .story--bleed .bg { margin-top: var(--space-lg); }
  .dusk .close .bg::after { background: linear-gradient(180deg, var(--color-paper) 0%, var(--color-scrim-0) 22%, var(--color-scrim-0) 45%, var(--color-paper) 100%); }
  .dusk .close .close__inner { row-gap: var(--space-lg); }
}
@media (max-width: 60rem) { .dusk .story--photo .story__inner { min-height: 0; } }

.story ol.msgs { aspect-ratio: auto; display: flex; flex-direction: column; gap: var(--space-lg); margin: 0; padding: 0; list-style: none; }
.close__form p { max-width: 40ch; }
.foot__links { display: flex; flex-wrap: wrap; gap: var(--space-md); }

/* Tap targets: every link is at least 44px tall. Negative margins give the extra height back, so nothing moves. */
.wm { min-height: 44px; min-width: 44px; }
.foot .wm { margin-block: min(0px, calc((max(34px * 1076 / 1424, 1.375rem) - 44px) / 2)); }
.foot__links a { display: inline-flex; align-items: center; min-height: 44px; margin-block: min(0px, calc((1lh - 44px) / 2)); }
.signup__trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* Focal points per photo. They sit last and specific enough to win at every width (the CSP forbids style attributes). */
html body.dusk .hero__photo > picture > img.pos-hero { object-position: 60% 50%; }
html body.dusk .story .bg > picture > img.pos-stoke { object-position: 72% 60%; }
html body.dusk .bg > picture > img.pos-close { object-position: 50% 60%; }

/* privacy notice: the same nav and footer, a readable column */
.legal { padding-block: calc(var(--space-3xl) + var(--space-2xl)) var(--section-gap-s); }
.legal__inner { display: grid; gap: var(--space-2xl); }
.legal h1 { max-width: none; font-size: clamp(2.5rem, 3vw + 1rem, 4rem); }
.legal__list { margin: 0; display: grid; max-width: 40rem; }
.legal__item { display: grid; gap: var(--space-xs); padding-block: var(--space-lg); border-top: var(--rule-hair) solid var(--color-rule); }
.legal__item:last-child { border-bottom: var(--rule-hair) solid var(--color-rule); }
.legal dt { font: 600 var(--text-title)/1.2 var(--font-display); letter-spacing: -0.02em; }
.legal dd { margin: 0; color: var(--color-ink-2); line-height: 1.55; max-width: 65ch; }
.legal dd a { color: var(--color-ink); }
.legal__inner > * { min-width: 0; }
.legal dd { overflow-wrap: anywhere; }
.legal dd a[href^="mailto:"] { display: inline-block; padding-block: max(0px, calc((44px - 1lh) / 2)); margin-block: min(0px, calc((1lh - 44px) / 2)); }
/* A text column never grows past its track. */
.story__text, .story__text > * { min-width: 0; }

/* ---- motion (src/reveal.ts, src/tide.ts): each piece plays once on screen; with JS off or reduced motion it's shown finished ---- */

/* The recorder's take: recording, the stop pressed, transcribing, then her note word by word. */
.rec__live, .rec__note { grid-area: 1 / 1; }
.rec__live { display: grid; justify-items: center; gap: var(--space-xl); }
/* The clock line keeps its height when it turns into "Transcribing 0:48…", so the ring doesn't move. */
.rec__time { height: clamp(2.5rem, 2vw + 1.5rem, 3.5rem); }
.rec__spin { stroke: var(--color-ink); stroke-dasharray: 16 84; opacity: 0; transform-box: fill-box; transform-origin: center; }
.rec__note { display: none; }
html.js .rec__note { display: grid; align-self: center; gap: var(--space-xs); width: min(100%, 26rem); padding: var(--space-lg); border-radius: var(--radius-card); background: var(--color-surface); box-shadow: var(--shadow-screen); container-type: inline-size; opacity: 0; transform: translateY(var(--space-sm)) scale(0.98); pointer-events: none; }
html.js .rec__note > p { --pt: calc(100cqw / 360); }
html.js .rec__note .rec__words { font-size: var(--text-lead); line-height: 1.45; }
html.js .rec__words > span { opacity: 0; }
html.js .rec .rec__arc { transition: stroke-dashoffset 1s linear, opacity var(--dur-short) var(--ease-out); }
html.js .rec.is-recording .rec__pulse { animation: rec-pulse 1.8s var(--ease-in-out) infinite; }
html.js .rec.is-recording .rec__dot { animation: rec-blink 1.6s var(--ease-in-out) infinite; }
html.js .rec .rec__pulse { transition: transform var(--dur-short) var(--ease-out), opacity var(--dur-short) var(--ease-out); }
html.js .rec.is-stopping .rec__pulse { transform: scale(0.9); }
html.js .rec .rec__time, html.js .rec .rec__hint { transition: opacity var(--dur-short) var(--ease-out); }
html.js .rec.is-transcribing .rec__time { font-size: var(--text-lead); font-family: var(--font-body); font-weight: 400; color: var(--color-ink-2); letter-spacing: 0; }
html.js .rec.is-transcribing .rec__dot, html.js .rec.is-transcribing .rec__hint { opacity: 0; }
html.js .rec.is-transcribing .rec__arc { opacity: 0; }
html.js .rec.is-transcribing .rec__spin { opacity: 1; animation: rec-spin 1.1s linear infinite; }
html.js .rec.is-transcribing .rec__pulse { opacity: 0.45; }
html.js .rec.is-noted .rec__live { opacity: 0; transform: scale(0.94); transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-long) var(--ease-out); }
html.js .rec.is-noted .rec__note { opacity: 1; transform: none; pointer-events: auto; transition: opacity var(--dur-long) var(--ease-out) 120ms, transform 600ms var(--ease-out) 120ms; }
html.js .rec.is-noted .rec__words > span { opacity: 1; transition: opacity 260ms var(--ease-out); transition-delay: calc(360ms + var(--i) * 55ms); }
@keyframes rec-spin { to { transform: rotate(360deg); } }

/* Reflect plays as a conversation: her spoken reply shows its recording, the coach its three dots, then the words. */
.msgs > li { position: relative; }
.wait { display: none; }
html.js .msgs.is-pending > li > .bubble { opacity: 0; transform: translateY(var(--space-xs)); transition: opacity var(--dur-long) var(--ease-out), transform var(--dur-long) var(--ease-out); }
html.js .msgs.is-pending > li:is(.is-in, .is-streaming) > .bubble { opacity: 1; transform: none; }
html.js .msgs.is-pending > li.is-streaming .w { opacity: 0; animation: word-in 240ms var(--ease-out) forwards; animation-delay: calc(var(--i) * 45ms); }
@keyframes word-in { to { opacity: 1; } }
html.js .msgs.is-pending > li.is-waiting > .wait { display: flex; position: absolute; top: var(--pc-space-1); animation: wait-in var(--dur-short) var(--ease-out); }
@keyframes wait-in { from { opacity: 0; transform: translateY(var(--space-xs)); } }
.msg--me .wait { right: var(--pc-space-1); }
.msg--coach .wait { left: var(--pc-space-1); }
/* The voice reply while it records (ChatInput's recording row): a moving wave and its length. */
.wait--voice { align-items: center; gap: var(--pc-space-3); padding: var(--pc-space-3) var(--pc-space-4); border-radius: var(--pc-radius-md); border-bottom-right-radius: var(--pc-radius-xs); background: var(--app-sea-soft); color: var(--app-ink); }
.wave { display: flex; align-items: center; gap: calc(3 * var(--pt)); height: calc(18 * var(--pt)); }
.wave > i { width: calc(3 * var(--pt)); height: 100%; border-radius: var(--pc-radius-pill); background: var(--app-sea); transform: scaleY(0.35); animation: wave 900ms var(--ease-in-out) infinite; }
.wave > i:nth-child(2) { animation-delay: 120ms; } .wave > i:nth-child(3) { animation-delay: 240ms; } .wave > i:nth-child(4) { animation-delay: 360ms; } .wave > i:nth-child(5) { animation-delay: 480ms; }
@keyframes wave { 50% { transform: scaleY(1); } }
/* The coach is writing (ChatMessage TypingBubble): three sea dots in a white bubble, 400 ms up, 400 ms down, 200 ms apart. */
.wait--dots { gap: var(--pc-space-1); padding: var(--pc-space-4); border-radius: var(--pc-radius-md); border-bottom-left-radius: var(--pc-radius-xs); background: var(--app-surface); border: 1px solid var(--app-edge); }
.wait--dots > i { width: calc(8 * var(--pt)); height: calc(8 * var(--pt)); border-radius: var(--pc-radius-pill); background: var(--app-sea); opacity: 0.35; animation: dot 800ms var(--ease-in-out) infinite; }
.wait--dots > i:nth-child(2) { animation-delay: 200ms; } .wait--dots > i:nth-child(3) { animation-delay: 400ms; }
@keyframes dot { 50% { opacity: 1; } }

/* The tide reads like the app's: drag, hover or the arrow keys move the line. */
.fc__tide { touch-action: pan-y; user-select: none; cursor: ew-resize; border-radius: var(--radius-xs); }
.fc__tide:focus-visible { outline: 2px solid var(--color-focus); outline-offset: var(--space-xs); }

/* Each section is a page: it fills the screen, and the next slides up over it while it settles back. Only a section
   that fits the screen sticks (data-fits, set by reveal.ts pages()); a taller one scrolls on as usual. */
html { scroll-padding-top: 0; }
main > section { min-height: 100svh; background-color: var(--color-paper); }
main > section[data-fits] { position: sticky; top: 0; }
main > section:not(.hero) { border-radius: var(--radius-card) var(--radius-card) 0 0; box-shadow: var(--shadow-page); }
.story--notice, .story--spots { background: var(--color-paper); }
.foot { position: relative; background: var(--color-paper); }
@media (min-width: 60rem) {
  main > section.story, main > section.close { display: grid; align-content: center; }
  .story--bleed .story__inner, .story--reflect .story__inner, .dusk .story--photo .story__inner, .dusk .close .close__inner { min-height: 0; }
  .noticed { height: clamp(520px, 100svh - 2 * var(--section-gap-s), 640px); }
  .piece--2 { top: 36%; }
}
/* Each section settles back on the next one's arrival, by name: the Journal's screen shows on a phone only. */
body { timeline-scope: --p-journal, --p-stoke, --p-notice, --p-reflect, --p-spots, --p-close; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .story--journal { view-timeline: --p-journal block; }
    .story--stoke { view-timeline: --p-stoke block; }
    .story--notice { view-timeline: --p-notice block; }
    .story--reflect { view-timeline: --p-reflect block; }
    .story--spots { view-timeline: --p-spots block; }
    main > section.close { view-timeline: --p-close block; }
    main > section { transform-origin: 50% 100%; }
    main > section::before { content: ""; position: absolute; inset: 0; z-index: var(--z-raised); background: var(--color-scrim); opacity: 0; pointer-events: none; border-radius: inherit; }
    main > section, main > section::before { animation: linear both; animation-range: entry 0% entry 100%; }
    main > section[data-fits] { animation-name: page-settle; }
    main > section[data-fits]::before { animation-name: page-dim; }
    .hero, .hero::before, .story--journal, .story--journal::before { animation-timeline: --p-stoke; }
    .story--stoke, .story--stoke::before { animation-timeline: --p-notice; }
    .story--notice, .story--notice::before { animation-timeline: --p-reflect; }
    .story--reflect, .story--reflect::before { animation-timeline: --p-spots; }
    .story--spots, .story--spots::before { animation-timeline: --p-close; }
    /* The close is where the visitor stops: it never recedes under the footer. */
    main > section.close, main > section.close::before { animation: none; }
    @media (max-width: 60rem) { .hero, .hero::before { animation-timeline: --p-journal; } }
    @keyframes page-settle { to { transform: scale(0.94); } }
    @keyframes page-dim { to { opacity: 0.7; } }
  }
}
@media (prefers-reduced-motion: reduce) {
  .wave > i, .wait--dots > i { animation: none; }
}
/* On a phone the list is below the heading: it grows message by message instead of holding empty room for all five. */
@media (max-width: 60rem) {
  html.js .msgs.is-pending > li.is-waiting { min-height: calc(56 * var(--pt)); }
}

/* ---- The phone: a second composition. Each section is one screen
   with its photo behind it, so each sticks as a page; on a screen too short for one it simply scrolls on. ---- */
main > section.story.story--journal { display: none; }
.journal__feed { margin: 0; container-type: inline-size; }
@media (max-width: 60rem) {
  main > section.story, main > section.close { padding-block: var(--space-2xl) var(--space-xl); display: flex; flex-direction: column; justify-content: center; }
  main > section .story__inner, main > section .close__inner { position: relative; z-index: 3; width: 100%; min-height: 0; margin-top: 0; row-gap: var(--space-lg); }
  .story h2 { font-size: clamp(2rem, 8.5vw, 2.5rem); }
  .story__text p { font-size: 1.0625rem; }
  /* Every photo is the screen's ground, as on the desktop: no stacked photo blocks, no seams. */
  .dusk .story--photo .bg, .dusk .story--bleed .bg, .dusk .close .bg, .story--reflect .reflect__photo { position: absolute; inset: 0; order: 0; margin: 0; aspect-ratio: auto; }

  /* Hero, Poster: the photo is the screen; the headline, its line and the form sit low on the dark water. */
  .hero { height: 100svh; min-height: 0; }
  .hero__inner { height: 100%; display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: var(--space-lg); }
  .hero__text { padding: 0; gap: var(--space-md); }
  .hero h1 { font-size: clamp(2.25rem, 10.5vw, 2.75rem); max-width: 14ch; }
  .hero__screen { display: none; }
  html body.dusk .hero__photo > picture > img.pos-hero { object-position: 64% 50%; transform: none; }
  .hero__scrim { background: linear-gradient(180deg, var(--color-scrim) 0%, var(--color-scrim-0) 16%, var(--color-scrim-0) 34%, var(--color-scrim) 72%); }

  /* The Journal's own screen: the same water, lower down, with the feed rising out of it. */
  main > section.story.story--journal { display: flex; overflow: hidden; isolation: isolate; padding-block: var(--space-2xl) 0; justify-content: flex-start; }
  .journal__photo { position: absolute; inset: 0; z-index: 0; }
  html body.dusk .journal__photo > picture > img.pos-journal { object-position: 55% 100%; }
  .journal__photo::after { content: ""; position: absolute; inset: 0; z-index: 2; background: linear-gradient(180deg, var(--color-scrim) 0%, color-mix(in oklab, var(--color-scrim) 40%, transparent) 60%, var(--color-scrim) 100%); }
  .journal__feed { position: relative; z-index: 3; width: min(100% - 2 * var(--gutter), 380px); margin-inline: auto; height: calc(100svh - var(--space-2xl)); overflow: hidden; -webkit-mask-image: linear-gradient(180deg, var(--mask-on) 72%, var(--mask-off) 100%); mask-image: linear-gradient(180deg, var(--mask-on) 72%, var(--mask-off) 100%); }
  .journal__feed .feed { --pt: calc(100cqw / 350); width: 100%; margin: 0; }

  /* Share your stoke: the words up top, the recorder under them, the two surfers walking out at the foot. */
  .dusk .story--bleed .bg::after { background: linear-gradient(180deg, var(--color-scrim) 0%, var(--color-scrim) 45%, color-mix(in oklab, var(--color-scrim) 40%, transparent) 72%, var(--color-scrim-0) 100%); }
  html body.dusk .story .bg > picture > img.pos-stoke { object-position: 72% 100%; }
  .story--bleed .story__inner { row-gap: var(--space-md); }
  .story--bleed .rec { padding-block: var(--space-md) 0; }
  .rec__live { gap: var(--space-lg); }
  .rec__ring { width: 184px; height: 184px; }

  /* Bad waves are loud: the surfer's photo behind, the words, then the three cards stacked, each its own piece. */
  .story--notice { overflow: hidden; isolation: isolate; }
  .story--notice .story__inner { position: static; display: flex; flex-direction: column; align-items: stretch; }
  .story--notice .story__text { position: relative; z-index: 1; order: -1; }
  .noticed { position: static; display: grid; justify-items: center; gap: var(--space-sm); width: 100%; height: auto; }
  .noticed > .piece { position: relative; z-index: 1; }
  .noticed__photo { position: absolute; inset: 0; z-index: 0; aspect-ratio: auto; border-radius: 0; }
  .noticed__photo::after { content: ""; position: absolute; inset: 0; z-index: 2; background: linear-gradient(180deg, var(--color-scrim) 0%, color-mix(in oklab, var(--color-scrim) 60%, transparent) 34%, color-mix(in oklab, var(--color-scrim) 20%, transparent) 100%); }
  .noticed__photo > picture > img { object-position: 60% 60%; }
  .piece, .piece--1, .piece--2, .piece--3 { margin: 0; width: 100%; max-width: 380px; }
  .piece > .pc { margin: 0; }

  /* Reflect: the band behind the words, the surfer in the photo behind the conversation. */
  main > section.story--reflect { overflow: hidden; isolation: isolate; padding-block: var(--space-2xl) var(--space-xl); justify-content: flex-start; }
  .story--reflect .reflect__photo { z-index: 0; }
  .story--reflect .reflect__photo > picture > img { object-position: 30% 100%; }
  .story--reflect .reflect__photo::after { background: linear-gradient(180deg, var(--color-band) 0%, var(--color-band) 38%, color-mix(in oklab, var(--color-band) 40%, transparent) 70%, var(--color-band-0) 100%); }
  .story--reflect .story__inner { padding-block: 0; }
  .story ol.msgs { gap: var(--space-xs); }
  .story--reflect .story__text { gap: var(--space-sm); }

  /* Your spot has moods: the words, the surf it read, the forecast. */
  .story--spots .story__inner { row-gap: var(--space-lg); }
  .spots { gap: var(--space-md); }

  /* The close: the photo behind, the line and the form over its calm part. */
  .dusk .close.story--photo { padding-block: var(--space-2xl); justify-content: flex-end; }
  .dusk .close .bg::after { background: linear-gradient(180deg, var(--color-scrim-0) 20%, var(--color-scrim) 62%, var(--color-scrim) 100%); }
  .dusk .close .close__inner { row-gap: var(--space-md); }
}

/* ---- Review pass, 2026-11-04 ---- */
/* The Journal's focus ring: the fade mask would clip it, so a keyboard focus shows the column unmasked. */
.hero__screen:focus-visible { -webkit-mask-image: none; mask-image: none; }
/* The headline leads the hero, over the cards' white. */
.hero h1 { font-size: clamp(min(2.75rem, 13.75vw), 4.6vw + 1rem, 5.75rem); }
/* The two long statements get the measure to break once, at the sentence. */
@media (min-width: 60rem) {
  .story--reflect .story__text { grid-column: 1 / 7; }
  .story h2.h2-reflect { width: min(640px, 100%); }
  .story--spots .story__text { grid-column: 1 / 7; }
  .story--spots h2 { max-width: 22ch; }
  .story--spots .story__media { grid-column: 8 / 13; width: 540px; }
  .story--bleed { padding-block: var(--space-3xl); }
}
/* The close: its line reads at the hero line's size. */
.close__form p { font-size: var(--text-lead); max-width: 46ch; }
/* The footer sits on the page's columns; no rule over the tone step it already has. */
.foot { border-top: 0; }
@media (min-width: 60rem) { .foot__inner { grid-template-columns: repeat(12, minmax(0, 1fr)); } .foot__inner > .wm { grid-column: 1 / 7; } .foot__inner > div { grid-column: 7 / 13; } }
/* Tablet: the forecast keeps the page's margins and a readable size. */
@media (max-width: 60rem) { .story--spots .story__media { width: min(100%, 420px); justify-self: start; } }
@media (max-width: 60rem) {
  /* Phone close: the words up in the sky, the surfer and the sun clear below them. */
  .dusk .close.story--photo { justify-content: flex-start; }
  html body.dusk .bg > picture > img.pos-close { object-position: 30% 50%; }
  .dusk .close .bg::after { background: linear-gradient(180deg, var(--color-scrim) 0%, var(--color-scrim) 40%, var(--color-scrim-0) 70%); }
  /* Phone stoke: the words and the recorder up top, the two surfers walking out below the ring. */
  main > section.story--stoke { justify-content: flex-start; }
  .rec__ring { width: 160px; height: 160px; }
  /* Phone Reflect fits one screen with all five messages in place. */
  main > section.story--reflect { padding-block: var(--space-xl); }
}
@media (max-width: 60rem) { .story ol.msgs { gap: var(--space-2xs); } }
