/* Somewhere — the marketing site.
 *
 * The palette is the app's palette, copied value for value from
 * ios/Somewhere/Design/Palette.swift. Nothing here mixes a new one.
 *
 * Two voices carry the page: a serif for the photographer (prose, headlines)
 * and a mono for the instrument (labels, frame numbers, readouts). The app
 * works the same way — narration in body text, every number in SF Mono.
 *
 * The composition is a single centre axis. Everything hangs off it, and the
 * three-step spine is drawn on it, so the page reads top to bottom the way
 * the app runs first to last.
 *
 * Motion is one idea: a focus pull. Everything arrives fractionally out of
 * focus and resolves, the way a print comes up in the tray. Nothing here
 * slides in from the side.
 */

:root {
  --ground: #0d0c0b;
  --panel: #181614;
  --edge: #2a2724;
  --ink: #f0ebe2;
  --muted: #8f877c;
  --amber: #e07a4b;
  --amber-ink: #1a0e07;

  --hairline: rgba(42, 39, 36, 0.85);
  --amber-wash: rgba(224, 122, 75, 0.09);
  --amber-edge: rgba(224, 122, 75, 0.45);

  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  /* One rhythm for every section, so nothing drifts. */
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --stack: clamp(3.25rem, 6.5vw, 5.75rem);
  --measure: 33rem;

  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The room. A safelight is a dim amber lamp above the trays — the only
 * thing lighting a darkroom. It sits behind everything and never moves. */
body::before {
  content: "";
  position: fixed;
  inset: -20vh 0 auto;
  height: 90vh;
  background:
    radial-gradient(60% 55% at 50% 0%, rgba(224, 122, 75, 0.13), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

/* Grain. Film has it; flat black doesn't. Kept under 4% so it reads as
 * texture and never as noise. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

main,
.masthead,
.colophon { position: relative; z-index: 2; }

/* ─── type ─────────────────────────────────────────────────────────── */

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-optical-sizing: auto;
  letter-spacing: -0.015em;
  line-height: 1.08;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--amber); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
  border-radius: 2px;
}

/* The instrument voice. Uppercase, tracked at .08em — tight, the way a
 * camera engraves. The wordmark is the one place a wide track is earned. */
.label {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

.data {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
  color: var(--muted);
  letter-spacing: 0.08em;
}

.lede {
  font-family: var(--serif);
  font-size: clamp(1.0625rem, 1.6vw, 1.3125rem);
  line-height: 1.55;
  color: #cdc5b9;
}

.prose { color: #beb6aa; }

.amber { color: var(--amber); }
.em { font-style: italic; }

/* ─── shell ────────────────────────────────────────────────────────── */

.wrap {
  max-width: 78rem;
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--stack); }

/* Every section header sits on the centre axis. */
.head {
  text-align: center;
  max-width: 40rem;
  margin: 0 auto clamp(2rem, 4vw, 2.75rem);
}

.head h2 {
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  margin-top: 0.6rem;
}

.head-note { margin-top: 0.9rem; }

/* ─── masthead ─────────────────────────────────────────────────────── */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.25rem;
  border-bottom: 1px solid var(--hairline);
}

.wordmark {
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}

.wordmark:hover { color: var(--ink); }

.masthead-links {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
}

.masthead-links a {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
}

.masthead-links a:hover { color: var(--ink); }

/* ─── the appstore button ──────────────────────────────────────────── */

/* Live App Store CTA. */
.appstore {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 1.05rem;
  border: 1px solid var(--amber);
  background: var(--amber);
  color: var(--amber-ink);
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 2px;
  transition: background 160ms ease, color 160ms ease;
}

.appstore:hover { background: transparent; color: var(--amber); }
.appstore svg { width: 14px; height: 16px; fill: currentColor; flex: none; }

/* The full label is too wide to share a phone screen with the wordmark. */
.cta-short { display: none; }

.appstore[aria-disabled="true"] {
  background: transparent;
  color: var(--amber);
  border-style: dashed;
  cursor: default;
}

/* ─── hero ─────────────────────────────────────────────────────────── */

.hero {
  text-align: center;
  padding-block: clamp(3.5rem, 8vw, 6rem) var(--stack);
}

.hero h1 {
  font-size: clamp(2.375rem, 5.6vw, 4.25rem);
  max-width: 17ch;
  margin: 0 auto 1.5rem;
}

.hero .lede {
  max-width: 38rem;
  margin: 0 auto 2.25rem;
}


/* ─── scrub stage ──────────────────────────────────────────────────── */

.hero-scrub {
  --hero-inset: max(1.25rem, 5.5vh);
  height: 122vh;
  position: relative;
}

.hero-stage {
  --cl: 0.34;
  --ct: 0.33;
  --cw: 0.44;
  --ch: 0.44;
  --hero-scale: 1;
  --hero-tx: 0%;
  --hero-ty: 0%;
  --hero-rect: 0;
  --hero-found: 0;
  --hero-as: 1;
  position: sticky;
  top: var(--hero-inset);
  width: min(46rem, 100%);
  margin: 0 auto;
}

.hero-stage-frame {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--edge);
  border-radius: 2px;
  background: #000;
  aspect-ratio: 4 / 3;
  width: min(100%, calc((100vh - var(--hero-inset) - 1.5rem) * 4 / 3));
  max-height: calc(100vh - var(--hero-inset) - 1.5rem);
  margin-inline: auto;
}

.hero-zoom {
  position: absolute;
  inset: 0;
  transform-origin: 0 0;
  transform: scale(var(--hero-scale)) translate(var(--hero-tx), var(--hero-ty));
  will-change: transform;
}

.hero-asshot,
.hero-found {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.hero-found {
  position: absolute;
  inset: 0;
  opacity: var(--hero-found);
  z-index: 1;
  pointer-events: none;
}

.hero-crop-rect {
  position: absolute;
  left: calc(var(--cl) * 100%);
  top: calc(var(--ct) * 100%);
  width: calc(var(--cw) * 100%);
  height: calc(var(--ch) * 100%);
  border: 1.5px solid var(--amber);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.38);
  opacity: var(--hero-rect);
  pointer-events: none;
  border-radius: 1px;
  z-index: 2;
}

.hero-cap {
  position: absolute;
  left: 0.75rem;
  bottom: 0.65rem;
  z-index: 3;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.85);
  pointer-events: none;
}

.hero-cap-as { opacity: var(--hero-as); }
.hero-cap-found { opacity: var(--hero-found); }

.hero-stage.is-static {
  position: relative;
  top: auto;
  --hero-scale: 1;
  --hero-rect: 0;
  --hero-found: 1;
  --hero-as: 0;
}

.hero-stage.is-static .hero-zoom { opacity: 0; }
.hero-stage.is-static .hero-crop-rect { display: none; }

@media (prefers-reduced-motion: reduce) {
  .hero-scrub { height: auto; }
  .hero-stage {
    position: relative;
    top: auto;
    --hero-scale: 1;
    --hero-rect: 0;
    --hero-found: 1;
    --hero-as: 0;
  }
  .hero-zoom { opacity: 0; }
  .hero-crop-rect { display: none; }
}


.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  margin-bottom: clamp(3rem, 6vw, 4.5rem);
}

.steps-line {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.steps-line b { color: var(--ink); font-weight: 500; }

/* ─── the contact sheet (the signature) ────────────────────────────── */

.sheet-figure {
  margin: 0 auto;
  max-width: 54rem;
}

.sheet {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 5px;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: 3px;
}

.frame {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #000;
}

.frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  animation: develop 900ms ease-out forwards;
  animation-delay: calc(var(--i) * 65ms + 250ms);
}

/* The frame numbers run along the edge of a real contact sheet. */
.frame::after {
  content: attr(data-frame);
  position: absolute;
  left: 4px;
  bottom: 3px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: rgba(240, 235, 226, 0.78);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
}

.frame.keeper::after { color: var(--amber); }

@keyframes develop {
  from { opacity: 0; filter: brightness(0.25) contrast(0.7); }
  to   { opacity: 1; filter: none; }
}

/* The grease-pencil ring. A real one overshoots its corners and never
 * closes cleanly — that's the whole charm, so the path is drawn by hand. */
.ring {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  overflow: visible;
}

.ring path {
  fill: none;
  stroke: var(--amber);
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-dasharray: 400;
  stroke-dashoffset: 400;
  animation: draw 950ms cubic-bezier(0.4, 0, 0.2, 1) forwards 1400ms;
  filter: drop-shadow(0 0 6px rgba(224, 122, 75, 0.35));
}

@keyframes draw { to { stroke-dashoffset: 0; } }

.sheet-caption {
  display: block;
  text-align: center;
  margin-top: 0.9rem;
}

/* ─── before / after ───────────────────────────────────────────────── */

.compare-band { border-block: 1px solid var(--hairline); }

.compare {
  position: relative;
  /* Half and half is the honest resting state, and it is what a reader with
   * no JavaScript is left looking at. The scroll drive resets it to 0 the
   * moment it takes over. */
  --split: 50%;
  max-width: 58rem;
  margin: 0 auto;
  border: 1px solid var(--edge);
  border-radius: 3px;
  overflow: hidden;
  background: #000;
  touch-action: pan-y;
}

.compare img {
  display: block;
  width: 100%;
  height: auto;
}

.compare .over {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  clip-path: inset(0 0 0 var(--split));
}

.compare figcaption {
  position: absolute;
  bottom: 0.75rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  background: rgba(13, 12, 11, 0.72);
  border: 1px solid rgba(240, 235, 226, 0.14);
  padding: 0.25rem 0.55rem;
  border-radius: 2px;
  backdrop-filter: blur(4px);
}

.cap-before { left: 0.75rem; }
.cap-after { right: 0.75rem; }

.compare-bar {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--split);
  width: 1px;
  background: var(--amber);
  pointer-events: none;
  box-shadow: 0 0 12px rgba(224, 122, 75, 0.55);
}

.compare-bar::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 38px;
  height: 38px;
  transform: translate(-50%, -50%);
  border: 1px solid var(--amber);
  border-radius: 50%;
  background: rgba(13, 12, 11, 0.6);
  backdrop-filter: blur(4px);
}

/* The range input is the real control — invisible, but it is what makes
 * the wipe keyboard-operable and screen-reader-announceable. */
.compare-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}

.compare-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 44px;
  height: 100%;
}

.compare-range::-moz-range-thumb {
  width: 44px;
  height: 100%;
  border: 0;
  background: transparent;
}

.compare:focus-within .compare-bar::after {
  box-shadow: 0 0 0 3px rgba(224, 122, 75, 0.35);
}

.compare-hint {
  text-align: center;
  margin-top: 1.1rem;
}

/* ─── steps ────────────────────────────────────────────────────────── */

/* No bottom padding: the next step's spine is the separation, and doubling
 * the two just opens a hole in the middle of the sequence. */
.step { text-align: center; }

/* The spine: one hairline dropped down the centre axis into each step, so
 * the three of them read as a sequence and not as three panels. */
.spine {
  display: block;
  width: 1px;
  height: clamp(4.5rem, 9vw, 7.5rem);
  margin: 0 auto clamp(1.5rem, 3vw, 2.25rem);
  background: linear-gradient(to bottom, transparent, var(--edge));
}

.step-eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  margin: 0 0 1.25rem;
}

.step-eyebrow .idx {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--amber);
}

.step-eyebrow .dot { color: var(--edge); }

.step h2 {
  font-size: clamp(1.875rem, 3.8vw, 2.875rem);
  max-width: 18ch;
  margin: 0 auto 1.35rem;
}

.step .prose {
  max-width: var(--measure);
  margin: 0 auto;
}

.step-spec {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
}

.step-spec li {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--edge);
  border-radius: 2px;
  padding: 0.3rem 0.6rem;
}

/* The screenshot sits in the thinnest possible frame. The app's own
 * chrome is the design; a drawn bezel would only compete with it. */
.step-shot { margin: clamp(2.25rem, 5vw, 3.25rem) 0 0; }

.device {
  position: relative;
  max-width: 17rem;
  margin-inline: auto;
  border: 1px solid var(--edge);
  border-radius: 20px;
  padding: 5px;
  background: var(--panel);
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.9);
}

.device img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 15px;
}

/* ─── roster ───────────────────────────────────────────────────────── */

/* Auto-fit rather than a fixed four, because the number of proofs on the
 * page tracks the shipped roster and a hardcoded column count leaves a
 * ragged last row the moment that changes. */
.roster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 6px;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: 3px;
  margin: 0 auto;
  max-width: 62rem;
}

.plate {
  margin: 0;
  transition: filter 220ms ease;
}

.plate:hover { filter: brightness(1.12) saturate(1.06); }

.plate img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #000;
}

.plate figcaption {
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.45rem 0.1rem 0.15rem;
}

.plate:hover figcaption { color: var(--ink); }

/* The untouched frame sits in the same row as the looks, and has to read as
 * the reference rather than as one more grade. */
.plate figcaption.as-shot { color: var(--ink); }

/* ─── chapters ─────────────────────────────────────────────────────── */

/* A chapter is one step of the app, told in numbered beats. The beats carry
 * the evidence; the chapter head is the only centred thing in it. */
.chapter { padding-block: var(--stack) 0; }

.chapter-h {
  font-size: clamp(1.875rem, 4vw, 3rem);
  max-width: 20ch;
  margin: 0 auto 1.35rem;
  text-align: center;
}

.chapter-lede {
  max-width: 38rem;
  margin: 0 auto;
  text-align: center;
}

.chapter .step-eyebrow { margin-bottom: 1.25rem; }

/* One beat: a numbered stage of the walkthrough. */
.beat { padding-block: clamp(2.5rem, 5vw, 4rem) 0; }

.beat-n {
  color: var(--amber);
  text-align: center;
  margin: 0 0 1.25rem;
}

.beat-prose {
  max-width: var(--measure);
  margin: 0 auto;
  text-align: left;
}

.beat-prose + .layers,
.beat-prose + .triptych,
.layers + .beat-prose,
.beat-prose + .figures { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }

/* ─── the word chips ───────────────────────────────────────────────── */

/* The inventory as the app hands it to you: amber for recommended, outline
 * for listed-but-keep. Static on the page — this is a picture of the app's
 * answer, not a control. */
.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
  max-width: 48rem;
  margin: clamp(1.5rem, 3vw, 2rem) auto 0;
}

.chip {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  padding: 0.4rem 0.7rem;
  border-radius: 2px;
  border: 1px solid var(--edge);
  color: var(--muted);
}

.chip-on {
  color: var(--amber);
  border-color: var(--amber-edge);
  background: var(--amber-wash);
}

.chip-off { text-decoration: line-through; opacity: 0.65; }

/* ─── the layer switcher ───────────────────────────────────────────── */

.layers { margin-inline: auto; max-width: 62rem; }

.layer-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
  margin-bottom: 1rem;
}

.layer-buttons button {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--edge);
  border-radius: 2px;
  padding: 0.45rem 0.75rem;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
}

.layer-buttons button:hover { color: var(--ink); }

.layer-buttons button.is-on {
  color: var(--amber-ink);
  background: var(--amber);
  border-color: var(--amber);
}

/* Without JS every layer stays in the flow, stacked and captioned. */
.layer-stack > figure { margin: 0 0 1.25rem; }

.layer-stack img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--edge);
  border-radius: 3px;
  background: #000;
}

.layer-stack figcaption { display: block; text-align: center; margin-top: 0.75rem; }

/* Live: one at a time, in a fixed box so switching does not jump the page. */
.layers.is-live .layer-stack { position: relative; }
.layers.is-live .layer-stack > figure { display: none; margin: 0; }
.layers.is-live .layer-stack > figure.is-shown { display: block; }

/* ─── triptych ─────────────────────────────────────────────────────── */

/* Three states of one detail, side by side. Three columns is the whole
 * point — a two-up would lose the middle term, which is the argument. */
.triptych {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.5rem, 1.5vw, 1rem);
  max-width: 58rem;
  margin-inline: auto;
}

.triptych figure { margin: 0; }

.triptych img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--edge);
  border-radius: 3px;
  background: #000;
}

.triptych figcaption { display: block; text-align: center; margin-top: 0.6rem; }

/* ─── measured figures ─────────────────────────────────────────────── */

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1px;
  padding: 1px;
  max-width: 58rem;
  margin-inline: auto;
  list-style: none;
  background: var(--edge);
  border: 1px solid var(--edge);
  border-radius: 3px;
}

.figures li {
  background: var(--ground);
  padding: clamp(1.1rem, 2.2vw, 1.5rem);
  text-align: center;
}

.fig-k { margin: 0 0 0.6rem; }

.fig-v {
  font-family: var(--mono);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  margin: 0 0 0.5rem;
}

.fig-c {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--muted);
  margin: 0;
}

/* ─── the bracket ──────────────────────────────────────────────────── */

.bracket {
  margin: 0 auto;
  max-width: 56rem;
}

.bracket svg { display: block; width: 100%; height: auto; }

.br-h {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  fill: var(--muted);
  text-anchor: middle;
}

.br-n {
  font-family: var(--mono);
  font-size: 22px;
  fill: var(--ink);
  text-anchor: middle;
}

.br-s {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  fill: var(--muted);
  text-anchor: middle;
}

.br-win { fill: var(--amber); }
.br-funnel { fill: rgba(240, 235, 226, 0.035); }
.br-funnel-hot { fill: var(--amber-wash); }
.br-cells rect { fill: var(--panel); stroke: var(--edge); stroke-width: 1; }
.br-cells rect.br-winner { fill: var(--amber-wash); stroke: var(--amber); }

.bracket figcaption { display: block; text-align: center; margin-top: 1rem; }

/* ─── how it works ─────────────────────────────────────────────────── */

/* The hero's second paragraph. Smaller than the lede and mono-adjacent in
 * weight, because it is the claim, not the pitch. */
.hero-kicker {
  max-width: 34rem;
  margin: 0 auto;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.65;
}

/* The mechanism list: how a step actually works, one numbered card per
 * mechanism. Left-aligned inside a centred section on purpose — running
 * prose this long down a centre axis is unreadable. */
.mechs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1px;
  margin: clamp(2.25rem, 5vw, 3.25rem) auto 0;
  padding: 1px;
  max-width: 62rem;
  list-style: none;
  background: var(--edge);
  border: 1px solid var(--edge);
  border-radius: 3px;
  text-align: left;
}

.mech {
  background: var(--ground);
  padding: clamp(1.25rem, 2.4vw, 1.75rem);
}

.mech-n {
  color: var(--amber);
  margin: 0 0 0.75rem;
}

.mech h3 {
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.25;
  margin: 0 0 0.6rem;
  color: var(--ink);
}

.mech p:not(.mech-n) {
  color: #b3aba0;
  font-size: 0.9375rem;
  line-height: 1.6;
  margin: 0;
}

/* A caption that has to carry a caveat — too long for figcaption's mono. */
.fig-note {
  max-width: var(--measure);
  margin: 1.25rem auto 0;
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.6;
  text-align: center;
}

/* An evidence image at the width of the argument it supports. */
.wide-figure {
  margin: clamp(1.5rem, 3vw, 2.25rem) auto 0;
  max-width: 62rem;
}

/* The ballot sheet is portrait and would otherwise fill a screen and a half. */
.wide-figure.tall { max-width: 26rem; }

.wide-figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--edge);
  border-radius: 3px;
  background: #000;
}

.wide-figure figcaption,
.step-shot figcaption {
  display: block;
  text-align: center;
  margin-top: 0.9rem;
}

/* ─── closing ──────────────────────────────────────────────────────── */

.closing { text-align: center; }

.closing h2 {
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  margin-bottom: 1rem;
}

.closing-lede {
  color: #b3aba0;
  font-size: 0.9375rem;
  max-width: 28rem;
  margin: 0 auto;
}

/* ─── colophon ─────────────────────────────────────────────────────── */

.colophon {
  border-top: 1px solid var(--hairline);
  padding-block: 2.5rem 3.5rem;
}

.colophon-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  text-align: center;
}

.colophon nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2rem);
}

.colophon a {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
}

.colophon a:hover { color: var(--ink); }

/* ─── holding page ─────────────────────────────────────────────────── */

/* What is live at somewherecamera.com until the landing page has real
 * photographs in it. Its whole job is to say what this is and carry the
 * three links the App Store listing has to point at. */
.holding {
  min-height: 66vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding-block: var(--stack);
}

.holding h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  max-width: 17ch;
  margin-bottom: 1.5rem;
}

.holding .lede { max-width: 34rem; }

.holding .label { margin-top: 2.5rem; }

/* ─── document pages (privacy, terms, support) ─────────────────────── */

.doc {
  max-width: 42rem;
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

.doc h1 {
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  margin-bottom: 0.75rem;
}

.doc h2 {
  font-size: 1.375rem;
  margin: 2.75rem 0 0.85rem;
}

.doc p,
.doc li { color: #b3aba0; }

.doc ul { padding-left: 1.1rem; margin: 0 0 1.1em; }
.doc li { margin-bottom: 0.4em; }

.doc .updated {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2.5rem;
}

.doc .callout {
  border-left: 2px solid var(--amber);
  background: var(--amber-wash);
  padding: 1rem 1.25rem;
  margin: 1.75rem 0;
  border-radius: 0 2px 2px 0;
}

.doc .callout p { color: #cdc5b9; }

/* ─── the focus pull ───────────────────────────────────────────────── */

/* One motion for the whole page: everything arrives fractionally out of
 * focus and resolves. --d staggers siblings within a section.
 *
 * Every rule below is gated on .js, set by an inline script in the head.
 * Without it the page is simply visible — a reader with no JavaScript gets
 * the site, not a black screen. */
.js .reveal {
  opacity: 0;
  transform: translateY(24px) scale(0.988);
  filter: blur(8px);
  transition:
    opacity 820ms var(--ease) calc(var(--d, 0) * 95ms),
    transform 820ms var(--ease) calc(var(--d, 0) * 95ms),
    filter 820ms var(--ease) calc(var(--d, 0) * 95ms);
}

.js .reveal.seen {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Big photographs skip the blur. It is the one property here that costs a
 * frame, and a full-width plate is exactly where that would show. */
.js .compare.reveal,
.js .step-shot.reveal {
  filter: none;
  transform: translateY(28px);
}

.js .compare.reveal.seen,
.js .step-shot.reveal.seen { transform: none; }

/* The roster comes up the way a print comes up in the tray: from nearly
 * black, one frame after the next. */
.js .plate.develops img {
  opacity: 0;
  filter: brightness(0.2) contrast(0.65) saturate(0.35);
  transition:
    opacity 700ms ease calc(var(--i) * 55ms),
    filter 950ms ease calc(var(--i) * 55ms);
}

.js .plate.develops.seen img {
  opacity: 1;
  filter: none;
}

/* ─── narrow ───────────────────────────────────────────────────────── */

@media (max-width: 62rem) {
  .device { max-width: 15.5rem; }
}

@media (max-width: 48rem) {
  .roster { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 34rem) {
  body { font-size: 16px; }
  .sheet { grid-template-columns: repeat(3, 1fr); }
  .roster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .masthead-links a:not(.appstore) { display: none; }

  .masthead .cta-long { display: none; }
  .masthead .cta-short { display: inline; }

  .hero-actions { gap: 0.9rem 1.25rem; }
  .hero h1 { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .frame img,
  .ring path {
    animation: none;
    opacity: 1;
    stroke-dashoffset: 0;
  }

  .js .reveal,
  .js .plate.develops img {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }
}
