/* OleOle — the one stylesheet for every page.
   Brand rules live in marketing/branding/BRAND-GUIDE.html. This file applies them; it does not
   reinterpret them. Mobile first: every rule is written for a phone, then widened at the end.

   Sections
     1  Fonts            4  Header and footer     7  The phone (the app, drawn in CSS)
     2  Colour           5  The mark + 6 states   8  Home page sections
     3  Page basics      6  Hero animation (S4)   9  Wider screens   10  Reduced motion   */

/* ---------------------------------------------------------------------------------------------
   1. Fonts. Self-hosted so the site makes no request to Google (see assets/fonts/README.md). */
@font-face {
  font-family: "Pacifico";
  src: url("/assets/fonts/pacifico-latin.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Fredoka";
  src: url("/assets/fonts/fredoka-latin.woff2") format("woff2");
  font-weight: 300 700; /* one variable file covers every weight we use */
  font-display: swap;
}
@font-face {
  font-family: "Outfit";
  src: url("/assets/fonts/outfit-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

/* ---------------------------------------------------------------------------------------------
   2. Colour. Four brand colours; ink and cream swap in dark mode (guide §04).
   Vermilion is for display sizes only (24 px and up): body text is never orange.
   The personality colours (guide §08) belong to characters, never to the logo or the UI. */
:root {
  --vermilion: #ff5a2b;
  --marigold: #ffc23c;
  --ink: #15100e;
  --cream: #fff3e4;

  --mint: #1fbfae;
  --punch: #f2385a;
  --lilac: #9b8cff;
  --leaf: #7fb069;
  --plum: #3f2a63;

  --ground: var(--cream);              /* page background */
  --text: var(--ink);                  /* body text */
  --muted: rgb(21 16 14 / 0.7);        /* secondary text, still ink */
  --line: rgb(21 16 14 / 0.14);        /* hairlines and chip borders */
  --card: rgb(21 16 14 / 0.05);        /* soft card background */

  --font-logo: "Pacifico", cursive;                       /* the word OleOle, nowhere else */
  --font-display: "Fredoka", "Outfit", system-ui, sans-serif;
  --font-text: "Outfit", system-ui, sans-serif;

  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ground: var(--ink);
    --text: var(--cream);
    --muted: rgb(255 243 228 / 0.72);
    --line: rgb(255 243 228 / 0.18);
    --card: rgb(255 243 228 / 0.07);
  }
}

/* ---------------------------------------------------------------------------------------------
   3. Page basics. 16 px gutters; a narrow column for reading, a wide one for grids. */
* {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: var(--font-text);
  font-weight: 400;
  font-size: 1.0625rem; /* 17 px: reads well on a phone without zooming */
  line-height: 1.55;
  overflow-x: hidden; /* the hero pair and the Do-mine strip may poke past the edge mid-animation */
}
.wrap,
.wide {
  margin-inline: auto;
  padding-inline: 16px;
}
.wrap {
  max-width: 40rem; /* body copy near 65 characters (guide §05) */
}
.wide {
  max-width: 68rem;
}
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em; /* guide §05: tracking at display sizes */
  line-height: 1.1;
  margin: 0 0 0.5em;
}
h2 {
  font-size: 2rem; /* 32 px, so vermilion is allowed on it */
  color: var(--vermilion);
}
h3 {
  font-size: 1.375rem;
}
p {
  margin: 0 0 1em;
}
a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}
a:hover {
  color: var(--vermilion);
}
:focus-visible {
  outline: 3px solid var(--marigold);
  outline-offset: 3px;
}
.small {
  color: var(--muted);
  font-size: 0.9375rem;
}

/* ---------------------------------------------------------------------------------------------
   4. Header and footer. The same markup on every page, stamped in by scripts/build.sh. */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-block: 20px;
}
.site-header .lockup {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
}
.site-header .lockup:hover {
  color: var(--text);
}
.site-header .pair-mark {
  height: 36px; /* guide §01: a pair is never shorter than 32 px */
  width: auto;
}
.pair-mark .eye-fill {
  fill: var(--ground); /* the eye takes the ground colour, so it flips with dark mode */
}
.site-header .logotype {
  font-family: var(--font-logo);
  font-size: 1.75rem;
  line-height: 1;
  /* Pacifico sits a little high beside the mark; nudge it onto the x-height. */
  transform: translateY(2px);
}
.site-nav {
  display: flex;
  gap: 18px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
}
.site-nav a {
  text-decoration: none;
}
/* On a narrow phone the lockup and three links do not fit on one line; the hero has the
   waitlist button anyway, so the third link steps aside below 480 px. */
@media (max-width: 479px) {
  .site-nav a:nth-child(3) {
    display: none;
  }
}
.site-footer {
  margin-top: 64px;
  padding-block: 32px 40px;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.9375rem;
}
.site-footer p {
  margin-bottom: 0.5em;
}
.site-footer .pair-mark {
  height: 32px;
  width: auto;
  margin-bottom: 12px;
}

/* ---------------------------------------------------------------------------------------------
   5. The mark, built in CSS on the real shape (guide §01, §06, §07).
   A wedge is a circle split across its diameter: two half-discs that pivot on the centre,
   33° each when the mouth is open and 0° when closed. --d is the diameter, --colour the fill. */
.wedge {
  position: relative;
  width: var(--d, 64px);
  height: var(--d, 64px);
  --colour: var(--vermilion);
}
.wedge-marigold { --colour: var(--marigold); }
/* Character shells: same silhouette, a personality colour (guide §08). Never the logo. */
.shell-mint     { --colour: var(--mint); }
.shell-punch    { --colour: var(--punch); }
.shell-lilac    { --colour: var(--lilac); }
.shell-leaf     { --colour: var(--leaf); }
.shell-plum     { --colour: var(--plum); }
.shell-vermilion{ --colour: var(--vermilion); }
.shell-marigold { --colour: var(--marigold); }
.wedge.faces-left {
  transform: scaleX(-1); /* the pair faces each other */
}
.jaw {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  background: var(--colour);
}
.jaw-top {
  top: 0;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  transform-origin: 50% 100%;
  transform: rotate(-33deg); /* open, at rest */
}
.jaw-bottom {
  bottom: 0;
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  transform-origin: 50% 0;
  transform: rotate(33deg);
}
/* The eye rides on the top jaw, 12% of the circle wide, its centre 15% down from the top.
   It takes the ground colour, so on ink it is ink (guide §01, "Reversed"). */
.eye {
  position: absolute;
  width: 12%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--ground);
  left: 54%;
  top: 18%; /* of the half-disc, which puts the centre 15% of the circle from its top */
}
.phone .eye {
  background: var(--cream); /* the phone screen is always cream */
}
/* The contact shadow: 84% of the width, ink at 20%. It squashes when the wedge rises, which
   is what gives the pair weight (guide §06). It is the only shadow the mark ever gets. */
.shadow {
  position: absolute;
  left: 8%;
  top: 104%;
  width: 84%;
  height: calc(var(--d) * 0.1);
  border-radius: 50%;
  background: var(--ink);
  opacity: 0.2;
}
@media (prefers-color-scheme: dark) {
  .shadow {
    background: #000;
    opacity: 0.45; /* a 20% ink shadow vanishes on ink; darker keeps the weight */
  }
}

/* The chomp (guide §06). Resting 760 ms, eager 600 ms, talking 340 ms; ease-in-out. */
@keyframes chomp-top {
  from { transform: rotate(-33deg); }
  to   { transform: rotate(0deg); }
}
@keyframes chomp-bottom {
  from { transform: rotate(33deg); }
  to   { transform: rotate(0deg); }
}
.is-chomping .jaw-top {
  animation: chomp-top var(--chomp, 760ms) ease-in-out infinite alternate;
}
.is-chomping .jaw-bottom {
  animation: chomp-bottom var(--chomp, 760ms) ease-in-out infinite alternate;
}

/* A stage holds one wedge above its shadow, with headroom for jumps. */
.state-stage {
  --d: 96px;
  position: relative;
  width: var(--d);
  height: calc(var(--d) * 1.5);
  margin-bottom: 12px;
}
.state-stage .wedge {
  position: absolute;
  left: 0;
  top: calc(var(--d) * 0.4);
}
.state-stage .shadow {
  top: auto;
  bottom: 0;
}
.state-stage-small {
  --d: 64px;
  margin-top: 12px;
}

/* The six states that ship first (guide §07). The silhouette never changes; the whole body
   moves. Each is nameable with the label covered: that is the test. */

/* Idle: slow bob, barely opens, occasional blink. */
@keyframes idle-bob {
  from { translate: 0 0; }
  to   { translate: 0 -5%; }
}
@keyframes idle-top {
  from { transform: rotate(-8deg); }
  to   { transform: rotate(-16deg); }
}
@keyframes idle-bottom {
  from { transform: rotate(8deg); }
  to   { transform: rotate(16deg); }
}
@keyframes blink {
  0%, 90%, 100% { transform: scaleY(1); }
  94%           { transform: scaleY(0.1); }
}
.state-idle            { animation: idle-bob 1500ms ease-in-out infinite alternate; }
.state-idle .jaw-top   { animation: idle-top 1500ms ease-in-out infinite alternate; }
.state-idle .jaw-bottom{ animation: idle-bottom 1500ms ease-in-out infinite alternate; }
.state-idle .eye       { animation: blink 4s linear infinite; }

/* Listening: leans 14° in, sound arcs travel toward it, the eye widens. */
@keyframes lean-in {
  from { transform: rotate(10deg); }
  to   { transform: rotate(14deg); }
}
@keyframes arc-in {
  from { translate: 30% 0; opacity: 0; }
  40%  { opacity: 1; }
  to   { translate: -10% 0; opacity: 0; }
}
.state-listening       { animation: lean-in 900ms ease-in-out infinite alternate; }
.state-listening .eye  { transform: scale(1.3); }
.state-listening .jaw-top    { transform: rotate(-20deg); }
.state-listening .jaw-bottom { transform: rotate(20deg); }
.arcs {
  position: absolute;
  left: 100%;
  top: 50%;
  width: 0;
  height: 0;
}
.arcs i {
  position: absolute;
  translate: -50% -50%;
  border: 2.5px solid var(--text);
  border-color: transparent var(--text) transparent transparent;
  opacity: 0.8;
  border-radius: 50%;
  animation: arc-in 1500ms ease-out infinite;
}
.arcs i:nth-child(1) { width: calc(var(--d) * 0.3);  height: calc(var(--d) * 0.3); }
.arcs i:nth-child(2) { width: calc(var(--d) * 0.55); height: calc(var(--d) * 0.55); animation-delay: 300ms; }
.arcs i:nth-child(3) { width: calc(var(--d) * 0.8);  height: calc(var(--d) * 0.8); animation-delay: 600ms; }

/* Speaking: fast chomp, slight forward lean, words fly out. */
@keyframes word-out {
  from { translate: 0 0; opacity: 0; scale: 0.6; }
  20%  { opacity: 1; scale: 1; }
  to   { translate: 140% 0; opacity: 0; scale: 1; }
}
.state-speaking { transform: rotate(5deg); }
.state-speaking .jaw-top    { animation: chomp-top 340ms ease-in-out infinite alternate; }
.state-speaking .jaw-bottom { animation: chomp-bottom 340ms ease-in-out infinite alternate; }
.words {
  position: absolute;
  left: 92%;
  top: 44%;
  width: calc(var(--d) * 0.6);
  height: 12%;
}
.words i {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(var(--d) * 0.12);
  height: calc(var(--d) * 0.12);
  border-radius: 50%;
  background: var(--cream);
  animation: word-out 900ms ease-out infinite;
}
.words i:nth-child(2) { animation-delay: 300ms; top: -60%; }
.words i:nth-child(3) { animation-delay: 600ms; top: 60%; }
.state-stage .words i { background: var(--text); }

/* Delighted: jumps with squash and stretch, the eye becomes an arc, sparks pop. */
@keyframes jump {
  0%, 100% { translate: 0 0;    scale: 1.06 0.94; }
  30%      { translate: 0 -30%; scale: 0.94 1.08; }
  50%      { translate: 0 -30%; scale: 0.96 1.04; }
  75%      { translate: 0 0;    scale: 1.1 0.9; }
}
@keyframes spark {
  0%, 20%  { scale: 0; opacity: 0; }
  40%      { scale: 1; opacity: 1; }
  70%, 100%{ scale: 0; opacity: 0; translate: var(--fly); }
}
.state-delighted {
  transform-origin: 50% 100%;
  animation: jump 1500ms ease-in-out infinite;
}
.state-delighted .eye {
  aspect-ratio: 2 / 1;
  background: transparent;
  border-top: calc(var(--d) * 0.03) solid var(--ground);
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  top: 20%;
}
.sparks i {
  position: absolute;
  width: calc(var(--d) * 0.16);
  height: calc(var(--d) * 0.16);
  border-radius: 50%;
  background: var(--marigold);
  animation: spark 1500ms ease-out infinite;
}
.sparks i:nth-child(1) { left: -10%; top: 10%;  --fly: -40% -60%; }
.sparks i:nth-child(2) { left: 100%; top: 0;    --fly: 40% -60%;  animation-delay: 100ms; }
.sparks i:nth-child(3) { left: 40%;  top: -22%; --fly: 0 -70%;    animation-delay: 200ms; }
.sparks i:nth-child(4) { left: 105%; top: 55%;  --fly: 60% 0;     animation-delay: 150ms; }

/* Loading: a full turn while chomping. */
@keyframes spin {
  to { transform: rotate(360deg); }
}
.state-loading              { animation: spin 1200ms linear infinite; }
.state-loading .jaw-top     { animation: chomp-top 340ms ease-in-out infinite alternate; }
.state-loading .jaw-bottom  { animation: chomp-bottom 340ms ease-in-out infinite alternate; }

/* Sleeping: sinks and breathes, the eye closes, Zzz. */
@keyframes breathe {
  from { translate: 0 6%; scale: 1.05 0.94; }
  to   { translate: 0 6%; scale: 1 1; }
}
@keyframes zzz {
  from { translate: 0 0;     opacity: 0; }
  30%  { opacity: 0.7; }
  to   { translate: 30% -90%; opacity: 0; }
}
.state-sleeping {
  transform-origin: 50% 100%;
  animation: breathe 1500ms ease-in-out infinite alternate;
}
.state-sleeping .jaw-top    { transform: rotate(-5deg); }
.state-sleeping .jaw-bottom { transform: rotate(5deg); }
.state-sleeping .eye {
  aspect-ratio: auto;
  height: calc(var(--d) * 0.025);
  border-radius: 999px;
  top: 24%;
}
.zzz {
  position: absolute;
  left: 80%;
  top: -20%;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(var(--d) * 0.26);
  line-height: 1;
  color: var(--text);
}
.zzz i {
  position: absolute;
  font-style: normal;
  animation: zzz 3s ease-out infinite;
}
.zzz i:nth-child(2) { animation-delay: 1s; font-size: 0.85em; }
.zzz i:nth-child(3) { animation-delay: 2s; font-size: 0.7em; }

/* ---------------------------------------------------------------------------------------------
   6. Hero animation: S4, swap places (guide §06). They eat toward each other; at the meeting
   point the vermilion wedge loops up and over while the marigold dips under, each turning
   around, and they finish on each other's side. Then they do it again from the other side,
   so one 8-second loop brings them back to the start.

   Three things move on their own timelines, all 8 s long so the keyframes line up:
     .mover  travels left and right along the ground
     .lift   rises for the arc (or dips to go under) and turns the wedge to face the other way
     .shadow shrinks and fades as the wedge goes over, spreads and darkens as it goes under */
.hero-pair {
  --d: 84px;
  --chomp: 600ms; /* eager, from the timing vocabulary */
  position: relative;
  width: calc(var(--d) * 3.4);
  height: calc(var(--d) * 2.5);
  margin-inline: auto;
}
.mover {
  position: absolute;
  left: calc(50% - var(--d) / 2);
  top: calc(var(--d) * 1.05); /* leaves room above for the arc */
  width: var(--d);
  height: var(--d);
  animation: 8s ease-in-out infinite;
}
.mover-a { animation-name: travel-a; }
.mover-b { animation-name: travel-b; }
.lift {
  position: relative;
  width: 100%;
  height: 100%;
  animation: 8s ease-in-out infinite;
}
.mover-a .lift { animation-name: lift-a; }
.mover-b .lift { animation-name: lift-b; }
.mover .shadow {
  animation: 8s ease-in-out infinite;
}
.mover-a .shadow { animation-name: shadow-a; }
.mover-b .shadow { animation-name: shadow-b; }
.mover-b .jaw {
  animation-delay: -300ms; /* the second wedge chomps half a cycle behind the first */
}
/* Positions along the ground, in diameters: ±1.1 apart, ±0.56 touching (the 12% gap). */
@keyframes travel-a {
  0%   { transform: translateX(calc(var(--d) * -1.1)); }
  28%  { transform: translateX(calc(var(--d) * -0.56)); }
  42%  { transform: translateX(calc(var(--d) * 0.56)); }
  50%  { transform: translateX(calc(var(--d) * 1.1)); }
  78%  { transform: translateX(calc(var(--d) * 0.56)); }
  92%  { transform: translateX(calc(var(--d) * -0.56)); }
  100% { transform: translateX(calc(var(--d) * -1.1)); }
}
@keyframes travel-b {
  0%   { transform: translateX(calc(var(--d) * 1.1)); }
  28%  { transform: translateX(calc(var(--d) * 0.56)); }
  42%  { transform: translateX(calc(var(--d) * -0.56)); }
  50%  { transform: translateX(calc(var(--d) * -1.1)); }
  78%  { transform: translateX(calc(var(--d) * -0.56)); }
  92%  { transform: translateX(calc(var(--d) * 0.56)); }
  100% { transform: translateX(calc(var(--d) * 1.1)); }
}
/* A goes over first (rises 0.95 d), then under on the way back (dips 0.35 d). B is the
   mirror. The half-turn is a turn around the vertical axis, so the eye stays on top. */
@keyframes lift-a {
  0%, 28%   { transform: translateY(0) rotateY(0deg); }
  35%       { transform: translateY(calc(var(--d) * -0.95)) rotateY(90deg); }
  42%, 78%  { transform: translateY(0) rotateY(180deg); }
  85%       { transform: translateY(calc(var(--d) * 0.35)) rotateY(270deg); }
  92%, 100% { transform: translateY(0) rotateY(360deg); }
}
@keyframes lift-b {
  0%, 28%   { transform: translateY(0) rotateY(0deg); }
  35%       { transform: translateY(calc(var(--d) * 0.35)) rotateY(90deg); }
  42%, 78%  { transform: translateY(0) rotateY(180deg); }
  85%       { transform: translateY(calc(var(--d) * -0.95)) rotateY(270deg); }
  92%, 100% { transform: translateY(0) rotateY(360deg); }
}
@keyframes shadow-a {
  0%, 28%   { transform: scaleX(1);    opacity: 0.2; }
  35%       { transform: scaleX(0.55); opacity: 0.07; }
  42%, 78%  { transform: scaleX(1);    opacity: 0.2; }
  85%       { transform: scaleX(1.3);  opacity: 0.32; }
  92%, 100% { transform: scaleX(1);    opacity: 0.2; }
}
@keyframes shadow-b {
  0%, 28%   { transform: scaleX(1);    opacity: 0.2; }
  35%       { transform: scaleX(1.3);  opacity: 0.32; }
  42%, 78%  { transform: scaleX(1);    opacity: 0.2; }
  85%       { transform: scaleX(0.55); opacity: 0.07; }
  92%, 100% { transform: scaleX(1);    opacity: 0.2; }
}
/* Three pellets between them. The outer two go first, the middle one as they meet. */
.pellets {
  position: absolute;
  left: 50%;
  top: calc(var(--d) * 1.55);
  display: flex;
  gap: calc(var(--d) * 0.2);
  transform: translate(-50%, -50%);
}
.pellets i {
  display: block;
  width: calc(var(--d) * 0.1);
  height: calc(var(--d) * 0.1);
  border-radius: 50%;
  background: var(--text);
  opacity: 0.3;
  animation: 8s linear infinite;
}
.pellets i:nth-child(1),
.pellets i:nth-child(3) { animation-name: pellet-outer; }
.pellets i:nth-child(2) { animation-name: pellet-middle; }
@keyframes pellet-outer {
  0%, 17%  { opacity: 0.3; }
  19%, 48% { opacity: 0; }
  50%, 67% { opacity: 0.3; }
  69%, 98% { opacity: 0; }
  100%     { opacity: 0.3; }
}
@keyframes pellet-middle {
  0%, 26%  { opacity: 0.3; }
  28%, 48% { opacity: 0; }
  50%, 76% { opacity: 0.3; }
  78%, 98% { opacity: 0; }
  100%     { opacity: 0.3; }
}

/* ---------------------------------------------------------------------------------------------
   7. The phone. The app drawn in CSS: one video card from the feed and its two buttons.
   The screen is always cream on ink, whatever the page mode, because it is a picture. */
.phone-wrap {
  display: flex;
  justify-content: center;
  margin-top: 36px;
}
.phone {
  width: 272px;
  height: 560px;
  padding: 12px;
  border-radius: 44px;
  background: var(--ink);
  border: 1px solid rgb(255 243 228 / 0.18);
  box-shadow: 0 40px 60px -30px rgb(0 0 0 / 0.45);
}
.screen {
  height: 100%;
  padding: 18px 14px 14px;
  border-radius: 34px;
  background: var(--cream);
  color: var(--ink);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.screen-top {
  display: flex;
  justify-content: center;
  gap: 18px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.9375rem;
}
.tab {
  opacity: 0.45;
  padding-bottom: 4px;
}
.tab.is-on {
  opacity: 1;
  border-bottom: 3px solid var(--vermilion);
}
.ai-chip {
  position: absolute;
  top: 12px;
  left: 12px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid rgb(255 243 228 / 0.5);
  background: rgb(255 243 228 / 0.14);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
}
.actions {
  display: flex;
  gap: 8px;
}
.button {
  flex: 1;
  padding: 11px;
  border-radius: 999px;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9375rem;
}
.button-talk {
  background: var(--vermilion);
  color: var(--cream);
}

/* The feed version of the screen: no padding, the posts fill it, and it scrolls by itself.
   Five posts (the fifth repeats the first) so the loop is seamless: hold, scroll, hold... */
.screen-feed {
  position: relative;
  padding: 0;
  gap: 0;
}
.screen-feed .screen-top {
  position: absolute;
  top: 18px;
  left: 0;
  right: 0;
  z-index: 1;
  color: var(--cream);
}
.feed {
  height: 100%;
  animation: feed-scroll 16s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes feed-scroll {
  0%, 21%   { translate: 0 0; }
  25%, 46%  { translate: 0 -100%; }
  50%, 71%  { translate: 0 -200%; }
  75%, 96%  { translate: 0 -300%; }
  100%      { translate: 0 -400%; }
}
.post {
  position: relative;
  height: 100%;
  padding: 56px 14px 14px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
  color: var(--cream);
}
.post-leaf  { background: linear-gradient(170deg, var(--leaf),  var(--ink) 120%); }
.post-mint  { background: linear-gradient(170deg, var(--mint),  var(--ink) 120%); }
.post-punch { background: linear-gradient(170deg, var(--punch), var(--ink) 120%); }
.post-plum  { background: linear-gradient(170deg, var(--plum),  var(--ink) 130%); }
.post .ai-chip {
  top: 50px;
}
.post .wedge {
  --d: 84px;
  position: absolute;
  left: calc(50% - 42px);
  top: 27%;
}
.post-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.15;
  margin: 0;
}
.post-meta {
  margin: 0 0 4px;
  font-size: 0.75rem;
  opacity: 0.8;
}

/* ---------------------------------------------------------------------------------------------
   8. Home page sections. Every section is the same shape: a title, a lead, then its content. */
main > section {
  padding-block: 48px;
}
main > section + section {
  border-top: 1px solid var(--line);
}
.section-title {
  font-size: clamp(1.75rem, 6.5vw, 2.5rem);
}
.section-lead {
  font-size: 1.125rem;
  max-width: 36rem;
  margin-bottom: 28px;
}

/* Hero */
.hero {
  text-align: center;
  padding-top: 8px;
}
.hero h1 {
  font-size: clamp(2.25rem, 9.5vw, 4rem);
  margin-top: 8px;
}
.hero .lead {
  font-size: 1.25rem;
  font-weight: 500;
  max-width: 28rem;
  margin-inline: auto;
}
.coming {
  display: inline-block;
  margin-top: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 2px solid var(--marigold);
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--text);
}

/* Everything you scroll for: an explore page of AI videos. Tiles are 3:4 like a video
   thumbnail; on wide screens every other column drops a little {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
/* Each face chomps at its own pace { --chomp: 760ms; }

/* Three cards in a row (What your twin does). */
.trio {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 16px;
}
.trio li {
  padding: 24px;
  border-radius: 24px;
  background: var(--card);
}
.trio h3 {
  font-size: 1.75rem;
  color: var(--vermilion);
}
.trio p {
  margin: 0;
}

.step-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 36px;
}
.step-list p {
  max-width: 30rem;
  margin-bottom: 0;
}

.trust {
  margin-top: 24px;
  padding-left: 16px;
  border-left: 4px solid var(--vermilion);
  font-weight: 500;
}

/* Straight talk. */
.plain-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.plain-list li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 12px;
}
.plain-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--vermilion);
}

/* Watch free. Pay when they help you. */
.price {
  text-align: center;
}
.price h2 {
  font-size: clamp(2rem, 8vw, 3rem);
}
.price .lead {
  font-size: 1.25rem;
  font-weight: 500;
  margin-inline: auto;
}

/* Close. */
.close {
  text-align: center;
}
.close .state-stage {
  margin-inline: auto;
}

/* Sections fade up as they scroll into view, in browsers that can do it without JavaScript. */
@supports (animation-timeline: view()) {
  @keyframes reveal {
    from { opacity: 0.15; translate: 0 18px; }
    to   { opacity: 1;    translate: 0 0; }
  }
  main > section + section {
    animation: reveal linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 30%;
  }
}

/* ---------------------------------------------------------------------------------------------
   8b. Prose pages: privacy, terms, support. One reading column, ink headings, plain lists.
   These pages are read, not browsed, so nothing moves and nothing is orange below 24 px. */
.prose {
  padding-block: 8px 24px;
}
.prose h1 {
  font-size: clamp(2rem, 8vw, 3rem);
  color: var(--vermilion);
  margin-bottom: 0.25em;
}
.prose .updated {
  color: var(--muted);
  font-size: 0.9375rem;
  margin-bottom: 2em;
}
.prose h2 {
  font-size: 1.5rem; /* 24 px: ink anyway, so the vermilion size rule never comes up */
  color: var(--text);
  margin-top: 2em;
  padding-top: 1em;
  border-top: 1px solid var(--line);
}
.prose h3 {
  font-size: 1.125rem;
  margin-top: 1.5em;
}
.prose ul,
.prose ol {
  padding-left: 1.25em;
  margin: 0 0 1em;
}
.prose li {
  margin-bottom: 0.4em;
}
.prose li::marker {
  color: var(--vermilion);
}
.prose dl {
  margin: 0 0 1em;
}
.prose dt {
  font-family: var(--font-display);
  font-weight: 600;
  margin-top: 1em;
}
.prose dd {
  margin: 0.25em 0 0;
}
/* A short summary box at the top of a legal page: the whole policy in five lines. */
.summary {
  padding: 20px;
  border-radius: 20px;
  background: var(--card);
  border-left: 6px solid var(--marigold);
}
.summary ul {
  margin: 0;
}
/* Something the reader must do (delete an account, report a video) gets its own card. */
.action-card {
  padding: 20px;
  border-radius: 20px;
  border: 2px solid var(--line);
  margin: 1em 0;
}
.action-card h3 {
  margin-top: 0;
}
.action-card p:last-child,
.action-card ol:last-child {
  margin-bottom: 0;
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-bottom: 16px;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--text);
}
.footer-nav a {
  text-decoration: none;
}

/* ---------------------------------------------------------------------------------------------
   8c. The call to action and the waitlist form (includes/waitlist.html).
   Ink on vermilion, not cream on vermilion: cream on vermilion is 2.8:1 and fails the contrast
   test that Lighthouse runs; ink on vermilion is 6:1. The brand's colours, in a readable order. */
.cta {
  display: inline-block;
  padding: 14px 26px;
  border: 0;
  border-radius: 999px;
  background: var(--vermilion);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.125rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background 150ms ease-in-out, transform 150ms ease-in-out;
}
.cta:hover {
  background: var(--marigold);
  color: var(--ink);
  transform: translateY(-1px);
}
.cta:disabled {
  opacity: 0.6;
  cursor: wait;
  transform: none;
}
.cta-quiet {
  background: transparent;
  color: var(--text);
  border: 2px solid var(--line);
}
.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}
.waitlist-form {
  max-width: 28rem;
}
.waitlist-form label {
  display: block;
  margin: 16px 0 6px;
  font-family: var(--font-display);
  font-weight: 600;
}
.waitlist-form input {
  display: block;
  width: 100%;
  padding: 12px 14px;
  border: 2px solid var(--line);
  border-radius: 14px;
  background: var(--ground);
  color: var(--text);
  font: inherit;
}
.waitlist-form input:focus {
  border-color: var(--marigold);
  outline: none;
}
.waitlist-form .cta {
  margin-top: 20px;
  width: 100%;
}
.waitlist-note {
  margin: 12px 0 0;
  color: var(--muted);
  font-size: 0.9375rem;
}
.waitlist-status {
  margin: 12px 0 0;
  font-weight: 500;
  min-height: 1.5em; /* keeps the layout still when the message appears */
}
.waitlist-status:empty {
  margin: 0;
}
.waitlist-form.is-done .waitlist-status {
  padding: 16px 20px;
  border-radius: 16px;
  border-left: 6px solid var(--marigold);
  background: var(--card);
}
.waitlist-form.has-error .waitlist-status {
  padding-left: 16px;
  border-left: 4px solid var(--vermilion);
}
.waitlist {
  scroll-margin-top: 24px;
}

/* ---------------------------------------------------------------------------------------------
   8d. Shared shapes for the vision, coaches and home pages: a page hero, cards in a grid,
   a numbered roadmap, a big statement. Same skeleton on every page (brief §1: symmetry). */
.page-hero {
  text-align: center;
  padding-top: 16px;
}
.page-hero h1 {
  font-size: clamp(2.125rem, 8.5vw, 3.75rem);
  color: var(--vermilion);
  max-width: 22ch;
  margin-inline: auto;
}
.page-hero .lead {
  font-size: 1.25rem;
  font-weight: 500;
  max-width: 30rem;
  margin-inline: auto;
}
.page-hero .cta-row,
.cta-row-center {
  justify-content: center;
  margin-top: 8px;
}
.card-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 16px;
}
.card {
  padding: 24px;
  border-radius: 24px;
  background: var(--card);
}
.card h3 {
  font-size: 1.25rem;
}
.card p:last-child {
  margin-bottom: 0;
}
.card .shell {
  --d: 56px;
  --chomp: 900ms;
  margin-bottom: 16px;
}
.card-grid li:nth-child(2) .shell { --chomp: 1500ms; }
.card-grid li:nth-child(3) .shell { --chomp: 1200ms; }
.card-grid li:nth-child(4) .shell { --chomp: 600ms; }
/* The roadmap: now, next, later. A marigold spine, the "when" in display type. */
.roadmap {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 3px solid var(--marigold);
}
.roadmap li {
  position: relative;
  padding: 0 0 28px 24px;
}
.roadmap li::before {
  content: "";
  position: absolute;
  left: -9px;
  top: 6px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--vermilion);
  border: 3px solid var(--ground);
}
.roadmap .when {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.roadmap h3 {
  margin-bottom: 0.25em;
}
.roadmap p {
  margin: 0;
  max-width: 34rem;
}
/* A statement: one or two display lines, vermilion, at a size the contrast rule allows. */
.statement {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  font-size: clamp(1.5rem, 5.5vw, 2.25rem);
  color: var(--vermilion);
  max-width: 24ch;
  margin: 0 0 1em;
}
.numbered {
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: step;
  display: grid;
  gap: 20px;
}
.numbered li {
  position: relative;
  padding-left: 56px;
  counter-increment: step;
}
.numbered li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--marigold);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  display: grid;
  place-items: center;
}
.numbered h3 {
  font-size: 1.25rem;
  margin-bottom: 0.25em;
}
.numbered p {
  margin: 0;
  max-width: 34rem;
}

/* ---------------------------------------------------------------------------------------------
   8e. The twin home page: the tagline, the demo video slot, the badge, a two-column split.
   The hero, the phone feed and the mascot states above are reused as they are. */
.tagline {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  font-size: clamp(1.5rem, 5vw, 2rem); /* never below 24 px: it is vermilion */
  color: var(--vermilion);
  margin: 20px 0 0;
}
.hero .cta-row {
  justify-content: center;
  margin-top: 8px;
}
/* The demo slot: a 9:16 frame the size of a phone video, labelled, with the brand's Loading
   state in the middle until Rishi's twin video exists. No fake video, no fake play button. */
.demo-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 36px;
}
.demo-frame {
  position: relative;
  width: 272px;
  aspect-ratio: 9 / 16;
  border-radius: 28px;
  background: linear-gradient(165deg, var(--plum), var(--ink) 90%);
  color: var(--cream);
  border: 1px solid rgb(255 243 228 / 0.18);
  box-shadow: 0 40px 60px -30px rgb(0 0 0 / 0.45);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 18px;
  overflow: hidden;
}
.demo-frame .ai-chip {
  top: 16px;
  left: 16px;
}
.demo-frame .wedge {
  --d: 72px;
  position: absolute;
  left: calc(50% - 36px);
  top: calc(50% - 60px);
}
.demo-frame .eye {
  background: var(--ink);
}
.demo-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.15;
  margin: 0 0 4px;
}
.demo-meta {
  margin: 0;
  font-size: 0.8125rem;
  opacity: 0.8;
}
.demo-caption {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 0.9375rem;
  text-align: center;
}
/* Copy beside a picture: stacked on a phone, side by side from 900 px. */
.split {
  display: grid;
  gap: 24px;
  align-items: center;
}
.split .section-lead {
  margin-bottom: 16px;
}
.split .phone-wrap {
  margin-top: 8px;
}
/* The feed's buttons: ink on vermilion for the same contrast reason as .cta. */
.button-talk {
  color: var(--ink);
}
.button-quiet {
  background: transparent;
  color: var(--cream);
  border: 2px solid rgb(255 243 228 / 0.5);
  padding: 9px;
}
/* The section that links to /vision: a statement and a door. */
.teaser {
  text-align: center;
}
.teaser .statement {
  margin-inline: auto;
}
.teaser p:not(.statement) {
  max-width: 32rem;
  margin-inline: auto;
}

/* ---------------------------------------------------------------------------------------------
   9. Wider screens. Same skeleton, more air, grids spread out. */
@media (min-width: 640px) {
  main > section {
    padding-block: 72px;
  }
  .hero-pair {
    --d: 110px;
  }
  .step-list {
    grid-template-columns: repeat(3, 1fr);
    gap: 28px;
  }
  .trio {
    grid-template-columns: repeat(3, 1fr);
  }
.card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .numbered {
    grid-template-columns: repeat(2, 1fr);
    gap: 28px;
  }
  .site-nav {
    gap: 28px;
  }
}
@media (min-width: 900px) {
  .hero {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    align-items: center;
    gap: 32px;
    text-align: left;
    padding-block: 24px 64px;
  }
  .hero-pair {
    margin-inline: 0;
  }
  .hero .lead {
    margin-inline: 0;
  }
  .phone-wrap,
  .demo-wrap {
    margin-top: 0;
  }
  .hero .cta-row {
    justify-content: flex-start;
  }
  .split {
    grid-template-columns: 1fr 0.8fr;
    gap: 40px;
  }
  .split .phone-wrap {
    margin-top: 0;
  }
  .card-grid.cols-4 {
    grid-template-columns: repeat(4, 1fr);
  }
  .numbered.cols-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ---------------------------------------------------------------------------------------------
   10. Reduced motion (guide §06): the mark holds at the open position and nothing loops.
   Each state keeps its still pose, so Listening still leans and Sleeping still has its eye shut. */
@media (prefers-reduced-motion: reduce) {
  main *,
  main *::before,
  main *::after {
    animation: none !important;
  }
  html {
    scroll-behavior: auto;
  }
  .mover-a { transform: translateX(calc(var(--d) * -0.56)); }
  .mover-b { transform: translateX(calc(var(--d) * 0.56)); }
  .pellets,
  .arcs,
  .words,
  .sparks,
  .zzz {
    display: none;
  }
}
