/* ======================================================================
   LETSREAD · app.css
   Extends the fluid system in base.css: one --u unit, clamp() type,
   wrapping clusters and self-collapsing grids. No media queries.
   ====================================================================== */

@font-face {
  font-family: "Fraunces";
  src: url("/assets/fonts/fraunces-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("/assets/fonts/fraunces-latin-wght-italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("/assets/fonts/plus-jakarta-sans-latin-wght-normal.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Mono";
  src: url("/assets/fonts/space-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Mono";
  src: url("/assets/fonts/space-mono-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ----------------------------------------------------------------------
   Tokens
   ---------------------------------------------------------------------- */

:root {
  --font-display: "Fraunces", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --font-body: "Plus Jakarta Sans", "Segoe UI", system-ui, sans-serif;
  --font-caps: "Space Mono", "Courier New", monospace;

  --content: 84rem;
  --page-gutter: clamp(1rem, 0.55rem + 2vw, 2.75rem);
  --fs-5: clamp(2.75rem, 1.7rem + 4.6vw, 5.4rem);
  --fs-6: clamp(3.4rem, 2rem + 6vw, 7.5rem);

  --r-xs: 8px;
  --r-sm: 10px;
  --r-md: clamp(0.9rem, 0.75rem + 0.55vw, 1.15rem);
  --r-lg: clamp(1.15rem, 0.95rem + 0.8vw, 1.6rem);
  --r-xl: clamp(1.6rem, 1.2rem + 1.5vw, 2.4rem);

  --surface: color-mix(in oklab, var(--paper), var(--ink) 3.2%);
  --surface-raised: color-mix(in oklab, var(--paper), var(--ink) 1.4%);
  --surface-sunk: color-mix(in oklab, var(--paper), var(--ink) 6.5%);
  --glass: color-mix(in oklab, var(--paper) 78%, transparent);
  --accent-text: color-mix(in oklch, var(--accent), var(--ink) 24%);
  --alt-text: color-mix(in oklch, var(--alt), var(--ink) 18%);

  --shadow-soft:
    0 1px 1px color-mix(in oklab, #000 4%, transparent),
    0 14px 34px color-mix(in oklab, #000 8%, transparent);
  --shadow-lift:
    0 2px 2px color-mix(in oklab, #000 5%, transparent),
    0 26px 60px color-mix(in oklab, #000 16%, transparent);
  --shadow-inset:
    inset 0 1px 0 color-mix(in oklab, var(--paper) 70%, transparent),
    inset 0 -1px 0 color-mix(in oklab, #000 8%, transparent);
  --shadow-button:
    0 1px 0 color-mix(in oklab, var(--paper) 28%, transparent) inset,
    0 10px 24px color-mix(in oklab, #000 20%, transparent);

  --focus-ring: 0 0 0 3px color-mix(in oklch, var(--accent) 26%, transparent);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

html[data-theme="light"] {
  --ink: oklch(0.19 0.014 62);
  --paper: oklch(0.978 0.007 82);
  --accent: oklch(0.69 0.16 47);
  --alt: oklch(0.48 0.105 258);
}

html[data-theme="dark"] {
  --ink: oklch(0.955 0.008 82);
  --paper: oklch(0.155 0.011 62);
  --accent: oklch(0.77 0.14 50);
  --alt: oklch(0.68 0.09 255);
}

html[data-theme="custom"][data-base="light"] {
  --ink: oklch(0.19 0.014 62);
  --paper: oklch(0.978 0.007 82);
}
html[data-theme="custom"][data-base="dark"] {
  --ink: oklch(0.955 0.008 82);
  --paper: oklch(0.155 0.011 62);
}

/* ----------------------------------------------------------------------
   Base overrides
   ---------------------------------------------------------------------- */

html {
  scrollbar-color: color-mix(in oklch, var(--ink), var(--paper) 60%) transparent;
}

body {
  min-height: 100svh;
  background-color: var(--paper);
  background-image:
    radial-gradient(120% 80% at 6% -12%, color-mix(in oklab, var(--accent) 8%, transparent), transparent 60%),
    radial-gradient(90% 70% at 104% -4%, color-mix(in oklab, var(--alt) 8%, transparent), transparent 58%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.13;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

#app,
.noscript {
  position: relative;
  z-index: 1;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.04;
  text-wrap: balance;
}
h1 { font-size: var(--fs-5); }
h2 { font-size: var(--fs-3); }
h3 { font-size: var(--fs-2); }
p { line-height: 1.7; text-wrap: pretty; }

a {
  color: var(--alt-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
a:hover { color: var(--accent-text); }

button, input, textarea, select { font: inherit; }
button { color: inherit; }
img { max-width: 100%; }
hr { border: 0; border-block-start: 1px solid var(--line); }
::selection { background: var(--accent-soft); color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.icon { display: block; flex: none; }
.spin { animation: spin 0.9s linear infinite; }
[hidden] { display: none !important; }
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}
.noscript {
  max-width: 34rem;
  margin: 12vh auto;
  padding: var(--sp-md);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}

/* ----------------------------------------------------------------------
   Small primitives
   ---------------------------------------------------------------------- */

.wrap {
  width: min(100% - 2 * var(--page-gutter), var(--content));
  margin-inline: auto;
}
.page { padding-block: var(--sp-md) var(--sp-xl); }
.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-sm); }
.cluster--tight { gap: var(--sp-xs); }
.cluster--between { justify-content: space-between; }
.stack { display: grid; gap: var(--sp-sm); }
.stack--md { gap: var(--sp-md); }
.stack--lg { gap: var(--sp-lg); }
.stack--xl { gap: var(--sp-xl); }
.autogrid { display: grid; gap: var(--sp-md); grid-template-columns: repeat(auto-fit, minmax(min(var(--min, 16rem), 100%), 1fr)); }
.muted { color: var(--text-muted); }
.accent { color: var(--accent-text); }
.alt { color: var(--alt-text); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.fluid-italic { font-style: italic; }
.mono {
  font-family: var(--font-caps);
  font-size: var(--fs-0);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.rule { height: 1px; background: var(--line); border: 0; }
.hairline { border-block-end: 1px solid var(--line); }

/* ----------------------------------------------------------------------
   Brand
   ---------------------------------------------------------------------- */

.brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--ink);
  line-height: 1;
  flex: none;
}
.brand-glyph {
  display: block;
  flex: none;
  border-radius: 32%;
  box-shadow: 0 7px 18px color-mix(in oklab, var(--accent) 22%, transparent);
  transition: transform 0.35s var(--ease-spring);
}
.brand-lockup:hover .brand-glyph { transform: rotate(-5deg) scale(1.04); }
.brand-words { display: flex; flex-direction: column; gap: 0.24rem; }
.brand-name {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.1rem + 0.5vw, 1.6rem);
  font-weight: 600;
  letter-spacing: -0.045em;
  color: var(--ink);
}
.brand-dot { color: var(--accent-text); }
.brand-tag {
  font-family: var(--font-caps);
  font-size: clamp(0.46rem, 0.4rem + 0.15vw, 0.56rem);
  font-weight: 700;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ----------------------------------------------------------------------
   Buttons
   ---------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.48rem;
  min-height: 2.85rem;
  padding: 0.62rem 1.15rem;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  font-size: var(--fs-sm);
  font-weight: 650;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 0.22s ease,
    border-color 0.22s ease,
    color 0.22s ease,
    transform 0.22s var(--ease-out),
    box-shadow 0.22s ease;
}
.btn:active { transform: translateY(1px) scale(0.995); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.btn .icon { width: 1.05rem; height: 1.05rem; }

.btn-accent {
  background: var(--accent-strong);
  color: var(--paper);
  box-shadow: var(--shadow-button);
}
.btn-accent:hover { background: var(--accent); color: var(--paper); transform: translateY(-2px); }

.btn-ink { background: var(--ink); color: var(--paper); box-shadow: var(--shadow-button); }
.btn-ink:hover { background: var(--accent-strong); color: var(--paper); transform: translateY(-2px); }

.btn-quiet {
  background: color-mix(in oklab, var(--paper), var(--ink) 2%);
  border-color: var(--line-strong);
  color: var(--ink);
}
.btn-quiet:hover { background: var(--surface-sunk); border-color: var(--ink); transform: translateY(-1px); }

.btn-danger { background: var(--ink); color: var(--paper); }
.btn-danger:hover { background: var(--accent-strong); color: var(--paper); }

.btn-link {
  min-height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  cursor: pointer;
  color: var(--alt-text);
  font-size: var(--fs-sm);
  font-weight: 650;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}
.btn-link:hover { color: var(--accent-text); }

.btn-sm { min-height: 2.25rem; padding: 0.42rem 0.85rem; font-size: var(--fs-0); }
.btn-lg { min-height: 3.25rem; padding: 0.85rem 1.5rem; font-size: var(--fs-base); }
.btn-block { width: 100%; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  flex: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: color-mix(in oklab, var(--paper), var(--ink) 2%);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s var(--ease-out), border-color 0.2s ease;
}
.icon-btn:hover { background: var(--surface-sunk); border-color: var(--line-strong); transform: translateY(-1px); }
.icon-btn--small { width: 2.25rem; height: 2.25rem; }
.icon-btn--bare { border-color: transparent; background: transparent; }
.icon-btn--bare:hover { background: var(--surface-sunk); }
.icon-btn--accent { background: var(--accent-soft); color: var(--accent-text); border-color: transparent; }

.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.28rem 0.75rem 0.28rem 0.3rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: color-mix(in oklab, var(--paper), var(--ink) 2%);
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.user-chip:hover { border-color: var(--line-strong); background: var(--surface-sunk); color: var(--ink); }
.user-chip .avatar { width: 2rem; height: 2rem; font-size: 0.68rem; margin: 0; }
.user-chip-name { font-size: var(--fs-0); font-weight: 650; white-space: nowrap; }

.avatar {
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  display: inline-grid;
  place-items: center;
  overflow: hidden;
  flex: none;
  background: linear-gradient(145deg, var(--alt-soft), var(--accent-soft));
  color: var(--ink);
  font-family: var(--font-caps);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid color-mix(in oklab, var(--ink) 10%, transparent);
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }

.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.27rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--text-muted);
  font-family: var(--font-caps);
  font-size: clamp(0.58rem, 0.54rem + 0.1vw, 0.66rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.tag--accent { background: var(--accent-soft); color: var(--accent-text); border-color: transparent; }
.tag--alt { background: var(--alt-soft); color: var(--alt-text); border-color: transparent; }
.tag .icon { width: 0.85rem; height: 0.85rem; }

/* ----------------------------------------------------------------------
   Forms
   ---------------------------------------------------------------------- */

.field { display: grid; gap: 0.4rem; }
.field-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.field label { font-size: var(--fs-0); font-weight: 650; color: var(--ink); letter-spacing: 0.01em; }
.field-hint { font-size: var(--fs-0); color: var(--text-muted); }
.field input,
.field textarea,
.field select {
  width: 100%;
  min-height: 2.9rem;
  padding: 0.65rem 0.85rem;
  color: var(--ink);
  background: color-mix(in oklab, var(--paper), var(--ink) 2.2%);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  transition: border-color 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease;
}
.field select { appearance: none; padding-inline-end: 2.4rem; cursor: pointer; }
.field textarea { resize: vertical; min-height: 7rem; line-height: 1.6; }
.field input::placeholder,
.field textarea::placeholder { color: color-mix(in oklch, var(--text-muted), transparent 24%); }
.field :is(input, textarea, select):focus {
  outline: none;
  border-color: var(--accent);
  background: var(--paper);
  box-shadow: var(--focus-ring);
}
.field input[readonly] { color: var(--text-muted); background: var(--surface-sunk); }
.field.has-error input,
.field.has-error textarea,
.field.has-error select { border-color: var(--accent); }
.field-error { color: var(--accent-text); font-size: var(--fs-0); }
.field-row { display: grid; gap: var(--sp-sm); grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr)); }

.page-stepper {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: stretch;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: color-mix(in oklab, var(--paper), var(--ink) 2.2%);
  transition: border-color 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease;
}
.page-stepper:focus-within {
  border-color: var(--accent);
  background: var(--paper);
  box-shadow: var(--focus-ring);
}
.page-stepper-btn {
  display: grid;
  place-items: center;
  width: clamp(2.7rem, 2.25rem + 1.2vw, 3.2rem);
  padding: 0;
  border: 0;
  background: color-mix(in oklab, var(--paper), var(--ink) 3.5%);
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease;
}
.page-stepper-btn:hover { background: var(--surface-sunk); color: var(--ink); }
.page-stepper-btn:active { background: color-mix(in oklab, var(--paper), var(--ink) 7%); }
.page-stepper-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.page-stepper-btn .icon { width: 1rem; height: 1rem; }
.page-stepper input {
  width: 100%;
  min-width: 0;
  min-height: 2.9rem;
  padding: 0.4rem;
  border: 0;
  border-inline: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-caps);
  font-size: var(--fs-base);
  font-weight: 700;
  text-align: center;
  appearance: textfield;
}
.page-stepper input:focus { outline: none; border-color: var(--line); background: transparent; box-shadow: none; }
.page-stepper input::-webkit-outer-spin-button,
.page-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* The cover drop zone is drawn as a book before it holds one: the same 3:4 as a shelf card, so the
   picture a parent picks lands at roughly the size it will be seen at and nothing jumps when it loads.
   The dashed edge says "put something here"; a solid one would read as a frame that is already full. */
.cover-field { container-type: inline-size; }
.cover-pick {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--sp-sm);
  padding: clamp(0.9rem, 0.75rem + 0.8vw, 1.4rem);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface-sunk);
  transition: border-color 0.18s ease, background-color 0.18s ease;
}
.cover-pick.is-over {
  border-style: solid;
  border-color: var(--accent);
  background: var(--accent-wash);
}
.cover-pick-image {
  width: min(10.5rem, 100%);
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--paper);
  box-shadow: var(--shadow-soft);
}
.cover-pick-empty {
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  max-width: 30ch;
  padding-block: 0.6rem;
  text-align: center;
  color: var(--text-muted);
  font-size: var(--fs-0);
  line-height: 1.55;
}
.cover-pick-empty .icon { color: var(--accent-text); }
.cover-pick-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem; }
.cover-pick-actions .icon { width: 0.95rem; height: 0.95rem; }
.cover-pick-busy {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: inherit;
  background: color-mix(in oklab, var(--paper) 72%, transparent);
  backdrop-filter: blur(3px);
  color: var(--ink);
  font-size: var(--fs-0);
}

@container (max-width: 26rem) {
  .cover-pick-image { width: min(8.5rem, 60%); }
}

/* A link that sits under a stepper, not beside a heading: it has to read as a way out of the limit
   above it, which means no button chrome and no weight of its own. */
.plan-inline-link {
  margin-block-start: 0.4rem;
  padding-inline: 0;
  color: var(--accent-text);
  font-size: var(--fs-0);
}
.plan-inline-link .icon { width: 0.85rem; height: 0.85rem; }

.input-shell { position: relative; }
.input-shell .input-icon {
  position: absolute;
  inset-inline-start: 0.8rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}
.input-shell input { padding-inline-start: 2.45rem; }
.input-shell--password input { padding-inline-end: 2.85rem; }
.reveal-button {
  position: absolute;
  inset-inline-end: 0.32rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2.2rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.reveal-button:hover { background: var(--surface-sunk); color: var(--ink); }

.form-alert {
  display: flex;
  gap: 0.55rem;
  align-items: flex-start;
  padding: 0.7rem 0.85rem;
  margin-block-end: var(--sp-sm);
  border: 1px solid color-mix(in oklch, var(--accent) 38%, transparent);
  border-radius: var(--r-sm);
  background: var(--accent-wash);
  color: var(--ink);
  font-size: var(--fs-sm);
}
.form-alert .icon { color: var(--accent-text); margin-top: 0.15rem; }
.form-note { font-size: var(--fs-0); color: var(--text-muted); line-height: 1.55; }

.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  padding: 0.25rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-sunk);
}
.segmented button,
.segmented a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.42rem 0.85rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-0);
  font-weight: 650;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.18s ease, color 0.18s ease;
}
.segmented .is-active { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-soft); }
.segmented .icon { width: 0.95rem; height: 0.95rem; }

/* ----------------------------------------------------------------------
   App header / footer / workspace nav
   ---------------------------------------------------------------------- */

.app-screen { min-height: 100svh; display: flex; flex-direction: column; }
.app-main { flex: 1; }

.app-header {
  position: sticky;
  top: 0;
  z-index: 60;
  border-block-end: 1px solid var(--line);
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(1.2);
  -webkit-backdrop-filter: blur(18px) saturate(1.2);
}
.app-header-inner {
  container-type: inline-size;
  max-width: var(--content);
  margin-inline: auto;
  padding: 0.7rem var(--page-gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1rem;
}
.header-actions { display: flex; align-items: center; gap: 0.45rem; margin-inline-start: auto; }
.header-sep { width: 1px; height: 1.6rem; background: var(--line); margin-inline: 0.2rem; }

@container (max-width: 40rem) {
  .user-chip-name { display: none; }
  .user-chip { padding-inline-end: 0.3rem; }
}

.workspace-nav-wrap { padding-block: var(--sp-md) 0; }
.workspace-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  padding: 0.28rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in oklab, var(--paper), var(--ink) 2%);
  width: fit-content;
  max-width: 100%;
  box-shadow: var(--shadow-soft);
}
.workspace-nav a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.5rem 0.9rem;
  border-radius: 999px;
  color: var(--text-muted);
  font-size: var(--fs-0);
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.18s ease, color 0.18s ease;
}
.workspace-nav a:hover { color: var(--ink); background: var(--surface-sunk); }
.workspace-nav a.is-active { background: var(--accent-soft); color: var(--accent-text); }
.workspace-nav .icon { width: 0.9rem; height: 0.9rem; }

.site-footer {
  border-block-start: 1px solid var(--line);
  padding-block: var(--sp-md);
  margin-block-start: var(--sp-xl);
}
.site-footer-inner {
  max-width: var(--content);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-sm);
}
.footer-note { color: var(--text-muted); font-size: var(--fs-0); }
.footer-links { display: flex; flex-wrap: wrap; gap: 1rem; font-size: var(--fs-0); }
.footer-links a { color: var(--text-muted); text-decoration: none; }
.footer-links a:hover { color: var(--ink); }

/* ----------------------------------------------------------------------
   Page heads, panels, empty states
   ---------------------------------------------------------------------- */

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-md);
  padding-block: var(--sp-lg) var(--sp-md);
}
.page-head-copy { min-width: min(100%, 18rem); flex: 1 1 24rem; }
.page-head .eyebrow { margin-block-end: 0.5rem; }
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--accent-text);
  font-family: var(--font-caps);
  font-size: clamp(0.6rem, 0.55rem + 0.12vw, 0.7rem);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.eyebrow::before {
  content: "";
  width: 1.4rem;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}
.page-head h1 { font-size: clamp(2.35rem, 1.6rem + 2.6vw, 4rem); max-width: 20ch; }
.page-head .lead {
  margin-block-start: 0.8rem;
  max-width: 55ch;
  color: var(--text-muted);
  font-size: var(--fs-base);
}
.page-actions { display: flex; flex-wrap: wrap; gap: 0.55rem; align-items: center; }
.page-section { margin-block-start: var(--sp-lg); }
.section-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-sm); margin-block-end: var(--sp-sm); }

.panel {
  background: color-mix(in oklab, var(--paper), var(--ink) 1.4%);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(1.1rem, 0.95rem + 0.9vw, 1.7rem);
  box-shadow: var(--shadow-soft);
}
.panel--flush { padding: 0; overflow: hidden; }
.panel--sunk { background: var(--surface-sunk); box-shadow: none; }
.panel--accent {
  background:
    radial-gradient(100% 100% at 100% 0%, color-mix(in oklab, var(--accent) 11%, transparent), transparent 65%),
    var(--surface);
  border-color: color-mix(in oklch, var(--accent) 24%, var(--line));
}
.panel-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--sp-sm); margin-block-end: var(--sp-md); }
.panel-title { font-size: var(--fs-2); letter-spacing: -0.02em; }
.panel-copy { color: var(--text-muted); font-size: var(--fs-sm); margin-block-start: 0.35rem; max-width: 52ch; }
.panel-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.empty-state {
  display: grid;
  place-items: center;
  gap: var(--sp-sm);
  text-align: center;
  padding: clamp(2rem, 1.2rem + 4vw, 4.5rem) var(--sp-md);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background:
    radial-gradient(80% 100% at 50% 0%, color-mix(in oklab, var(--accent) 6%, transparent), transparent 70%),
    color-mix(in oklab, var(--paper), var(--ink) 1.6%);
}
.empty-state h2 { font-size: var(--fs-3); }
.empty-state p { max-width: 38ch; color: var(--text-muted); }
.empty-icon {
  display: grid;
  place-items: center;
  width: 4.4rem;
  height: 4.4rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-text);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--accent) 22%, transparent);
}

/* ----------------------------------------------------------------------
   Library
   ---------------------------------------------------------------------- */

.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
  gap: var(--sp-md);
}
.book-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s ease, border-color 0.3s ease;
}
.book-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lift); border-color: var(--line-strong); }
.book-cover {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface-sunk);
  border-block-end: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem);
  color: var(--paper);
  isolation: isolate;
}
.book-cover--fallback {
  background: linear-gradient(145deg, var(--alt-strong), var(--accent-strong));
}
.book-cover--fallback::before {
  content: "";
  position: absolute;
  inset: -20%;
  z-index: -1;
  background:
    radial-gradient(circle at 30% 22%, color-mix(in oklab, var(--paper) 22%, transparent), transparent 42%),
    repeating-radial-gradient(circle at 80% 110%, transparent 0 1.6rem, color-mix(in oklab, var(--paper) 11%, transparent) 1.7rem 1.75rem);
  opacity: 0.9;
}
.book-cover--fallback::after {
  content: "";
  position: absolute;
  inset: 0.85rem;
  z-index: -1;
  border: 1px solid color-mix(in oklab, var(--paper) 26%, transparent);
  border-radius: calc(var(--r-md) * 0.8);
}
.book-cover--alt { background: linear-gradient(145deg, var(--accent-strong), var(--alt-strong)); }
.book-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s var(--ease-out); }
.book-card:hover .book-cover img { transform: scale(1.035); }
.book-cover--image::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, color-mix(in oklab, #000 36%, transparent));
}
.cover-top { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-family: var(--font-caps); font-size: clamp(0.5rem, 0.46rem + 0.1vw, 0.6rem); font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: color-mix(in oklab, var(--paper) 80%, transparent); position: relative; z-index: 1; }
.cover-mark { width: 0.85rem; height: 0.85rem; border-radius: 50%; background: currentColor; opacity: 0.7; }
.cover-title {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 1.1rem + 0.9vw, 1.85rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--paper);
  max-width: 14ch;
  text-wrap: balance;
}
.cover-bottom { display: flex; align-items: flex-end; justify-content: space-between; gap: 0.5rem; position: relative; z-index: 1; }
.cover-author { font-size: var(--fs-0); color: color-mix(in oklab, var(--paper) 82%, transparent); }
.cover-count { font-family: var(--font-caps); font-size: clamp(0.55rem, 0.5rem + 0.1vw, 0.65rem); color: color-mix(in oklab, var(--paper) 72%, transparent); }
.cover-image-title {
  position: absolute;
  left: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem);
  right: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem);
  bottom: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem);
  z-index: 2;
  color: #fff;
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.45);
}
.book-body { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem 1.1rem 0.9rem; flex: 1; }
.book-title { font-family: var(--font-display); font-size: var(--fs-2); line-height: 1.1; letter-spacing: -0.02em; color: var(--ink); }
.book-description { color: var(--text-muted); font-size: var(--fs-0); line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.4em; }
.book-meta { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-block-start: auto; }
.book-actions { display: flex; align-items: center; gap: 0.35rem; padding: 0 1.1rem 1.05rem; }
.book-actions .btn { flex: 1; }
.book-actions .icon-btn { width: 2.45rem; height: 2.45rem; }

.library-summary {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-md);
  align-items: center;
  padding: 0.8rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: color-mix(in oklab, var(--paper), var(--ink) 1.6%);
  margin-block-end: var(--sp-md);
  font-size: var(--fs-0);
  color: var(--text-muted);
}
.library-summary strong { color: var(--ink); font-weight: 700; }
.library-summary .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--line-strong); }

/* ----------------------------------------------------------------------
   Profile
   ---------------------------------------------------------------------- */

.profile-grid { display: grid; gap: var(--sp-md); grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr)); align-items: start; }
.profile-card { display: grid; gap: var(--sp-sm); }
.avatar-xl {
  width: clamp(6rem, 5rem + 4vw, 8rem);
  height: clamp(6rem, 5rem + 4vw, 8rem);
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, var(--alt-soft), var(--accent-soft));
  border: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.5rem + 2vw, 3rem);
  color: var(--ink);
  box-shadow: var(--shadow-soft);
}
.avatar-xl img { width: 100%; height: 100%; object-fit: cover; }
.profile-id { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-md); }
.profile-id h2 { font-size: var(--fs-3); }
.profile-id p { color: var(--text-muted); font-size: var(--fs-sm); }
.avatar-actions { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.readonly-value {
  min-height: 2.9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.65rem 0.85rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-sunk);
  color: var(--text-muted);
  font-size: var(--fs-sm);
}
.detail-list { display: grid; gap: 0.75rem; }
.detail-row { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; padding-block-end: 0.75rem; border-block-end: 1px solid var(--line); }
.detail-row:last-child { border: 0; padding-block-end: 0; }
.detail-row dt { color: var(--text-muted); font-size: var(--fs-0); }
.detail-row dd { color: var(--ink); font-size: var(--fs-sm); font-weight: 650; }

/* ----------------------------------------------------------------------
   Family
   ---------------------------------------------------------------------- */

.family-grid { display: grid; gap: var(--sp-md); grid-template-columns: repeat(auto-fill, minmax(min(19rem, 100%), 1fr)); }
.family-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  padding: 1.2rem;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--paper), var(--ink) 1.3%);
  box-shadow: var(--shadow-soft);
  transition: transform 0.25s var(--ease-out), border-color 0.25s ease;
}
.family-card:hover { transform: translateY(-3px); border-color: var(--line-strong); }
.family-top { display: flex; align-items: center; gap: 0.8rem; }
.family-avatar {
  width: 3.1rem;
  height: 3.1rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, var(--accent-soft), var(--alt-soft));
  border: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--font-caps);
  font-size: 0.82rem;
  font-weight: 700;
  flex: none;
}
.family-info { min-width: 0; }
.family-name { font-family: var(--font-display); font-size: var(--fs-2); letter-spacing: -0.02em; color: var(--ink); }
.family-relation { color: var(--text-muted); font-size: var(--fs-0); }
.family-contact { color: var(--text-muted); font-size: var(--fs-0); display: flex; align-items: center; gap: 0.35rem; }
.family-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-block-start: auto; padding-block-start: 0.35rem; }
.family-actions .btn { flex: 1 1 auto; }

/* ----------------------------------------------------------------------
   Help
   ---------------------------------------------------------------------- */

.help-steps { display: grid; gap: var(--sp-md); grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr)); }
.help-step {
  position: relative;
  display: grid;
  gap: 0.65rem;
  padding: 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--paper), var(--ink) 1.4%);
  overflow: hidden;
}
.help-step::after {
  content: attr(data-step);
  position: absolute;
  inset-inline-end: 0.8rem;
  top: -0.35rem;
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 2.5rem + 4vw, 5.5rem);
  line-height: 1;
  color: color-mix(in oklch, var(--ink), transparent 92%);
  pointer-events: none;
}
.help-step-icon { width: 2.6rem; height: 2.6rem; display: grid; place-items: center; border-radius: 50%; background: var(--accent-soft); color: var(--accent-text); }
.help-step h3 { font-size: var(--fs-2); }
.help-step p { color: var(--text-muted); font-size: var(--fs-sm); max-width: 30ch; }
.help-columns { display: grid; gap: var(--sp-md); grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr)); align-items: start; margin-block-start: var(--sp-lg); }
.help-card h2 { font-size: var(--fs-2); }
.help-card p, .help-card li { color: var(--text-muted); font-size: var(--fs-sm); }
.help-card ul { padding-inline-start: 1.1rem; display: grid; gap: 0.4rem; }
.help-card .checklist li::before { color: var(--accent-text); }
.faq details { border-block-start: 1px solid var(--line); }
.faq details:last-child { border-block-end: 1px solid var(--line); }
.faq summary { cursor: pointer; padding-block: 0.9rem; font-weight: 650; color: var(--ink); list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--accent-text); font-weight: 700; font-size: 1.2rem; }
.faq details[open] summary::after { content: "−"; }
.faq details p { padding-block-end: var(--sp-sm); color: var(--text-muted); font-size: var(--fs-sm); }
.help-note {
  margin-block-start: var(--sp-lg);
  padding: 1.2rem 1.35rem;
  border-radius: var(--r-lg);
  border: 1px solid color-mix(in oklch, var(--accent) 26%, var(--line));
  background: var(--accent-wash);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-sm);
}
.help-note .icon { color: var(--accent-text); }
.help-note p { margin: 0; color: var(--ink); font-size: var(--fs-sm); flex: 1 1 18rem; }

/* ----------------------------------------------------------------------
   Appearance
   ---------------------------------------------------------------------- */

.theme-grid { display: grid; gap: var(--sp-sm); grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr)); }
.theme-card {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 0.65rem;
  background: var(--paper);
  text-align: start;
  cursor: pointer;
  display: grid;
  gap: 0.6rem;
  transition: border-color 0.2s ease, transform 0.2s var(--ease-out), box-shadow 0.2s ease;
}
.theme-card:hover { transform: translateY(-2px); border-color: var(--line-strong); }
.theme-card.is-active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), var(--shadow-soft); }
.theme-card-label { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: var(--fs-0); font-weight: 650; padding-inline: 0.2rem; }
.theme-card-label .icon { color: var(--accent-text); }
.theme-preview {
  height: 4.6rem;
  border-radius: calc(var(--r-sm) * 0.9);
  border: 1px solid color-mix(in oklab, #000 10%, transparent);
  padding: 0.55rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  position: relative;
}
.theme-preview--light { background: oklch(0.978 0.007 82); color: oklch(0.19 0.014 62); }
.theme-preview--dark { background: oklch(0.155 0.011 62); color: oklch(0.955 0.008 82); }
.theme-preview--custom { background: linear-gradient(145deg, color-mix(in oklab, var(--accent), #fff 22%), color-mix(in oklab, var(--alt), #fff 10%)); color: #111; }
.theme-preview .mini-bar { width: 55%; height: 0.35rem; border-radius: 999px; background: currentColor; opacity: 0.32; }
.theme-preview .mini-bar--short { width: 32%; }
.theme-preview .mini-dot { width: 0.75rem; height: 0.75rem; border-radius: 50%; background: var(--accent); }
.theme-preview .mini-row { display: flex; align-items: center; gap: 0.35rem; }
.theme-preview .mini-btn { width: 1.65rem; height: 0.65rem; border-radius: 999px; background: currentColor; opacity: 0.75; }
.customizer { display: grid; gap: var(--sp-md); margin-block-start: var(--sp-md); }
.color-grid { display: grid; gap: var(--sp-sm); grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); }
.color-field { display: flex; align-items: center; gap: 0.65rem; padding: 0.55rem; border: 1px solid var(--line); border-radius: var(--r-sm); background: color-mix(in oklab, var(--paper), var(--ink) 2%); }
.color-well { position: relative; width: 2.6rem; height: 2.6rem; flex: none; border-radius: 50%; overflow: hidden; border: 1px solid var(--line-strong); }
.color-well input[type="color"] { position: absolute; inset: -0.5rem; width: 150%; height: 150%; border: 0; padding: 0; background: transparent; cursor: pointer; }
.color-meta { display: grid; gap: 0.1rem; min-width: 0; }
.color-meta span { font-size: var(--fs-0); color: var(--text-muted); }
.color-meta strong { font-family: var(--font-caps); font-size: var(--fs-0); letter-spacing: 0.08em; color: var(--ink); }
.preset-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.preset {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.7rem 0.35rem 0.35rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--text-muted);
  font-size: var(--fs-0);
  cursor: pointer;
}
.preset:hover { border-color: var(--line-strong); color: var(--ink); }
.preset-swatch { display: inline-block; vertical-align: -0.18em; width: 1.15rem; height: 1.15rem; border-radius: 50%; background: linear-gradient(145deg, var(--c1), var(--c2)); border: 1px solid color-mix(in oklab, #000 12%, transparent); }
.appearance-status { font-size: var(--fs-0); color: var(--text-muted); }
.appearance-preview { display: grid; gap: 0.7rem; padding: 1.1rem; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); }
.appearance-preview .ap-title { font-family: var(--font-display); font-size: var(--fs-2); letter-spacing: -0.02em; }
.appearance-preview .ap-copy { font-size: var(--fs-sm); color: var(--text-muted); }
.appearance-preview .cluster { gap: 0.4rem; }

/* ----------------------------------------------------------------------
   Membership
   ---------------------------------------------------------------------- */

/* Usage on the left, the checkout's own honesty on the right, and the three plans underneath all
   three. The panels are allowed to sit at unequal heights on purpose: the meter list is the thing a
   parent scans, and pulling the mock-checkout note down to match it would make a disclaimer the
   tallest object on the screen. */
.membership-grid {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
  align-items: start;
}
.panel-title-strong { color: var(--accent-text); }
.membership-note .panel-title { display: flex; align-items: center; gap: 0.5rem; }
.membership-note .panel-title .icon { color: var(--accent-text); flex: none; }

.plan-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  border: 1px solid color-mix(in oklch, var(--accent) 30%, var(--line));
  background: var(--accent-soft);
  color: var(--accent-text);
  font-family: var(--font-caps);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

.plan-meters { display: grid; gap: 0.6rem; }
.plan-meter {
  display: grid;
  gap: 0.4rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: color-mix(in oklab, var(--paper), var(--ink) 2%);
}
.plan-meter-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
}
.plan-meter-name { font-size: var(--fs-0); font-weight: 650; color: var(--ink); }
.plan-meter-figure {
  font-family: var(--font-caps);
  font-size: 0.72rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.plan-meter-figure strong { color: var(--ink); font-weight: 700; }
/* The fill is a plain width in a track, not a scaled transform, so it grows from the correct edge in
   Hebrew without a directional rule of its own. --meter arrives from the markup. */
.plan-meter-bar {
  height: 0.45rem;
  border-radius: 999px;
  background: var(--surface-sunk);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.plan-meter-bar i {
  display: block;
  width: var(--meter, 0%);
  min-width: 0;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent), var(--alt));
  animation: meterGrow 0.6s var(--ease-out) both;
}
.plan-meter-note { font-size: var(--fs-0); color: var(--text-muted); }
.plan-meter.is-full { border-color: color-mix(in oklch, var(--accent) 40%, var(--line)); background: var(--accent-wash); }
.plan-meter.is-full .plan-meter-bar i { background: var(--accent); }
.plan-meter.is-full .plan-meter-note { color: var(--accent-text); }

/* Cards stretch their own height to the row, and the limit list absorbs the slack so the button on
   every plan sits on the same line even when one blurb wraps and another does not. */
.plan-grid {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  margin-block-start: var(--sp-lg);
}
.plan-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  padding: clamp(1.1rem, 0.95rem + 0.9vw, 1.6rem);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--paper), var(--ink) 1.4%);
  box-shadow: var(--shadow-soft);
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s ease, border-color 0.3s ease;
}
.plan-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lift); border-color: var(--line-strong); }
.plan-card.is-current {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), var(--shadow-soft);
}
.plan-flag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  align-self: flex-start;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-text);
  font-family: var(--font-caps);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.plan-flag .icon { width: 0.8rem; height: 0.8rem; }
.plan-name { font-family: var(--font-display); font-size: var(--fs-2); letter-spacing: -0.02em; }
.plan-price {
  margin-block-start: calc(var(--sp-sm) * -0.5);
  font-family: var(--font-caps);
  font-size: var(--fs-0);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent-text);
}
.plan-blurb { color: var(--text-muted); font-size: var(--fs-sm); line-height: 1.55; }
.plan-limits {
  flex: 1 1 auto;
  display: grid;
  gap: 0.5rem;
  align-content: start;
  margin: 0;
  padding: 0;
  list-style: none;
  border-block-start: 1px solid var(--line);
  padding-block-start: var(--sp-sm);
}
.plan-limits li { display: flex; align-items: center; gap: 0.5rem; font-size: var(--fs-0); }
.plan-limits li .icon { color: var(--accent-text); flex: none; }
.plan-limits li span { color: var(--text-muted); min-width: 0; }
.plan-limits li strong {
  margin-inline-start: auto;
  font-family: var(--font-caps);
  font-size: 0.72rem;
  color: var(--ink);
  white-space: nowrap;
}
.plan-card .btn { margin-block-start: 0; }

/* The ceilings that no money can move are stated once, below every card, so a plan that says
   "Unlimited" is never read as a promise the app cannot keep. */
.plan-site-note { margin-block-start: var(--sp-lg); }
.plan-site-limits {
  display: grid;
  gap: 0.3rem;
  max-width: 62ch;
  margin: 0.4rem 0 0;
  padding-inline-start: 1.15rem;
  color: var(--text-muted);
  font-size: var(--fs-0);
  line-height: 1.6;
}

/* ----------------------------------------------------------------------
   Media controls — radial, glossy, physical
   ---------------------------------------------------------------------- */

.mc-btn {
  --size: clamp(3rem, 2.3rem + 2.4vw, 4.05rem);
  --p: 0;
  position: relative;
  width: var(--size);
  height: var(--size);
  flex: none;
  padding: 3px;
  border: 0;
  border-radius: 50%;
  background: conic-gradient(
    from 215deg,
    var(--accent) calc(var(--p) * 1%),
    color-mix(in oklab, var(--ink) 13%, transparent) 0
  );
  box-shadow:
    0 3px 0 color-mix(in oklab, #000 18%, transparent),
    0 12px 26px color-mix(in oklab, #000 26%, transparent);
  cursor: pointer;
  display: grid;
  place-items: center;
  color: var(--ink);
  transition: transform 0.22s var(--ease-spring), box-shadow 0.22s ease, filter 0.22s ease;
}
.mc-btn:hover { transform: translateY(-3px); filter: brightness(1.04); }
.mc-btn:active {
  transform: translateY(1px) scale(0.985);
  box-shadow:
    0 1px 0 color-mix(in oklab, #000 20%, transparent),
    0 5px 12px color-mix(in oklab, #000 24%, transparent);
}
.mc-btn:disabled { opacity: 0.34; cursor: not-allowed; transform: none; filter: none; }
.mc-face {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(circle at 33% 24%, color-mix(in oklab, var(--paper) 96%, transparent), transparent 48%),
    radial-gradient(circle at 50% 115%, color-mix(in oklab, var(--ink) 14%, transparent), transparent 70%),
    linear-gradient(158deg, color-mix(in oklab, var(--paper), var(--ink) 2%), color-mix(in oklab, var(--paper), var(--ink) 13%));
  box-shadow:
    inset 0 1px 1px color-mix(in oklab, var(--paper) 90%, transparent),
    inset 0 -9px 16px color-mix(in oklab, #000 15%, transparent),
    inset 0 3px 8px color-mix(in oklab, var(--paper) 28%, transparent);
  color: var(--ink);
}
.mc-face .icon { filter: drop-shadow(0 1px 1px color-mix(in oklab, #000 24%, transparent)); }
.mc-btn--primary .mc-face {
  background:
    radial-gradient(circle at 33% 24%, color-mix(in oklab, var(--paper) 55%, var(--accent)), transparent 46%),
    radial-gradient(circle at 52% 115%, color-mix(in oklab, var(--ink) 26%, transparent), transparent 68%),
    linear-gradient(155deg, var(--accent), color-mix(in oklch, var(--accent), var(--ink) 32%));
  color: var(--paper);
}
.mc-btn--record .mc-face {
  background:
    radial-gradient(circle at 33% 24%, color-mix(in oklab, var(--paper) 42%, var(--accent)), transparent 46%),
    radial-gradient(circle at 52% 118%, color-mix(in oklab, var(--ink) 30%, transparent), transparent 68%),
    linear-gradient(155deg, color-mix(in oklch, var(--accent), var(--alt) 16%), color-mix(in oklch, var(--accent), var(--ink) 36%));
  color: var(--paper);
}
.mc-btn--record.is-recording {
  animation: recordGlow 1.7s ease-in-out infinite;
  color: var(--paper);
}
.mc-btn--stop .mc-face {
  background:
    radial-gradient(circle at 33% 24%, color-mix(in oklab, var(--paper) 55%, transparent), transparent 45%),
    linear-gradient(155deg, color-mix(in oklab, var(--paper), var(--ink) 10%), color-mix(in oklab, var(--paper), var(--ink) 20%));
}
.mc-btn--sm { --size: clamp(2.5rem, 2.1rem + 1.4vw, 3rem); }
.mc-btn--lg { --size: clamp(3.5rem, 2.8rem + 3vw, 4.6rem); }

.audio-deck {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-md);
}
.audio-controls { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(0.55rem, 0.4rem + 0.8vw, 0.85rem); }
.audio-readout { flex: 1 1 12rem; min-width: min(100%, 12rem); display: grid; gap: 0.45rem; }
.audio-time { font-family: var(--font-caps); font-size: var(--fs-0); color: var(--text-muted); display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.audio-time strong { color: var(--ink); font-weight: 700; }
.audio-time .recording-dot,
.audio-status .recording-dot { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--accent-text); }
.audio-time .recording-dot::before,
.audio-status .recording-dot::before { content: ""; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--accent); animation: pulse 1.4s ease-in-out infinite; }
.wavebars { display: flex; align-items: center; gap: clamp(1px, 0.12vw, 2px); height: 2.15rem; width: 100%; overflow: hidden; }
.wavebars i {
  display: block;
  flex: 1;
  height: var(--h, 40%);
  min-height: 2px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--ink) 18%, transparent);
  transition: background-color 0.3s ease, height 0.35s var(--ease-out);
}
.audio-readout.is-playing .wavebars i,
.audio-readout.is-recording .wavebars i {
  background: linear-gradient(180deg, var(--accent), var(--alt));
  animation: wave 1.15s ease-in-out infinite alternate;
  animation-delay: var(--d, 0s);
}
.audio-studio {
  border: 1px solid color-mix(in oklch, var(--accent) 18%, var(--line));
  border-radius: var(--r-lg);
  padding: clamp(1rem, 0.9rem + 0.7vw, 1.35rem);
  background:
    radial-gradient(120% 100% at 0% 0%, color-mix(in oklab, var(--accent) 10%, transparent), transparent 62%),
    color-mix(in oklab, var(--paper), var(--ink) 2.5%);
  display: grid;
  gap: var(--sp-sm);
}
.audio-studio-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.6rem; }
.audio-studio-head h3 { font-size: var(--fs-2); display: flex; align-items: center; gap: 0.45rem; }
.audio-studio-head h3 .icon { color: var(--accent-text); }
.audio-hint { font-size: var(--fs-0); color: var(--text-muted); }
.audio-status { font-size: var(--fs-0); color: var(--accent-text); display: inline-flex; align-items: center; gap: 0.35rem; }
.audio-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem; }
.audio-delete { color: var(--text-muted); font-size: var(--fs-0); }
.audio-delete:hover { color: var(--ink); }

/* ----------------------------------------------------------------------
   Editor
   ---------------------------------------------------------------------- */

.editor-screen { min-height: 100svh; display: flex; flex-direction: column; }
.editor-topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  border-block-end: 1px solid var(--line);
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(1.2);
  -webkit-backdrop-filter: blur(18px) saturate(1.2);
}
.editor-topbar-inner {
  max-width: var(--content);
  margin-inline: auto;
  padding: 0.65rem var(--page-gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1rem;
}
.editor-topbar .brand-lockup { order: 1; }
.editor-top-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; margin-inline-start: auto; order: 3; }
.editor-top-title { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; flex: 1 1 12rem; order: 2; }
.editor-top-title span { font-family: var(--font-caps); font-size: clamp(0.55rem, 0.5rem + 0.1vw, 0.64rem); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.editor-top-title strong { font-family: var(--font-display); font-size: var(--fs-2); font-weight: 500; letter-spacing: -0.02em; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.save-state { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--fs-0); color: var(--text-muted); white-space: nowrap; }
.save-state::before { content: ""; width: 0.46rem; height: 0.46rem; border-radius: 50%; background: var(--line-strong); }
.save-state.is-dirty { color: var(--accent-text); }
.save-state.is-dirty::before { background: var(--accent); box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 16%, transparent); }
.save-state.is-saved { color: var(--text-muted); }
.save-state.is-saved::before { background: var(--alt); }

.editor-main { flex: 1; padding-block: var(--sp-md) var(--sp-xl); }
.editor-layout { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--sp-md); container-type: inline-size; }
.editor-rail { flex: 1 1 18rem; max-inline-size: 23rem; display: grid; gap: var(--sp-sm); align-self: flex-start; }
.editor-main-col { flex: 999 1 34rem; min-width: 0; display: grid; gap: var(--sp-sm); }
@container (max-width: 54rem) {
  .editor-main-col { order: -1; }
}
.rail-panel { padding: 1.05rem; border: 1px solid var(--line); border-radius: var(--r-lg); background: color-mix(in oklab, var(--paper), var(--ink) 1.3%); }
.rail-panel h2 { font-size: var(--fs-2); margin-block-end: 0.2rem; }
.rail-panel .panel-copy { margin-block-end: var(--sp-sm); }
.rail-heading { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-block-end: var(--sp-xs); }
.rail-heading h2 { margin: 0; }
:is(.rail-heading, .panel-head, .audio-studio-head) :is(h1, h2, h3, h4) { min-width: 0; }
.book-form { display: grid; gap: 0.7rem; }
.book-form .field input, .book-form .field textarea { min-height: 2.55rem; font-size: var(--fs-0); }
.book-form .field textarea { min-height: 4.2rem; }
.danger-zone { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem; padding-block-start: 0.8rem; border-block-start: 1px solid var(--line); }
.danger-zone span { color: var(--text-muted); font-size: var(--fs-0); }
.danger-zone .btn { color: var(--accent-text); border-color: color-mix(in oklch, var(--accent) 26%, var(--line)); background: transparent; }
.danger-zone .btn:hover { background: var(--accent-wash); }

.page-list { display: grid; gap: 0.32rem; }
.page-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.5rem;
  border: 1px solid transparent;
  border-radius: calc(var(--r-sm) * 0.9);
  background: transparent;
  text-align: start;
  cursor: pointer;
  color: var(--text-muted);
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.page-item:hover { background: var(--surface-sunk); color: var(--ink); }
.page-item.is-active { background: var(--paper); border-color: var(--line-strong); color: var(--ink); box-shadow: var(--shadow-soft); }
.page-item__num {
  width: 2rem;
  height: 2rem;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: var(--surface-sunk);
  font-family: var(--font-caps);
  font-size: 0.62rem;
  font-weight: 700;
}
.page-item.is-active .page-item__num { background: var(--accent-soft); color: var(--accent-text); }
.page-item__copy { min-width: 0; flex: 1; display: grid; gap: 0.08rem; }
.page-item__copy strong { font-size: var(--fs-0); font-weight: 650; color: inherit; }
.page-item__copy span { font-size: 0.68rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.page-item__icons { display: flex; align-items: center; gap: 0.2rem; color: var(--text-muted); }
.page-item__icons .icon { width: 0.85rem; height: 0.85rem; }
.page-item__icons .has-audio { color: var(--accent-text); }
.add-page { width: 100%; margin-block-start: 0.45rem; }

.studio {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--paper);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
  scroll-margin-top: 7.5rem;
}
.studio-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem;
  padding: 1rem 1.15rem;
  border-block-end: 1px solid var(--line);
  background: color-mix(in oklab, var(--paper), var(--ink) 1.8%);
}
.studio-heading { display: grid; gap: 0.15rem; }
.studio-heading h2 { font-size: var(--fs-2); }
.studio-heading span { font-size: var(--fs-0); color: var(--text-muted); }
.studio-body { display: grid; gap: var(--sp-md); padding: clamp(1rem, 0.9rem + 0.8vw, 1.5rem); }
.studio-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem; }
.studio-toolbar .cluster { gap: 0.45rem; }
.studio-save { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.studio-tip { color: var(--text-muted); font-size: var(--fs-0); }

.writing-shell {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background:
    linear-gradient(180deg, color-mix(in oklab, var(--paper), var(--ink) 0.8%), var(--paper));
  padding: clamp(0.8rem, 0.7rem + 0.7vw, 1.25rem);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.writing-shell:focus-within { border-color: var(--accent); box-shadow: var(--focus-ring); }
.writing-shell textarea {
  width: 100%;
  min-height: clamp(18rem, 15rem + 18vw, 32rem);
  resize: vertical;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--writing-size, 22px);
  line-height: 1.55;
  letter-spacing: -0.012em;
}
.writing-shell textarea:focus { outline: none; box-shadow: none; }
.writing-shell textarea::placeholder { color: color-mix(in oklch, var(--text-muted), transparent 38%); font-style: italic; }
.writing-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem; margin-block-start: 0.5rem; padding-block-start: 0.6rem; border-block-start: 1px solid var(--line); }
.char-count { font-family: var(--font-caps); font-size: 0.64rem; color: var(--text-muted); letter-spacing: 0.06em; }
/* Past the ceiling the counter stops reporting a total and reports the excess, so the number it turns
   to is the amount of work, not the size of the page. */
.char-count.is-over { color: var(--accent-text); font-weight: 700; }
.type-scale { display: inline-flex; align-items: center; gap: 0.35rem; }
.scale-btn {
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}
.scale-btn:hover { background: var(--accent-soft); border-color: transparent; color: var(--accent-text); }
.scale-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.scale-label { font-family: var(--font-caps); font-size: 0.64rem; color: var(--text-muted); min-width: 2.4rem; text-align: center; }

/* A page holds a sequence of pictures now, so the strip is drawn as a running row of numbered frames
   with a clock under each one — the order on screen is the order they are read in, and the numbers
   make that visible without a caption. The row wraps instead of scrolling: a parent arranging a
   slideshow needs to see all twelve at once, and a hidden third picture is a picture nobody retimed. */
.picture-strip {
  container-type: inline-size;
  display: grid;
  gap: var(--sp-sm);
  align-content: start;
  min-height: clamp(14rem, 11rem + 15vw, 22rem);
  padding: clamp(0.85rem, 0.7rem + 0.7vw, 1.3rem);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  background:
    repeating-linear-gradient(45deg, transparent 0 1.2rem, color-mix(in oklab, var(--ink) 2%, transparent) 1.2rem 1.21rem),
    color-mix(in oklab, var(--paper), var(--ink) 1.4%);
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.picture-strip.is-dragging { border-color: var(--accent); background-color: var(--accent-wash); }
/* Not opacity: a strip that fades looks like a strip that finished. The tiles hold their colour and
   the row simply stops answering the pointer while a file is being resized and uploaded. */
.picture-strip.is-busy { pointer-events: none; border-color: var(--accent); }
.strip-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.strip-title { display: inline-flex; align-items: center; gap: 0.45rem; font-size: var(--fs-2); letter-spacing: -0.02em; }
.strip-title .icon { color: var(--accent-text); }
.strip-count { font-family: var(--font-caps); font-size: 0.7rem; color: var(--text-muted); }
.strip-track { display: flex; flex-wrap: wrap; gap: var(--sp-sm); align-items: stretch; }
.strip-note { margin: 0; color: var(--text-muted); font-size: var(--fs-0); line-height: 1.55; max-width: 62ch; }
.strip-note.is-plan { color: var(--ink); }
.strip-note .btn-link { display: inline; padding: 0; font-size: var(--fs-0); }

.strip-tile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.4rem;
  align-items: center;
  margin: 0;
  width: clamp(8rem, 6rem + 8vw, 11.5rem);
}
.tile-frame {
  grid-column: 1 / -1;
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-sunk);
  box-shadow: var(--shadow-soft);
}
.tile-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tile-num {
  position: absolute;
  inset-inline-start: 0.4rem;
  inset-block-start: 0.4rem;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: color-mix(in oklab, var(--ink) 62%, transparent);
  color: var(--paper);
  font-family: var(--font-caps);
  font-size: 0.6rem;
  font-weight: 700;
}
/* Always faintly visible rather than hover-only: a phone has no hover, and a picture that cannot be
   removed is a picture that has to be re-uploaded over. */
.tile-over {
  position: absolute;
  inset-inline-end: 0.4rem;
  inset-block-start: 0.4rem;
  display: flex;
  gap: 0.2rem;
  opacity: 0.55;
  transition: opacity 0.18s ease;
}
.strip-tile:hover .tile-over,
.tile-over:focus-within { opacity: 1; }
.tile-over .icon-btn {
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  background: color-mix(in oklab, var(--paper) 82%, transparent);
  backdrop-filter: blur(6px);
  color: var(--ink);
}
.tile-time { display: grid; gap: 0.15rem; min-width: 0; }
.tile-time label { font-size: 0.6rem; color: var(--text-muted); white-space: nowrap; }
.tile-time input {
  width: 4.2rem;
  min-height: 2rem;
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-xs);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-caps);
  font-size: 0.72rem;
  appearance: textfield;
}
.tile-time input::-webkit-outer-spin-button,
.tile-time input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tile-move { display: flex; gap: 0.15rem; }
.tile-move .icon-btn { width: 1.9rem; height: 1.9rem; border: 1px solid var(--line); border-radius: var(--r-xs); }

.strip-add {
  display: grid;
  place-items: center;
  width: clamp(8rem, 6rem + 8vw, 11.5rem);
  aspect-ratio: 4 / 3.35;
  padding: 0.5rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-sm);
  background: color-mix(in oklab, var(--paper) 70%, transparent);
  color: var(--text-muted);
  cursor: pointer;
  transition: border-color 0.18s ease, color 0.18s ease, background-color 0.18s ease;
}
.strip-add:hover { border-color: var(--accent); color: var(--accent-text); background: var(--accent-wash); }
.strip-add:disabled { cursor: not-allowed; opacity: 0.45; }
.strip-add-inner { display: grid; justify-items: center; gap: 0.35rem; font-size: var(--fs-0); }

@container (max-width: 30rem) {
  .strip-tile,
  .strip-add { width: calc(50% - var(--sp-sm) / 2); }
  .strip-add { aspect-ratio: 4 / 3; }
}

.page-hint { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; color: var(--text-muted); font-size: var(--fs-0); }
.page-hint .icon { color: var(--accent-text); }
.editor-loading, .reader-loading { display: grid; place-items: center; min-height: 60svh; color: var(--text-muted); gap: var(--sp-sm); }
.loading-mark { width: 2.2rem; height: 2.2rem; border-radius: 50%; border: 2px solid var(--line); border-top-color: var(--accent); animation: spin 0.9s linear infinite; }

/* ----------------------------------------------------------------------
   Reader
   ---------------------------------------------------------------------- */

.reader-screen {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(90% 60% at 50% -10%, color-mix(in oklab, var(--accent) 7%, transparent), transparent 60%),
    var(--paper);
}
.reader-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1rem;
  padding: 0.7rem clamp(0.8rem, 0.5rem + 2vw, 2rem);
  border-block-end: 1px solid var(--line);
  background: var(--glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  position: relative;
  z-index: 20;
}
.reader-title-block { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; flex: 1 1 12rem; }
.reader-title-block span { font-family: var(--font-caps); font-size: clamp(0.52rem, 0.48rem + 0.12vw, 0.62rem); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.reader-title-block strong { font-family: var(--font-display); font-size: var(--fs-2); font-weight: 500; letter-spacing: -0.025em; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.reader-header-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-inline-start: auto; }
.reader-page-count { font-family: var(--font-caps); font-size: var(--fs-0); letter-spacing: 0.1em; color: var(--text-muted); white-space: nowrap; }
.reader-progress { height: 2px; background: var(--line); position: relative; z-index: 21; }
.reader-progress span { display: block; height: 100%; width: var(--reader-progress, 0%); background: linear-gradient(90deg, var(--accent), var(--alt)); transition: width 0.45s var(--ease-out); }
.reader-main {
  flex: 1;
  display: grid;
  place-items: center;
  padding: clamp(0.9rem, 0.5rem + 2.6vw, 3.5rem) clamp(0.9rem, 0.5rem + 2.4vw, 3.5rem) 0;
  min-height: 0;
  overflow-y: auto;
}
.reader-stage { width: min(100%, 68rem); display: grid; place-items: center; }
.reader-page {
  width: 100%;
  display: grid;
  place-items: center;
  gap: var(--sp-md);
  animation: pageIn 0.42s var(--ease-out) both;
}
.reader-page.is-exiting { animation: pageOut 0.18s ease both; }
.reader-text {
  width: min(100%, 60ch);
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 0.95rem + 1.4vw, 2rem);
  line-height: 1.52;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-align: center;
  white-space: pre-wrap;
  text-wrap: pretty;
  overflow-wrap: anywhere;
}
.reader-text.is-long { text-align: start; font-size: clamp(1.12rem, 0.95rem + 0.7vw, 1.5rem); line-height: 1.65; }
/* The placeholder is set as a custom property by i18n.js so it follows the interface language;
   the literal is only the fallback for a locale that has not been applied yet. */
.reader-text:empty::before { content: var(--reader-empty-label, "This page is waiting for words."); color: var(--text-muted); font-style: italic; }
.reader-image-wrap { width: 100%; display: grid; place-items: center; }
.reader-image {
  max-width: 100%;
  max-height: min(68svh, 48rem);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--r-md);
  box-shadow: 0 2px 2px color-mix(in oklab, #000 8%, transparent), 0 30px 70px color-mix(in oklab, #000 26%, transparent);
  background: var(--surface-sunk);
}
/* A page with more than one picture stacks them all in the same grid cell and lets the reader's
   clock decide which is on screen. One cell rather than absolute positioning because the box then
   takes the size of the largest picture, so a portrait giving way to a landscape moves the picture
   and not the page underneath it. The scale is a settle, not a flourish: 1.5% is enough to feel like
   the drawing came towards you, and small enough that it never reads like a slide deck. */
.reader-slideshow { width: 100%; display: grid; grid-template-areas: "slide"; place-items: center; }
.reader-slide { grid-area: slide; opacity: 0; transform: scale(0.985); transition: opacity 0.5s ease, transform 0.9s var(--ease-out); }
.reader-slide.is-live { opacity: 1; transform: none; z-index: 1; }
.reader-empty { display: grid; place-items: center; gap: var(--sp-sm); text-align: center; color: var(--text-muted); }
.reader-empty .empty-icon { width: 5rem; height: 5rem; }
.reader-footer {
  position: sticky;
  bottom: 0;
  z-index: 30;
  padding: 0.5rem clamp(0.8rem, 0.5rem + 2vw, 2rem) max(0.55rem, env(safe-area-inset-bottom));
  background: linear-gradient(180deg, transparent, var(--paper) 24%, var(--paper));
}
.reader-controls { width: min(100%, 62rem); margin-inline: auto; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: clamp(0.3rem, 0.2rem + 0.7vw, 1.2rem); }
.reader-media .mc-btn--sm { --size: clamp(2.4rem, 2rem + 1.2vw, 3rem); }
.reader-media-wrap { min-width: 0; }
.reader-nav {
  width: clamp(2.45rem, 2.1rem + 1.6vw, 3.4rem);
  height: clamp(2.45rem, 2.1rem + 1.6vw, 3.4rem);
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(160deg, var(--paper), color-mix(in oklab, var(--paper), var(--ink) 5%));
  color: var(--ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow:
    inset 0 1px 0 color-mix(in oklab, var(--paper) 85%, transparent),
    0 2px 0 color-mix(in oklab, #000 12%, transparent),
    0 10px 22px color-mix(in oklab, #000 18%, transparent);
  transition: transform 0.2s var(--ease-spring), background-color 0.2s ease, color 0.2s ease;
}
.reader-nav:hover:not(:disabled) { transform: translateY(-2px); background: var(--accent-soft); color: var(--accent-text); border-color: transparent; }
.reader-nav:active:not(:disabled) { transform: translateY(1px); }
.reader-nav:disabled { opacity: 0.28; cursor: not-allowed; }
.reader-nav--prev { justify-self: start; }
.reader-nav--next { justify-self: end; }
.reader-media-wrap { display: grid; justify-items: center; gap: 0.35rem; }
.reader-media { display: flex; align-items: center; justify-content: center; gap: clamp(0.45rem, 0.3rem + 1vw, 0.8rem); }
/* The one row under the media buttons. It is a target rather than a lid: a long translation wraps
   inside it instead of being cut, and only then does the footer grow past 36px. */
.reader-status {
  width: min(100%, 62rem);
  margin-inline: auto;
  margin-block-start: 0.3rem;
  min-height: 2.25rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.1rem 1rem;
  line-height: 1.35;
}
.reader-status-state { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.1rem 0.8rem; min-width: 0; }
.reader-timer { font-family: var(--font-caps); font-size: clamp(0.56rem, 0.52rem + 0.12vw, 0.66rem); letter-spacing: 0.08em; color: var(--text-muted); text-align: center; white-space: nowrap; }
.reader-timer .is-recording { color: var(--accent-text); }
.reader-note {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.2rem 0.5rem;
  font-size: 0.68rem;
  color: var(--text-muted);
  text-align: center;
}
.reader-note .btn-link { font-size: var(--fs-0); }
.reader-voice {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0.18rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
}
.reader-voice button {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  border-radius: 999px;
  padding: 0.28rem 0.6rem;
  font-size: 0.68rem;
  font-weight: 650;
  cursor: pointer;
}
.reader-voice button.is-active { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-soft); }
.reader-record-state { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--fs-0); color: var(--accent-text); }
.reader-error { display: grid; place-items: center; gap: var(--sp-md); min-height: 100svh; padding: var(--sp-lg); text-align: center; }
.reader-error h1 { font-size: var(--fs-4); }
.reader-error p { max-width: 38ch; }
.reader-footer-note { text-align: center; font-size: 0.66rem; color: var(--text-muted); }
.reader-signed-in { display: inline-flex; align-items: center; gap: 0.4rem; }

/* ----------------------------------------------------------------------
   Auth
   ---------------------------------------------------------------------- */

.auth-screen { min-height: 100svh; display: flex; flex-wrap: wrap; position: relative; }
.auth-theme { position: absolute; inset-block-start: clamp(0.8rem, 0.6rem + 1vw, 1.5rem); inset-inline-end: clamp(0.8rem, 0.6rem + 1vw, 1.5rem); z-index: 40; }
.auth-hero {
  flex: 1.15 1 28rem;
  min-height: 38rem;
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
  padding: clamp(1.2rem, 0.8rem + 2.5vw, 3.4rem);
  background:
    radial-gradient(110% 90% at 12% 0%, color-mix(in oklab, var(--accent) 12%, transparent), transparent 58%),
    radial-gradient(100% 90% at 100% 100%, color-mix(in oklab, var(--alt) 10%, transparent), transparent 58%),
    color-mix(in oklab, var(--paper), var(--ink) 1.6%);
  position: relative;
  overflow: hidden;
  container-type: inline-size;
}
.auth-orbit {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  --inner-size: 58%;
}
.auth-flow {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
}
.auth-score {
  position: absolute;
  z-index: 0;
  left: calc(50% - var(--inner-size) / 2);
  top: calc(50% - var(--inner-size) / 2);
  width: var(--inner-size);
  height: var(--inner-size);
  border-radius: 50%;
  overflow: hidden;
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}
.auth-score-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* The band is the left half of this circle box — the hero clips the disc at its own
     middle — so the mask fades the lines in over the first 3% of the band and away over
     the last 10%, which is the same curve auth-flow.js dims the notes with. They go
     transparent together, at the same place, every time. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 1.5%, #000 45%, transparent 50%);
  mask-image: linear-gradient(to right, transparent, #000 1.5%, #000 45%, transparent 50%);
  pointer-events: none;
}
/* The five lines are SVG paths, not a repeating gradient: the band has to bend to follow
   the rim of the circle at the top and bottom of the disc, and only a curve can do that.
   The SVG carries no viewBox, so one user unit is one CSS pixel and the paths are written
   in the same numbers the notes are placed with. */
.auth-staff {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.auth-staff-line {
  fill: none;
  stroke: color-mix(in oklab, var(--accent) 46%, transparent);
  stroke-width: 1;
}
.auth-orbit-ring {
  position: absolute;
  z-index: 2;
  border-radius: 50%;
  pointer-events: none;
}
.auth-orbit-ring--outer {
  inset: 0;
  border: 1px solid color-mix(in oklab, var(--accent) 15%, transparent);
  box-shadow: inset 0 0 7rem color-mix(in oklab, var(--accent) 3%, transparent);
}
.auth-orbit-ring--inner {
  width: var(--inner-size);
  height: var(--inner-size);
  left: calc(50% - var(--inner-size) / 2);
  top: calc(50% - var(--inner-size) / 2);
  border: 1px solid color-mix(in oklab, var(--alt) 17%, transparent);
  box-shadow: inset 0 0 4rem color-mix(in oklab, var(--alt) 3%, transparent);
}
.auth-orbit.is-static .auth-flow { display: none; }
.auth-hero-top { position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.auth-hero-copy { position: relative; z-index: 1; display: grid; gap: var(--sp-sm); margin-block-start: auto; }
.auth-headline {
  font-size: clamp(2.5rem, 1.4rem + 4.4vw, 5rem);
  line-height: 0.97;
  letter-spacing: -0.048em;
  max-width: 13ch;
  color: var(--ink);
}
.auth-headline em { font-style: italic; color: var(--accent-text); font-weight: 400; }
.auth-lead { max-width: 44ch; font-size: var(--fs-base); color: var(--text-muted); }
.auth-story { position: relative; z-index: 1; margin-block-start: var(--sp-md); display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap; }
.story-card {
  width: min(100%, 25rem);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: 0.75rem;
  box-shadow: var(--shadow-lift);
  transform: rotate(-1.6deg);
  transition: transform 0.45s var(--ease-out);
}
.auth-story:hover .story-card { transform: rotate(0deg) translateY(-3px); }
.story-art {
  height: clamp(8rem, 6rem + 6vw, 11rem);
  border-radius: calc(var(--r-md) * 0.85);
  background: linear-gradient(180deg, var(--alt-soft), var(--accent-soft));
  position: relative;
  overflow: hidden;
  border: 1px solid color-mix(in oklab, var(--ink) 7%, transparent);
}
.story-art::before {
  content: "";
  position: absolute;
  left: 12%;
  bottom: -38%;
  width: 85%;
  aspect-ratio: 1;
  border-radius: 50%;
  /* Lit from the upper left like the moon above them: a hot highlight, the body colour in
     the middle, then a deep fall to the lower-right limb so the circle reads as a sphere
     rather than a flat hill. */
  background: radial-gradient(circle at 31% 24%,
    color-mix(in oklab, var(--alt-strong), #fff 55%),
    color-mix(in oklab, var(--alt-strong), #fff 18%) 24%,
    var(--alt-strong) 50%,
    color-mix(in oklab, var(--alt-strong), #000 42%) 78%,
    color-mix(in oklab, var(--alt-strong), #000 62%));
  opacity: 0.94;
}
.story-art::after {
  content: "";
  position: absolute;
  right: -14%;
  bottom: -50%;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  /* Same upper-left key light as the blue sphere, in the accent hue, so the two read as
     siblings under one sun. */
  background: radial-gradient(circle at 34% 22%,
    color-mix(in oklab, var(--accent-strong), #fff 58%),
    color-mix(in oklab, var(--accent-strong), #fff 20%) 22%,
    var(--accent-strong) 48%,
    color-mix(in oklab, var(--accent-strong), #000 42%) 76%,
    color-mix(in oklab, var(--accent-strong), #000 62%));
  opacity: 0.88;
}
/* The end card's moon is one SVG sphere (moonMarkup in views/auth.js): a 120-unit frame carrying a
   disc of r=42, which leaves the rest of the box for the glow and the orbit it turns in. The box is
   deliberately much bigger than the old circle, and the disc centre lands where the old moon sat, so
   the composition grows without moving. */
.story-moon {
  position: absolute;
  z-index: 1;
  width: clamp(4.6rem, 3.2rem + 5.4vw, 8.5rem);
  aspect-ratio: 1;
  top: 6%;
  right: 8%;
  overflow: visible;
}
/* The moon is lit, not printed: its ramp runs from white through the accent to a darkened accent,
   and deliberately not through --paper and --ink. Those two swap when the theme goes dark, and a
   sphere whose highlight is the darkest thing on it reads as a hole rather than a moon. The hue
   still comes from --accent, so a themed accent moves the whole night scene together. */
.moon-body-a { stop-color: color-mix(in oklab, #fff, var(--accent) 8%); }
.moon-body-b { stop-color: color-mix(in oklab, #fff, var(--accent) 22%); }
.moon-body-c { stop-color: color-mix(in oklab, #fff, var(--accent) 48%); }
.moon-body-d { stop-color: var(--accent); }
/* Limb darkening goes over everything inside the disc: nothing until well past half the radius,
   then a slow wash to the edge. On its own this is what makes the circle read as a ball. */
.moon-limb-a { stop-color: #000; stop-opacity: 0; }
.moon-limb-b { stop-color: #000; stop-opacity: 0.1; }
.moon-limb-c { stop-color: #000; stop-opacity: 0.3; }
/* The glow starts where the disc ends — 42 of the box's 60-unit radius — so none of it is wasted
   underneath the moon, and all of it is the halo the old box-shadow was trying to be. */
.moon-glow-a { stop-color: var(--accent); stop-opacity: 0; }
.moon-glow-b { stop-color: var(--accent); stop-opacity: 0.4; }
.moon-glow-c { stop-color: var(--accent); stop-opacity: 0; }
/* The plains darken whatever they lie on rather than replacing it, so they read in both themes. */
.moon-mare-a,
.moon-mare-b,
.moon-mare-c { stop-color: #b3968a; }
.moon-mare-a { stop-opacity: 0.5; }
.moon-mare-b { stop-opacity: 0.3; }
.moon-mare-c { stop-opacity: 0; }
.moon-mare { mix-blend-mode: multiply; }
/* The floor of a pit is a grey ramp multiplied onto the terrain: white where the sun reaches the
   far wall, mid-grey on the floor, dark where the near wall hides it. The focal sits at the lower
   right of every crater, and the same stops serve a 3.4-unit pit and a 9.5 one. */
.moon-pit-a { stop-color: #fff; }
.moon-pit-b { stop-color: #c9b6aa; }
.moon-pit-c { stop-color: #7d6857; }
.moon-pit-floor { mix-blend-mode: multiply; }
/* Strokes scale with their crater in the markup, so only the paint lives here. */
.moon-pit-wall { fill: none; stroke: #8d7666; stroke-linecap: round; mix-blend-mode: multiply; }
.moon-pit-lit { fill: none; stroke: #fff; stroke-linecap: round; mix-blend-mode: screen; }
.story-moon-edge { fill: none; stroke: color-mix(in oklab, #fff 26%, transparent); stroke-width: 0.5; }
/* The ring takes --ink rather than the accent because it is the art panel behind it it has to stand
   out from, and that panel is warm in both themes: the ink is the one colour guaranteed to oppose
   it. The dots are a hair over a unit wide, which is the least that survives the trip to the screen
   at card size. */
.story-orbit-ring {
  fill: none;
  stroke: color-mix(in oklab, var(--ink) 42%, transparent);
  stroke-width: 1.1;
  stroke-dasharray: 0.1 3.6;
  stroke-linecap: round;
}
.moon-earth-a { stop-color: color-mix(in oklab, #fff, var(--alt) 20%); }
.moon-earth-b { stop-color: var(--alt); }
.moon-earth-c { stop-color: color-mix(in oklab, var(--alt), #000 40%); }
/* 11.4s is the hero notes' own walk — DRIFT_WALK in auth-flow.js, 0.55 rad/s for one full up and
   down — so the moon leans in on the same beat the staff drifts on and the two move as one gesture.
   The orbit is deliberately slower: a 26s turn is only just perceptible, which is the point. */
.story-moon-sphere {
  transform-box: view-box;
  transform-origin: 50% 50%;
  animation: moonLean 11.4s ease-in-out infinite;
}
.story-moon-halo { animation: moonGlow 11.4s ease-in-out infinite; }
.story-moon-orbit {
  transform-box: view-box;
  transform-origin: 50% 50%;
  animation: moonOrbit 26s linear infinite;
}
/* The earth turns about its own middle, against the turn of the ring it rides, so the lit side of
   it keeps facing the same way as the moon's while it goes round. */
.story-moon-orbit .story-orbit-earth {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: moonOrbit 26s linear infinite reverse;
}
.story-star {
  position: absolute;
  width: 0.3rem;
  height: 0.3rem;
  border-radius: 50%;
  background: color-mix(in oklab, var(--paper) 86%, transparent);
  animation: starTwinkle 5.4s ease-in-out infinite;
}
.story-star--1 { left: 18%; top: 20%; }
.story-star--2 { left: 32%; top: 34%; width: 0.18rem; height: 0.18rem; opacity: 0.7; }
.story-star--3 { right: 34%; top: 12%; width: 0.2rem; height: 0.2rem; opacity: 0.6; }
.story-text { font-family: var(--font-display); font-size: clamp(1.05rem, 0.95rem + 0.6vw, 1.35rem); line-height: 1.25; letter-spacing: -0.015em; color: var(--ink); padding: 0.75rem 0.25rem 0.15rem; max-width: 26ch; }
.story-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.55rem 0.25rem 0.1rem; }
.story-page-no { font-family: var(--font-caps); font-size: 0.58rem; letter-spacing: 0.12em; color: var(--text-muted); }
.story-audio-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.65rem 0.4rem 0.4rem;
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.66rem;
  font-weight: 650;
  box-shadow: var(--shadow-soft);
  transform: rotate(2.5deg) translateY(-0.2rem);
}
.story-audio-chip .mini-play {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: var(--paper);
}
.story-audio-chip .mini-play .icon { width: 0.7rem; height: 0.7rem; }
.auth-trust { position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.5rem 0.9rem; color: var(--text-muted); font-size: var(--fs-0); }
.auth-trust .icon { color: var(--accent-text); }
/* Icon and label sit on one line; on small screens the trust items stack from the left. */
.auth-trust-item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.auth-trust-mark {
  display: grid;
  place-items: center;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: 0.5rem;
  background: color-mix(in oklab, var(--accent) 10%, transparent);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  pointer-events: none;
}
@container (max-width: 42rem) {
  .auth-hero-copy { margin-block-start: 0; }
  .auth-story { display: none; }
  .auth-trust { margin-block-start: auto; flex-direction: column; align-items: flex-start; }
}
.auth-panel {
  flex: 0.85 1 24rem;
  display: grid;
  place-items: center;
  padding: clamp(1.2rem, 0.8rem + 2.5vw, 3.4rem);
  background: var(--paper);
}
.auth-form-wrap { width: min(100%, 27.5rem); }
.auth-form-head { display: grid; gap: 0.4rem; margin-block-end: var(--sp-md); }
.auth-form-head h2 { font-size: var(--fs-3); }
.auth-form-head p { color: var(--text-muted); font-size: var(--fs-sm); }
.auth-new-here { margin-block-end: 0.6rem; color: var(--text-muted); font-size: var(--fs-0); }
.auth-switch { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-block-end: var(--sp-md); }
.auth-switch a,
.auth-switch button {
  padding: 0.4rem 0.85rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-0);
  font-weight: 650;
  text-decoration: none;
  cursor: pointer;
}
.auth-switch a.is-active,
.auth-switch button.is-active { background: var(--surface-sunk); color: var(--ink); }
.auth-form { display: grid; gap: 0.85rem; }
.auth-submit { margin-block-start: 0.3rem; }
.auth-legal { margin-block-start: var(--sp-sm); text-align: center; }
.auth-legal p { font-size: 0.68rem; color: var(--text-muted); line-height: 1.6; }
.auth-divider { display: flex; align-items: center; gap: 0.7rem; color: var(--text-muted); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.14em; font-family: var(--font-caps); }
.auth-divider::before, .auth-divider::after { content: ""; height: 1px; flex: 1; background: var(--line); }
.auth-modal-tabs { margin-block-end: var(--sp-sm); }
.auth-modal .modal-card { width: min(92vw, 29rem); }

/* ----------------------------------------------------------------------
   Modal & toast
   ---------------------------------------------------------------------- */

dialog.modal {
  width: min(92vw, 38rem);
  max-width: none;
  max-height: none;
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  overflow: visible;
}
dialog.modal::backdrop {
  background: color-mix(in oklab, #000 58%, transparent);
  backdrop-filter: blur(7px);
}
dialog.modal[open] .modal-card { animation: modalIn 0.28s var(--ease-out) both; }
.modal-card {
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lift);
  max-height: 88svh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-sm);
  padding: 1.1rem 1.2rem 0.6rem;
}
.modal-head h2 { font-size: var(--fs-3); line-height: 1.05; }
.modal-subtitle { color: var(--text-muted); font-size: var(--fs-sm); margin-block-start: 0.35rem; max-width: 46ch; }
.modal-body { padding: 0.6rem 1.2rem 1.3rem; overflow-y: auto; }
.modal-copy { color: var(--text-muted); font-size: var(--fs-sm); }
.modal-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem; margin-block-start: var(--sp-md); }

/* A refusal is one thought, so the paygate dialog is narrower than the default sheet: at 38rem the
   sentence "Your plan allows 3 pictures per page" would float in the middle of a very wide card and
   the two buttons would sit at opposite ends of it. */
dialog.modal.paygate-modal { width: min(92vw, 28rem); }
.paygate-body { display: grid; gap: 0.7rem; }
.paygate-count {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin: 0;
  padding: 0.7rem 0.85rem;
  border: 1px solid color-mix(in oklch, var(--accent) 30%, transparent);
  border-radius: var(--r-sm);
  background: var(--accent-wash);
  color: var(--ink);
  font-size: var(--fs-sm);
  line-height: 1.5;
}
.paygate-count .icon { color: var(--accent-text); flex: none; margin-top: 0.12rem; }
.paygate-copy { margin: 0; color: var(--text-muted); font-size: var(--fs-sm); line-height: 1.55; }
.paygate-body .modal-actions { margin-block-start: 0.2rem; }
.share-success { display: grid; gap: 0.8rem; }
.link-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.45rem 0.45rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface-sunk);
}
.link-box input {
  flex: 1 1 12rem;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-caps);
  font-size: 0.68rem;
  outline: none;
}
.share-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.share-actions .btn { flex: 1 1 9rem; }
.wa-btn { background: var(--alt-strong); color: var(--paper); }
.wa-btn:hover { background: var(--alt); color: var(--paper); }
.share-note { display: flex; gap: 0.5rem; align-items: flex-start; color: var(--text-muted); font-size: var(--fs-0); line-height: 1.55; }
.share-note .icon { color: var(--accent-text); margin-top: 0.1rem; }
.family-picker { display: grid; gap: 0.45rem; }
.family-choice {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper);
  cursor: pointer;
  text-align: start;
  transition: border-color 0.18s ease, background-color 0.18s ease;
}
.family-choice:hover { border-color: var(--line-strong); background: var(--surface); }
.family-choice.is-selected { border-color: var(--accent); background: var(--accent-wash); }
.family-choice .family-avatar { width: 2.4rem; height: 2.4rem; font-size: 0.65rem; }
.family-choice strong { display: block; font-size: var(--fs-sm); color: var(--ink); }
.family-choice span { display: block; font-size: var(--fs-0); color: var(--text-muted); }
.family-choice .choice-check { margin-inline-start: auto; width: 1.35rem; height: 1.35rem; border-radius: 50%; border: 1px solid var(--line-strong); display: grid; place-items: center; color: transparent; background: transparent; transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease; }
.family-choice.is-selected .choice-check { color: var(--paper); background: var(--accent); border-color: var(--accent); }
.share-empty { display: grid; gap: 0.6rem; text-align: center; padding: var(--sp-md) 0; }
.share-empty p { color: var(--text-muted); font-size: var(--fs-sm); }

.toast-region {
  position: fixed;
  left: 50%;
  bottom: max(1.2rem, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 3000;
  display: grid;
  gap: 0.5rem;
  width: min(92vw, 24rem);
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: color-mix(in oklab, var(--paper) 92%, transparent);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-lift);
  color: var(--ink);
  font-size: var(--fs-sm);
  line-height: 1.45;
  pointer-events: auto;
  animation: toastIn 0.3s var(--ease-out) both;
}
.toast .icon { color: var(--accent-text); margin-top: 0.1rem; }
.toast--error { border-color: color-mix(in oklch, var(--accent) 46%, var(--line)); }
.toast--error .icon { color: var(--accent-text); }
.toast.is-leaving { animation: toastOut 0.3s ease both; }

/* ----------------------------------------------------------------------
   Motion
   ---------------------------------------------------------------------- */

html[data-reduced-motion="true"] *,
html[data-reduced-motion="true"] *::before,
html[data-reduced-motion="true"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.35; transform: scale(0.8); } }
@keyframes recordGlow {
  0%, 100% { box-shadow: 0 3px 0 color-mix(in oklab, #000 18%, transparent), 0 12px 26px color-mix(in oklab, #000 26%, transparent), 0 0 0 0 color-mix(in oklab, var(--accent) 34%, transparent); }
  50% { box-shadow: 0 3px 0 color-mix(in oklab, #000 18%, transparent), 0 12px 26px color-mix(in oklab, #000 26%, transparent), 0 0 0 9px color-mix(in oklab, var(--accent) 0%, transparent); }
}
@keyframes wave { from { transform: scaleY(0.55); } to { transform: scaleY(1.15); } }
@keyframes pageIn { from { opacity: 0; transform: translateY(14px) scale(0.995); } to { opacity: 1; transform: none; } }
@keyframes pageOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-8px); } }
@keyframes modalIn { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: none; } }
@keyframes toastIn { from { opacity: 0; transform: translateY(12px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes toastOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(8px) scale(0.98); } }
/* The meter's own fill is declared as a width, so this only has to say where it starts. Animate from
   nothing rather than to --meter: the property is already the end value, and a keyframe that names a
   `to` here would have to be kept in step with a number the markup writes. */
@keyframes meterGrow { from { width: 0; } }
/* The end card's night: the moon leans toward the line of text and its glow swells with the lean
   (one 11.4s beat, the hero notes' own drift), the earth goes round the ring on a slower turn, and
   the three stars come up and down on periods that never quite line up with each other. */
@keyframes moonLean {
  0%, 100% { transform: none; }
  50% { transform: translate(-3px, 2.5px) rotate(-3.5deg); }
}
@keyframes moonGlow { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
@keyframes moonOrbit { to { transform: rotate(360deg); } }
@keyframes starTwinkle { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

/* ----------------------------------------------------------------------
   Direction
   ---------------------------------------------------------------------- */

/* i18n.js puts dir="rtl" on <html> for Hebrew, and the flex/grid layout follows it on its
   own because every offset in these screens is written with logical properties. Three things
   cannot: glyphs that draw a direction, the progress bar's growth edge, and text whose own
   language differs from the interface language. */

/* Only arrows and chevrons that mean "back" or "onward" carry .icon--dir. Decorative marks —
   the auth hero staff, the story stars, the radial media bezels — keep their drawn direction. */
[dir="rtl"] .icon--dir { transform: scaleX(-1); }
[dir="rtl"] .scroll-progress { transform-origin: 100% 50%; }
