/* ==========================================================================
   LAYRD — getlayrd.app

   The palette and the typographic system are lifted from the app itself, not
   invented for the web: the five colours are the app repo's
   `tailwind.config.js` verbatim, and the eyebrow-over-light-heading pattern is
   what every screen in the app already does (`text-[11px] uppercase
   tracking-[2px]` over `text-[26px] font-light`). The serif is the wordmark
   voice from the app's assets/icon.png.

   Nothing keeps these in sync — this repo is standalone. If the app's palette
   moves, move it here by hand.

   Light-only on purpose. The app is `userInterfaceStyle: "light"` and the
   whole palette is described in its own config as a warm print neutral —
   there is no dark counterpart to be faithful to. Every colour is painted
   explicitly so the page holds on any background.
   ========================================================================== */

:root {
  color-scheme: only light;

  /* Straight from the app's tailwind.config.js */
  --bone: #fbfaf8; /* page background */
  --sand: #f1ede7; /* tile / surface behind a garment */
  --line: #e6e1d9; /* hairline dividers */
  --ink: #1c1917; /* primary text */
  --muted: #8c8378; /* secondary text */
  --faint: #b5ada2; /* the app's placeholder / inactive grey */

  --serif: 'Playfair Display', 'Didot', 'Bodoni MT', Georgia, serif;
  --sans: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --gutter: 24px;
  --measure: 1120px;
  --section-y: clamp(72px, 11vw, 136px);
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
p,
figure,
ul,
ol {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img,
video {
  display: block;
  max-width: 100%;
}

/* The hidden attribute only sets display:none at the browser-default level,
   so any later display rule silently beats it — which is how the waitlist's
   success panel ended up on screen next to the form it replaces. */
[hidden] {
  display: none !important;
}

a {
  color: inherit;
}

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

/* --------------------------------------------------------------------------
   Type roles
   -------------------------------------------------------------------------- */

/* The app's section label: 10–11px, uppercase, wide tracking, muted. */
.eyebrow {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1.4;
}

.eyebrow--faint {
  color: var(--faint);
}

/* The app's screen heading: large, light, gently tracked. */
.heading {
  font-family: var(--sans);
  font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.375rem);
  font-weight: 300;
  letter-spacing: 0.02em;
  line-height: 1.2;
  text-wrap: balance;
  max-width: 18ch;
}

.lede {
  font-size: 1.0625rem;
  font-weight: 300;
  line-height: 1.7;
  color: var(--muted);
  max-width: 56ch;
}

.body {
  color: var(--muted);
  max-width: 62ch;
}

/* The Didone from the app icon. Used for the mark and the two statements. */
.wordmark {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-indent: 0.2em; /* balance the trailing letter-space */
  line-height: 1;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding-block: var(--section-y);
  border-top: 1px solid var(--line);
}

.section__head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: clamp(40px, 6vw, 64px);
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  position: fixed;
  left: 16px;
  top: 16px;
  z-index: 20;
  background: var(--ink);
  color: var(--bone);
  padding: 12px 18px;
  font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

/* Matches components/ui.tsx: ink fill, generous radius, semibold label. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 26px;
  border-radius: 12px;
  border: 1px solid transparent;
  font-family: var(--sans);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.2s ease;
}

.btn--primary {
  background: var(--ink);
  color: var(--bone);
}

.btn--primary:hover {
  background: #000;
  transform: translateY(-1px);
}

.btn--secondary {
  background: transparent;
  border-color: var(--line);
  color: var(--ink);
}

.btn--secondary:hover {
  border-color: var(--faint);
  background: var(--sand);
}

/* On the inverted closing panel the fills swap. */
.btn--invert {
  background: var(--bone);
  color: var(--ink);
}

.btn--invert:hover {
  background: #fff;
  transform: translateY(-1px);
}

.btn__glyph {
  width: 15px;
  height: 15px;
  flex: none;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bone) 90%, transparent);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--line);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 78px;
}

/* Weight as well as size. A Didone at 400 with this much tracking is mostly
   hairline, so scaling it alone would still read as faint — 500 gives the
   stems enough thickness to hold at a glance. Set here rather than on
   .wordmark, which the closing panel also uses at a much larger size. */
.header__mark {
  font-size: clamp(1.25rem, 1.05rem + 0.7vw, 1.5rem);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  color: var(--ink);
  text-decoration: none;
}

.header__nav {
  display: flex;
  align-items: center;
  gap: 32px;
}

.header__link {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  transition: color 0.2s ease;
}

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

.header__cta {
  padding: 10px 18px;
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

@media (max-width: 720px) {
  .header__nav {
    gap: 18px;
  }

  .header__link {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(64px, 10vw, 120px) clamp(48px, 7vw, 88px);
}

.hero__eyebrow {
  margin-bottom: 28px;
}

/* The one place the Didone runs at size. It is the brand's own asset — the
   icon is nothing but this wordmark — so the hero says the thing the icon
   says, in the face the icon says it in. */
.hero__statement {
  font-family: var(--serif);
  font-weight: 400;
  /* Smaller ceiling than the old headline needed: this line is 35 characters
     against its 26, and at 84px it could not reach the comma before wrapping. */
  font-size: clamp(2.5rem, 1.1rem + 4.6vw, 4rem);
  line-height: 1.05;
  letter-spacing: -0.015em;
  margin: 0;
  max-width: 20ch;
  /* Deliberately not `balance`. Balancing evens the line lengths, which on
     this line pushed the break to "wardrobe, in / your pocket" and left "in"
     dangling. Normal wrapping fills the first line and breaks at the comma,
     which is where the sense breaks too. */
  text-wrap: normal;
}

.hero__statement em {
  font-style: italic;
}

.hero__lede {
  margin-top: 32px;
  font-size: 1.125rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 40px;
}

.hero__note {
  margin-top: 20px;
}

/* --------------------------------------------------------------------------
   The device

   A real iPhone frame with a transparent screen cutout, laid OVER the media
   rather than around it. The bezel, buttons and Dynamic Island are part of the
   image, so they paint on top of the video exactly as they would on a phone.

   The four percentages below are measured from the frame file itself — screen
   cutout at 43..892 x 39..1881 in a 933x1920 image. Re-measure them if the
   frame is ever swapped for a different render, or the screen will sit crooked
   inside the bezel.

   Until a frame image exists the bezel is drawn in CSS instead, so every slot
   still looks like a phone.
   -------------------------------------------------------------------------- */

.device {
  position: relative;
  width: 100%;
  aspect-ratio: 933 / 1920;
  margin-inline: auto;
}

.device__screen {
  position: absolute;
  left: 4.609%;
  top: 2.031%;
  width: 91.104%;
  height: 95.99%;
  /* The cutout's bounding box has square corners; the real screen is rounded,
     so without this the media pokes into the bezel. Roughly a 55pt corner. */
  border-radius: 14% / 6.5%;
  overflow: hidden;
  background: var(--sand);
  z-index: 1;
}

/* On top, and never in the way of a click or a scroll. */
.device__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 2;
}

.device__frame.is-ready {
  opacity: 1;
}

/* No frame image yet — draw the bezel, and let the screen fill it. */
.device:not(.has-frame) {
  background: var(--ink);
  border-radius: 8% / 3.8%;
}

.device:not(.has-frame) .device__screen {
  left: 2.2%;
  top: 1.05%;
  width: 95.6%;
  height: 97.9%;
  border-radius: 6.5% / 3%;
}

/* ---- What goes on the screen ---- */

.device__shot,
.device__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.4s ease;
}

/* Set by main.js once the file really decodes. A missing file never fires it,
   so the layer below stays visible instead of a broken image. */
.device__shot.is-ready,
.device__video.is-ready {
  opacity: 1;
}

.device__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px;
  text-align: center;
  background: var(--sand);
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0 11px,
    rgba(140, 131, 120, 0.07) 11px 22px
  );
}

.device__placeholder-mark {
  font-family: var(--serif);
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-indent: 0.24em;
  color: var(--faint);
}

/* ---- The hero's device ---- */

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

@media (max-width: 900px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 48px;
  }
}

.hero__device {
  width: 100%;
  max-width: 310px;
}

/* --------------------------------------------------------------------------
   The reel — three devices side by side
   -------------------------------------------------------------------------- */

.reel {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 4vw, 48px);
}

@media (max-width: 860px) {
  .reel {
    grid-template-columns: minmax(0, 1fr);
    max-width: 420px;
    margin-inline: auto;
  }
}

/* Capped, not fluid. A device filling a third of a 1120px column comes out
   over 700px tall, which is a poster rather than a phone. */
.reel__item {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  max-width: 248px;
  margin-inline: auto;
}

.reel__caption {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.reel__title {
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 0.01em;
}

.reel__text {
  font-size: 0.875rem;
  color: var(--muted);
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   How it works — a real sequence, so it is really numbered
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  gap: 0;
}

.step {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: clamp(20px, 4vw, 56px);
  padding-block: clamp(28px, 4vw, 40px);
  border-top: 1px solid var(--line);
  align-items: start;
}

.step:first-child {
  border-top: 0;
  padding-top: 0;
}

.step:last-child {
  padding-bottom: 0;
}

.step__index {
  font-family: var(--serif);
  font-size: 1.75rem;
  font-weight: 400;
  line-height: 1;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}

.step__body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.step__title {
  font-size: 1.25rem;
  font-weight: 300;
  letter-spacing: 0.01em;
}

.step__text {
  color: var(--muted);
  max-width: 60ch;
}

/* The line that closes the sequence.

   No rule above it: a full-width rule is the page's own signal for "new
   section", which is precisely what this is not. It is set in the serif italic
   the hero already uses for an aside, and kept smaller than a step title so it
   cannot be mistaken for a fifth step. Flush left, with the section heading
   rather than with the steps' text. */
.steps__close {
  margin: clamp(26px, 3.5vw, 40px) 0 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.125rem, 0.95rem + 0.8vw, 1.375rem);
  font-weight: 400;
  line-height: 1.45;
  color: var(--ink);
  max-width: 52ch;
  text-wrap: balance;
}

@media (max-width: 620px) {
  .step {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  .step__index {
    font-size: 1.25rem;
  }
}

/* --------------------------------------------------------------------------
   Explore — a contents page, not a card deck
   -------------------------------------------------------------------------- */

.uses {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}

.use {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: clamp(24px, 3vw, 34px);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--bone);
  transition: background-color 0.25s ease;
}

.use:hover {
  background: var(--sand);
}

.use__label {
  margin-bottom: 2px;
}

.use__title {
  font-size: 1.125rem;
  font-weight: 300;
  letter-spacing: 0.01em;
}

.use__text {
  font-size: 0.9375rem;
  color: var(--muted);
  line-height: 1.6;
}

@media (max-width: 900px) {
  .uses {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .uses {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --------------------------------------------------------------------------
   Closing panel — the app icon, full bleed
   -------------------------------------------------------------------------- */

.closing {
  background: var(--ink);
  color: var(--bone);
  border-top: 0;
}

.closing__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 26px;
  padding-block: clamp(80px, 12vw, 148px);
}

.closing__mark {
  font-size: clamp(2.5rem, 1rem + 6vw, 4.5rem);
  color: var(--bone);
}

/* Its own column so the two lines sit closer to each other than the panel's
   26px gap, and read as one statement rather than two. */
.closing__copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

/* The offer, at full strength. */
.closing__lead {
  margin: 0;
  font-size: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--bone);
}

.closing__text {
  font-size: 1.0625rem;
  font-weight: 300;
  line-height: 1.7;
  color: rgba(251, 250, 248, 0.66);
  max-width: 44ch;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer {
  background: var(--bone);
  padding-block: clamp(48px, 6vw, 72px);
}

.footer__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 40px;
  padding-bottom: 44px;
  border-bottom: 1px solid var(--line);
}

.footer__col {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.footer__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.footer__link {
  font-size: 0.9375rem;
  color: var(--muted);
  text-decoration: none;
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition:
    color 0.2s ease,
    border-color 0.2s ease;
}

.footer__link:hover {
  color: var(--ink);
  border-bottom-color: var(--line);
}

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 28px;
}

.footer__made {
  font-size: 0.8125rem;
  color: var(--muted);
}

.footer__heart {
  color: var(--ink);
  font-style: normal;
}

@media (max-width: 700px) {
  .footer__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }
}

/* --------------------------------------------------------------------------
   The waitlist

   One column, one job. Fields are the app's own idiom from components/ui.tsx:
   sand ground, hairline border, generous radius, label above rather than a
   placeholder inside — a placeholder disappears the moment someone types,
   which is exactly when they need to know what the field was.
   -------------------------------------------------------------------------- */

.join {
  padding-block: clamp(48px, 7vw, 88px) clamp(64px, 9vw, 112px);
  max-width: 520px;
}

.join__title {
  font-family: var(--serif);
  font-size: clamp(2rem, 1.2rem + 3vw, 2.75rem);
  font-weight: 400;
  line-height: 1.1;
  margin-top: 14px;
  text-wrap: balance;
}

.join__lede {
  margin-top: 18px;
}

.join__form {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: clamp(32px, 5vw, 44px);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0; /* a fieldset will not shrink below its content without this */
}

.field__label {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0;
}

.field__input {
  width: 100%;
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
  font-family: var(--sans);
  /* 16px exactly: iOS Safari zooms the whole page in on focus for anything
     smaller, which throws the layout sideways mid-form. */
  font-size: 16px;
  color: var(--ink);
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.field__input:focus {
  outline: none;
  border-color: var(--ink);
  background: var(--bone);
}

/* ---- Phone, with its dialling code ---- */

.phone {
  display: flex;
  gap: 8px;
}

/* Sized to its content so a +1 does not reserve the room a +1868 needs. */
.phone__code {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: none;
  padding: 0 14px;
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 16px;
  color: var(--ink);
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.phone__code:hover {
  border-color: var(--faint);
}

.phone__code[aria-expanded='true'] {
  border-color: var(--ink);
  background: var(--bone);
}

.phone__flag {
  font-size: 18px;
  line-height: 1;
}

.phone__dial {
  font-variant-numeric: tabular-nums;
}

/* Small, muted, and it turns over when the list is open — the whole job is
   saying "this opens", which the flag and number alone do not. */
.phone__caret {
  width: 10px;
  height: 6px;
  flex: none;
  color: var(--faint);
  transition: transform 0.2s ease, color 0.2s ease;
}

.phone__code:hover .phone__caret {
  color: var(--muted);
}

.phone__code[aria-expanded='true'] .phone__caret {
  transform: rotate(180deg);
  color: var(--ink);
}

.phone__number {
  flex: 1;
  min-width: 0;
}

/* ---- The country list ---- */

/* In flow rather than absolutely positioned: on a phone an overlay this tall
   either covers the form or escapes the viewport, and pushing the fields down
   costs nothing on a page this short. */
.picker {
  margin-top: 8px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bone);
  overflow: hidden;
}

.picker__search {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--bone);
  padding: 13px 16px;
  font-family: var(--sans);
  font-size: 16px;
  color: var(--ink);
}

.picker__search:focus {
  outline: none;
  background: var(--sand);
}

.picker__search::placeholder {
  color: var(--faint);
}

.picker__list {
  list-style: none;
  margin: 0;
  padding: 4px;
  max-height: 260px;
  overflow-y: auto;
  /* Stops a flick inside the list from scrolling the page once it bottoms out. */
  overscroll-behavior: contain;
}

.picker__row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9375rem;
  color: var(--ink);
}

.picker__row:hover {
  background: var(--sand);
}

.picker__row[aria-selected='true'] {
  background: var(--sand);
  font-weight: 500;
}

.picker__flag {
  font-size: 17px;
  line-height: 1;
  flex: none;
}

.picker__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.picker__dial {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex: none;
}

.picker__empty {
  margin: 0;
  padding: 18px 16px;
  font-size: 0.875rem;
  color: var(--faint);
}

.choice {
  display: flex;
  gap: 10px;
}

.choice__option {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 12px;
  background: var(--sand);
  border: 1px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  font-size: 0.9375rem;
  color: var(--muted);
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.choice__option:hover {
  border-color: var(--faint);
}

/* :has lets the whole tile react to its own radio, so the hit target is the
   tile rather than the 16px dot. */
.choice__option:has(input:checked) {
  border-color: var(--ink);
  color: var(--ink);
  background: var(--bone);
}

.choice__option:has(input:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.choice__option input {
  accent-color: var(--ink);
  margin: 0;
}

/* Off-screen rather than display:none — a bot reading the DOM still finds it,
   which is the point, while nobody sighted or on a screen reader meets it. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.join__submit {
  margin-top: 4px;
  width: 100%;
  padding-block: 17px;
}

.join__note {
  margin: 0;
  min-height: 1.2em;
  font-size: 0.875rem;
  color: var(--muted);
}

.join__note.is-error {
  color: #a3341f;
}

.join__small {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--faint);
}

.join__small a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

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

.join__done {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  margin-top: clamp(32px, 5vw, 44px);
}

/* The two buttons after the confirmation: the beta offer first, because the
   sentence above it just made that offer, and the way back last. */
.join__after {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  margin-top: 26px;
}

/* Set apart from the beta button — it is the way out, not another offer. */
.join__back {
  margin-top: 10px;
}

/* Quiet, and below the buttons: remembering someone has joined must not trap
   a second person on a shared phone. */
.join__again {
  margin-top: 28px;
}

/* The iPhone escape hatch, set apart so it reads as an aside to the form
   rather than a second thing being asked of them. */
.join__now {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-top: clamp(44px, 6vw, 64px);
  padding-top: clamp(28px, 4vw, 36px);
  border-top: 1px solid var(--line);
}

.join__now .btn {
  margin-top: 6px;
}

/* --------------------------------------------------------------------------
   Job applications

   The waitlist's form, longer. Everything below adds the controls that form
   never needed — a long answer, a year, a file — in the same sand-and-hairline
   idiom, so the two pages read as one site.
   -------------------------------------------------------------------------- */

/* ---- The role, above the form ---- */

.role__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin: clamp(28px, 4vw, 36px) 0 0;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
}

.role__fact {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  background: var(--sand);
}

.role__fact--wide {
  grid-column: 1 / -1;
}

.role__fact dt {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.role__fact dd {
  margin: 0;
  font-size: 1rem;
  color: var(--ink);
}

.role__fact .role__note {
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--muted);
}

.role__heading {
  margin-top: clamp(32px, 5vw, 44px);
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 400;
  line-height: 1.2;
  color: var(--ink);
}

/* Set apart like the form's sections, so the pitch ends where the asking
   begins. */
.role__heading--apply {
  padding-top: clamp(28px, 4vw, 36px);
  border-top: 1px solid var(--line);
}

.role__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 14px 0 0;
  padding-left: 20px;
  list-style: disc;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--muted);
}

.role__list li::marker {
  color: var(--faint);
}

.role__about {
  margin-top: 14px;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--muted);
}

/* The one instruction people kept missing, so it is not set like the
   hints around it. */
.field__help.apply__phone {
  margin: 0;
  padding: 10px 14px;
  border-left: 2px solid var(--ink);
  background: var(--sand);
  border-radius: 0 8px 8px 0;
  color: var(--ink);
}

/* ---- Assignment submission ---- */

.role__list--numbered {
  list-style: decimal;
}

.role__list strong {
  font-weight: 500;
  color: var(--ink);
}

.brief__counts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 14px;
}

@media (max-width: 520px) {
  .brief__counts {
    grid-template-columns: 1fr;
  }
}

.brief__counts .role__list {
  margin-top: 8px;
}

.brief__label {
  margin: 0;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The brief's own emphasis: the second half of each heading in italic. */
.join__title em,
.role__heading em {
  font-style: italic;
}


.submit__pair {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 8px;
}

@media (max-width: 520px) {
  .submit__pair {
    grid-template-columns: 1fr;
  }
}

/* Breaks a long form into the few things it is actually asking. */
.apply__section {
  margin-top: 20px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.apply__section:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* Questions are sentences, so they are set as sentences rather than in the
   11px uppercase that suits a one-word label. */
.field__label--question {
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  line-height: 1.4;
}

.field__optional {
  color: var(--faint);
}

.field__help {
  margin: -2px 0 2px;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--muted);
}

.field__help a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.apply__steps {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-left: 18px;
}

.apply__steps strong {
  font-weight: 500;
  color: var(--ink);
}

.apply__substeps {
  margin: 4px 0 0;
  padding-left: 20px;
  list-style: decimal;
}

.field__input::placeholder {
  color: var(--faint);
}

.field__area {
  resize: vertical;
  min-height: 120px;
  line-height: 1.55;
}

.field__select {
  appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23b5ada2' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 10px 6px;
  padding-right: 40px;
}

.field__select:invalid {
  color: var(--faint);
}

/* The native file input cannot be styled, so it sits behind a label that
   can. Visually hidden, not display:none, so it still takes focus. */
.file__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.file {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--sand);
  border: 1px dashed var(--faint);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.file:hover {
  border-color: var(--muted);
}

.file:has(+ .file__input:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.file.is-set {
  border-style: solid;
  border-color: var(--ink);
  background: var(--bone);
}

.file__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink);
}

.file__hint {
  flex: none;
  font-size: 0.8125rem;
  color: var(--faint);
}

/* --------------------------------------------------------------------------
   Legal pages

   Set for reading rather than for skimming: one 680px column, generous
   leading, and headings that are quiet enough not to fight the text. A policy
   nobody can read is a policy nobody has consented to.
   -------------------------------------------------------------------------- */

.legal {
  padding-block: clamp(48px, 7vw, 84px) clamp(64px, 9vw, 112px);
  max-width: 680px;
}

.legal__title {
  font-family: var(--serif);
  font-size: clamp(2rem, 1.2rem + 3vw, 3rem);
  font-weight: 400;
  line-height: 1.1;
  margin-top: 16px;
}

.legal__meta {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--faint);
}

/* The plain-language précis. Sand rather than a border, so it reads as a
   quieter aside and not as the fine print. */
.legal__summary {
  margin-top: 36px;
  padding: 26px 28px;
  background: var(--sand);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.legal__summary p {
  margin: 0;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.7;
}

.legal__summary strong {
  color: var(--ink);
  font-weight: 500;
}

.legal__body {
  margin-top: 44px;
  display: flex;
  flex-direction: column;
  gap: 40px;
}

.legal__section {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.legal__section h2 {
  font-size: 1.25rem;
  font-weight: 300;
  letter-spacing: 0.01em;
  line-height: 1.3;
  color: var(--ink);
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.legal__section:first-child h2 {
  padding-top: 0;
  border-top: 0;
}

.legal__section h3 {
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  margin-top: 8px;
}

.legal__section p {
  margin: 0;
  color: var(--muted);
  line-height: 1.75;
}

.legal__section strong {
  color: var(--ink);
  font-weight: 500;
}

.legal__section a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--faint);
}

.legal__section a:hover {
  text-decoration-color: var(--ink);
}

.legal__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-left: 20px;
  list-style: disc;
  color: var(--muted);
}

.legal__list li {
  line-height: 1.75;
  padding-left: 4px;
}

.legal__list li::marker {
  color: var(--faint);
}

/* Who receives what. A table because it is genuinely tabular, and because a
   reader looking for one recipient should be able to find that row. */
.legal__table-wrap {
  overflow-x: auto;
  margin-top: 4px;
}

.legal__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  min-width: 460px;
}

.legal__table th,
.legal__table td {
  text-align: left;
  vertical-align: top;
  padding: 12px 16px 12px 0;
  border-bottom: 1px solid var(--line);
  line-height: 1.6;
}

.legal__table th {
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
  border-bottom-color: var(--ink);
  padding-bottom: 10px;
  white-space: nowrap;
}

.legal__table td:first-child {
  color: var(--ink);
  white-space: nowrap;
  padding-right: 24px;
}

.legal__table td {
  color: var(--muted);
}

/* An unfilled placeholder in a legal page is a publishing accident waiting to
   happen, so it is made loud rather than left to blend in. */
.legal__todo {
  background: #fdf3d8;
  border-bottom: 1px dashed #b8912f;
  color: #7a5c12;
  padding: 0 4px;
  font-size: 0.9em;
  letter-spacing: 0.04em;
}

/* The lead paragraph above the numbered sections — no heading of its own, so
   it needs the rule the sections get. */
.legal__section--intro p {
  color: var(--muted);
  line-height: 1.75;
  margin: 0;
}

.legal__steps {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-left: 20px;
  margin: 0;
  list-style: decimal;
  color: var(--muted);
}

.legal__steps li {
  line-height: 1.75;
  padding-left: 4px;
}

.legal__steps li::marker {
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.legal__back {
  display: inline-block;
  margin-top: 52px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
  width: 100%;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
}

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

/* --------------------------------------------------------------------------
   Motion — one quiet load sequence, and nothing that hides content
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .rise {
    animation: rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) backwards;
  }

  .rise--1 {
    animation-delay: 0.05s;
  }
  .rise--2 {
    animation-delay: 0.14s;
  }
  .rise--3 {
    animation-delay: 0.23s;
  }
  .rise--4 {
    animation-delay: 0.32s;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
  }
}
