/* LoveBlossom "paper and ink": the design system every screen builds on.
   Tokens live on :root (light) and under prefers-color-scheme: dark. Names are
   exactly those in EXPERIENCE_PLAN.md (design system); garden.css, loop.css,
   book.css and play.css use them and add only their own prefixed classes.
   Rules: no color-mix() (iOS 15 lacks it); type, spacing and tap targets in rem
   so Dynamic Type and the Aa sheet scale everything, except side padding and
   gutters, which stop growing at their 17px-root size (min(1rem, 17px)) so large
   text keeps its line length; every theme difference is a
   token; every movement sits in the prefers-reduced-motion: no-preference block
   at the end, scoped to html:not(.calm). Fonts and pictures are our own files. */

/* ---------------------------------------------------------------- fonts */
@font-face {
  font-family: 'Atkinson Next';
  src: url(/static/fonts/atkinson-next-526.woff2) format('woff2');
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  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: 'Fraunces LB';
  src: url(/static/fonts/fraunces-lb-529.woff2) format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  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;
}
/* Metric-matched fallbacks (scripts/make_fonts.py measures them), so the swap
   barely moves a line. Browsers without these descriptors ignore them. */
@font-face {
  font-family: 'Atkinson Fallback';
  src: local('Arial'), local('ArialMT');
  size-adjust: 99.54%;
  ascent-override: 98.85%;
  descent-override: 31.75%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Fraunces Fallback';
  src: local('Georgia');
  size-adjust: 105.4%;
  ascent-override: 92.79%;
  descent-override: 24.19%;
  line-gap-override: 0%;
}

/* --------------------------------------------------------------- tokens */
:root {
  color-scheme: light dark;

  /* surfaces */
  --paper: #FBF5EE;
  --paper-92: rgba(251, 245, 238, .92);
  --paper-70: rgba(251, 245, 238, .70);
  --card: #FFFDF9;
  --sunken: #F4EAE0;
  --hairline: #E8D9CB;
  --field-line: #9C7B6D;   /* a text field's drawn edge: 3.5:1 on paper, 3.2:1 on its fill */
  --scrim: rgba(59, 31, 51, .40);

  /* ink */
  --ink: #3B1F33;
  --muted: #75566A;

  /* action: rose is the only action colour */
  --rose: #C8326B;
  --on-rose: #FFFFFF;
  --rose-pressed: #A82457;
  --rose-soft: #FBE3EA;
  --rose-text: #A82457;
  --rose-glow: rgba(200, 50, 107, .55);

  /* signals: decoration / text shade / soft fill */
  --leaf: #6FB37A;
  --leaf-text: #276B45;
  --leaf-soft: #E3F3E9;
  --honey: #F2B33D;
  --honey-text: #8F5A0B;
  --honey-soft: #FCEFD2;
  --peri: #8FA2F2;
  --peri-text: #4152B0;
  --peri-soft: #E6EAFD;
  --danger: #B4361A;
  --on-danger: #FFFFFF;
  --gold-a: #F6D58A;
  --gold-b: #D9A13B;
  --gold-c: #F3CF7A;

  /* kind accents (a .kind-* container overrides them; rose by default) */
  --kind: var(--rose);
  --kind-soft: var(--rose-soft);
  --kind-text: var(--rose-text);

  /* garden */
  --stake: #E6CFAE;
  --soil: #8A5A44;
  --soil-rim: #A87458;
  --stem: #5E9F64;
  --leaf-a: #7DBB78;
  --leaf-b: #B5DB9C;
  --vein: #4E8A55;
  --line-art: rgba(74, 35, 56, .60);
  --moon: #F6E7B8;
  --star: #FFF4D6;
  --firefly: #F9E27D;
  --sky-dawn: #FFE3D3;
  --sky-day: #E4F2F1;
  --sky-dusk-a: #FFD7C0;
  --sky-dusk-b: #F7C3D3;
  --sky-eve: #ECE3F4;
  /* Dark mode's Home sky follows the clock too (ux-35): the same dawn, day and dusk, dimmed.
     Fixed values like --night-*: garden.css uses them only in its dark block. */
  --sky-dawn-dk: #40292E;
  --sky-day-dk: #24334A;
  --sky-dusk-dk: #432436;
  --night-a: #120C14;
  --night-b: #2A1C33;

  /* book cloth (cream titles on every cloth) */
  --cloth-romantic: #7A2E46;
  --cloth-platonic: #8A5A2B;
  --cloth-familial: #3F5E4A;
  --cloth-title: #F7E8D8;

  /* Sign in with Apple follows Apple's black / white rule */
  --apple-bg: #000000;
  --apple-fg: #FFFFFF;

  /* elevation */
  --e1: inset 0 1px 0 rgba(255, 255, 255, .7), 0 1px 2px rgba(59, 31, 51, .06), 0 6px 18px -8px rgba(110, 45, 75, .16);
  --e2: inset 0 1px 0 rgba(255, 255, 255, .8), 0 2px 4px rgba(59, 31, 51, .06), 0 18px 40px -16px rgba(110, 45, 75, .28);
  --lip: inset 0 -3px 0 rgba(0, 0, 0, .14);
  --hair: 1px;
  --grain: url(/static/img/paper-grain.png);

  /* type */
  --font-ui: 'Atkinson Next', 'Atkinson Fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-story: 'Fraunces LB', 'Fraunces Fallback', 'Iowan Old Style', Georgia, 'Times New Roman', serif;

  /* motion */
  --t-press: 120ms;
  --t-quick: 200ms;
  --t-base: 320ms;
  --t-slow: 520ms;
  --t-bloom: 900ms;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-in: cubic-bezier(.55, 0, 1, .45);
  --ease-move: cubic-bezier(.65, 0, .35, 1);
  --ease-pop: cubic-bezier(.34, 1.56, .64, 1);
  --ease-stamp: cubic-bezier(.2, 1.4, .4, 1);

  /* shape and size */
  --r-qcard: 28px;
  --r-card: 22px;
  --r-tile: 16px;
  --r-pill: 999px;
  --r-paper: 6px;
  --tap: 3rem;
  --tap-lg: 3.5rem;
  --tap-xl: 4rem;
  --gutter: min(1rem, 17px);
  --header-h: 3.25rem;
}
@supports (animation-timing-function: linear(0, 1)) {
  :root { --ease-pop: linear(0, .25 8%, .7 18%, 1.05 32%, 1.08 38%, 1.02 50%, .99 62%, 1); }
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #1B1219;
    --paper-92: rgba(27, 18, 25, .92);
    --paper-70: rgba(27, 18, 25, .70);
    --card: #261A24;
    --sunken: #33232F;
    --hairline: #3E2C39;
    --field-line: #8E7484;
    --scrim: rgba(0, 0, 0, .60);
    --ink: #F7E9EF;
    --muted: #C9AFBE;
    --rose: #FF7AA2;
    --on-rose: #2A0F1C;
    --rose-pressed: #F0608E;
    --rose-soft: #4A2335;
    --rose-text: #FFB3CB;
    --rose-glow: rgba(255, 122, 162, .35);
    --leaf: #5CC28D;
    --leaf-text: #7FD9A0;
    --leaf-soft: #1F3A2B;
    --honey: #F0B75A;
    --honey-text: #F5C46A;
    --honey-soft: #3A2A12;
    --peri: #8FA2F2;
    --peri-text: #A9B6FF;
    --peri-soft: #262B4A;
    --danger: #FF9A7A;
    --on-danger: #2A0F1C;
    --stake: #4A3628;
    --soil: #3A2520;
    --soil-rim: #5A3A30;
    --stem: #6FBF7E;
    --leaf-a: #5FA26A;
    --leaf-b: #8FCB8A;
    --line-art: rgba(255, 240, 246, .35);
    --apple-bg: #FFFFFF;
    --apple-fg: #000000;
    --e1: inset 0 1px 0 rgba(255, 255, 255, .05), 0 1px 2px rgba(0, 0, 0, .40), 0 8px 22px -8px rgba(0, 0, 0, .55);
    --e2: inset 0 1px 0 rgba(255, 255, 255, .06), 0 2px 4px rgba(0, 0, 0, .45), 0 20px 44px -16px rgba(0, 0, 0, .65);
  }
}

/* prefers-contrast: more: muted becomes ink, hairlines become 2px and darker,
   no grain, flat primary buttons, underlined links. */
@media (prefers-contrast: more) {
  :root { --muted: var(--ink); --hairline: #9C7B6D; --hair: 2px; --grain: none; --lip: 0 0 0 transparent; --rose-glow: transparent; }
}
@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
  :root { --hairline: #8E7484; }
}

/* ----------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html {
  font-size: 106.25%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Things scrolled into view (focus, #anchors) land below the sticky header. */
  scroll-padding-top: calc(var(--header-h) + env(safe-area-inset-top) + .75rem);
  scroll-padding-bottom: 1rem;
}
/* iOS only: follow the phone's text size (Dynamic Type). macOS Safari keeps 17px. */
@supports (font: -apple-system-body) and (-webkit-touch-callout: none) {
  html { font: -apple-system-body; }
}
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--font-ui);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  color: var(--ink);
  background-color: var(--paper);
  background-image: var(--grain);
  background-size: 128px 128px;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
  overflow-wrap: break-word;
}
h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
ul, ol { padding-left: 1.25rem; }
h1, h2, h3, h4 { font-family: var(--font-story); color: var(--ink); text-wrap: balance; }
h1, .h1 { font-family: var(--font-story); font-size: 2rem; line-height: 1.1; font-weight: 650; letter-spacing: -.005em; }
h2, .h2 { font-family: var(--font-story); font-size: 1.35rem; line-height: 1.2; font-weight: 600; }
h3, .h3 { font-family: var(--font-story); font-size: 1.125rem; line-height: 1.25; font-weight: 600; }
h4 { font-family: var(--font-ui); font-size: 1rem; font-weight: 700; }
strong, b { font-weight: 700; }
/* No italics anywhere: Fraunces ships no italic file and Atkinson's isn't loaded. */
em, i, cite, dfn, var, address { font-style: normal; }
em { font-weight: 700; }
a { color: var(--rose); text-decoration-thickness: from-font; text-underline-offset: .15em; }
img, video { max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
::selection { background: var(--rose-soft); color: var(--ink); }
hr { border: 0; border-top: var(--hair) solid var(--hairline); margin: 0; }

/* focus: one ring everywhere, ink at 3px, 2px out */
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }

/* ----------------------------------------------------------- type scale */
.display { font-family: var(--font-story); font-weight: 650; font-size: 2.25rem; line-height: 1.1; letter-spacing: -.01em; text-wrap: balance; }
.question {
  font-family: var(--font-story);
  font-weight: 600;
  font-size: clamp(1.6rem, 6.5vw, 2.1rem);
  line-height: 1.15;
  text-wrap: balance;
  color: var(--ink);
}
.story {
  font-family: var(--font-story);
  font-weight: 450;
  font-size: 1.25rem;
  line-height: 1.5;
  font-optical-sizing: auto;
  max-width: 34em;
  white-space: pre-wrap;
  -webkit-hyphens: auto;   /* a long word at large text breaks with a hyphen, not "blackberri / es" */
  hyphens: auto;
}
.story--lg { font-size: 1.5rem; }
.num { font-family: var(--font-story); font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.lead { font-family: var(--font-ui); font-weight: 400; font-size: 1.1875rem; line-height: 1.5; }
.label { font-family: var(--font-ui); font-weight: 700; font-size: .9375rem; letter-spacing: .02em; line-height: 1.3; }
.meta, .small { font-family: var(--font-ui); font-weight: 500; font-size: .875rem; line-height: 1.45; }
.chapter-label { font-family: var(--font-ui); font-weight: 700; font-size: .875rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.signature { font-family: var(--font-ui); font-weight: 700; font-size: .9375rem; color: var(--muted); text-align: right; }

/* ---------------------------------------------------------------- layout */
.wrap {
  width: 100%;
  max-width: 35rem;
  margin: 0 auto;
  padding: 1.25rem max(var(--gutter), env(safe-area-inset-right)) calc(2.5rem + env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-left));
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.stack { display: flex; flex-direction: column; gap: .875rem; }
.stack-sm { display: flex; flex-direction: column; gap: .625rem; }
/* Children share the row equally and stack by themselves once they no longer
   fit (larger text, longer names). */
.row { display: flex; flex-wrap: wrap; gap: .625rem; }
.row > * { flex: 1 1 9rem; min-width: 0; }
.center { text-align: center; }
.stack.center, .stack-sm.center { align-items: center; }
.muted { color: var(--muted); }
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: .5rem; top: -10rem; z-index: 70;
  background: var(--card); color: var(--ink); padding: .5rem 1rem; border-radius: var(--r-pill); box-shadow: var(--e2);
  font-weight: 700; text-decoration: none;
}
.skip-link:focus { top: calc(.5rem + env(safe-area-inset-top)); }

/* ---------------------------------------------------------------- header */
.top {
  position: sticky;
  top: 0;
  z-index: 30;
  padding-top: env(safe-area-inset-top);
  background: var(--paper);
  border-bottom: var(--hair) solid var(--hairline);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .top { background: var(--paper-92); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
}
.top__in {
  max-width: 35rem;
  min-height: var(--header-h);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: 0 max(.375rem, env(safe-area-inset-right)) 0 max(.375rem, env(safe-area-inset-left));
}
/* .top__start is a container, so at large text the header makes room by itself: the
   wordmark keeps only its blossom, and a back link reads "Back", then shows its arrow
   alone. Both links keep their full names for VoiceOver. Older Safari ellipsizes. */
.top__start { display: flex; align-items: center; min-width: 0; flex: 1 1 auto; container: top-start / inline-size; }
.top__end { display: flex; align-items: center; gap: .125rem; flex: none; }
.top .icon-btn { width: min(2.75rem, 56px); height: min(2.75rem, 56px); }
.top .icon-btn .mark { width: min(1.25em, 30px); height: min(1.25em, 30px); }
.wordmark {
  display: inline-flex; align-items: center; gap: .375rem;
  min-height: var(--tap); min-width: 0; padding: 0 .5rem;
  font-family: var(--font-story); font-weight: 650; font-size: 1.125rem; line-height: 1;
  color: var(--ink); text-decoration: none; white-space: nowrap;
  --mark-accent: var(--honey); --mark-accent-o: 1;
}
.wordmark > span { overflow: hidden; text-overflow: ellipsis; }
.wordmark .mark { color: var(--rose); width: 1.5em; height: 1.5em; vertical-align: middle; }
.back {
  display: inline-flex; align-items: center; gap: .25rem;
  min-height: var(--tap); min-width: var(--tap); max-width: 100%; padding: 0 .75rem 0 .25rem;
  color: var(--rose-text); font-weight: 700; font-size: 1rem; text-decoration: none;
  border-radius: var(--r-pill);
}
.back > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.back > .back__short { display: none; }
.back:active { background: var(--sunken); }
@container top-start (max-width: 10.5rem) {
  .wordmark > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); }
}
@container top-start (max-width: 9.5rem) {
  .back > .back__label { display: none; }
  .back > .back__short { display: inline; }
}
@container top-start (max-width: 4.75rem) {
  .back > .back__short { display: none; }
  .back { padding: 0; justify-content: center; }
}

/* ----------------------------------------------------------------- marks */
.mark { display: inline-block; width: 1.25em; height: 1.25em; flex: none; vertical-align: -.25em; overflow: visible; }
.mark--lg { width: 2rem; height: 2rem; }
.mark--xl { width: 3rem; height: 3rem; }

/* ---------------------------------------------------------- kind accents */
.kind-romantic { --kind: var(--rose); --kind-soft: var(--rose-soft); --kind-text: var(--rose-text); }
.kind-platonic { --kind: var(--honey); --kind-soft: var(--honey-soft); --kind-text: var(--honey-text); }
.kind-familial { --kind: var(--peri); --kind-soft: var(--peri-soft); --kind-text: var(--peri-text); }

/* ----------------------------------------------------------------- cards */
.card {
  background: var(--card);
  border: var(--hair) solid var(--hairline);
  border-radius: var(--r-card);
  padding: 1.125rem min(1.125rem, 19px);
  box-shadow: var(--e1);
}
.card--quiet { background: var(--sunken); border-color: transparent; box-shadow: none; }
.card--kind { box-shadow: inset 0 6px 0 var(--kind-soft), var(--e1); padding-top: calc(1.125rem + 6px); }
.card__title { display: flex; align-items: center; gap: .5rem; }
.card__title > .mark:first-child { color: var(--kind-text); }
.card__title > span { min-width: 0; }
.card__title-words { -webkit-hyphens: auto; hyphens: auto; }   /* "Notifi-cations" at the largest text, never past the card */

/* Question card: a seed packet. --qcard-bg tints it. */
.qcard {
  position: relative;
  background: var(--qcard-bg, var(--card));
  border: var(--hair) solid var(--hairline);
  border-radius: var(--r-qcard);
  box-shadow: var(--e2);
  padding: 1.25rem min(1.25rem, 21px) 1.5rem;
}
.qcard__band {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .5rem;
  min-height: 3.25rem;
  margin: -1.25rem calc(-1 * min(1.25rem, 21px)) 0;
  padding: .5rem 1rem;
  background: var(--kind-soft);
  border-radius: calc(var(--r-qcard) - var(--hair)) calc(var(--r-qcard) - var(--hair)) 0 0;
}
.qcard__stake {
  display: inline-flex; align-items: center; gap: .375rem;
  min-height: 2rem; padding: .25rem 1.25rem .25rem .625rem;
  background: var(--stake); color: var(--ink);
  font-family: var(--font-ui); font-weight: 700; font-size: .9375rem; letter-spacing: .02em; line-height: 1.2;
  border-radius: 6px 2px 2px 6px;
  clip-path: polygon(0 0, calc(100% - .625rem) 0, 100% 50%, calc(100% - .625rem) 100%, 0 100%);
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .07);
}
.qcard__stake .mark { color: var(--kind-text); }
.qcard__packet { font-family: var(--font-story); font-weight: 600; font-size: .9375rem; color: var(--kind-text); }
.qcard__perf {
  height: 6px;
  margin: 0 calc(-1 * min(1.25rem, 21px)) 1.125rem;
  background: radial-gradient(circle at 6px 3px, var(--sunken) 2.5px, transparent 3px) 0 0 / 12px 6px repeat-x;
}
.qcard .question { margin-bottom: 1.125rem; }
/* One or two cards peeking out behind (data-more=1|2). The card's own surface is
   ::after, so the peeking card stays behind it even while the card is moved or
   faded (a transform or opacity would otherwise lift ::before above it). */
.qcard--more { isolation: isolate; background: transparent; border-color: transparent; box-shadow: none; }
.qcard--more::before, .qcard--more::after {
  content: ""; position: absolute; inset: calc(-1 * var(--hair)); border-radius: inherit; pointer-events: none;
  background: var(--qcard-bg, var(--card)); border: var(--hair) solid var(--hairline);
}
.qcard--more::after { z-index: -1; box-shadow: var(--e2); }
.qcard--more::before { z-index: -2; box-shadow: var(--e1); transform: translateY(6px) rotate(-1.5deg); }
html.nocq-15 .qcard--more::before { transform: translateY(6px); }
.qcard--more[data-more="2"] {
  box-shadow: 0 .75rem 0 -.3rem var(--card), 0 .75rem 0 calc(-.3rem + var(--hair)) var(--hairline), 0 1.25rem 1.5rem -1rem rgba(59, 31, 51, .25);
}

/* People's own words: a sheet of paper with a rule 10px in. */
.paper {
  position: relative;
  background-color: var(--card);
  background-image: var(--grain);
  background-size: 128px 128px;
  border-radius: var(--r-paper);
  box-shadow: var(--e1);
  outline: 1px solid var(--hairline);
  outline-offset: -11px;
  padding: 1.5rem min(1.5rem, 26px) 1.375rem;
  font-family: var(--font-story);
  font-weight: 450;
  font-size: 1.25rem;
  line-height: 1.5;
  -webkit-hyphens: auto;
  hyphens: auto;
}
.paper:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
.paper__sig { display: block; margin-top: .75rem; font-family: var(--font-ui); font-weight: 700; font-size: .9375rem; color: var(--muted); text-align: right; }
.slip {
  display: block;
  background: var(--sunken);
  border-radius: 12px;
  padding: .75rem 1rem .875rem;
  transform: rotate(-1deg);
  font-family: var(--font-story);
  font-weight: 450;
  font-size: 1.125rem;
  line-height: 1.4;
}
.slip__label { display: block; font-family: var(--font-ui); font-weight: 700; font-size: .875rem; color: var(--muted); margin-bottom: .125rem; }

/* --------------------------------------------------------------- buttons */
.btn {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: var(--tap);
  padding: .375rem min(1.25rem, 21px);
  border: 0;
  /* a pill on one line; a rounded card, not a stadium, when large text wraps it */
  border-radius: 1.75rem;
  background: var(--sunken);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.btn .mark { width: 1.25em; height: 1.25em; }
.btn--primary {
  min-height: var(--tap-lg);
  background: var(--rose);
  color: var(--on-rose);
  box-shadow: var(--lip), 0 6px 16px -6px var(--rose-glow);
}
.btn--primary:active { background: var(--rose-pressed); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .14), 0 3px 10px -6px var(--rose-glow); }
.btn--secondary { background: var(--sunken); color: var(--ink); }
.btn--secondary:active { background: var(--hairline); }
.btn--tertiary {
  background: transparent;
  color: var(--rose-text);
  padding-left: .625rem;
  padding-right: .625rem;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.btn--tertiary:active { background: var(--sunken); }
.btn--danger { background: transparent; color: var(--danger); box-shadow: inset 0 0 0 2px var(--danger); }
.btn--danger:active { background: var(--sunken); }
.btn--danger-solid { background: var(--danger); color: var(--on-danger); }
.btn--apple { background: var(--apple-bg); color: var(--apple-fg); }
.btn--lg { min-height: var(--tap-lg); font-size: 1.125rem; }
.btn--xl { min-height: var(--tap-xl); font-size: 1.1875rem; padding-left: min(1.5rem, 26px); padding-right: min(1.5rem, 26px); border-radius: 2rem; }
.btn--block { display: flex; width: 100%; }
/* Busy: a small seed pod beside the label; the label stays. */
.btn[aria-busy="true"]::before {
  content: "";
  flex: none;
  width: .75em;
  height: 1em;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: currentColor;
  opacity: .55;
}
/* Truly disabled (rare): never a faded pink, just quiet. */
.btn:disabled, .btn[aria-disabled="true"] { background: var(--sunken); color: var(--muted); box-shadow: none; cursor: default; }
.icon-btn {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
}
.icon-btn:active, .icon-btn[aria-expanded="true"] { background: var(--sunken); }
.speak-btn {
  -webkit-appearance: none; appearance: none;
  position: relative;
  display: none; align-items: center; justify-content: center; flex: none;
  width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: var(--r-pill);
  background: var(--sunken); color: var(--ink); cursor: pointer;
}
.speak-btn[aria-pressed="true"] { background: var(--rose-soft); color: var(--rose-text); }
/* Its words name the button, visually hidden until a layout shows them. */
.speak-btn__label { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
/* .speak-btn--row: its own full-width row with its words, under the question (ux-16). A
   screen's large-text layout can give the button the same look with these rules. */
html.can-speak.speak-on .speak-btn.speak-btn--row { display: flex; }
.speak-btn--row { width: 100%; height: auto; min-height: var(--tap); gap: .5rem; padding: .375rem min(1.25rem, 21px); border-radius: 1.75rem; font-family: var(--font-ui); font-weight: 700; font-size: 1.0625rem; line-height: 1.25; text-align: center; }
.speak-btn--row .speak-btn__label { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; clip-path: none; white-space: normal; }
.actions { display: flex; flex-direction: column; gap: .625rem; }

/* ----------------------------------------------------------------- chips */
.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chips.center { justify-content: center; }
.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 2rem;
  padding: .125rem .75rem;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--sunken);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: .875rem;
  line-height: 1.2;
  text-decoration: none;
  max-width: 100%;
}
.chip--rose { background: var(--rose-soft); color: var(--rose-text); }
.chip--leaf { background: var(--leaf-soft); color: var(--leaf-text); }
.chip--honey { background: var(--honey-soft); color: var(--honey-text); }
.chip--peri { background: var(--peri-soft); color: var(--peri-text); }
.chip--kind { background: var(--kind-soft); color: var(--kind-text); }
/* A chip you can tap keeps a 3rem tall hit area. */
a.chip, button.chip { cursor: pointer; -webkit-appearance: none; appearance: none; }
a.chip::after, button.chip::after { content: ""; position: absolute; left: 0; right: 0; top: -.5rem; bottom: -.5rem; }
button.chip[aria-pressed="true"], a.chip[aria-current] { background: var(--rose-soft); color: var(--rose-text); box-shadow: inset 0 0 0 2px var(--rose); }

/* ---------------------------------------------------------------- inputs */
.field { display: flex; flex-direction: column; gap: .375rem; font-family: var(--font-ui); font-weight: 700; font-size: .9375rem; }
.field__note { font-weight: 500; font-size: .875rem; color: var(--muted); }
.input,
textarea,
select,
input:not([type]),
input[type=text], input[type=email], input[type=search], input[type=tel],
input[type=url], input[type=number], input[type=password] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: .625rem .875rem;
  border: 2px solid transparent;
  border-radius: var(--r-tile);
  background: var(--sunken);
  /* A drawn line along the foot, so an empty field still reads as "write here" on the paper
     (its fill alone is 1.1:1 against it). */
  box-shadow: inset 0 -2px 0 var(--field-line);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: max(16px, 1.125rem);   /* never under 16px: iOS zooms into a smaller field on focus */
  line-height: 1.4;
}
.input:focus, textarea:focus, select:focus, input:not([type]):focus,
input[type=text]:focus, input[type=email]:focus, input[type=search]:focus, input[type=tel]:focus,
input[type=url]:focus, input[type=number]:focus, input[type=password]:focus {
  border-color: var(--rose);
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}
::placeholder { color: var(--muted); opacity: 1; }
textarea { min-height: 6rem; resize: vertical; }
/* A box that grows with what's written (app.js lbGrow does it where this isn't supported). */
@supports (field-sizing: content) {
  textarea[data-grow] { field-sizing: content; max-height: 60vh; }
}
.textarea--ruled {
  line-height: 1.5em;
  padding-top: .5rem;
  background-image: repeating-linear-gradient(to bottom, transparent 0, transparent calc(1.5em - 1px), var(--hairline) calc(1.5em - 1px), var(--hairline) 1.5em);
  background-position: 0 .5rem;
  background-attachment: local;
}
.code-input { font-family: var(--font-story); font-weight: 700; font-size: 1.75rem; letter-spacing: .35em; text-align: center; font-variant-numeric: lining-nums tabular-nums; }

/* A checkbox row: the box draws a petal checkmark. Markup on /dev/components. */
.check-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: .875rem;
  min-height: 3.5rem;
  padding: .5rem .875rem;
  border-radius: var(--r-tile);
  background: var(--sunken);
  font-weight: 700;
  cursor: pointer;
}
.check-row--lg { min-height: 4rem; }
.check-row > input { position: absolute; opacity: 0; width: 1.75rem; height: 1.75rem; margin: 0; left: .875rem; top: 50%; transform: translateY(-50%); cursor: pointer; }
.check-row__box {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 8px;
  border: 2px solid var(--muted);
  background: var(--card);
  color: var(--on-rose);
}
.check-row__box svg { width: 1.25rem; height: 1.25rem; overflow: visible; }
.check-row__box path { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
.check-row > input:checked + .check-row__box { background: var(--rose); border-color: var(--rose); }
.check-row > input:checked + .check-row__box path { stroke-dashoffset: 0; }
.check-row > input:focus-visible + .check-row__box { outline: 3px solid var(--ink); outline-offset: 2px; }
.check-row__text { flex: 1 1 auto; min-width: 0; }

/* A switch: gold when on, with a tiny pressed flower on the thumb. */
.switch-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem 1rem; min-height: 3.5rem; cursor: pointer; }
/* The words shrink before the switch wraps: it drops under them only at the top of the text range. */
.switch-row > :not(.switch) { flex: 1 1 10rem; min-width: 0; }
.switch-row > .switch { margin-left: auto; }
.switch {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  flex: none;
  width: 3.25rem;
  height: 2rem;
  margin: 0;
  border-radius: var(--r-pill);
  background: var(--hairline);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .12);
  cursor: pointer;
}
.switch::before {
  content: "";
  position: absolute;
  top: .1875rem;
  left: .1875rem;
  width: 1.625rem;
  height: 1.625rem;
  border-radius: 50%;
  background: #FFFDF9;
  box-shadow: 0 1px 3px rgba(59, 31, 51, .25);
}
.switch::after {
  content: "";
  position: absolute;
  top: .5625rem;
  left: .5625rem;
  width: .875rem;
  height: .875rem;
  background: var(--gold-b);
  opacity: 0;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(72 12 12)'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(144 12 12)'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(216 12 12)'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(288 12 12)'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='black'%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(72 12 12)'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(144 12 12)'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(216 12 12)'/%3E%3Cellipse cx='12' cy='6.5' rx='3.6' ry='5' transform='rotate(288 12 12)'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}
.switch:checked { background: linear-gradient(90deg, var(--gold-a), var(--gold-b)); }
.switch:checked::before, .switch:checked::after { transform: translateX(1.25rem); }
.switch:checked::after { opacity: 1; }

/* Segmented control (the Aa sheet): native radios styled as 3rem segments. */
.segmented { border: 0; margin: 0; padding: .25rem; min-width: 0; display: grid; gap: .25rem; background: var(--sunken); border-radius: var(--r-tile);
  /* side by side while the words fit; stacked at large text */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 5.5rem), 1fr)); }
/* Three choices: all three in a row while 17rem fits, else all stacked, never two and one
   (the 999 makes the second term jump from 0 to the full width at that line). */
.segmented--3 { grid-template-columns: repeat(auto-fit, minmax(max((100% - .5rem) / 3, min(100%, (17rem - 100%) * 999)), 1fr)); }
.segmented > label { position: relative; display: flex; }
.segmented input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.segmented span {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: var(--tap); padding: .25rem .5rem;
  border-radius: 12px; font-weight: 700; line-height: 1.15; color: var(--ink);
}
.segmented input:checked + span { background: var(--card); box-shadow: var(--e1), inset 0 0 0 2px var(--rose); color: var(--rose-text); }
.segmented input:focus-visible + span { outline: 3px solid var(--ink); outline-offset: 2px; }

/* ----------------------------------------------------------------- tiles */
.tiles { display: grid; gap: .625rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); }
.tile {
  -webkit-appearance: none;
  appearance: none;
  position: relative;
  display: flex;
  align-items: center;
  gap: .75rem;
  width: 100%;
  min-height: 3.75rem;
  padding: .75rem 1rem;
  border: 2px solid transparent;
  border-radius: var(--r-tile);
  background: var(--sunken);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
}
.tile::before {
  content: "";
  flex: none;
  width: 1.375rem;
  height: 1.375rem;
  border: 2px solid var(--muted);
  border-radius: 50% 0 50% 50%;
  transform: rotate(-8deg) scale(.86);
}
.tile[aria-pressed="true"] { background: var(--rose-soft); border-color: var(--rose); }
.tile[aria-pressed="true"]::before { background: var(--rose); border-color: var(--rose); }

/* Number tiles: a radio group of ten, two rows of five, stacking to two
   columns when large text leaves no room for five. */
.numtiles { display: flex; flex-direction: column; gap: .625rem; container-type: inline-size; container-name: numtiles; }
.numtiles__ends { display: flex; justify-content: space-between; align-items: flex-end; gap: .75rem; font-size: .875rem; font-weight: 700; color: var(--muted); line-height: 1.3; }
.numtiles__ends > :last-child { text-align: right; }
.numtiles__grid { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr)); }
@container numtiles (min-width: 17rem) { .numtiles__grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@container numtiles (max-width: 16.99rem) {
  .numtiles__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .numtiles__ends { flex-direction: column; align-items: flex-start; gap: .125rem; }
  .numtiles__ends > :last-child { text-align: left; }
}
/* The same without container queries (iOS 15): html.nocq-18 from base.html's head script. */
html.nocq-18 .numtiles__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
html.nocq-18 .numtiles__ends { flex-direction: column; align-items: flex-start; gap: .125rem; }
html.nocq-18 .numtiles__ends > :last-child { text-align: left; }
.numtile {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 3.5rem;
  padding: .25rem;
  border: 2px solid transparent;
  border-radius: var(--r-tile);
  background: var(--sunken);
  color: var(--ink);
  font-family: var(--font-story);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
  cursor: pointer;
  touch-action: manipulation;
}
.numtile[aria-checked="true"] { background: var(--rose); color: var(--on-rose); border-color: var(--rose); }
.numtiles__value { display: flex; align-items: center; justify-content: center; gap: .5rem; min-height: 3.5rem; font-family: var(--font-story); font-weight: 700; font-size: 3rem; line-height: 1; color: var(--ink); font-variant-numeric: lining-nums tabular-nums; }
.numtiles__value .mark { width: 2.75rem; height: 2.75rem; color: var(--leaf-text); --mark-accent: var(--rose); --mark-accent-o: .55; }
.numtiles__value[data-empty] { display: none; }

/* ----------------------------------------------------- progress and steps */
.vine { position: relative; display: block; }
.vine__draw { position: relative; display: block; height: 1.5rem; }
.vine__svg { display: block; width: 100%; height: 100%; overflow: visible; }
.vine__track { fill: none; stroke: var(--hairline); stroke-width: 2; stroke-dasharray: 3 5; stroke-linecap: round; }
.vine__grow { fill: none; stroke: var(--leaf-text); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 1 1; }
.vine__leaf {
  position: absolute; top: 50%; width: .7rem; height: 1.05rem;
  margin: -1.05rem 0 0 -.1rem;
  border-radius: 50% 0 50% 50% / 50% 0 50% 50%;
  border: 2px solid var(--hairline); background: var(--card);
  transform: rotate(30deg); transform-origin: 0 100%;
}
.vine__leaf--on { background: var(--leaf-text); border-color: var(--leaf-text); }
.vine__label { margin-top: .375rem; font-size: .875rem; font-weight: 700; color: var(--muted); }
.seeds { display: inline-flex; align-items: center; gap: .625rem; font-size: .875rem; font-weight: 700; color: var(--muted); }
.seeds__row { display: inline-flex; gap: .375rem; }
.seed {
  display: inline-block;
  width: .875rem;
  height: .875rem;
  border: 2px solid var(--muted);
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
}
.seed--done { background: var(--leaf-text); border-color: var(--leaf-text); }
.seeds--lg .seed { width: 1.125rem; height: 1.125rem; }

/* -------------------------------------------------- notes and messages */
.hint { display: flex; align-items: flex-start; gap: min(.625rem, 11px); padding: .75rem min(1rem, 17px); border-radius: 14px; background: var(--leaf-soft); color: var(--ink); }
.hint > .mark:first-child { color: var(--leaf-text); margin-top: .0625rem; }
.hint-error { display: block; padding: .625rem .875rem; border-radius: 14px; background: var(--rose-soft); color: var(--rose-text); font-weight: 700; }
.needs-attention { outline: 2px solid var(--rose); outline-offset: 4px; border-radius: var(--r-tile); }
.notice { padding: .75rem 1rem; border-radius: 14px; background: var(--sunken); color: var(--ink); }
.toast {
  position: fixed;
  z-index: 60;
  left: 50%;
  top: calc(env(safe-area-inset-top) + var(--header-h) + 12px);
  width: max-content;
  max-width: min(22rem, calc(100% - 2rem));
  padding: .625rem 1.125rem .6875rem;
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--e2);
  border: var(--hair) solid var(--hairline);
  font-weight: 700;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%);
  transition: opacity 150ms linear, visibility 0s linear 150ms;
}
.toast::before { content: ""; position: absolute; left: 50%; bottom: 100%; width: 1px; height: 12px; background: var(--muted); opacity: .6; }
.toast::after { content: ""; position: absolute; left: calc(50% - 3px); top: 5px; width: 6px; height: 6px; border-radius: 50%; background: var(--paper); box-shadow: inset 0 0 0 1px var(--hairline); }
.toast.is-shown { opacity: 1; visibility: visible; transition: opacity 150ms linear; }
.toast:empty { display: none; }
.undo-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .25rem .75rem;
  min-height: var(--tap);
  padding: .25rem .375rem .25rem 1rem;
  border-radius: var(--r-tile);
  background: var(--sunken);
  color: var(--ink);
  font-weight: 700;
  transition: opacity 150ms linear;
}
.undo-bar.is-leaving { opacity: 0; }

/* ---------------------------------------------------------------- sheets */
.sheet { position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column; justify-content: flex-end; }
.sheet__scrim { position: absolute; inset: 0; background: var(--scrim); opacity: 0; transition: opacity 150ms linear; }
.sheet__panel {
  position: relative;
  width: 100%;
  max-width: 35rem;
  max-height: 90vh;
  max-height: 90dvh;
  margin: 0 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: .5rem max(1.25rem, env(safe-area-inset-right)) calc(1.25rem + env(safe-area-inset-bottom)) max(1.25rem, env(safe-area-inset-left));
  background: var(--card);
  border-radius: 28px 28px 0 0;
  box-shadow: var(--e2);
  opacity: 0;
  transition: opacity 150ms linear;
}
.sheet.is-open .sheet__scrim, .sheet.is-open .sheet__panel { opacity: 1; }
.sheet__grab { display: block; width: 2.5rem; height: 5px; margin: 0 auto .375rem; border-radius: var(--r-pill); background: var(--hairline); }
.sheet__head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; margin-bottom: .75rem; }
.sheet__title { padding-top: .5rem; font-family: var(--font-story); font-weight: 600; font-size: 1.35rem; line-height: 1.2; }
.sheet__close { margin: 0 -.5rem 0 0; }
/* At large text a long word in a title (a name, "something?") and the close button outgrow the
   panel (at a 35px root the button slid off the screen), so the button takes its own row at the
   top right, above the title; a name longer than a whole line still wraps. html.nocq-14-5
   stands in on iOS 15 (no container queries). */
.sheet__panel { container-type: inline-size; }
.sheet__title { min-width: 0; overflow-wrap: break-word; }
@container (max-width: 13.5rem) {
  .sheet__head { flex-wrap: wrap-reverse; justify-content: flex-end; row-gap: 0; }
  .sheet__title { padding-top: 0; }
}
html.nocq-14-5 .sheet__head { flex-wrap: wrap-reverse; justify-content: flex-end; row-gap: 0; }
html.nocq-14-5 .sheet__title { padding-top: 0; }
.sheet__body { display: flex; flex-direction: column; gap: .875rem; }
.sheet__text { font-size: 1.0625rem; }
.sheet__actions { display: flex; flex-direction: column; gap: .625rem; margin-top: .375rem; }
.sheet--tall .sheet__panel { min-height: min(34rem, 90vh); min-height: min(34rem, 90dvh); display: flex; flex-direction: column; }
.sheet--tall .sheet__body { flex: 1 1 auto; }
.sheet--tall .sheet__actions { margin-top: auto; padding-top: 1rem; }
html.sheet-open, html.sheet-open body { overflow: hidden; }

/* ------------------------------------------------------- a photo, big (lbZoom) */
[data-zoom] { cursor: zoom-in; }
.zoom {
  position: fixed; inset: 0; z-index: 55;
  background-color: var(--paper); background-image: var(--grain); background-size: 128px 128px;
  opacity: 0; transition: opacity 150ms linear;
}
.zoom.is-open { opacity: 1; }
/* The stage takes every touch (touch-action: none), so a pinch zooms the photo, not the page. */
.zoom__stage {
  position: absolute; inset: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  padding: calc(env(safe-area-inset-top) + var(--tap) + 1.25rem) max(var(--gutter), env(safe-area-inset-right)) calc(env(safe-area-inset-bottom) + 1rem) max(var(--gutter), env(safe-area-inset-left));
  touch-action: none; overscroll-behavior: contain;
}
.zoom__img {
  display: block; max-width: 100%; max-height: 100%; width: auto; height: auto;
  border-radius: var(--r-paper); box-shadow: var(--e2);
  transform-origin: 50% 50%; cursor: zoom-in;
  -webkit-user-select: none; user-select: none;
}
.zoom.is-zoomed .zoom__img { cursor: zoom-out; }
.zoom__bar {
  position: absolute; top: 0; left: 0; right: 0; display: flex; justify-content: flex-end;
  padding: calc(env(safe-area-inset-top) + .625rem) max(var(--gutter), env(safe-area-inset-right)) .625rem max(var(--gutter), env(safe-area-inset-left));
  pointer-events: none;
}
.zoom__done { pointer-events: auto; box-shadow: var(--e1); }
html.zoom-open, html.zoom-open body { overflow: hidden; }

/* ---------------------------------------------------------------- stamps */
.stamp { display: flex; align-items: center; gap: 1rem; text-align: left; color: var(--stamp-c, var(--ink)); }
.stamp__mark { flex: none; width: 4rem; height: 4rem; transform: rotate(-4deg); overflow: visible; }
.stamp__word { font-family: var(--font-story); font-weight: 700; font-size: 1.5rem; line-height: 1.1; }
.stamp__line { margin-top: .25rem; color: var(--ink); }
.stamp--nailed { --stamp-c: var(--leaf-text); }
.stamp--close { --stamp-c: var(--honey-text); }
.stamp--new, .stamp--missed { --stamp-c: var(--peri-text); }
.stamp--heard { --stamp-c: var(--rose-text); }

.reply-grid { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr)); }   /* 2 x 2, one column at large text */
.reply {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .375rem;
  min-height: 4.5rem;
  padding: .625rem .5rem;
  border: 2px dashed var(--hairline);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: .9375rem;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  touch-action: manipulation;
}
.reply .mark { width: 2rem; height: 2rem; color: var(--muted); }
.reply[aria-pressed="true"] { background: var(--kind-soft); border-style: solid; border-color: var(--kind); }
.reply[aria-pressed="true"] .mark { color: var(--kind-text); --mark-accent: var(--kind); --mark-accent-o: .6; }
.reply-badge { display: inline-flex; align-items: center; gap: .625rem; font-weight: 700; color: var(--kind-text); }
.reply-badge__stamp {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 2.75rem; height: 2.75rem; border-radius: 6px;
  background: var(--card); border: 2px dashed var(--hairline);
  color: var(--kind-text); --mark-accent: var(--kind); --mark-accent-o: .5;
}
.reply-badge__stamp .mark { width: 1.75rem; height: 1.75rem; }

/* ---------------------------------------------------- envelope and seal */
.envelope {
  position: relative;
  width: 100%;
  max-width: 21rem;
  aspect-ratio: 1.55;
  margin: 0 auto;
  border-radius: 12px;
  border: var(--hair) solid var(--hairline);
  box-shadow: var(--e2);
  background:
    linear-gradient(to top right, transparent calc(50% - 1px), var(--hairline) 50%, transparent calc(50% + 1px)) left bottom / 50.5% 62% no-repeat,
    linear-gradient(to top left, transparent calc(50% - 1px), var(--hairline) 50%, transparent calc(50% + 1px)) right bottom / 50.5% 62% no-repeat,
    var(--card);
}
.envelope__flap { position: absolute; left: 0; right: 0; top: 0; height: 60%; transform-origin: 50% 0; filter: drop-shadow(0 1.5px 0 var(--hairline)) drop-shadow(0 4px 6px rgba(59, 31, 51, .10)); }
.envelope__flap-in { width: 100%; height: 100%; border-radius: 11px 11px 0 0; background: var(--sunken); clip-path: polygon(0 0, 100% 0, 50% 100%); }
.envelope .seal { position: absolute; left: 50%; top: 60%; width: 3.5rem; height: 3.5rem; margin: -1.75rem 0 0 -1.75rem; }
.envelope__label { position: absolute; left: 50%; bottom: .875rem; transform: translateX(-50%); max-width: calc(100% - 2rem); width: max-content; padding: .25rem .875rem; border-radius: 8px; background: var(--card); box-shadow: 0 0 0 1px var(--hairline); text-align: center; font-family: var(--font-story); font-weight: 600; font-size: 1.125rem; line-height: 1.2; color: var(--ink); }
.seal { display: block; width: 3.5rem; height: 3.5rem; overflow: visible; filter: drop-shadow(0 2px 2px rgba(59, 31, 51, .25)); }
.seal--split { position: relative; }
.seal__whole, .seal__half { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
/* At rest the seal is whole; add .seal--broken to swap in the two halves for the break. */
.seal__half { opacity: 0; }
.seal--broken .seal__whole { opacity: 0; }
.seal--broken .seal__half { opacity: 1; }

/* The waiting state: a seed pod (the breathing lives in the motion block). */
.seedpod {
  display: inline-block;
  position: relative;
  width: 1.375rem;
  height: 1.875rem;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: linear-gradient(160deg, var(--leaf-b), var(--leaf-a));
  vertical-align: middle;
}
.seedpod::after { content: ""; position: absolute; left: 50%; top: 18%; bottom: 14%; width: 2px; margin-left: -1px; border-radius: 2px; background: var(--leaf-text); opacity: .45; }

/* ---------------------------------------------------------------- player */
.player { display: flex; flex-wrap: wrap; align-items: center; gap: .875rem; row-gap: .5rem; min-width: 0; }
/* The 48-bar wave needs about 9rem: at large text the button goes above it instead of the
   wave spilling out of its card. */
.player__btn {
  -webkit-appearance: none; appearance: none;
  position: relative; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap-xl); height: var(--tap-xl); padding: 0; border: 0; border-radius: 50%;
  background: var(--rose); color: var(--on-rose);
  box-shadow: var(--lip), 0 6px 16px -6px var(--rose-glow);
  cursor: pointer; touch-action: manipulation;
  --mark-accent: currentColor; --mark-accent-o: 1;
}
.player--md .player__btn { width: var(--tap); height: var(--tap); }
.player__btn .mark { width: 1.5rem; height: 1.5rem; }
.player--md .player__btn .mark { width: 1.25rem; height: 1.25rem; }
.player__pause { display: none; }
.player.is-playing .player__play { display: none; }
.player.is-playing .player__pause { display: inline-block; }
.player__main { flex: 1 1 8.875rem; min-width: 0; display: flex; flex-direction: column; gap: .25rem; }
.player__title { font-weight: 700; font-size: .9375rem; }
.player__track { position: relative; display: block; padding: .25rem 0; cursor: pointer; touch-action: none; border-radius: 8px; }
.player__wave { display: flex; align-items: center; gap: 2px; height: 2.25rem; }
.player--md .player__wave { height: 1.75rem; }
.player__bar { flex: 1 1 0; min-width: 1px; height: var(--h, 40%); min-height: 3px; border-radius: 2px; background: var(--muted); opacity: .38; }
.player__bar.is-played { background: var(--kind-text); opacity: 1; }
.player__bar-track { display: block; position: relative; height: .5rem; margin-top: .375rem; border-radius: var(--r-pill); background: var(--hairline); overflow: hidden; }
.player__bar-fill { position: absolute; inset: 0; border-radius: inherit; background: var(--kind-text); transform-origin: 0 50%; transform: scaleX(var(--p, 0)); }
.player__time { display: flex; justify-content: space-between; gap: .5rem; font-size: .875rem; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.player.is-error .player__btn { background: var(--sunken); color: var(--muted); box-shadow: none; }

/* --------------------------------------------------------- comfort rows */
.comfort { display: flex; flex-direction: column; gap: 1.125rem; }
.comfort__row { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
.comfort__label { font-weight: 700; font-size: 1.0625rem; }
.comfort__note { font-size: .875rem; color: var(--muted); }
.comfort__row--speak { display: none; }
html.can-speak .comfort__row--speak { display: flex; }
/* Guests: "Stuck? Ask Craig for help" and our address, under the comfort rows (f-12). */
.comfort-help { display: flex; flex-direction: column; gap: .625rem; padding-top: 1.125rem; border-top: var(--hair) solid var(--hairline); }
.comfort-help__ask { flex-wrap: wrap; }   /* at large text the mark sits above the words, not beside a squeezed column */
.comfort-help__ask .mark { color: var(--rose-text); --mark-accent: var(--honey); --mark-accent-o: 1; }

/* ----------------------------------------------------- prose and lists */
.prose { display: flex; flex-direction: column; gap: .875rem; }
.prose h2 { margin-top: .75rem; }
.prose ul { display: flex; flex-direction: column; gap: .5rem; }
.prose a { text-decoration: underline; }
.petal-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: .625rem; }
.petal-list > li { position: relative; padding-left: 1.75rem; }
.petal-list > li::before {
  content: "";
  position: absolute;
  left: .25rem;
  top: .4em;
  width: .8rem;
  height: .8rem;
  background: var(--kind);
  border-radius: 50% 0 50% 50%;
  transform: rotate(-45deg);
}

/* -------------------------------------------------- pages owned here */
.intro { display: flex; flex-direction: column; align-items: center; gap: .625rem; text-align: center; padding-top: .5rem; }
.intro__art { width: 5.5rem; height: 5.5rem; color: var(--rose); --mark-accent: var(--honey); --mark-accent-o: 1; }
.intro__flower { display: block; width: 5.5rem; height: 5.5rem; }
.intro .lead { max-width: 26rem; }
.email { overflow-wrap: anywhere; }   /* min-content shrinks too, so the centred column can wrap it */
.error-page { padding-top: 2rem; gap: .875rem; }
.error-page .btn { margin-top: .5rem; }
.intro__art--leaf { color: var(--leaf-text); --mark-accent: var(--leaf); --mark-accent-o: .35; }
.divider-or { display: flex; align-items: center; gap: .75rem; color: var(--muted); font-weight: 700; font-size: .875rem; }
.divider-or::before, .divider-or::after { content: ""; flex: 1 1 auto; border-top: var(--hair) solid var(--hairline); }
.settings-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .5rem 1rem; }
.danger-zone { border-color: var(--hairline); }
.danger-zone h2 { color: var(--danger); }
/* "Save your books first?" before Delete everything (ux-5): one row per closing flower. */
.delete-books { padding: .875rem min(1rem, 17px); border-radius: 14px; background: var(--sunken); }
.delete-books__list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: .125rem; }
.delete-books__list a {
  display: flex; align-items: center; gap: .5rem; min-height: var(--tap); padding: .25rem 0;
  color: var(--rose-text); font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px;
}
.delete-books__list .mark { color: var(--rose-text); }

/* ------------------------------------------- the reports queue (_admin.py, f-12) */
.admin-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: .75rem; }
.admin-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .625rem 1rem; }
.admin-row__text { flex: 1 1 8rem; min-width: 0; display: flex; flex-direction: column; gap: .125rem; }
.admin-row__what { font-weight: 700; font-size: 1.0625rem; }
.admin-row__what .chip { vertical-align: .0625rem; }
.admin-row__go { flex: none; }
.admin-empty { align-items: center; padding-block: 1.75rem; }
.admin-empty .mark { color: var(--rose-text); --mark-accent: var(--honey); --mark-accent-o: 1; }
.admin-item__q { font-family: var(--font-story); font-weight: 600; font-size: 1.25rem; line-height: 1.25; text-wrap: balance; }
.admin-item__photo { display: block; width: 100%; max-width: 24rem; border-radius: var(--r-paper); box-shadow: var(--e1); }
.admin-actions { margin-top: .25rem; }

/* ------------------------------------------------------------ root states */
html.lb-paused *, html.lb-paused *::before, html.lb-paused *::after { animation-play-state: paused !important; }
html.can-speak.speak-on [data-speak] { display: inline-flex; }
[data-speak]:not(.speak-btn) { display: none; }
html.in-app [data-print], html.in-app [data-hide-in-app] { display: none !important; }

/* --------------------------------------------------------------- motion
   Every movement lives here, so prefers-reduced-motion and the Calmer screen
   (html.calm) keep the same words and states with 150 ms fades and no motion. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 200ms; }
  html:not(.calm) .qcard { view-transition-name: qcard; }

  html:not(.calm) .btn,
  html:not(.calm) .icon-btn,
  html:not(.calm) .tile,
  html:not(.calm) .numtile,
  html:not(.calm) .reply,
  html:not(.calm) .chip,
  html:not(.calm) .player__btn {
    transition: transform var(--t-press) var(--ease-out), background-color var(--t-quick) var(--ease-out),
      box-shadow var(--t-quick) var(--ease-out), border-color var(--t-quick) var(--ease-out), color var(--t-quick) var(--ease-out);
  }
  html:not(.calm) .btn:active, html:not(.calm) .tile:active, html:not(.calm) .numtile:active,
  html:not(.calm) .reply:active, html:not(.calm) .player__btn:active { transform: scale(.975); }
  html:not(.calm) .btn--primary:active { transform: translateY(1px) scale(.985); }

  html:not(.calm) .tile[aria-pressed="true"]::before { animation: lb-marker-pop 180ms var(--ease-pop); }
  html:not(.calm) .numtile[aria-checked="true"] { animation: lb-tile-pop 220ms var(--ease-pop); }
  html:not(.calm) .reply[aria-pressed="true"] .mark { animation: lb-reply-stamp 280ms var(--ease-stamp) both; }

  html:not(.calm) .check-row__box path { transition: stroke-dashoffset 220ms var(--ease-out); }
  html:not(.calm) .check-row__box { transition: background-color var(--t-quick) var(--ease-out), border-color var(--t-quick) var(--ease-out); }
  html:not(.calm) .switch { transition: background var(--t-quick) var(--ease-out); }
  html:not(.calm) .switch::before, html:not(.calm) .switch::after { transition: transform 220ms var(--ease-pop), opacity var(--t-quick) linear; }
  html:not(.calm) .segmented span { transition: background-color var(--t-quick) var(--ease-out), box-shadow var(--t-quick) var(--ease-out); }

  html:not(.calm) .sheet__scrim { transition: opacity var(--t-quick) linear; }
  html:not(.calm) .sheet__panel { opacity: 1; transform: translateY(100%); transition: transform 240ms var(--ease-in); }
  html:not(.calm) .sheet.is-open .sheet__panel { transform: none; transition: transform 360ms var(--ease-out); }

  html:not(.calm) .zoom { transition: opacity var(--t-quick) linear; }
  html:not(.calm) .zoom.is-open .zoom__stage { animation: lb-zoom-in 260ms var(--ease-out); }
  html:not(.calm) .zoom__img.is-easing { transition: transform 260ms var(--ease-out); }

  html:not(.calm) .toast { transform: translate(-50%, -12px); transition: opacity 200ms var(--ease-in), transform 200ms var(--ease-in), visibility 0s linear 200ms; }
  html:not(.calm) .toast.is-shown { transform: translate(-50%, 0); transition: opacity 240ms var(--ease-out), transform 240ms var(--ease-out); }
  html:not(.calm) .undo-bar { animation: lb-fade-in 200ms var(--ease-out); }

  html:not(.calm) .needs-attention { animation: lb-attention 900ms var(--ease-out) 1; }
  html:not(.calm) .seedpod,
  html:not(.calm) .btn[aria-busy="true"]::before { animation: lb-breathe 1200ms var(--ease-move) infinite; }
  html:not(.calm) .player__bar { transition: background-color var(--t-quick) linear; }
}
html.calm::view-transition-group(*) { animation: none; }

@keyframes lb-marker-pop { from { transform: rotate(-8deg) scale(.4); } to { transform: rotate(-8deg) scale(.86); } }
@keyframes lb-tile-pop { 0% { transform: scale(.9); } 60% { transform: scale(1.06); } 100% { transform: scale(1); } }
@keyframes lb-reply-stamp { from { transform: scale(1.2) rotate(0deg); } to { transform: scale(1) rotate(-4deg); } }
@keyframes lb-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes lb-attention { 0% { outline-color: transparent; outline-offset: 10px; } 40% { outline-color: var(--rose); outline-offset: 4px; } 100% { outline-offset: 4px; } }
@keyframes lb-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.03); } }
@keyframes lb-zoom-in { from { transform: scale(.96); } to { transform: none; } }

/* ----------------------------------------------------------------- print
   White page, plum-black ink, no shadows or grain. Flowers stay. */
@media print {
  /* Every colour dark mode changes goes back to its light value, so a page printed from a
     phone in dark mode is dark ink on white paper. */
  :root {
    color-scheme: light;
    --paper: #FFFFFF; --paper-92: rgba(255, 255, 255, .92); --paper-70: rgba(255, 255, 255, .70);
    --card: #FFFFFF; --sunken: #F6F0EA; --hairline: #DCCBBE; --scrim: transparent;
    --ink: #2E2125; --muted: #5E4656; --rose: #A82457; --on-rose: #FFFFFF; --rose-pressed: #A82457;
    --rose-text: #A82457; --rose-soft: #F8E1E8;
    --leaf: #6FB37A; --leaf-text: #276B45; --leaf-soft: #E3F3E9;
    --honey: #F2B33D; --honey-text: #8F5A0B; --honey-soft: #FCEFD2;
    --peri: #8FA2F2; --peri-text: #4152B0; --peri-soft: #E6EAFD;
    --danger: #B4361A; --on-danger: #FFFFFF;
    --stake: #E6CFAE; --soil: #8A5A44; --soil-rim: #A87458; --stem: #5E9F64; --leaf-a: #7DBB78; --leaf-b: #B5DB9C;
    --line-art: rgba(74, 35, 56, .60);
    --e1: none; --e2: none; --grain: none; --lip: 0 0 0 transparent; --rose-glow: transparent;
  }
  body { background: #FFFFFF; color: #2E2125; }
  .top, .toast, .sheet, .zoom, .undo-bar, .skip-link, #lb-live, [data-print], [data-speak], .no-print { display: none !important; }
  .wrap { max-width: none; padding: 0; }
  .card, .paper, .qcard, .slip { box-shadow: none; break-inside: avoid; }
  a { color: inherit; text-decoration: none; }
}

/* --------------------------------------------------- high contrast extras */
@media (prefers-contrast: more) {
  a { text-decoration: underline; }
  .btn--primary, .player__btn { box-shadow: none; }
  .card, .qcard, .paper, .tile, .numtile, .reply, .check-row { border-width: 2px; }
  .tile, .numtile, .check-row, .segmented, .input, textarea, select, input:not([type]), input[type=text],
  input[type=email], input[type=search], input[type=tel], input[type=url], input[type=number],
  input[type=password] { box-shadow: inset 0 0 0 2px var(--hairline); }
}
@media (forced-colors: active) {
  .tile[aria-pressed="true"], .numtile[aria-checked="true"], .reply[aria-pressed="true"] { outline: 3px solid Highlight; }
  .switch { border: 1px solid ButtonText; }
}
