/* Calm and readable: warm paper, generous spacing, one clear highlight. */
:root {
  --paper: #fbf7ef;
  --ink: #1f1d1a;
  --muted: #6b645a;
  --line: #e4dccd;
  --reading: #f0e3c4;
  --heard: #ffd86b;
  --heard-ink: #1f1d1a;
  --accent: #2f6f62;
  --accent-ink: #ffffff;
  --text-size: 1.5rem;
  --line-height: 1.7;
  --letter-spacing: 0.01em;
  --word-spacing: 0.08em;
  /* Pictures always sit on a light backdrop (TH5); in light it is the page itself. */
  --picture-backdrop: #fbf7ef;
  --picture-pad: 0;
  --card: #fffdf8;
  --shadow: 31 29 26;
  --speaker-0: #b4472f;
  --speaker-1: #2f63b0;
  --speaker-2: #7a4ea8;
  --speaker-3: #2e7d4f;
  --speaker-4: #9a5800;
  --speaker-5: #b03a74;
  color-scheme: light;
}
/* Light unless the reader picks Dark, or Follow this device on a dark device
   (docs/specs/reader-theme.md). The two dark blocks must stay the same. */
:root[data-theme="dark"] {
  --paper: #1d1b18;
  --ink: #f1ebe0;
  --muted: #b0a796;
  --line: #3a362f;
  --reading: #353027;
  --heard: #ffd86b;
  --heard-ink: #1d1b18;
  --accent: #7cc4b3;
  --accent-ink: #10201c;
  --picture-pad: 0.5rem;
  --card: #26231f;
  --shadow: 0 0 0;
  --speaker-0: #f0937c;
  --speaker-1: #8db7f2;
  --speaker-2: #c3a3ef;
  --speaker-3: #7fcf9d;
  --speaker-4: #e8b060;
  --speaker-5: #ef94c0;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    --paper: #1d1b18;
    --ink: #f1ebe0;
    --muted: #b0a796;
    --line: #3a362f;
    --reading: #353027;
    --heard: #ffd86b;
    --heard-ink: #1d1b18;
    --accent: #7cc4b3;
    --accent-ink: #10201c;
    --picture-pad: 0.5rem;
    --card: #26231f;
    --shadow: 0 0 0;
    --speaker-0: #f0937c;
    --speaker-1: #8db7f2;
    --speaker-2: #c3a3ef;
    --speaker-3: #7fcf9d;
    --speaker-4: #e8b060;
    --speaker-5: #ef94c0;
    color-scheme: dark;
  }
}
:root[data-size="s"] { --text-size: 1.25rem; }
:root[data-size="l"] { --text-size: 1.85rem; }
:root[data-size="xl"] { --text-size: 2.3rem; }
:root[data-spacing="wide"] {
  --line-height: 2.1;
  --letter-spacing: 0.06em;
  --word-spacing: 0.3em;
}

/* Fonts (docs/specs/reader-fonts.md): the book's text and its code each in the
   font the reader chose. Every font but the device's own is served from fonts/. */
:root {
  --font-device: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Verdana, sans-serif;
  --font-serif: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  --font-atkinson: "Atkinson Hyperlegible Next", var(--font-device);
  --font-lexend: "Lexend", var(--font-device);
  --font-andika: "Andika", var(--font-device);
  --font-opendyslexic: "OpenDyslexic", var(--font-device);
  --font-lato: "Lato", var(--font-device);
  --font-open-sans: "Open Sans", var(--font-device);
  --font-courier-prime: "Courier Prime", ui-monospace, monospace;
  --code-device: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --code-jetbrains: "JetBrains Mono", var(--code-device);
  --code-fira: "Fira Code", var(--code-device);
  --code-cascadia: "Cascadia Code", var(--code-device);
  --code-atkinson-mono: "Atkinson Hyperlegible Mono", var(--code-device);
  --read-font: var(--font-device);
  --code-font: var(--code-jetbrains);
  --code-ligatures: normal;
}
:root[data-font="serif"] { --read-font: var(--font-serif); }
:root[data-font="atkinson"] { --read-font: var(--font-atkinson); }
:root[data-font="lexend"] { --read-font: var(--font-lexend); }
:root[data-font="andika"] { --read-font: var(--font-andika); }
:root[data-font="opendyslexic"] { --read-font: var(--font-opendyslexic); }
:root[data-font="lato"] { --read-font: var(--font-lato); }
:root[data-font="open-sans"] { --read-font: var(--font-open-sans); }
:root[data-font="courier-prime"] { --read-font: var(--font-courier-prime); }
:root[data-code-font="device"] { --code-font: var(--code-device); }
:root[data-code-font="fira"] { --code-font: var(--code-fira); }
:root[data-code-font="cascadia"] { --code-font: var(--code-cascadia); }
:root[data-code-font="atkinson-mono"] { --code-font: var(--code-atkinson-mono); }
:root[data-ligatures="off"] { --code-ligatures: none; }

* { box-sizing: border-box; }
html { background: var(--paper); color: var(--ink); }
body {
  margin: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Verdana, sans-serif;
  padding-bottom: calc(6rem + env(safe-area-inset-bottom));
}
button {
  font: inherit;
  font-size: 1rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  padding: 0.6rem 1.1rem;
  min-height: 44px;
  cursor: pointer;
}
button:focus-visible, input:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
button:disabled { opacity: 0.4; cursor: default; }

.top {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem max(1rem, env(safe-area-inset-left));
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  background: var(--paper);
  z-index: 2;
}
.book { flex: 1; min-width: 0; }
.book h1 { font-size: 1.1rem; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book p { margin: 0; color: var(--muted); font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mode {
  font-size: 0.85rem;
  color: var(--accent);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
}

#message {
  margin: 1rem auto;
  max-width: 38rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

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

@media (max-width: 560px) {
  .top { gap: 0.25rem; }
  .top .mode { display: none; }
  .top .quiet { padding-inline: 0.6rem; }
  /* Only the ribbon on a phone; "Bookmark" stays its name (BM8). */
  .top .bookmark { padding-inline: 0.5rem; }
  .top .bookmark .label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
/* A narrow phone with every header button (Practice on, and the studio's Fix): tighter,
   so Settings still fits beside the ribbon. */
@media (max-width: 430px) {
  .top { padding-inline: max(0.75rem, env(safe-area-inset-left)); gap: 0; }
  .top .quiet { padding-inline: 0.45rem; }
  .top .bookmark { padding-inline: 0.4rem; }
}

/* The library: a shelf of book cards, a page at a time (docs/specs/reader-library.md). */
:root[data-view="library"] #mode,
:root[data-view="library"] #open-ask { display: none; }
.library {
  max-width: 72rem;
  margin: 0 auto;
  padding: 2.5rem max(1.25rem, env(safe-area-inset-left)) 1rem;
}
.library-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.75rem;
}
.library-head h2 {
  margin: 0;
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.library-head h2:focus { outline: none; }
.library-count { margin: 0; color: var(--muted); font-variant-numeric: tabular-nums; }

.shelf {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 2.25rem 1.75rem;
}
@media (max-width: 560px) {
  .library { padding-top: 1.5rem; }
  .shelf { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.75rem 1rem; }
}

.card { position: relative; display: flex; flex-direction: column; min-width: 0; }
.cover {
  position: relative;
  aspect-ratio: 2 / 3;
  border-radius: 0.3rem 0.6rem 0.6rem 0.3rem;
  overflow: hidden;
  background: var(--line);
  box-shadow:
    0 1px 2px rgb(var(--shadow) / 0.12),
    0 6px 16px -6px rgb(var(--shadow) / 0.28);
  transition: transform 180ms ease, box-shadow 180ms ease;
}
/* The spine: a soft fold down the left edge, on every cover. */
.cover::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgb(0 0 0 / 0.22) 0, rgb(255 255 255 / 0.16) 3%, rgb(0 0 0 / 0.08) 6%, transparent 11%);
}
.cover.made {
  background:
    radial-gradient(120% 80% at 30% 0%, rgb(255 255 255 / 0.14), transparent 60%),
    var(--cloth);
  color: var(--foil);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  padding: 1.1rem 1rem 1.1rem 1.4rem;
  text-align: center;
}
/* A gilt frame inside the cloth, like a bound book. */
.cover.made::before {
  content: "";
  position: absolute;
  inset: 0.55rem 0.55rem 0.55rem 0.85rem;
  border: 1px solid color-mix(in srgb, var(--foil) 55%, transparent);
  border-radius: 0.2rem;
  pointer-events: none;
}
.cover.made.with-picture {
  justify-content: center;
  /* Centered in the band below the picture: 62% of the height is 93% of the width. */
  padding: 93% 0.9rem 0 1.2rem;
  gap: 0.5rem;
  background: var(--cloth);
}
/* A book's own cover, shown whole on its cloth (LB12). */
.cover.own { background: var(--cloth); }
.cover.own::before {
  content: "";
  position: absolute;
  inset: -12%;
  background: var(--art) center / cover;
  filter: blur(14px) brightness(0.85);
}
.cover-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* The picture fills the top of the cover; the cloth below carries the lettering. */
.cover-picture {
  position: absolute;
  inset: 0 0 auto 0;
  width: 100%;
  height: 62%;
  object-fit: cover;
  background: #fbf7ef; /* line art keeps a light page behind it (TH5) */
}
/* A gilt line where the picture meets the cloth. */
.cover.made.with-picture::before {
  inset: 62% 0 auto 0;
  height: 0;
  border: 0;
  border-top: 2px solid color-mix(in srgb, var(--foil) 75%, transparent);
  border-radius: 0;
}
.cover.made.with-picture .cover-title { font-size: 1rem; -webkit-line-clamp: 2; }
.cover.made.with-picture .cover-rule { display: none; }
.cover.made.with-picture .cover-author { font-size: 0.62rem; }
.cover-title { font-size: 1.05rem; -webkit-line-clamp: 3; }
.cover-title { font-size: 1rem; -webkit-line-clamp: 3; }
.cover-title {
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 1.15rem;
  line-height: 1.2;
  font-weight: 600;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cover-rule { width: 2rem; height: 1px; background: var(--foil); opacity: 0.7; }
.cover-author {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.85;
}
.cover-author:empty, .cover-rule:has(+ .cover-author:empty) { display: none; }

.card-title {
  margin: 0.9rem 0 0.2rem;
  font-size: 1rem;
  line-height: 1.3;
  font-weight: 600;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-title a { color: var(--ink); text-decoration: none; }
/* The whole card opens the book; the link itself is only the title. */
.card-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: 0.6rem; }
.card-title a:focus-visible { outline: none; }
.card-title a:focus-visible::after { outline: 3px solid var(--accent); outline-offset: 6px; }
.card-author {
  margin: 0;
  color: var(--muted);
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The book's description, a few lines of it; screen readers hear it all (LB12). */
.card-description {
  margin: 0.35rem 0 0;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-meta { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.55rem; }
.card-meta:empty { display: none; }
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  line-height: 1;
  padding: 0.3rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--muted);
  background: var(--card);
}
.tag.narrated { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.tag svg { width: 0.95rem; height: 0.95rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tag svg path:first-child { fill: currentColor; stroke: none; }
/* Putting a book on Yoto, from a reader on this computer (yoto-export.md, YT26). The
   button sits above the card's link, which covers the card. */
.yoto { position: relative; z-index: 2; margin-top: 0.6rem; display: grid; gap: 0.35rem; justify-items: start; }
.yoto-put { font-size: 0.85rem; min-height: 36px; padding: 0.3rem 0.8rem; }
.yoto-status { margin: 0; font-size: 0.82rem; color: var(--muted); }
.yoto-status:empty { display: none; }
.yoto-status.failed { color: var(--ink); font-weight: 600; }
#yoto h2 { margin-top: 0; font-size: 1.2rem; }
#yoto .check { display: flex; gap: 0.5rem; align-items: flex-start; margin: 0.75rem 0; }
#yoto .check input { margin-top: 0.25rem; }
#yoto .hint { color: var(--muted); font-size: 0.9rem; }
#yoto .dialog-buttons { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem; }

@media (hover: hover) {
  .card:hover .cover {
    transform: translateY(-4px) rotate(-0.4deg);
    box-shadow:
      0 2px 4px rgb(var(--shadow) / 0.12),
      0 18px 32px -10px rgb(var(--shadow) / 0.4);
  }
  .card:hover .card-title a { color: var(--accent); }
}

/* While a page's books arrive: quiet placeholders the same size as cards. */
.card.loading .cover { box-shadow: none; }
.card.loading .bar {
  display: block;
  height: 0.8rem;
  margin-top: 0.9rem;
  width: 80%;
  border-radius: 999px;
  background: var(--line);
}
.card.loading .bar.short { width: 50%; margin-top: 0.5rem; }
.card.loading .cover, .card.loading .bar { animation: shimmer 1.4s ease-in-out infinite; }
@keyframes shimmer { 50% { opacity: 0.55; } }

@media (prefers-reduced-motion: reduce) {
  .cover { transition: none; }
  .card:hover .cover { transform: none; }
  .card.loading .cover, .card.loading .bar { animation: none; }
}

.library-empty {
  text-align: center;
  max-width: 30rem;
  margin: 2rem auto 1rem;
  padding: 2.5rem 1.5rem;
  border: 1px dashed var(--line);
  border-radius: 1.25rem;
  background: var(--card);
}
.library-empty svg { width: 7.5rem; height: auto; margin-bottom: 0.75rem; }
.library-empty .page-left, .library-empty .page-right {
  fill: var(--paper);
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linejoin: round;
}
.library-empty .lines { fill: none; stroke: var(--line); stroke-width: 2; stroke-linecap: round; }
.library-empty h3 {
  margin: 0 0 0.5rem;
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 1.4rem;
}
.library-empty p { margin: 0; color: var(--muted); line-height: 1.55; }

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 3rem 0 1rem;
}
.pager .numbers { list-style: none; margin: 0; padding: 0; display: flex; gap: 0.25rem; }
.pager a, .pager .page-turn, .pager .gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  min-width: 44px;
  min-height: 44px;
  padding: 0 0.85rem;
  border-radius: 999px;
  color: var(--ink);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.pager .numbers a { padding: 0; }
.pager a:hover { background: var(--reading); }
.pager a:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.pager a[aria-current="page"] { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
.pager .page-turn { border: 1px solid var(--line); }
.pager .page-turn[aria-disabled="true"] { opacity: 0.4; }
.pager .gap { min-width: 1.5rem; padding: 0; color: var(--muted); }
@media (max-width: 560px) {
  .pager .page-turn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .pager .page-turn { padding: 0; }
  .pager a, .pager .page-turn { min-width: 40px; }
}

.by-address {
  max-width: 38rem;
  margin: 2.5rem auto 0;
  padding: 0.25rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 1rem;
  background: var(--card);
}
.by-address summary {
  cursor: pointer;
  padding: 0.75rem 0;
  min-height: 44px;
  color: var(--muted);
  list-style-position: inside;
}
.by-address summary:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 0.5rem; }
.by-address[open] summary { color: var(--ink); }
.by-address form { padding-bottom: 1rem; }
.by-address label { display: block; font-size: 0.95rem; margin-bottom: 0.5rem; }
.address-row { display: flex; gap: 0.5rem; }
.address-row input {
  flex: 1;
  min-width: 0;
  font: inherit;
  padding: 0.6rem 0.9rem;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
}

/* A pinch over the page changes the text size instead of zooming the whole screen
   (pinch-zoom.md, PZ2); one finger still scrolls either way. */
#reader { touch-action: pan-x pan-y; }

#text {
  max-width: 36em;
  margin: 0 auto;
  padding: 1.5rem max(1.25rem, env(safe-area-inset-left));
  font-family: var(--read-font);
  font-size: var(--text-size);
  line-height: var(--line-height);
  letter-spacing: var(--letter-spacing);
  word-spacing: var(--word-spacing);
}
#text .block { margin: 0 0 1em; }
#text h2, #text h3, #text h4, #text h5, #text h6 { line-height: 1.3; margin: 1.5em 0 0.75em; }
#text .list-item { padding-left: 1.2em; text-indent: -0.8em; }
#text .list-item::before { content: "•"; display: inline-block; width: 0.8em; text-indent: 0; }
/* Code keeps its columns: no added spacing, which would also break ligatures (FO3). */
#text pre.block {
  margin: 0 0 1em;
  padding: 0.9em 1.1em;
  font-family: var(--code-font);
  font-size: 0.78em;
  line-height: 1.6;
  letter-spacing: 0;
  word-spacing: 0;
  font-variant-ligatures: var(--code-ligatures);
  tab-size: 4;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}
#text blockquote { margin-left: 1em; padding-left: 1em; border-left: 3px solid var(--line); }
#text figure { margin: 0 0 1em; text-align: center; }
#text figure img {
  max-width: 100%;
  height: auto;
  border-radius: 0.5rem;
  background: var(--picture-backdrop);
  padding: var(--picture-pad);
}
.seg.figure { display: inline-block; padding: 0.3em; }
#text .caption { text-align: center; }
#text .summary { padding-left: 0.75em; border-left: 3px solid var(--accent); }
#text .summary::before {
  content: attr(data-label);
  display: block;
  font-size: 0.7em;
  color: var(--muted);
}
#text [data-summary][hidden] { display: none; }
/* Show the original under a summary, and the original once open (AC16, AC18). */
#text .object-bar { margin: -0.5em 0 1em 0.75em; }
#text .object-bar button, #text .object-tools button {
  font-family: system-ui, sans-serif;
  font-size: 0.85rem;
  min-height: 44px;
  padding: 0.35rem 0.9rem;
}
#text .object-bar button[aria-expanded="true"] { background: var(--reading); border-color: transparent; }
#text .object.open {
  margin: 0 0 1em;
  padding: 0.75em;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}
#text .object-tools { display: none; margin: 0 0 0.75em; }
#text .object.open .object-tools { display: block; }
#text .object-tools button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
/* A table as a table (RA-70), scrolling sideways on its own when it is wide. */
#text table.block {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  margin: 0 0 1em;
  border-collapse: collapse;
}
#text table.block th, #text table.block td {
  padding: 0.35em 0.75em;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
#text table.block th { font-weight: 600; white-space: nowrap; }
.sentinel { height: 1px; }

.seg { border-radius: 0.3em; transition: background-color 0.2s; }
/* A chapter opened from Contents starts below the sticky header, not under it. */
#text .seg { scroll-margin-top: 6rem; }
.seg.reading { background: var(--reading); }
/* Sentences an answer cites ("Show me", book-qa.md QA20). */
.seg.cited { outline: 0.15em solid var(--heard); outline-offset: 0.1em; }
.w { border-radius: 0.2em; cursor: pointer; }
.w.heard {
  background: var(--heard);
  color: var(--heard-ink);
  box-shadow: 0 0 0 0.12em var(--heard);
}

/* Who is speaking (reader-speakers.md): a small name where a speaker starts (WS2), and
   with colors, their words underlined in a color of their own (WS4). Off by default. */
.speech[data-name]::before {
  content: attr(data-name);
  display: none;
  margin-right: 0.3em;
  padding: 0.1em 0.45em;
  border-radius: 0.5em;
  vertical-align: 0.15em;
  font-size: 0.6em;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.3;
  color: var(--muted);
  background: color-mix(in srgb, var(--line) 60%, transparent);
}
:root:not([data-speakers="off"]) .speech[data-name]::before { display: inline-block; }
.speech[data-color="0"] { --speaker: var(--speaker-0); }
.speech[data-color="1"] { --speaker: var(--speaker-1); }
.speech[data-color="2"] { --speaker: var(--speaker-2); }
.speech[data-color="3"] { --speaker: var(--speaker-3); }
.speech[data-color="4"] { --speaker: var(--speaker-4); }
.speech[data-color="5"] { --speaker: var(--speaker-5); }
:root[data-speakers="colors"] .speech {
  text-decoration: underline 0.1em color-mix(in srgb, var(--speaker) 75%, transparent);
  text-underline-offset: 0.25em;
}
:root[data-speakers="colors"] .speech[data-name]::before {
  color: var(--speaker);
  background: color-mix(in srgb, var(--speaker) 14%, transparent);
}

[hidden] { display: none !important; }

#controls {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
  background: var(--paper);
  border-top: 1px solid var(--line);
}
#controls .buttons {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1rem;
}
#voice-credit {
  margin: 0.4rem 0 0;
  text-align: center;
  font-size: 0.8rem;
  color: var(--muted);
}
body:has(#voice-credit:not([hidden])) { padding-bottom: calc(7.25rem + env(safe-area-inset-bottom)); }
#play {
  min-width: 11rem;
  min-height: 56px;
  font-size: 1.2rem;
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}
.step { font-size: 1.6rem; width: 56px; min-height: 56px; padding: 0; }
/* Read to me shows a play symbol, and a pause symbol while it reads; how much is left
   is a quiet line above the buttons and a thread along the top of the controls that
   fills as the chapter is heard (docs/specs/reader-time-left.md). */
#play { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; }
#play .glyph { width: 1.15em; height: 1.15em; flex: none; fill: currentColor; }
#play .pause-glyph, #play[aria-pressed="true"] .play-glyph { display: none; }
#play[aria-pressed="true"] .pause-glyph { display: inline; }
.time-left {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin: -0.15rem 0 0.55rem;
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.time-left span { white-space: nowrap; }
#book-left::before { content: "·" / ""; margin-inline: 0.45em; }
#controls.timed::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: var(--chapter-heard, 0%);
  height: 2px;
  background: var(--accent);
  transition: width 0.3s linear;
}
@media (prefers-reduced-motion: reduce) { #controls.timed::before { transition: none; } }
body:has(#time-left:not([hidden])) { padding-bottom: calc(7.4rem + env(safe-area-inset-bottom)); }
body:has(#time-left:not([hidden])):has(#voice-credit:not([hidden])) { padding-bottom: calc(8.65rem + env(safe-area-inset-bottom)); }

/* The bookmark (docs/specs/reader-bookmark.md): a ribbon button in the header, a ribbon
   beside the bookmarked sentence, and a line above the reading controls. */
.top .bookmark { display: inline-flex; align-items: center; gap: 0.35rem; }
.bookmark svg, .bookmark-pill svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
.bookmark[aria-pressed="true"] { color: var(--accent); }
.bookmark[aria-pressed="true"] svg { fill: currentColor; }
.seg.bookmarked::before {
  content: "" / "Bookmark";
  display: inline-block;
  width: 0.55em;
  height: 0.85em;
  margin-inline-end: 0.3em;
  vertical-align: -0.05em;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 72%, 0 100%);
}
.bookmark-row {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 0.6rem);
  display: flex;
  flex-wrap: wrap-reverse;
  justify-content: center;
  gap: 0.5rem;
  padding-inline: 0.5rem;
  pointer-events: none;
}
.bookmark-pill {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  min-height: 44px;
  padding: 0 0.5rem 0 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 4px 14px rgb(var(--shadow) / 0.14);
  font-size: 0.95rem;
}
.bookmark-pill[hidden] { display: none; }
button.bookmark-pill { padding-inline: 0.9rem 1.1rem; }
button.bookmark-pill svg { color: var(--accent); fill: currentColor; stroke: none; }
/* The sleep timer (docs/specs/reader-sleep-timer.md): a moon beside the reading controls,
   a small sheet of choices, and a line above the controls with the time left. */
.step.sleep svg { width: 1.35rem; height: 1.35rem; }
.step.sleep.on { color: var(--accent); border-color: var(--accent); }
.step.sleep.on svg { fill: currentColor; }
.sleep-pill svg { width: 1.1rem; height: 1.1rem; color: var(--accent); fill: currentColor; stroke: none; }
#sleep-said { font-variant-numeric: tabular-nums; }
#sleep-cancel, #bookmark-undo {
  border-color: transparent;
  background: none;
  color: var(--accent);
  font-weight: 600;
  padding: 0 0.6rem;
}
dialog.sheet.sleep {
  margin: auto auto 8rem;
  width: min(28rem, calc(100vw - 2rem));
  height: fit-content;
  border-radius: 1.25rem;
  border-width: 1px;
}
.sleep .sheet-head h2 { margin: 0 0 0.25rem; }
.sleep-choices {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  padding: 1.1rem 1.5rem 1.25rem;
}
.sleep-choices button {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0.35rem 0.5rem;
}
.sleep-choices button.wide { grid-column: 1 / -1; }
.sleep-choices button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.sleep-last { font-size: 0.75rem; color: var(--muted); }
.sleep-off { margin: 0 1.5rem 1.5rem; }
@media (max-width: 560px) {
  dialog.sheet.sleep {
    margin: auto 0 0;
    width: 100vw; max-width: 100vw;
    border-radius: 1.25rem 1.25rem 0 0;
    border-width: 1px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
}
/* A phone has room for the moon beside the arrows once they sit a little closer. */
@media (max-width: 430px) {
  #controls .buttons { gap: 0.55rem; }
  #play { min-width: 0; flex: 0 1 11rem; }
  .step { width: 52px; }
}
.quiet { border-color: transparent; }

dialog {
  border: 1px solid var(--line);
  border-radius: 1rem;
  background: var(--paper);
  color: var(--ink);
  width: min(32rem, calc(100vw - 2rem));
  max-height: 85vh;
}
dialog::backdrop { background: rgb(0 0 0 / 0.35); }
fieldset { border: 0; padding: 0; margin: 0 0 1rem; }
legend { font-weight: 600; margin-bottom: 0.4rem; }
fieldset label { display: inline-flex; align-items: center; gap: 0.35rem; margin: 0 1rem 0.5rem 0; min-height: 44px; }
fieldset label:has(input:disabled) { flex-wrap: wrap; color: var(--muted); }
fieldset label .unavailable { flex-basis: 100%; font-size: 0.85em; }

@media (prefers-reduced-motion: reduce) {
  .seg { transition: none; }
}

/* The Ask panel (book-qa.md, "The reader"): a side sheet on wide screens and a
   bottom sheet on phones, so the page stays in view behind it. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
button.icon {
  width: 44px; padding: 0; display: inline-grid; place-items: center;
  border-color: transparent;
}
button svg { width: 1.3rem; height: 1.3rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
button.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }

dialog.sheet {
  margin: 0 0 0 auto;
  padding: 0;
  width: min(28rem, 100vw);
  height: 100dvh;
  max-height: 100dvh;
  border-radius: 1.25rem 0 0 1.25rem;
  border-width: 0 0 0 1px;
  box-shadow: -12px 0 40px rgb(0 0 0 / 0.12);
}
dialog.sheet[open] { display: flex; flex-direction: column; animation: sheet-in 0.2s ease-out; }
dialog.sheet::backdrop { background: rgb(0 0 0 / 0.15); }
@keyframes sheet-in { from { transform: translateX(2rem); opacity: 0; } }

.sheet-head {
  display: flex; align-items: flex-start; gap: 0.5rem;
  padding: 1.25rem 1rem 0.75rem 1.5rem;
  border-bottom: 1px solid var(--line);
}
.sheet-head > div { flex: 1; }
.sheet-head h2 { font-size: 1.25rem; margin: 0.35rem 0 0.25rem; }
.sheet-note { margin: 0; color: var(--muted); font-size: 0.9rem; }

.ask-body {
  flex: 1; overflow-y: auto;
  padding: 1.25rem 1.5rem;
  display: flex; flex-direction: column; gap: 1.25rem;
}
.ask-empty { margin-top: auto; }
.ask-empty p { margin: 0 0 0.6rem; color: var(--muted); font-size: 0.9rem; }
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chip { background: var(--reading); border-color: transparent; text-align: left; }

.turns { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1.25rem; }
.turn, .turns li { display: flex; flex-direction: column; gap: 0.6rem; }
.bubble {
  align-self: flex-end;
  max-width: 85%;
  margin: 0;
  padding: 0.6rem 0.95rem;
  border-radius: 1.1rem 1.1rem 0.3rem 1.1rem;
  background: var(--accent);
  color: var(--accent-ink);
  line-height: 1.4;
}
.bubble:empty { display: none; }
.reply {
  align-self: flex-start;
  max-width: 95%;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 1.1rem 1.1rem 1.1rem 0.3rem;
  background: var(--paper);
}
.reply-tag {
  margin: 0 0 0.35rem;
  font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--accent);
}
.reply.not-found .reply-tag { display: none; }
#ask-answer, .reply .text { margin: 0; font-size: 1.15rem; line-height: 1.55; }
.reply-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.8rem; }
.reply-actions:not(:has(button:not([hidden]))) { display: none; }
.turns .reply { opacity: 0.85; }

.ask-status { margin: 0; color: var(--muted); }
.ask-status:empty { display: none; }
.ask-status.thinking::after {
  content: ""; display: inline-block; width: 1.2em; text-align: left;
  animation: dots 1.2s steps(4) infinite;
}
@keyframes dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }
.ask-status.problem {
  color: var(--ink);
  padding: 0.75rem 1rem;
  border-radius: 0.9rem;
  border: 1px solid var(--line);
  background: var(--reading);
}

.composer {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
}
#question {
  flex: 1; min-width: 0; min-height: 48px;
  font: inherit; font-size: 1.05rem;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
}
.composer .send {
  width: 48px; min-height: 48px; padding: 0;
  display: inline-grid; place-items: center;
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
}
.composer .mic {
  display: inline-flex; align-items: center; gap: 0.4rem;
  min-height: 48px; padding-inline: 0.9rem;
}
.composer .mic[aria-pressed="true"] {
  background: var(--heard); color: var(--heard-ink); border-color: var(--heard);
  animation: listening 1.4s ease-in-out infinite;
}
@keyframes listening { 50% { box-shadow: 0 0 0 0.4rem rgb(255 216 107 / 0.35); } }
/* Talking with the book (QA55): End stops the conversation. */
.composer .end { min-height: 48px; padding-inline: 0.9rem; }

@media (max-width: 560px) {
  dialog.sheet {
    margin: auto 0 0;
    width: 100vw; max-width: 100vw;
    height: 88dvh;
    border-radius: 1.25rem 1.25rem 0 0;
    border-width: 1px 0 0;
  }
  @keyframes sheet-in { from { transform: translateY(2rem); opacity: 0; } }
  .composer .mic .label { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  dialog.sheet[open], .composer .mic[aria-pressed="true"], .ask-status.thinking::after { animation: none; }
}

/* Practice mode C, read to a grown-up (sounds-and-practice.md, stage S-D). While
   practicing, the voice and the other panels are out of the way, and the page shows
   no count, clock or "wrong" mark (SP17): a missed word gets a quiet dotted line. */
:root[data-practice] #open-ask,
:root[data-practice] #open-settings,
:root[data-practice] #open-toc { display: none; }
:root[data-practice] .mode { color: var(--ink); background: var(--reading); border-color: transparent; }
:root[data-practice] .w { cursor: pointer; }
@media (hover: hover) {
  :root[data-practice] .w:hover { background: var(--reading); }
}
.w.practice-start {
  box-shadow: -0.22em 0 0 0 var(--accent);
  border-radius: 0 0.2em 0.2em 0;
}
:root[data-practice="start"] .w.practice-start { background: var(--reading); }
.w.missed {
  text-decoration: underline dotted var(--muted);
  text-decoration-thickness: 0.1em;
  text-underline-offset: 0.28em;
}

#practice-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
  background: var(--paper);
  border-top: 1px solid var(--line);
  z-index: 2;
}
#practice-hint { margin: 0; color: var(--muted); font-size: 1rem; text-align: center; }
.practice-actions { display: flex; gap: 0.5rem; }
#practice-go { min-width: 9rem; min-height: 56px; font-size: 1.2rem; }
:root[data-practice="last"] #practice-hint { color: var(--ink); font-weight: 600; }

.sheet-kicker {
  margin: 0;
  font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--accent);
}
.practice-body {
  flex: 1; overflow-y: auto;
  padding: 1.25rem 1.5rem 2rem;
  display: flex; flex-direction: column; gap: 1.75rem;
}
.practice-body h3 { font-size: 1rem; margin: 0 0 0.6rem; }
.practice-body section > :last-child { margin-bottom: 0; }
.practice-body .empty { margin: 0; color: var(--muted); }
.how { margin: 0 0 1rem; padding-left: 1.3rem; line-height: 1.5; }
.how li + li { margin-top: 0.35rem; }
#practice-choose { width: 100%; }

/* Pattern hunt, practice mode B (pattern-hunt.md): the pattern's words underlined with
   their letters in bold, a map of where they are, and a bar to step through them. */
.hunt-about { margin: 0 0 0.9rem; line-height: 1.5; }
.hunt-patterns { display: flex; flex-direction: column; gap: 0.6rem; }
.hunt-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
.hunt-group-name { flex-basis: 100%; margin: 0; font-size: 0.8rem; color: var(--muted); }
.hunt-group .chip { min-height: 40px; min-width: 3rem; padding: 0.2rem 0.7rem; text-align: center; font-weight: 600; }
.hunt-group .chip[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.hunt-own { margin-top: 0.9rem; }
.hunt-own label { display: block; font-weight: 600; margin-bottom: 0.3rem; }
.hunt-own-row { display: flex; gap: 0.5rem; }
.hunt-own-row input { flex: 1; min-width: 0; min-height: 44px; }
.hunt-note { margin: 0.8rem 0 0; }
.hunt-note:empty, .hunt-words:empty { display: none; }
.hunt-words { margin: 0.3rem 0 0; color: var(--muted); font-size: 0.9rem; }
.hunt-map { display: flex; flex-direction: column; gap: 0.3rem; margin: 0.8rem 0; }
.hunt-map:empty { display: none; }
.hunt-row {
  display: grid; grid-template-columns: minmax(5rem, 9rem) 1fr 2.5rem; align-items: center; gap: 0.6rem;
  width: 100%; min-height: 40px; padding: 0.25rem 0.5rem; text-align: left;
  border-color: transparent; background: var(--reading);
}
.hunt-row-name { font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hunt-strip { position: relative; height: 14px; border-radius: 7px; background: color-mix(in srgb, var(--muted) 18%, transparent); }
.hunt-strip .tick { position: absolute; top: 2px; width: 4px; height: 10px; margin-left: -2px; border-radius: 2px; background: var(--accent); }
.hunt-strip .tick.many { top: 0; height: 14px; width: 6px; margin-left: -3px; }
.hunt-row-count { font-size: 0.85rem; color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
#hunt-start { width: 100%; }
.w.hunt {
  text-decoration: underline var(--accent);
  text-decoration-thickness: 0.12em;
  text-underline-offset: 0.25em;
  cursor: pointer;
}
.w.hunt .hunt-letters { font-weight: 700; }
.w.hunt.hunt-at { background: var(--reading); border-radius: 0.2em; box-shadow: 0 0 0 0.12em var(--reading); }
.w.hunt.hunt-found { text-decoration-style: double; }
.hunt-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.4rem 1rem; margin-bottom: 0.6rem; }
#hunt-what { margin: 0; color: var(--muted); text-align: center; }
.hunt-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; }
.hunt-actions button { min-height: 44px; }
@media (max-width: 34rem) {
  .hunt-bar { gap: 0.3rem; margin-bottom: 0.45rem; }
  #hunt-what { font-size: 0.9rem; }
  .hunt-actions { flex-wrap: nowrap; gap: 0.25rem; }
  .hunt-actions button { min-height: 40px; padding: 0.3rem 0.65rem; font-size: 0.95rem; white-space: nowrap; }
}
body:has(#hunt-bar:not([hidden])) { padding-bottom: calc(10rem + env(safe-area-inset-bottom)); }

.result {
  padding: 1.1rem 1.1rem 1.2rem;
  border-radius: 1rem;
  background: var(--reading);
}
.result-passage { margin: -0.3rem 0 0.9rem; color: var(--muted); font-size: 0.9rem; }
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
}
.stat {
  margin: 0;
  display: flex; flex-direction: column; gap: 0.1rem;
  padding: 0.6rem 0.7rem;
  border-radius: 0.75rem;
  background: var(--paper);
}
.stat .value { font-size: 1.35rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.stat .name { font-size: 0.78rem; color: var(--muted); line-height: 1.25; }
.stat.main { grid-column: 1 / -1; flex-direction: row; align-items: baseline; gap: 0.6rem; }
.stat.main .value { font-size: 2.6rem; color: var(--accent); line-height: 1.1; }
.stat.main .name { font-size: 0.95rem; }
.missed-words { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.9rem; }
.missed-words .chip { background: var(--paper); padding: 0.3rem 0.75rem; border-radius: 999px; font-size: 1rem; }
.result-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }

.word-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.word-list li {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding-left: 0.85rem;
  border: 1px solid var(--line);
  border-radius: 999px;
}
.word-list .word { font-size: 1.05rem; }
.word-list .count { color: var(--muted); font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.word-list button.icon { width: 36px; min-height: 36px; }
.word-list button svg { width: 1rem; height: 1rem; }

#practice-history { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
#practice-history th { text-align: left; font-weight: 600; color: var(--muted); font-size: 0.78rem; }
#practice-history th, #practice-history td { padding: 0.45rem 0.4rem 0.45rem 0; border-bottom: 1px solid var(--line); vertical-align: top; }
#practice-history td:nth-child(n + 3), #practice-history th:nth-child(n + 3) { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
#practice-history td:nth-child(2) { color: var(--muted); }

.practice-data { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.practice-data p { flex-basis: 100%; margin: 0; color: var(--muted); }
.practice-data p:empty { display: none; }
button.danger.confirm { background: var(--ink); color: var(--paper); border-color: var(--ink); }

@media (max-width: 560px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  #practice-bar { gap: 0.5rem; }
}
.counts {
  margin: 0 0 1rem;
  padding: 0.75rem 0.9rem;
  border-radius: 0.75rem;
  background: var(--reading);
  font-size: 0.95rem;
  line-height: 1.45;
}
.counts p { margin: 0; }
.counts p + p { margin-top: 0.4rem; }
.why { margin-top: 1rem; font-size: 0.95rem; line-height: 1.5; }
.why summary { cursor: pointer; color: var(--accent); min-height: 44px; display: flex; align-items: center; }
.why p { margin: 0 0 0.6rem; color: var(--muted); }

/* The Contents panel (reader-contents.md): a sheet from the left on wide screens,
   like turning back to a book's front, and a bottom sheet on phones. The chapter
   being read is marked, with how far into it the reader is. */
dialog.sheet.contents {
  margin: 0 auto 0 0;
  width: min(27rem, 100vw);
  border-radius: 0 1.25rem 1.25rem 0;
  border-width: 0 1px 0 0;
  box-shadow: 12px 0 40px rgb(0 0 0 / 0.12);
}
dialog.sheet.contents[open] { animation-name: contents-in; }
@keyframes contents-in { from { transform: translateX(-2rem); opacity: 0; } }

.contents-head { align-items: center; gap: 0.9rem; padding: 1.25rem 1rem 1rem 1.5rem; border-bottom: 0; }
.contents-head .sheet-kicker { margin: 0; font-size: 0.72rem; letter-spacing: 0.12em; font-weight: 600; }
.contents-book {
  margin: 0.2rem 0 0.15rem;
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
}
.contents-head .sheet-note span:empty { display: none; }
.contents-head .sheet-note span + span:not(:empty)::before { content: " · "; }

/* The book's own cover, small: its cloth, a gilt frame and its first letter. */
.contents-head > .mini-cover {
  position: relative;
  flex: none;
  width: 3.4rem;
  aspect-ratio: 2 / 3;
  display: grid;
  place-items: center;
  border-radius: 0.2rem 0.4rem 0.4rem 0.2rem;
  background:
    radial-gradient(120% 80% at 30% 0%, rgb(255 255 255 / 0.16), transparent 60%),
    var(--cloth, var(--accent));
  color: var(--foil, var(--accent-ink));
  box-shadow: 0 1px 2px rgb(var(--shadow) / 0.14), 0 6px 14px -6px rgb(var(--shadow) / 0.4);
  overflow: hidden;
}
.mini-cover::before {
  content: "";
  position: absolute;
  inset: 0.25rem 0.25rem 0.25rem 0.4rem;
  border: 1px solid color-mix(in srgb, var(--foil, #fff) 55%, transparent);
  border-radius: 0.12rem;
}
.mini-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgb(0 0 0 / 0.22) 0, rgb(255 255 255 / 0.16) 4%, rgb(0 0 0 / 0.08) 8%, transparent 14%);
}
.mini-cover > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mini-cover.with-image::before, .mini-cover.with-image .initial { display: none; }
.mini-cover .initial {
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 1.6rem;
  font-weight: 600;
  padding-left: 0.15rem;
}

/* Where the reader is in the whole book. */
.contents-progress { padding: 0 1.5rem 1rem; border-bottom: 1px solid var(--line); }
.contents-progress p {
  display: flex; justify-content: space-between; gap: 1rem;
  margin: 0 0 0.45rem;
  font-size: 0.85rem; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.contents-progress .where { color: var(--ink); font-weight: 600; }
.contents-progress .track, .chapter-progress {
  display: block; height: 4px; border-radius: 999px;
  background: var(--line); overflow: hidden;
}
.contents-progress .fill, .chapter-progress > span {
  display: block; height: 100%; width: var(--done, 0%);
  border-radius: inherit; background: var(--accent);
}

.contents-body { flex: 1; overflow-y: auto; padding: 0.75rem 0.75rem 2rem; overscroll-behavior: contain; }
.contents-find { padding: 0.25rem 0.5rem 0.75rem; }
#toc-query {
  width: 100%; min-height: 44px;
  font: inherit; font-size: 1rem;
  padding: 0.55rem 1rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--ink);
}
.contents-none { margin: 1rem 0.75rem; color: var(--muted); }

/* Opening pages: there to find, but out of the way, since reading skips them. */
.opening { padding: 0.25rem 0.75rem 0.9rem; }
.opening h3 {
  margin: 0 0 0.5rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.opening ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.opening-entry {
  min-height: 36px; padding: 0.35rem 0.85rem;
  font-size: 0.88rem; color: var(--muted);
  background: var(--card);
}
.opening-entry:hover { color: var(--ink); border-color: color-mix(in srgb, var(--ink) 25%, transparent); }
.opening-entry[aria-current] { color: var(--accent); border-color: currentColor; }

.chapters { list-style: none; margin: 0; padding: 0; }
.chapters li + li { border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
.chapters li:has(.chapter[aria-current]), .chapters li:has(.chapter[aria-current]) + li { border-top-color: transparent; }
.chapter {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  align-items: center;
  column-gap: 0.75rem;
  padding: 0.8rem 0.9rem 0.8rem 0.5rem;
  min-height: 60px;
  text-align: left;
  border: 0;
  border-radius: 0.9rem;
  background: transparent;
}
.chapter.level-2 { padding-left: 2rem; }
.chapter.level-3 { padding-left: 3.5rem; }
.chapter .num {
  justify-self: center;
  display: grid; place-items: center;
  width: 2.3rem; height: 2.3rem;
  border-radius: 999px;
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 1.15rem;
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.chapter .num:empty { border-color: transparent; }
.chapter .num:empty::before { content: "❧"; font-size: 1rem; color: var(--muted); }
.chapter .words { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.chapter .kicker {
  font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
}
.chapter .name {
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 1.12rem;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.chapters li.before .name { color: color-mix(in srgb, var(--ink) 72%, var(--paper)); }
.chapter .here {
  grid-column: 2;
  justify-self: start;
  margin-top: 0.35rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent);
}
.chapter .chapter-progress { grid-column: 2; margin-top: 0.4rem; height: 3px; background: color-mix(in srgb, var(--accent) 18%, transparent); }
@media (hover: hover) {
  .chapter:hover { background: color-mix(in srgb, var(--reading) 70%, transparent); }
  .chapter:hover .num { border-color: var(--accent); }
}
.chapter:focus-visible { outline-offset: -3px; }
.chapter[aria-current] { background: color-mix(in srgb, var(--accent) 10%, var(--paper)); }
.chapter[aria-current] .num { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.chapter[aria-current] .name { font-weight: 600; }

@media (max-width: 560px) {
  dialog.sheet.contents {
    margin: auto 0 0;
    width: 100vw;
    border-radius: 1.25rem 1.25rem 0 0;
    border-width: 1px 0 0;
    box-shadow: 0 -12px 40px rgb(0 0 0 / 0.12);
  }
  @keyframes contents-in { from { transform: translateY(2rem); opacity: 0; } }
  .contents-head { padding: 1rem 0.75rem 0.85rem 1.25rem; }
  .contents-progress { padding-inline: 1.25rem; }
  .contents-body { padding-inline: 0.5rem; padding-bottom: calc(1.5rem + env(safe-area-inset-bottom)); }
}
@media (prefers-reduced-motion: reduce) {
  dialog.sheet.contents[open] { animation: none; }
}

/* The Settings sheet (reader-settings.md): from the right like Ask, in groups,
   with the page settings shown on a line of the book as they change. */
dialog.sheet.settings { width: min(30rem, 100vw); }
:root[data-view="library"] #settings .book-only { display: none; }
.settings .sheet-head h2 { margin-top: 0.15rem; }
.settings-body {
  flex: 1; overflow-y: auto; overscroll-behavior: contain;
  padding: 0.5rem 1.5rem 1.5rem;
}
.settings-group { padding: 1.25rem 0 0.25rem; }
.settings-group + .settings-group { border-top: 1px solid var(--line); margin-top: 0.5rem; }
.settings-group h3 {
  margin: 0 0 0.9rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent);
}
#settings fieldset { margin: 0 0 1.1rem; min-width: 0; }
#settings legend { font-weight: 600; font-size: 0.95rem; margin-bottom: 0.5rem; padding: 0; }
#settings label { margin: 0; min-height: 0; }
/* Each radio covers its whole option, unseen, so the option is the control. */
#settings input[type="radio"] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer; z-index: 1;
}
#settings input[type="radio"]:disabled { cursor: default; }
.fieldset-note { margin: 0.5rem 0 0; color: var(--muted); font-size: 0.85rem; line-height: 1.4; flex-basis: 100%; }

/* A line of the book, set as the reader has chosen. */
.preview {
  margin: 0 0 1.1rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  background: var(--card);
  max-height: 11rem;
  overflow: hidden;
  position: relative;
}
.preview::after {
  content: ""; position: absolute; inset: auto 0 0; height: 2rem;
  background: linear-gradient(transparent, var(--card));
}
.preview p {
  margin: 0;
  font-family: var(--read-font);
  font-size: var(--text-size);
  line-height: var(--line-height);
  letter-spacing: var(--letter-spacing);
  word-spacing: var(--word-spacing);
}

/* Segmented controls: one rounded track, the chosen option raised in it. */
#settings .segmented {
  display: flex; flex-wrap: wrap; gap: 0;
}
#settings .segmented > label {
  flex: 1 1 0;
  position: relative;
  display: grid; place-items: center;
  min-height: 44px;
  padding: 0.45rem 0.6rem;
  text-align: center;
  font-size: 0.92rem;
  line-height: 1.25;
  color: var(--muted);
  background: color-mix(in srgb, var(--line) 55%, transparent);
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease, box-shadow 150ms ease;
}
#settings .segmented > label:first-of-type { border-radius: 0.8rem 0 0 0.8rem; }
#settings .segmented > label:last-of-type { border-radius: 0 0.8rem 0.8rem 0; }
#settings .segmented > label + label { border-left: 1px solid var(--paper); }
/* Speed has nine choices: small pills in one row, or three rows of three on phones. */
#settings .segmented.speeds {
  display: grid; grid-template-columns: repeat(9, 1fr); gap: 4px;
}
#settings .segmented.speeds > label {
  border-radius: 0.6rem; border-left: 0; padding: 0.45rem 0;
  font-size: 0.85rem; font-variant-numeric: tabular-nums; white-space: nowrap;
}
@media (max-width: 560px) {
  #settings .segmented.speeds { grid-template-columns: repeat(3, 1fr); }
  #settings .segmented.speeds > label { font-size: 0.92rem; }
}
#settings .segmented > label:has(input:checked) {
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
#settings .segmented > label:hover:not(:has(input:checked, input:disabled)) { color: var(--ink); }
#settings label:has(input:focus-visible) { outline: 3px solid var(--accent); outline-offset: 2px; z-index: 1; }
#settings label:has(input:disabled) { opacity: 0.45; cursor: default; }
.sizes .glyph {
  font-family: ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-weight: 600;
  line-height: 1;
}
.sizes label:nth-of-type(1) .glyph { font-size: 0.95rem; }
.sizes label:nth-of-type(2) .glyph { font-size: 1.2rem; }
.sizes label:nth-of-type(3) .glyph { font-size: 1.5rem; }
.sizes label:nth-of-type(4) .glyph { font-size: 1.85rem; }

/* Colors: a small page in each, so the choice is seen, not read. */
#settings .swatches { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.6rem; }
#settings .swatches legend { grid-column: 1 / -1; }
#settings .swatches > label {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 0.45rem;
  padding: 0.6rem 0.4rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  font-size: 0.85rem; text-align: center; line-height: 1.2;
  cursor: pointer;
}
#settings .swatches > label:has(input:checked) {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--accent);
  font-weight: 600;
}
.swatch {
  display: flex; flex-direction: column; justify-content: center; gap: 0.3rem;
  width: 100%; height: 3.6rem;
  padding: 0 0.8rem;
  border-radius: 0.5rem;
  border: 1px solid rgb(0 0 0 / 0.08);
}
.swatch i { display: block; height: 0.3rem; border-radius: 999px; }
.swatch i:nth-child(2) { width: 80%; }
.swatch i:nth-child(3) { width: 55%; }
.swatch.light { background: #fbf7ef; }
.swatch.light i { background: #1f1d1a; opacity: 0.75; }
.swatch.light i:first-child { background: #ffd86b; opacity: 1; }
.swatch.dark { background: #1d1b18; border-color: rgb(255 255 255 / 0.1); }
.swatch.dark i { background: #f1ebe0; opacity: 0.8; }
.swatch.dark i:first-child { background: #ffd86b; opacity: 1; }
.swatch.system { background: linear-gradient(90deg, #fbf7ef 0 50%, #1d1b18 50% 100%); }
.swatch.system i { background: #8f877b; }
.swatch.system i:first-child { background: #ffd86b; opacity: 1; }

/* Choices with a line saying what each does. */
#settings .choices { display: flex; flex-direction: column; gap: 0.5rem; }
#settings .choices > label {
  position: relative;
  display: flex; align-items: flex-start; gap: 0.8rem;
  padding: 0.8rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
}
#settings .choices > label::before {
  content: "";
  box-sizing: border-box;
  flex: none;
  width: 1.15rem; height: 1.15rem; margin-top: 0.1rem;
  border-radius: 999px;
  border: 2px solid color-mix(in srgb, var(--ink) 35%, transparent);
  background: var(--paper);
  transition: border-color 150ms ease, border-width 150ms ease;
}
#settings .choices > label:has(input:checked) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, var(--paper));
}
#settings .choices > label:has(input:checked)::before { border: 0.36rem solid var(--accent); }
.choice { display: flex; flex-direction: column; gap: 0.15rem; }
.choice-title { font-weight: 600; }
.choice-note { color: var(--muted); font-size: 0.86rem; line-height: 1.35; }

/* On and off: switches, one row each. */
#settings .switches > label {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 1rem;
  padding: 0.7rem 0;
  min-height: 48px;
  cursor: pointer;
}
#settings .switches > label + label { border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
#settings .switches .unavailable { order: 3; flex-basis: 100%; color: var(--muted); font-size: 0.85rem; }
input[role="switch"] {
  appearance: none;
  flex: none;
  position: relative;
  width: 2.9rem; height: 1.7rem; margin: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 22%, transparent);
  cursor: pointer;
  transition: background-color 150ms ease;
}
input[role="switch"]::after {
  content: "";
  box-sizing: border-box;
  position: absolute; top: 0.2rem; left: 0.2rem;
  width: 1.3rem; height: 1.3rem;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.25);
  transition: transform 150ms ease;
}
input[role="switch"]:checked { background: var(--accent); }
input[role="switch"]:checked::after { transform: translateX(1.2rem); }
input[role="switch"]:disabled { opacity: 0.45; cursor: default; }

.offline-card {
  display: flex; gap: 0.9rem; align-items: flex-start;
  padding: 1rem 1.1rem;
  border-radius: 0.9rem;
  background: var(--reading);
}
.offline-card > svg {
  flex: none; width: 1.6rem; height: 1.6rem; margin-top: 0.1rem;
  fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.offline-card p { margin: 0 0 0.75rem; line-height: 1.4; }
.offline-card button { background: var(--paper); }
#offline-status { margin: 0.6rem 0 0; color: var(--muted); font-size: 0.88rem; }
#offline-status:empty { display: none; }

.settings-foot {
  display: flex; justify-content: flex-end;
  padding: 0.75rem 1.5rem calc(0.75rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
}
.settings-foot .primary { min-width: 8rem; }

@media (max-width: 560px) {
  .settings-body { padding-inline: 1.1rem; }
  .settings-foot { padding-inline: 1.1rem; }
  .settings-foot .primary { flex: 1; }
}
@media (prefers-reduced-motion: reduce) {
  #settings .segmented > label, #settings .choices > label, input[role="switch"], input[role="switch"]::after { transition: none; }
}

/* Fonts: each choice shown in its own letters (reader-fonts.md, FO2). */
#settings .fonts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
#settings .fonts legend { grid-column: 1 / -1; }
#settings .fonts > label {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-content: center;
  column-gap: 0.75rem;
  row-gap: 0.15rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  background: var(--card);
  cursor: pointer;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
#settings .fonts .face {
  grid-row: 1 / span 2;
  display: grid; place-items: center;
  width: 2.75rem; height: 2.75rem;
  border-radius: 0.6rem;
  background: color-mix(in srgb, var(--line) 45%, transparent);
  font-size: 1.35rem;
  line-height: 1;
  color: var(--ink);
}
#settings .font-name { font-size: 0.9rem; font-weight: 600; line-height: 1.2; }
#settings .fonts .font-name { align-self: end; }
#settings .font-note { align-self: start; font-size: 0.78rem; line-height: 1.3; color: var(--muted); }
@media (max-width: 480px) {
  #settings .fonts { grid-template-columns: minmax(0, 1fr); }
}
#settings [data-face="device"] .face { font-family: var(--font-device); }
#settings [data-face="serif"] .face { font-family: var(--font-serif); }
#settings [data-face="atkinson"] .face { font-family: var(--font-atkinson); }
#settings [data-face="lexend"] .face { font-family: var(--font-lexend); }
#settings [data-face="andika"] .face { font-family: var(--font-andika); }
#settings [data-face="opendyslexic"] .face { font-family: var(--font-opendyslexic); font-size: 1.15rem; }
#settings [data-face="lato"] .face { font-family: var(--font-lato); }
#settings [data-face="open-sans"] .face { font-family: var(--font-open-sans); }
#settings [data-face="courier-prime"] .face { font-family: var(--font-courier-prime); }
#settings .fonts .fieldset-note { grid-column: 1 / -1; margin-top: 0.1rem; }
#settings .fonts > label:hover:not(:has(input:checked)) { border-color: color-mix(in srgb, var(--ink) 25%, transparent); }
#settings .fonts > label:has(input:checked) {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
#settings .fonts > label:has(input:checked) .face { background: var(--accent); color: var(--accent-ink); }
#settings .fonts > label:has(input:checked) .font-name { color: var(--accent); }

/* Code fonts: one row each, with symbols set in the font as the switch below says. */
#settings .code-fonts { margin-bottom: 0.4rem; }
#settings .code-fonts .rows {
  display: flex; flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  background: var(--card);
  overflow: hidden;
}
#settings .code-fonts label {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-height: 48px;
  padding: 0.55rem 1rem;
  cursor: pointer;
}
#settings .code-fonts label + label { border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
#settings .code-fonts .font-name { font-weight: 500; }
#settings .code-fonts label:has(input:checked) { background: color-mix(in srgb, var(--accent) 10%, var(--card)); }
#settings .code-fonts label:has(input:checked) .font-name { color: var(--accent); font-weight: 600; }
#settings .code-fonts label:has(input:checked)::after {
  content: ""; position: absolute; left: 0; top: 0.6rem; bottom: 0.6rem; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--accent);
}
.code-sample {
  flex: none;
  font-size: 1rem;
  letter-spacing: 0;
  font-variant-ligatures: var(--code-ligatures);
  color: var(--ink);
}
[data-code-face="device"] .code-sample { font-family: var(--code-device); }
[data-code-face="jetbrains"] .code-sample { font-family: var(--code-jetbrains); }
[data-code-face="fira"] .code-sample { font-family: var(--code-fira); }
[data-code-face="cascadia"] .code-sample { font-family: var(--code-cascadia); }
[data-code-face="atkinson-mono"] .code-sample { font-family: var(--code-atkinson-mono); }

/* Sound it out (sounds-and-practice.md, stage S-C): one word, its letters grouped by
   the sounds they spell, lit as each sound plays. A small sheet, so the page stays in
   view behind it. */
dialog.sheet.sound {
  margin: auto auto 6rem;
  width: min(30rem, calc(100vw - 2rem));
  height: fit-content;
  border-radius: 1.25rem;
  border-width: 1px;
}
.sound .sheet-head h2 { margin: 0; }
.sound-body { padding: 1.25rem 1.5rem 1.5rem; display: flex; flex-direction: column; gap: 1.1rem; }
.sound-letters {
  margin: 0;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 0.35rem;
  font-family: var(--read-font); font-size: 3rem; line-height: 1.2;
}
.sound-letters .letters {
  font: inherit; line-height: inherit;
  min-height: 0; padding: 0.05em 0.2em;
  border: 1px solid var(--line); border-radius: 0.6rem;
  background: var(--paper); color: var(--ink);
}
.sound-letters span.letters { border-color: transparent; }
.sound-letters .letters.tricky { text-decoration: underline dotted; text-underline-offset: 0.18em; }
.sound-letters .letters.lit { background: var(--heard); color: var(--heard-ink); border-color: var(--heard); }
.sound-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.sound-actions button { min-width: 8rem; }
#sound-credit { text-align: center; }
@media (max-width: 560px) {
  dialog.sheet.sound {
    margin: auto 0 0;
    width: 100vw; max-width: 100vw;
    height: fit-content;
    border-radius: 1.25rem 1.25rem 0 0;
    border-width: 1px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
}

/* Footnotes and endnotes (accessible-content.md, AC13, AC14). A marker is a small
   button where the book had its number; a note body is set smaller where it stands. */
#text .noteref {
  display: inline-grid;
  place-items: center;
  min-width: 1.6em;
  min-height: 1.6em;
  margin: 0 0.1em;
  padding: 0 0.3em;
  vertical-align: super;
  font-family: system-ui, sans-serif;
  font-size: 0.6em;
  line-height: 1;
  color: var(--accent);
  border-color: var(--accent);
  position: relative;
}
/* A target at least 44px square, larger than the mark itself. */
#text .noteref::after { content: ""; position: absolute; inset: -0.9rem -0.6rem; }
#text p.note { font-size: 0.85em; color: var(--muted); }
dialog.sheet.note-sheet {
  margin: auto 0 0 auto;
  height: fit-content;
  max-height: 70dvh;
  border-radius: 1.25rem 0 0 0;
  border-width: 1px 0 0 1px;
}
.note-text { margin: 0; padding: 1.25rem 1.5rem; overflow-y: auto; font-size: 1.1rem; line-height: 1.6; }
.note-actions { display: flex; gap: 0.75rem; justify-content: flex-end; padding: 0 1.5rem 1.25rem; }
@media (max-width: 560px) {
  dialog.sheet.note-sheet { margin: auto 0 0; width: 100vw; border-radius: 1.25rem 1.25rem 0 0; border-width: 1px 0 0; }
}
