/* SOTTO — site styles.
   The palette is the app's own (Theme.swift), converted to hex. Unlike
   Graze, this site does NOT commit to one world: Sotto's identity is an
   adaptive pair — midnight is the home look, daylight is the same voice on
   paper — so the site honours prefers-color-scheme, which is the brand rule
   demonstrating itself. (BRAND.md, "Visual identity".) */

:root {
  /* Daylight — the light palette, exactly as the app renders it. */
  --field-top: #F5F7FA;
  --field-bottom: #E9EDF4;
  --card: rgba(255, 255, 255, 0.72);
  --ink: #1B202B;
  --body: rgba(27, 32, 43, 0.78);
  --dim: rgba(27, 32, 43, 0.56);
  --line: rgba(27, 32, 43, 0.12);

  --brand: #166B4E;          /* spruce: mint deepened so it can speak as text */
  --brand-soft: rgba(22, 107, 78, 0.12);
  --stop: #2FA47C;           /* the lockup's full stop, deep enough to survive small sizes */

  /* Tier identities (Theme.swift). Each check-in keeps its colour here so
     the page and the phone in a reader's hand agree. */
  --dusk: #6C58A8;           /* happy and safe */
  --moss: #2E7D4F;           /* arrived safe */
  --harbour: #3A6BA5;        /* on my way home */
  --amber: #A8681F;          /* call me with an excuse */
  --ember: #BF4038;          /* come and get me */

  /* SF Rounded is the brand's own face — the wordmark, the icon's `s`, and
     every title in the app. ui-rounded reaches it on Apple platforms;
     elsewhere the stack degrades to whatever humanist sans is present,
     which is the deal BRAND.md already made for email. */
  --display: ui-rounded, "SF Pro Rounded", -apple-system, "Segoe UI", system-ui, sans-serif;
  --text: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --field-top: #1B202B;
    --field-bottom: #0F131C;
    --card: rgba(255, 255, 255, 0.08);
    --ink: #F2F5F9;
    --body: rgba(255, 255, 255, 0.76);
    --dim: rgba(255, 255, 255, 0.54);
    --line: rgba(255, 255, 255, 0.12);

    --brand: #8BE4C2;
    --brand-soft: rgba(139, 228, 194, 0.16);
    --stop: #FFFFFF;

    --dusk: #A48FD9;
    --moss: #6FBF8A;
    --harbour: #6F9BD1;
    --amber: #FFC93C;
    --ember: #E0655C;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: linear-gradient(var(--field-top), var(--field-bottom)) fixed;
  color: var(--body);
  font-family: var(--text);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 22px;
}

/* ---- The lockup (BRAND.md, F3-deep) ----
   `sotto.` in the brand colour with a contrasting full stop: ink + deep mint
   on paper, mint + white on midnight. Same mark as the app header and every
   email. */
.lockup {
  font-family: var(--display);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.01em;
  text-decoration: none;
  display: inline-block;
}
.lockup i { font-style: normal; color: var(--stop); }
@media (prefers-color-scheme: dark) {
  .lockup { color: var(--brand); }
}

/* ---- Chrome ---- */
header.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 0 8px;
}
header.bar .lockup { font-size: 26px; }
header.bar nav { display: flex; gap: 18px; font-size: 15px; }
header.bar nav a { color: var(--dim); text-decoration: none; }
header.bar nav a:hover { color: var(--ink); }

/* ---- Type ---- */
h1, h2, h3 {
  font-family: var(--display);
  color: var(--ink);
  line-height: 1.2;
  margin: 0 0 12px;
}
h1 { font-size: clamp(34px, 6vw, 56px); font-weight: 600; letter-spacing: -0.01em; }
h2 { font-size: clamp(24px, 3.4vw, 32px); font-weight: 600; margin-top: 0; }
h3 { font-size: 19px; font-weight: 600; }
p { margin: 0 0 14px; }
strong { color: var(--ink); font-weight: 600; }
a { color: var(--brand); }

.lede { font-size: clamp(18px, 2.2vw, 21px); color: var(--body); }
.eyebrow {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 10px;
}

section { padding: 54px 0; border-top: 1px solid var(--line); }
section:first-of-type { border-top: 0; }

/* A section is a heading and its evidence. Below 900px they stack, which is
   the phone reading order anyway; above it they sit side by side, so the
   page uses the desktop width instead of leaving a third of it empty while
   each column keeps a sane measure of its own. */
@media (min-width: 900px) {
  .split {
    display: grid;
    grid-template-columns: 20rem 1fr;
    gap: 20px 56px;
    align-items: start;
  }
  .split > .sec-head { position: sticky; top: 34px; }
  /* Side by side, the column gap is the separation, so the heading needs no
     trailing space of its own. Stacked, it very much does. */
  .split > .sec-head h2 { margin-bottom: 0; }
}
.sec-head h2 { margin-bottom: 18px; }
.sec-body > :first-child { margin-top: 0; }

/* ---- Hero ----
   No phone mockup: the product IS the five sentences a child taps, so the
   page shows those instead of a picture of them. */
.hero { padding: 40px 0 60px; border-top: 0; }
.hero h1 { margin-bottom: 16px; }
@media (min-width: 900px) {
  /* The copy and the five taps it describes, side by side. */
  .hero {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 60px;
    align-items: center;
    padding: 56px 0 70px;
  }
}


.cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
  padding: 13px 22px;
  border-radius: 999px;
  background: var(--brand);
  color: var(--field-bottom);
  font-family: var(--display);
  font-weight: 700;
  font-size: 16px;
  text-decoration: none;
}
.cta[aria-disabled="true"] {
  background: var(--brand-soft);
  color: var(--brand);
  cursor: default;
}
.store-name {
  margin-top: 10px;
  font-size: 14px;
  color: var(--dim);
}

/* ---- Tiles: the app's own buttons, drawn in CSS ----
   Same tint-over-raised-surface recipe as Theme.cardSurface, so a reader who
   downloads recognises what they saw here. */
.tiles { display: grid; gap: 10px; margin: 32px 0 0; }
@media (min-width: 900px) { .tiles { margin: 0; } }
.tile {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border-radius: 22px;
  background: var(--card);
  border: 1px solid color-mix(in srgb, var(--tint) 30%, transparent);
  box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--tint) 12%, transparent);
}
.tile .glyph {
  flex: none;
  width: 50px; height: 50px;
  display: grid; place-items: center;
  border-radius: 50%;
  /* Firm, not a wash: 15–40% is where every hue turns to mud, and past
     that the colour survives. This is where each tier is stated outright,
     which lets the tile behind it stay quiet. Mirrors ChildHomeView. */
  background: color-mix(in srgb, var(--tint) 60%, transparent);
  font-size: 26px;
}
.tile b {
  display: block;
  font-family: var(--display);
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
}
.tile span { font-size: 15px; color: var(--dim); }

/* The warm tier, on midnight only. Brown is what dark yellow *is*: at the
   12% every other tile uses, this one lands near 25% lightness and reads as
   mud. There is no dark yellow that isn't brown, so the only way for it to
   look yellow is to be light — it washes to 36%, where the surface matches
   its own border and is plainly the colour it claims. The cost is that this
   tile carries more weight than its siblings; yellow can't be both dark and
   yellow. Mirrors Theme.surfaceWash in the app. */
@media (prefers-color-scheme: dark) {
  .t-excuse {
    box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--tint) 36%, transparent);
  }
}
.t-arrived  { --tint: var(--moss); }
.t-happy    { --tint: var(--dusk); }
.t-home     { --tint: var(--harbour); }
.t-excuse   { --tint: var(--amber); }
.t-collect  { --tint: var(--ember); }

/* ---- The receipt journey ----
   The app's own four-step bar. It is the product's second idea after the
   buttons: the child watches the message land rather than wondering. */
.journey {
  display: flex;
  align-items: center;
  margin: 26px 0 8px;
}
.journey .step {
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand);
  font-size: 15px;
}
.journey .step.last { background: var(--brand); color: var(--field-bottom); }
.journey .link { flex: 1; height: 2px; background: color-mix(in srgb, var(--brand) 45%, transparent); }
.journey-labels {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--dim);
  max-width: 100%;
}

/* ---- Screenshots ----
   Two phones side by side inside a section's body column; below that they
   become a swipeable row, same as Graze's gallery. Each <picture> carries a
   light and a dark capture and the browser picks — the app is an adaptive
   pair, so a screenshot of it should be too. */
.shots {
  display: flex;
  gap: 18px;
  margin-top: 22px;
  padding-bottom: 4px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.shot {
  flex: 0 0 auto;
  width: min(248px, 60vw);
  margin: 0;
  scroll-snap-align: start;
}
.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 26px;
  border: 1px solid var(--line);
}
.shot figcaption {
  font-size: 14px;
  color: var(--dim);
  margin-top: 10px;
}

/* ---- Cards / grids ---- */
.grid { display: grid; gap: 16px; margin-top: 24px; }
@media (min-width: 720px) {
  .grid.two { grid-template-columns: 1fr 1fr; }
  .grid.three { grid-template-columns: repeat(3, 1fr); }
}
.card {
  padding: 20px;
  border-radius: 18px;
  background: var(--card);
  border: 1px solid var(--line);
}
.card p:last-child { margin-bottom: 0; }

/* A list where each line is a promise, ticked or crossed. */
.promises { list-style: none; padding: 0; margin: 18px 0 0; }
.promises li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}
.promises li:first-child { border-top: 0; }
.promises .mark { flex: none; font-weight: 700; }
/* The brand accent, not the arrived-safe tier's green: two greens a few
   degrees apart read as a clash rather than a family, and a tier colour
   means a tier. Matches Theme.affirm in the app. */
.promises .yes { color: var(--brand); }
.promises .no { color: var(--ember); }

.quote {
  font-family: var(--display);
  font-size: clamp(20px, 3vw, 26px);
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 8px;
}

/* ---- Footer ----
   Same shape as Graze's: the studio's copyright on the left, page navigation
   on the right. Sister apps under one studio should end the same way. */
.site-foot {
  border-top: 1px solid var(--line);
  margin-top: 60px;
  padding: 30px 0 48px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  align-items: baseline;
  justify-content: space-between;
  font-size: 14px;
  color: var(--dim);
}
.site-foot nav { display: flex; flex-wrap: wrap; gap: 22px; }
.site-foot a { color: var(--dim); text-decoration: none; }
.site-foot a:hover { color: var(--ink); }

/* ---- Legal pages ----
   Same width and the same two-column split as the landing page: the section
   heading in the rail, its text beside it. A policy read at the full 1100px
   would be a 115-character measure, which is exactly the sort of unreadable
   that makes people scroll past a privacy page instead of reading it. */
.doc { padding: 34px 0 6px; }
.doc .lede { max-width: 62ch; }
.doc-sec { padding: 30px 0; }
.doc-sec ul { padding-left: 20px; margin-top: 0; }
.doc-sec li { margin-bottom: 8px; }
.doc-sec table { border-collapse: collapse; width: 100%; margin: 0 0 18px; font-size: 15px; }
/* A table is the one thing here that must not be squeezed: let it scroll
   inside its own column rather than crushing the columns to fit. */
.doc-sec table { display: table; }
.doc-sec th, .doc-sec td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.doc-sec th { color: var(--ink); font-weight: 600; }
.updated { font-size: 14px; color: var(--dim); }

/* ---- Reveal on scroll ----
   Only active when JS added the class, so a blocked script shows everything
   rather than an empty page. Respects reduced motion. */
.js .reveal { opacity: 0; transform: translateY(10px); }
.js .reveal.in { opacity: 1; transform: none; transition: opacity .5s ease, transform .5s ease; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
  .js .reveal.in { transition: none; }
}

.doc-sec .sec-body h3 { margin-top: 22px; }
.doc-sec .sec-body > :first-child { margin-top: 0; }
