:root {
  --bg: #ffffff;
  --text: #1f1a1d;
  --muted: #6b5f66;
  --rule: #f0dbe5;
  --accent: #d1006a;
  --pink: #ff2e88;
  --soft: #fff2f8;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #161214;
    --text: #f4eef1;
    --muted: #b3a5ad;
    --rule: #3a2a32;
    --accent: #ff7ab5;
    --soft: #241a1f;
  }
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 17px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Noto Sans", sans-serif;
}

header, main, footer {
  max-width: 44rem;
  margin: 0 auto;
  padding: 0 16px;
}

header { padding-top: 20px; padding-bottom: 8px; }

.brand {
  display: inline-flex;
  align-items: center;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
}

/* The app's icon beside the name, rounded like a home-screen icon (Sean, 2026-11-11). */
.brand { gap: 9px; }
.brand-icon { display: block; width: 30px; height: 30px; border-radius: 22.5%; box-shadow: 0 1px 2px rgb(58 11 34 / 0.18); }

main { padding-bottom: 32px; }

h1 { font-size: 2rem; line-height: 1.2; margin: 1.2em 0 0.4em; }
h2 { font-size: 1.3rem; line-height: 1.3; margin: 2em 0 0.5em; }
h3 { font-size: 1.1rem; margin: 1.6em 0 0.4em; }

p, ul, ol { margin: 0 0 1em; }
li { margin-bottom: 0.35em; }

a { color: var(--accent); }
em { color: var(--muted); }

.table { overflow-x: auto; margin: 0 0 1em; }

table { border-collapse: collapse; width: 100%; font-size: 0.94rem; }

th, td {
  text-align: left;
  vertical-align: top;
  padding: 8px 10px;
  border-bottom: 1px solid var(--rule);
}

th { background: var(--soft); }
td:first-child { width: 38%; }

footer {
  border-top: 1px solid var(--rule);
  padding-top: 16px;
  padding-bottom: 40px;
  color: var(--muted);
  font-size: 0.9rem;
}

footer a { color: var(--muted); }
/* The social links: monochrome icons from Simple Icons (CC0), in the footer's own colour. */
footer .social { display: flex; gap: 18px; margin: 0 0 0.6em; }
footer .social a { display: inline-flex; color: var(--muted); }
footer .social a:hover { color: var(--accent); }
footer .social svg { width: 20px; height: 20px; fill: currentColor; }
/* Apple's credit line, on pages with the App Store badge (site/build.py). */
footer .credit { margin: 1em 0 0; font-size: 0.8rem; }

.home { text-align: center; padding-top: 32px; }
.home-icon { border-radius: 28px; box-shadow: 0 8px 24px rgb(255 46 136 / 0.25); }
.home h1 { margin-top: 0.6em; }
.home .lede { font-size: 1.25rem; font-weight: 500; }
.home p { max-width: 32rem; margin-left: auto; margin-right: auto; }
.home .cta { margin-top: 1.6em; }

/* The home page (site/home.html): full-width bands, hot pink and plain by turns, each with a
   drawing of the Lens cat (site/art.py). The cat is white on the pink bands, pink on the others.
   Headings are SF Pro Rounded on Apple devices and Nunito elsewhere, like the App Store
   screenshots. */
@font-face {
  font-family: "Nunito";
  font-weight: 700 900;
  font-display: swap;
  src: url("/fonts/nunito-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Nunito";
  font-weight: 700 900;
  font-display: swap;
  src: url("/fonts/nunito-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

.landing {
  --round: ui-rounded, "SF Pro Rounded", "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ink: #3a0b22;
  --deep: #d1006a; /* the pink for headings and buttons on the white cards, in either theme */
  --wide: 66rem;
  /* The drawings' colours on a plain band (site/art.py); .band.pink sets its own. */
  --cat: #ff2e88;
  --bean: #d4166f;
  --ground: rgb(58 11 34 / 0.08);
  --leader: #f0bcd5;
  --beam: rgb(255 46 136 / 0.12);
  --edge: var(--rule);
  --cushion-rim: #f7c6dd;
  --cushion-top: #ffe3f0;
  --py-accent: #ff2e88;
  --ledge: var(--rule);
  --art-text: var(--text);
  --action: #ff2e88;
  --touch: #ff2e88;
  --touch-fill: rgb(255 46 136 / 0.37);
  --paper: #ffe3f0; /* signs and messages in the drawings: white would vanish into a plain band */
  --hanger: #3a0b22; /* what holds them up: a sign's bracket, a board's legs */
}

@media (prefers-color-scheme: dark) {
  .landing { --ground: rgb(0 0 0 / 0.35); --leader: #5a3346; --beam: rgb(255 46 136 / 0.2); --paper: #fff; --hanger: #8a6b7b; }
}

.landing header, .landing footer { max-width: none; padding-left: max(16px, calc((100% - var(--wide)) / 2)); padding-right: max(16px, calc((100% - var(--wide)) / 2)); }
.landing header { background: var(--pink); padding-top: 18px; padding-bottom: 0; }
.landing .brand { color: #fff; font-family: var(--round); font-weight: 800; font-size: 1.1rem; }
.landing main { max-width: none; padding: 0; }
.landing footer { border-top: 0; }

.band-in {
  max-width: var(--wide);
  margin: 0 auto;
  padding: clamp(44px, 9vw, 104px) 16px;
  display: grid;
  gap: 8px 56px;
  align-items: center;
}

.band.pink {
  background: var(--pink);
  color: var(--ink);
  --cat: #fff;
  --bean: #ff8ec0;
  --ground: rgb(212 22 111 / 0.35);
  --leader: rgb(255 255 255 / 0.65);
  --beam: rgb(255 255 255 / 0.16);
  --edge: transparent;
  --cushion-rim: #d4166f;
  --cushion-top: #e8247f;
  --py-accent: #fff;
  --ledge: rgb(255 255 255 / 0.55);
  --art-text: var(--ink);
  --action: #fff;
  --touch: #fff;
  --touch-fill: rgb(255 255 255 / 0.4);
  --paper: #fff;
  --hanger: #3a0b22;
}
.band.hero .band-in { padding-top: clamp(28px, 5vw, 56px); }

.band h1, .band h2 {
  font-family: var(--round);
  font-weight: 800;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.band h1 { font-size: clamp(2.7rem, 7.4vw, 4.6rem); line-height: 1.02; margin: 0 0 0.35em; }
.band h2 { font-size: clamp(1.85rem, 4.2vw, 2.75rem); line-height: 1.08; margin: 0 0 0.45em; }
/* On a pink band the words sit on a white card: dark text on hot pink shimmers, and white on it is
   too faint for small text. The pink stays as the frame around the card and the drawing. */
.band.pink .copy { background: #fff; color: var(--ink); border-radius: 28px; padding: clamp(22px, 4vw, 40px); }
.band.pink :is(h1, h2) { color: var(--deep); }
.band.pink h1 { font-size: clamp(2.3rem, 5.2vw, 3.5rem); }

.band p { max-width: 30rem; font-size: 1.12rem; }
.band .lede { font-size: clamp(1.18rem, 2vw, 1.35rem); font-weight: 500; }
.band .lede + .lede { margin-top: 1lh; }
.band .fine { font-size: 0.98rem; color: var(--muted); }
.band.pink .fine { color: var(--ink); opacity: 0.8; }

/* The gap is at least the badge's clear space, a quarter of its height (Apple's rule). */
.band .cta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; margin-top: 1.5em; }
/* A note beside the badge. */
.band .cta span { font-size: 0.98rem; opacity: 0.7; }

/* Apple's Download on the App Store badge (site/app-store-badge.svg), as Apple made it: black,
   unchanged, 54 px tall, above Apple's 40 px minimum. */
.app-store { display: inline-block; border-radius: 9px; }
.app-store img { display: block; height: 54px; width: auto; }
.app-store:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.art { margin: 0; min-width: 0; }
.art svg { display: block; width: 100%; height: auto; overflow: visible; }

@media (min-width: 52rem) {
  .band-in { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); }
  .band-in.flip .art { order: -1; }
  .band-in.flip { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
}

.closing .band-in { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0; }
.closing .art { width: min(100%, 300px); margin-bottom: 8px; }
.closing p { margin-left: auto; margin-right: auto; }
.closing .cta { justify-content: center; }

/* The guide (site/guides/): a pink band that answers the question beside a drawing, then the
   details in one column. */
.guide-hero h1 { font-size: clamp(2.1rem, 4.4vw, 3.1rem); }
.guide { max-width: 44rem; margin: 0 auto; padding: clamp(36px, 7vw, 72px) 16px; }
.guide h2 { font-family: var(--round); font-weight: 800; letter-spacing: -0.01em; font-size: clamp(1.45rem, 3vw, 1.9rem); line-height: 1.15; margin: 1.6em 0 0.5em; }
.guide h2:first-child { margin-top: 0; }
.guide :is(p, li) { font-size: 1.08rem; }
.guide .cta { margin-top: 2em; }

/* Inside the drawings: Chinese in the system's Chinese font, pinyin in the rounded one. */
.art .zh { font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", sans-serif; font-weight: 600; }
.art .py { font-family: var(--round); font-weight: 800; }
.art .halo { paint-order: stroke; stroke: #fff; stroke-width: 4px; stroke-linejoin: round; }
.art svg { color: var(--art-text); }
.art .cat { fill: var(--cat); }
.art .cat-line { stroke: var(--cat); }
.art .bean { fill: var(--bean); }
.art .ground { fill: var(--ground); }
.art .leader { stroke: var(--leader); }
.art .beam { fill: var(--beam); }
.art .card-edge { stroke: var(--edge); stroke-width: 2px; }
.art .cushion-rim { fill: var(--cushion-rim); }
.art .cushion-top { fill: var(--cushion-top); }
.art .py-accent { fill: var(--py-accent); }
.art .ledge { stroke: var(--ledge); }
.art .action { fill: var(--action); }
.art .touch { fill: var(--touch-fill); stroke: var(--touch); }
/* A fingertip on the cat's own phone: outlined, since behind it is the cat, pink or white. */
.art .press-mark { fill: rgb(255 255 255 / 0.6); stroke: #3a0b22; }
.art .paper { fill: var(--paper); }
.art .hanger { stroke: var(--hanger); }

/* The beats (see site/art.py). Each waits at its first frame until its drawing gets .play. */
.art :is(.pop, .sweep, .rise, .fly, .blip, .twitch, .flip-out, .flip-in, .swap-out, .swap-in, .focus, .fade, .press-paw, .push, .brush) { transform-box: fill-box; }
.art .pop { transform-origin: 50% 100%; }
.art .sweep { transform-origin: 0 50%; }
.art :is(.flip-out, .flip-in, .blip, .focus) { transform-origin: 50% 50%; }
.art .twitch { transform-origin: 50% 100%; }
.art .blip, .art .swap-out, .art .flip-out, .art .press-paw, .art .brush { opacity: 0; }
.art .push { transform-origin: 50% 50%; }
/* The screenshot in the Lens: its place there is its resting state; the beat starts it full size. */
.art .inset { transform-box: view-box; transform-origin: 0 0; transform: translate(var(--ix), var(--iy)) scale(var(--is)); }

.beats .art :is(.pop, .sweep, .rise, .fly, .blip, .twitch, .flip-out, .flip-in, .swap-out, .swap-in, .focus, .fade, .press-paw, .push, .brush, .inset) {
  animation-delay: var(--d, 0s);
  animation-fill-mode: both;
  animation-play-state: paused;
}

.beats .art .pop { animation-name: pop; animation-duration: 0.42s; animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
.beats .art .sweep { animation-name: sweep; animation-duration: 0.4s; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
.beats .art .rise { animation-name: rise; animation-duration: 0.6s; animation-timing-function: cubic-bezier(0.34, 1.4, 0.64, 1); }
.beats .art .fly { animation-name: fly; animation-duration: 0.8s; animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1); }
.beats .art .blip { animation-name: blip; animation-duration: 0.5s; }
.beats .art .twitch { animation-name: twitch; animation-duration: 0.45s; }
.beats .art .flip-out { animation-name: flip-out; animation-duration: 0.18s; animation-timing-function: ease-in; }
.beats .art .flip-in { animation-name: flip-in; animation-duration: 0.3s; animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
.beats .art .focus { animation-name: focus; animation-duration: 0.35s; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
.beats .art .fade { animation-name: fade; animation-duration: 0.4s; }
.beats .art .press-paw { animation-name: press; animation-duration: 0.9s; }
.beats .art .push { animation-name: push; animation-duration: 0.3s; }
.beats .art .inset { animation-name: inset; animation-duration: 0.45s; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
.beats .art .brush { animation-name: brush; animation-duration: 1s; animation-timing-function: linear; }
.beats .art .swap-out { animation-name: swap-out; animation-duration: 0.01s; }
.beats .art .swap-in { animation-name: swap-in; animation-duration: 0.01s; }
.beats .art.play :is(.pop, .sweep, .rise, .fly, .blip, .twitch, .flip-out, .flip-in, .swap-out, .swap-in, .focus, .fade, .press-paw, .push, .brush, .inset) { animation-play-state: running; }

@keyframes pop { from { opacity: 0; transform: scale(0.3); } 40% { opacity: 1; } }
@keyframes sweep { from { transform: scaleX(0); } }
@keyframes rise { from { transform: translateY(var(--from, 100px)); } }
@keyframes fly {
  from { opacity: 0; transform: translate(var(--fx), var(--fy)) scale(0.3); }
  15% { opacity: 1; }
  55% { transform: translate(calc(var(--fx) * 0.55), calc(var(--fy) * 0.35)) scale(0.75); }
  85% { transform: translateY(-6px) scale(1.04); }
}
@keyframes blip { from { opacity: 0; transform: scale(0.6); } 25% { opacity: 1; transform: scale(1); } to { opacity: 0; } }
@keyframes twitch { 30% { transform: rotate(-14deg); } 65% { transform: rotate(5deg); } }
@keyframes flip-out { from { opacity: 1; } to { opacity: 1; transform: scaleX(0); } }
@keyframes flip-in { from { transform: scaleX(0); } }
@keyframes focus { from { opacity: 0; transform: scale(1.35); } }
@keyframes fade { from { opacity: 0; } }
/* A fingertip reaches in from --reach (left by default), presses by --press, and leaves. */
@keyframes press {
  from { opacity: 0; transform: translateX(var(--reach, -36px)); }
  30% { opacity: 1; transform: none; }
  42% { transform: translateX(var(--press, 5px)) scale(0.92); }
  58% { transform: none; }
  80% { opacity: 1; }
  to { opacity: 0; transform: translateX(var(--reach, -36px)); }
}
@keyframes push { 50% { transform: translateX(var(--push-x, 4px)); } }
@keyframes inset { from { transform: none; } }
@keyframes brush {
  from { opacity: 0; transform: none; }
  12% { opacity: 1; transform: none; }
  88% { opacity: 1; transform: translateX(var(--dx)); }
  to { opacity: 0; transform: translateX(var(--dx)); }
}
@keyframes swap-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes swap-in { from { opacity: 0; } to { opacity: 1; } }

/* The invite page (infra/cloudflare/account.js): the inviter's photo, round. */
.invite-photo { border-radius: 50%; object-fit: cover; }

/* The opening lines of the home page and the invite page. */
.lede { font-size: 1.15rem; }

/* A link that looks like a button (the home page, the invite page). */
.button {
  display: inline-block;
  appearance: none;
  border: 0;
  border-radius: 999px;
  padding: 13px 30px;
  background: var(--accent);
  color: var(--bg);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

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

/* The home page since 2026-11-11 (site/home.html, body class storefront): the App Store page's look, white with ink type
   and the store's phone renders, every band plain. Always light, in either theme, since the
   renders are on white. Pink stays in the closing cat, the links and nothing else. */
.storefront {
  color-scheme: light;
  --bg: #ffffff;
  --text: #2a0f1f;
  --muted: #6b5f66;
  --rule: #f0dbe5;
  --accent: #d1006a;
  --soft: #fff2f8;
  --ground: rgb(58 11 34 / 0.08);
  --leader: #f0bcd5;
  --beam: rgb(255 46 136 / 0.12);
  --paper: #ffe3f0;
  --hanger: #3a0b22;
}
.storefront header { background: none; padding-top: 22px; }
.storefront .brand { color: var(--text); }
/* Sized so "Learn Chinese faster." (about 9.8 em) stays on one line: the whole column on a phone,
   the 1.3fr text column beside the picture from 52rem up. */
.storefront .band h1 { font-size: clamp(2rem, calc(9.6vw - 4px), 3.4rem); }
@media (min-width: 52rem) { .storefront .band h1 { font-size: clamp(2rem, calc(5.6vw - 4px), 3.4rem); } }
@media (min-width: 52rem) { .storefront .hero .band-in { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); } }
.nowrap { white-space: nowrap; }
.storefront .band p { color: rgb(42 15 31 / 0.75); }
.storefront .band .lede { color: var(--text); opacity: 0.8; }
.storefront .band-in { padding-block: clamp(32px, 6vw, 72px); }
.storefront .hero .band-in { padding-top: clamp(16px, 3vw, 40px); }
.storefront .band + .band:not(.closing) .band-in { padding-top: 0; }

/* Our own laurel beside Apple's badge, at least the badge's clear space away (.cta's gap). */
.laurel { display: inline-block; width: 180px; color: rgb(42 15 31 / 0.85); }
.laurel svg text { font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif; }

/* A store render: the phone, on white, kept to a height that fits a screen. */
.shot { margin: 0; position: relative; display: flex; justify-content: center; min-width: 0; }
.shot :is(img, video) { display: block; width: auto; max-width: 100%; height: auto; max-height: min(600px, 75vh); }
/* The camera render: the phone in a white room before the menu (docs/design/blender/home-camera.sh),
   its edges faded into the page. */
.shot.camera :is(img, video) { max-height: min(640px, 75vh); }
/* The apps posts come from, as Scan's Import from social media tile tilts them. */
.shot .frame { position: relative; display: block; }

/* A sidekick cat beside each render (site/art.py side_*), standing on the render's floor and
   leaning out past its edge, towards the page's margin. */
.storefront main { overflow-x: clip; }
.sidekick { position: absolute; pointer-events: none; width: 50%; bottom: 4%; }
.sidekick.s1 { left: -22%; bottom: 4%; width: 42%; }
/* 2 and 3 sit on the phone's top edge (the videos' last frames put it there; the camera holds
   still, so it's there throughout), turned with it. Percentages of the video's own box, so they
   hold at any width. */
.sidekick.s2, .sidekick.s3 { bottom: auto; transform-origin: 50% 96%; }
.sidekick.s2 { width: 24%; left: 56%; top: -8.2%; transform: rotate(4deg); }
.sidekick.s3 { width: 26%; left: 54%; top: -0.6%; transform: rotate(8deg); }
.sidekick.s4 { left: -26%; }
.sidekick.s5 { right: -24%; bottom: 3%; }
/* Narrow: the picture fills the column, so the cat can't stand beside it. It stands just below
   the picture's outer corner instead, clear of the popped-out word card, with room before the next
   section. */
@media (max-width: 52rem) {
  .storefront .band:not(.closing) .band-in { padding-bottom: 64px; }
  .sidekick.s1, .sidekick.s4, .sidekick.s5 { width: 30%; bottom: -11%; }
  .sidekick.s1, .sidekick.s4 { left: -4%; right: auto; }
  .sidekick.s5 { right: -4%; left: auto; }
}
.shot.posts .apps { position: absolute; left: -84px; top: 4%; display: grid; grid-template-columns: repeat(2, 44px); gap: 7px; }
.shot.posts .apps img { width: 44px; height: 44px; border-radius: 22%; max-height: none; }
.shot.posts .apps img:nth-child(1) { transform: rotate(-5deg); }
.shot.posts .apps img:nth-child(2) { transform: rotate(5deg); }
.shot.posts .apps img:nth-child(3) { transform: rotate(4deg); }
.shot.posts .apps img:nth-child(4) { transform: rotate(-4deg); }
/* Renders alternate sides like the drawings did. */
@media (min-width: 52rem) { .band-in.flip .shot { order: -1; } }
/* On a phone the laurel stays beside the badge. */
@media (max-width: 26rem) { .laurel { width: 150px; } .band .cta { gap: 14px 16px; } }
/* Narrow: the four icons in one column, the phone moved over to make room. */
@media (max-width: 52rem) {
  .shot.posts .frame { margin-left: 52px; }
  .shot.posts .apps { left: -50px; grid-template-columns: 38px; gap: 8px; }
  .shot.posts .apps img { width: 38px; height: 38px; }
}
/* The home page's questions, in one column before the closing cat. */
.faq .band-in { display: block; max-width: 44rem; }
.faq h3 { font-family: var(--round); font-weight: 800; letter-spacing: -0.01em; font-size: clamp(1.2rem, 2.4vw, 1.45rem); line-height: 1.2; margin: 1.3em 0 0.3em; }
.faq p { margin: 0; }
/* The home page's header: the icon and name a size up. */
.storefront .brand { font-size: 1.2rem; gap: 11px; }
.storefront .brand-icon { width: 38px; height: 38px; }
