/* Yafa website — light ground, Ocean Deep ink.
   App palette reference: DesignSystem/Colors.swift */

/* The app is dark navy. The site is deliberately light, so every screenshot reads as
   a device against a page instead of dissolving into it. Ocean Deep survives here as
   the accent and the ink, not as the ground. */
:root {
  --background: #eef2f6;
  --surface: #ffffff;
  --ink: #0c2340;          /* the app's background colour, used as text here */
  --tide: #2d8a9e;
  --mint: #16736e;         /* teal darkened until it passes AA on the light ground */
  --mint-strong: #0f5b57;
  --brand: #16736e;
  --text: var(--ink);

  /* Measured against #eef2f6: primary 14.0:1, secondary 6.39:1, tertiary 4.67:1.
     Tertiary carries the legal fine print, so it stays above 4.5:1. */
  --text-secondary: rgba(12, 35, 64, 0.74);
  --text-tertiary: rgba(12, 35, 64, 0.64);
  --border: rgba(12, 35, 64, 0.14);
  --rule: rgba(12, 35, 64, 0.10);

  /* The dark bands are literally the app's launch-screen colour, so the wordmark
     lockup drops into them with no visible seam. */
  --band: #01142d;
  --band-text: #ffffff;
  --band-secondary: rgba(255, 255, 255, 0.66);
  --band-mint: #64e6d8;   /* sampled from the "Fit" in the launch wordmark */

  --measure: 68ch;
  --radius: 18px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--background);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* A single soft light source behind the top of the page, the way the app glows */
body::before {
  content: "";
  position: fixed;
  inset: -20vh -10vw auto;
  height: 90vh;
  background: radial-gradient(60% 55% at 50% 0%, rgba(45, 138, 158, 0.22), transparent 70%);
  pointer-events: none;
  z-index: 0;
}

.wrap {
  position: relative;
  z-index: 1;
  width: min(1080px, 100% - 48px);
  margin-inline: auto;
}

a { color: var(--mint); text-decoration: none; }
a:hover { color: var(--mint-strong); text-decoration: underline; }

img { max-width: 100%; height: auto; display: block; }

/* ---------- dark bands (header, closing, footer) ---------- */

.band {
  background: var(--band);
  color: var(--band-text);
}

header.site {
  position: relative;
  z-index: 2;
  padding: 16px 0;
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.header-inner nav.site { margin-left: auto; }

/* The name alone, two-tone: "Vibe" in white, "Fit" in the launch screen's mint.

   The ring from the app icon used to sit to the left of it and was dropped on
   2026-08-27. Inside the icon the ring frames the wordmark and has something to do; on
   its own it is a hollow loop with nothing in the middle, and at 30px it read as a
   loading spinner rather than as a mark. The icon itself was not an option in its place,
   since it already contains this same name and would have said it twice. */
/* Nunito, because this is the same wordmark the app sets — see Typography.swift, where
   the brand face carries every step at 22 px and above and the system font carries the
   rest. Until 2026-09-09 the site set the name in the system stack while the app set it
   in Nunito, so the product's own name rendered in two different typefaces depending on
   where you read it. Weight 600 matches the Favs header, which is this element's exact
   counterpart: persistent chrome, ring beside name. */
.wordmark {
  display: inline-flex;
  align-items: center;
  font-family: Nunito, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* 24, up from 21 on 2026-08-27. Without the ring beside it the name is the whole
     lockup and was carrying less weight than it should against a 15px nav. */
  font-size: 24px;
  /* 700, and the same 700 the app uses in both of its own placements. The name was set
     at 600 here and at 800 on the app's splash, which meant a user saw the product's own
     name in two weights within five seconds of launching it. One brand element, one
     weight. */
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--band-text);
}
.wordmark:hover { text-decoration: none; opacity: 0.85; }

/* The ring, then the name in one colour.
   The name used to be split Ya + fa, white and mint, because the logo art was split the
   same way. The art has no lettering in it any more, so that reason is gone — and beside
   a teal ring a teal syllable reads as an accident rather than as a system. The ring
   carries the brand colour; the name carries the word. */
/* 48, not the 28 it shipped at for one afternoon, and the number is set against the
   button at the other end of the bar rather than against the type beside it. The same
   mistake was made in the app's Favs header on the same day and for the same two reasons:
   a mark is a picture rather than a letter, so matching the cap height makes it look
   smaller than the word; and this artwork fills only about 0.8 of its frame, so a 46 px
   frame would still draw a ring visibly smaller than the 46 px button it sits opposite. */
.wordmark img {
  width: 48px;
  height: 48px;
  margin-right: 10px;
}

nav.site a {
  color: var(--band-secondary);
  font-size: 15px;
  margin-left: 26px;
}
nav.site a:hover { color: var(--band-text); text-decoration: none; }

.btn {
  display: inline-block;
  background: var(--band-mint);
  color: var(--band);
  font-size: 15px;
  font-weight: 600;
  padding: 10px 22px;
  border-radius: 999px;
}
.btn:hover { background: #8df0e5; color: var(--band); text-decoration: none; }

.badge { display: inline-block; margin: 4px 0 0; }
.badge:hover { opacity: 0.85; }
.badge img { width: 180px; height: auto; }

/* ---------- not shipped yet ---------- */

/* The store link is real and points at a product that has not been released, so the
   page has to say so before the click rather than after it. Three pieces: the header
   button stops promising a download, the status line sits above the badge, and the
   badge itself is dimmed so it reads as a destination rather than an invitation. */

.btn-soon {
  background: none;
  color: var(--band-mint);
  border: 1px solid rgba(100, 230, 216, 0.45);
  cursor: default;
}
.btn-soon:hover { background: none; color: var(--band-mint); }

.status {
  font-size: 16px;
  color: var(--text-secondary);
  margin: 18px 0 10px;
  padding-left: 13px;
  border-left: 2px solid var(--mint);
  max-width: 46ch;
}
.status strong { color: var(--text); font-weight: 600; }

/* The eyebrow is uppercased by default, which is fine for a label and wrong for this
   one: its whole job is to show the two names in the form people should write them,
   and Docs/BRAND.md puts capitals in the drawn mark only. */
.eyebrow.name {
  text-transform: none;
  letter-spacing: 0.02em;
  font-size: 13px;
}

/* On the dark closing band the same line needs the band's own palette. */
.status.on-band {
  color: var(--band-secondary);
  border-left-color: var(--band-mint);
  margin: 16px auto 12px;
  text-align: left;
  display: inline-block;
}
.status.on-band strong { color: var(--band-text); }

.badge.is-soon { opacity: 0.6; }
.badge.is-soon:hover { opacity: 0.8; }

/* ---------- hero ---------- */

.hero {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 56px;
  align-items: center;
  padding: 56px 0 88px;
}

/* Nunito on the two largest steps only, which is the same split the app makes and for
   the same reason — see Typography.swift: the brand face carries every step at 22 pt and
   above, and the system font carries everything below, because at 12–19 px read on a
   phone San Francisco is simply better and was designed for it. So h1 and h2 change here
   and h3 does not: the h3s on this site are 17–19 px, the size at which the app also
   stays on the system face.

   Weight stays 700. The app sets its display steps at semibold, one step lighter, because
   light text on the Ocean Deep navy blooms at the edges and reads heavier than it is.
   These headings are dark ink on a pale ground, where the opposite holds. */
h1, h2 {
  font-family: Nunito, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

h1 {
  /* 56, down from 60, and the reason is Nunito rather than taste. This headline is two
     sentences and it reads one per line. Nunito sets wider than San Francisco at the same
     size: measured on the live page, "Say what you've got." came to 552 px inside a
     538 px column, so the line broke mid-sentence and the headline went to three lines.
     At 56 the longer sentence measures 513 px, which leaves 25 px — 58 also fits but with
     six, which is not enough margin to survive another locale or a font-loading hiccup.
     The vw term is scaled by the same ratio so the relationship holds at every width. */
  font-size: clamp(36px, 5.0vw, 56px);
  line-height: 1.08;
  letter-spacing: -0.025em;
  margin: 0 0 20px;
  font-weight: 700;
}

.lede {
  font-size: 19px;
  color: var(--text-secondary);
  margin: 0 0 30px;
  max-width: 46ch;
}

.eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mint);
  border: 1px solid rgba(22, 115, 110, 0.45);
  border-radius: 999px;
  padding: 6px 14px;
  margin-bottom: 24px;
}

.hero-note {
  font-size: 15px;
  color: var(--text-tertiary);
  margin-top: 14px;
}

.phone {
  border-radius: 34px;
  border: 1px solid rgba(12, 35, 64, 0.18);
  overflow: hidden;
  box-shadow: 0 50px 80px -34px rgba(12, 35, 64, 0.6),
    0 0 0 1px rgba(12, 35, 64, 0.05);
  max-width: 330px;
  margin-inline: auto;
}

.phone img { border-radius: inherit; }

/* ---------- sections ---------- */

section { padding: 72px 0; }

section + section { border-top: 1px solid var(--rule); }

h2 {
  font-size: clamp(26px, 3vw, 34px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
  font-weight: 700;
}

.section-lede {
  color: var(--text-secondary);
  max-width: 56ch;
  margin: 0 0 40px;
}

/* Step flow — deliberately not cards. The page already ends in a pricing card and a
   dark panel; three white boxes here made four box rows in a row. */
.flow {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 34px;
  padding: 0;
  margin: 0;
  counter-reset: step;
}

.flow li {
  border-top: 2px solid rgba(22, 115, 110, 0.28);
  padding-top: 20px;
}

.flow-num {
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--mint);
  margin-bottom: 12px;
}

.flow h3 {
  font-size: 19px;
  margin: 0 0 8px;
  font-weight: 600;
}

.flow p {
  margin: 0;
  color: var(--text-secondary);
  font-size: 16px;
}

.split {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: 56px;
  align-items: center;
}

.split.reverse .split-media { order: -1; }

.feature-list {
  list-style: none;
  padding: 0;
  margin: 24px 0 0;
}

.feature-list li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 12px;
  color: var(--text-secondary);
}

.feature-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 10px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--mint);
}

/* ---------- spoken prompts ---------- */

/* Bubbles, not a grid of boxes: these are lines of speech, and speech is uneven.
   Widths come from the text itself, and the flattened corner alternates side so the
   cluster reads as a conversation rather than a table. */
.bubbles {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  /* Without this, flex stretches every bubble to the tallest one on its row and the
     text sits at the top of the extra space. Each bubble should hug its own line. */
  align-items: flex-start;
  gap: 14px;
  max-width: 900px;
}

.bubbles li {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 24px 24px 24px 6px;
  padding: 14px 24px;
  font-size: 18px;
  font-style: italic;
  color: var(--text);
  box-shadow: 0 10px 24px -20px rgba(12, 35, 64, 0.55);
}

.bubbles li::before { content: "\201C"; }
.bubbles li::after { content: "\201D"; }

.bubbles li:nth-child(even) {
  border-radius: 24px 24px 6px 24px;
  background: rgba(22, 115, 110, 0.08);
  border-color: rgba(22, 115, 110, 0.18);
  box-shadow: none;
}

/* No per-item stagger here. Flex decides where rows break from the text width, so an
   offset on every third bubble lands arbitrarily and shows up as one row gap several
   times the others — measured 3 px, 3 px, 13 px, 3 px. The varied widths, the
   alternating flattened corner and the alternating tint carry the unevenness already. */

/* ---------- pricing ---------- */

.pricing { text-align: center; }
.pricing .section-lede { margin-left: auto; margin-right: auto; }
.pricing .fineprint { margin-left: auto; margin-right: auto; text-align: left; }

.plan {
  margin-inline: auto;
  text-align: left;
  max-width: 520px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 24px;
  padding: 34px;
  box-shadow: 0 26px 60px -34px rgba(12, 35, 64, 0.55);
  border-top: 3px solid var(--mint);
}

.plan-tag {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mint);
}

.plan-price {
  font-size: 44px;
  font-weight: 700;
  letter-spacing: -0.03em;
  margin: 10px 0 2px;
}

.plan-price span {
  font-size: 17px;
  font-weight: 400;
  color: var(--text-tertiary);
  letter-spacing: 0;
}

.plan-alt {
  margin: 0;
  color: var(--text-secondary);
  font-size: 16px;
}

.plan-features {
  list-style: none;
  padding: 0;
  margin: 26px 0;
  border-top: 1px solid var(--rule);
  padding-top: 22px;
}

.plan-features li {
  position: relative;
  padding-left: 30px;
  margin-bottom: 12px;
  color: var(--text-secondary);
}

.plan-features li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 8px;
  width: 12px;
  height: 7px;
  border-left: 2px solid var(--mint);
  border-bottom: 2px solid var(--mint);
  transform: rotate(-45deg);
}

.fineprint {
  font-size: 14px;
  color: var(--text-tertiary);
  max-width: var(--measure);
  margin-top: 28px;
}

/* ---------- two phones side by side ---------- */

/* Library and Favs are one idea, so they share a section rather than getting a split
   each — a fifth full-width phone would have turned the page into a slideshow. */
.phone-pair {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 40px;
  margin-top: 8px;
}

/* Aligned, not staggered. An offset this small reads as a mistake rather than as
   composition, and these two screens are a pair the eye should be able to compare.
   The margin reset matters: .phone carries margin-inline:auto for the single-phone
   layouts, and inside a flex row that auto margin eats all the free space and pushes
   the two apart. */
.phone-pair .phone { max-width: 300px; margin-inline: 0; }

/* ---------- privacy panel ---------- */

/* A dark inset panel: the third texture on the page, and it borrows the app's own
   ground for the one section that is about what stays on the device. */
.privacy { padding-top: 0; }
.privacy + section { border-top: none; }

.panel {
  background: var(--band);
  color: var(--band-text);
  border-radius: 28px;
  padding: 52px 54px 46px;
}

.panel h2 { color: var(--band-text); margin-bottom: 12px; }

.panel-lede {
  color: var(--band-secondary);
  max-width: 56ch;
  margin: 0 0 40px;
}

.panel-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 36px;
}

.panel-cols > div + div {
  border-left: 1px solid rgba(255, 255, 255, 0.14);
  padding-left: 36px;
}

.panel-cols h3 {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--band-text);
}

.panel-cols p {
  margin: 0;
  color: var(--band-secondary);
  font-size: 16px;
}

.panel-note {
  margin: 40px 0 0;
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 15px;
  color: var(--band-secondary);
}

.panel-note a { color: var(--band-mint); }
.panel-note a:hover { color: #a5f2ea; }

/* ---------- closing band ---------- */

.closing {
  text-align: center;
  padding: 76px 0 84px;
}

/* No mask any more. The old lockup PNG carried its own near-black square background,
   so it had to be masked to a circle to keep that square from lightening into view;
   ring.png has a real alpha channel and sits on the band directly. The name is type,
   matching the app — see Docs/mark.swift for why nothing bakes it in. */
.closing .lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin: 0 auto 10px;
}

.closing .lockup img {
  display: block;
  width: 200px;
  height: auto;
}

/* Sized against the ring rather than the type scale, the same relation the app uses:
   0.12 of the ring's drawn size. */
/* Nunito 800, matching the app's splash rather than the header: this is the one place on
   the site where the mark is presented at full size with the name under it, which is what
   the splash is. */
.closing .lockup-name {
  font-family: Nunito, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.01em;
  color: var(--band-text);
  line-height: 1.1;
}


.closing h2 {
  color: var(--band-text);
  font-size: clamp(30px, 4.2vw, 46px);
  margin: 0 0 12px;
}

.closing p {
  color: var(--band-secondary);
  font-size: 18px;
  margin: 0 0 28px;
}

/* ---------- footer ---------- */

footer.site {
  padding: 54px 0 46px;
  font-size: 15px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.footer-cols {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 40px;
}

.footer-longname {
  color: var(--band-text);
  font-weight: 600;
  margin: 10px 0 0;
  letter-spacing: 0.01em;
}

.footer-brand p {
  color: var(--band-secondary);
  margin: 14px 0 0;
  max-width: 34ch;
}

.footer-cols h3 {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  margin: 4px 0 16px;
}

.footer-cols a:not(.wordmark) {
  display: block;
  color: var(--band-secondary);
  margin-bottom: 12px;
}
.footer-cols a:not(.wordmark):hover { color: var(--band-text); text-decoration: none; }

footer.site .disclaimer {
  margin: 44px 0 0;
  padding-top: 26px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  max-width: var(--measure);
}

footer.site .copyright {
  margin: 18px 0 0;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
}

/* ---------- legal / text pages ---------- */

.doc {
  max-width: var(--measure);
  padding: 40px 0 80px;
}

.doc h1 { font-size: clamp(30px, 4vw, 42px); margin-bottom: 10px; }

.doc .updated {
  color: var(--text-tertiary);
  font-size: 15px;
  margin: 0 0 40px;
}

.doc h2 {
  font-size: 22px;
  margin: 44px 0 12px;
  padding-top: 8px;
}

.doc h3 {
  font-size: 17px;
  margin: 28px 0 8px;
  font-weight: 600;
}

.doc p, .doc li { color: var(--text-secondary); }

.doc ul { padding-left: 22px; }
.doc li { margin-bottom: 8px; }

.doc table {
  width: 100%;
  border-collapse: collapse;
  margin: 18px 0;
  font-size: 15px;
}

.doc th, .doc td {
  text-align: left;
  vertical-align: top;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text-secondary);
}

.doc th { color: var(--text); font-weight: 600; }

.table-scroll { overflow-x: auto; }

.callout {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--mint);
  border-radius: 12px;
  padding: 18px 22px;
  margin: 28px 0;
}

.callout p:last-child { margin-bottom: 0; }
.callout p:first-child { margin-top: 0; }

/* ---------- faq ---------- */

.faq { max-width: var(--measure); }

.faq details {
  border-bottom: 1px solid var(--border);
  padding: 18px 0;
}

.faq summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 17px;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 16px;
}

.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "+";
  color: var(--mint);
  font-weight: 400;
  font-size: 22px;
  line-height: 1;
}

.faq details[open] summary::after { content: "–"; }

.faq details p { color: var(--text-secondary); margin-bottom: 0; }

/* ---------- responsive ---------- */

@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; gap: 44px; padding: 32px 0 64px; }
  .flow { grid-template-columns: 1fr; gap: 26px; }
  .phone-pair { gap: 16px; }
  .phone-pair .phone { max-width: 47%; }
  .panel { padding: 34px 26px 30px; border-radius: 22px; }
  .panel-cols { grid-template-columns: 1fr; gap: 26px; }
  .panel-cols > div + div { border-left: none; padding-left: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.14); padding-top: 26px; }
  .split { grid-template-columns: 1fr; gap: 36px; }
  .split.reverse .split-media { order: 0; }
  .footer-cols { grid-template-columns: 1fr 1fr; gap: 32px; }
  .footer-brand { grid-column: 1 / -1; }
  .wrap { width: min(1080px, 100% - 36px); }
  section { padding: 56px 0; }
  .header-inner { gap: 14px; }
  .header-inner nav.site { order: 3; margin-left: 0; width: 100%; }
  nav.site a { margin-left: 0; margin-right: 22px; }
  .btn { margin-left: auto; }
}

@media (max-width: 620px) {
  .bubbles li { font-size: 16px; padding: 12px 20px; }
  .plan { padding: 26px; }
  .plan-price { font-size: 38px; }
}

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