/* web/static/css/book-page.css: the book page, /novel/{id} ("Cover-Lit Edition").
   Markup: web/templates/novel_details.html. Behaviour: static/js/book-page.js (inline
   play, running head, capsule, menus, show-all) and the mini-player
   (static/js/library-player.js, styled by library-card.css).

   Hand-written and served as-is, like components.css: nothing here needs a Tailwind
   rebuild. Cache-busted with BOOK_PAGE_CSS_VERSION (web/main.py).

   Rules the page keeps:
   - Everything is scoped under .bk (the page's <main>) so ended_novel_details.html,
     which extends the same template, keeps its own look.
   - One light source: the cover's, pre-blurred on the server (--amb, a 48px WebP) and
     a lamp colour normalised in OKLCH (--lamp). No CSS filter anywhere in the hero;
     backdrop-filter only on the two floating controls (running head, capsule).
   - Teal only on things you can press, and one teal object above the fold.
   - Stone ink only; #A8A29E is the dimmest text. Tabular numerals for every number
     that changes from row to row.
   - Hover lives behind (hover: hover); focus is a 2px #F5F5F4 ring (a teal ring would
     vanish on the teal button).
   - These rules are unlayered and Tailwind's utilities sit in @layer utilities, so a
     rule here outranks any utility class the page's older scripts still toggle. That
     is how the export, audio and review scripts keep working on this markup; it also
     means `.hidden` needs the explicit guard below. */

.bk {
  /* Brand tokens (input.css @theme); the one addition is the teal's hover. */
  --color-primary-lighter: #2DD4BF;
  --bk-ink-1: var(--color-text-heading, #F5F5F4);
  --bk-ink-2: var(--color-text-body, #D6D3D1);
  --bk-ink-3: var(--color-text-muted, #A8A29E);
  --bk-ground: var(--color-bg-base, #09090B);
  --bk-raised: var(--color-bg-subtle, #18181B);
  --bk-track: var(--color-bg-muted, #27272A);
  --bk-press: var(--color-primary-light, #14B8A6);
  --bk-press-hover: var(--color-primary-lighter);
  --bk-press-ink: var(--color-bg-base, #09090B);
  --bk-ok: var(--color-success, #22C55E);
  --bk-warn: var(--color-warning, #F59E0B);
  --bk-rule: var(--color-border-subtle, rgb(245 245 244 / .08));
  --bk-rule-row: rgb(245 245 244 / .06);
  --bk-ring-line: var(--color-border-default, rgb(245 245 244 / .12));
  --bk-tonal: rgb(245 245 244 / .10);
  --bk-tonal-hover: rgb(245 245 244 / .16);
  --bk-icon-fill: rgb(245 245 244 / .08);
  --bk-icon-hover: rgb(245 245 244 / .14);
  --bk-row-hover: rgb(245 245 244 / .05);
  --bk-ease-out: cubic-bezier(.16, 1, .3, 1);
  --bk-display: var(--font-heading, "DM Serif Display", Georgia, serif);
  --bk-body: var(--font-body, "Plus Jakarta Sans", system-ui, sans-serif);
  --bk-wrap: min(1200px, 100% - 128px);
  --bk-nav-h: 64px;

  /* The light. novel_details.html prints the book's own values inline; these are the
     neutral warm smoke for a cover with no palette yet (and for no cover at all). */
  --tint: #211f1d;
  --lamp: 177 169 164;
  --g: .6;
  --lo: .44;
  --amb: none;
  --scrim: 0;
  --scrim-t: 0;

  display: block;
  overflow-x: clip;                     /* contains the light without a scroll container */
  color: var(--bk-ink-1);
  font-family: var(--bk-body);
  -webkit-font-smoothing: antialiased;
}
@media (max-width: 1023.98px) { .bk { --bk-nav-h: 56px; } }
@media (max-width: 767.98px) { .bk { --bk-wrap: calc(100% - 32px); } }

/* The page's older scripts toggle Tailwind's .hidden on elements this sheet gives a
   display (progress lines, share icons, the free-sample card). Unlayered rules beat
   the layered utility, so the hook has to win here, as in the navbar. */
.bk .hidden { display: none !important; }

/* The cover is the only light: the navbar's teal ambient stays off on this page. */
body:has(> main.bk) .nh-nav__amb { display: none; }

/* Resets at zero specificity, so every single-class rule below (.bk-mbtn, .bk-icon,
   .bk-link…) still sets its own font and colour. */
:where(.bk) a { color: inherit; text-decoration: none; }
.bk :is(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--bk-ink-1);
  outline-offset: 3px;
  border-radius: 4px;
}
:where(.bk) button { font: inherit; color: inherit; cursor: pointer; }
.bk-wrap { width: var(--bk-wrap); margin-inline: auto; }
.bk-sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.bk-sep { opacity: .5; margin: 0 8px; }
.bk-only-m { display: none; }

/* ── Owner Manage bar: a row in normal flow between the nav and the hero ── */
.bk-manage {
  position: relative; z-index: 4;       /* its "…" menu opens over the hero */
  background: rgb(24 24 27 / .6);
  box-shadow: inset 0 -1px 0 rgb(245 245 244 / .10);
}
.bk-manage__row {
  min-height: 56px; padding: 10px 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px;
}
.bk-manage__status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; }
.bk-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.bk-chip {
  height: 28px; display: inline-flex; align-items: center; gap: 8px; padding: 0 10px; border-radius: 8px;
  background: rgb(245 245 244 / .06); font: 500 13px/18px var(--bk-body); color: var(--bk-ink-2);
  white-space: nowrap;
}
.bk-chip__sub { color: var(--bk-ink-3); font-variant-numeric: tabular-nums; }
.bk-dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--bk-ink-2); }
.bk-dot--ok { background: var(--bk-ok); }
.bk-dot--warn { background: var(--bk-warn); }
.bk-dot--off { background: transparent; box-shadow: inset 0 0 0 1.5px var(--bk-ink-3); }
.bk-manage__spent { font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); font-variant-numeric: tabular-nums; }
.bk-manage__actions { display: flex; align-items: center; gap: 8px; }
/* Chips and actions share one height (36) and one radius family. */
.bk-mbtn {
  height: 36px; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 14px; border: 0; border-radius: 10px; white-space: nowrap;
  font: 600 14px/20px var(--bk-body); color: var(--bk-ink-1); background: transparent;
  transition: background-color .15s ease;
}
.bk-mbtn svg { width: 16px; height: 16px; flex: none; }
.bk-mbtn--tonal { background: var(--bk-tonal); }
/* The contextual action takes the page's one teal fill. The audio scripts toggle
   status utilities (bg-amber-600, bg-red-600, bg-teal-600) on #generateAudioBtn;
   status colours never fill a button, so the teal wins over all of them. */
.bk .bk-mbtn--teal, .bk #generateAudioBtn { background: var(--bk-press); color: var(--bk-press-ink); }
.bk #generateAudioBtn.bk-mbtn--tonal { background: var(--bk-tonal); color: var(--bk-ink-1); }   /* behind "Publish changes" */
.bk #generateAudioBtn:disabled { opacity: .6; cursor: default; }
#audioGenContainer { display: inline-flex; }
.bk-more { position: relative; }
.bk-more > summary {
  width: 36px; height: 36px; display: grid; place-items: center; list-style: none; border-radius: 10px;
  background: var(--bk-icon-fill); box-shadow: inset 0 0 0 1px var(--bk-ring-line); cursor: pointer;
}
.bk-more > summary::-webkit-details-marker { display: none; }
.bk-more > summary svg { width: 18px; height: 18px; }
.bk-more > .bk-menu { top: calc(100% + 8px); right: 0; }
.bk-manage__panel { padding: 0 0 12px; display: grid; gap: 10px; }
.bk-manage__panel:empty { display: none; }
.bk-note { margin: 0; font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); }
@media (hover: hover) {
  .bk-mbtn--tonal:hover, .bk-mbtn--ghost:hover { background: var(--bk-tonal-hover); }
  .bk .bk-mbtn--teal:hover, .bk #generateAudioBtn:not(:disabled):hover { background: var(--bk-press-hover); }
  .bk-more > summary:hover { background: var(--bk-icon-hover); }
}
@media (max-width: 767.98px) {
  /* nowrap: a wrapping column is as wide as its widest item (the chips), not the screen. */
  .bk-manage__row { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .bk-manage__status { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-right: -16px; padding-right: 16px; }
  .bk-manage__status::-webkit-scrollbar { display: none; }
  .bk-chips { flex-wrap: nowrap; }
  .bk-manage__actions { flex-wrap: wrap; position: relative; }
  /* The "…" sits near the left of the row: its menu hangs from the row's left edge
     (inside the gutter), not from the button's right edge, off the screen. */
  .bk-more { position: static; }
  .bk-more > .bk-menu { left: 0; right: auto; }
  .bk-manage__actions > :first-child:is(.bk-mbtn--teal, #audioGenContainer, #detailPublishAllBtn) { flex: 1 0 100%; height: 44px; }
  .bk-manage__actions > #audioGenContainer:first-child #generateAudioBtn { width: 100%; height: 44px; }   /* second, it keeps the row's 36px */
}

/* One line of progress, never a card: recording (owner), voice preparation (import),
   an audio export. The bars are stone, not teal: nothing here can be pressed. */
.bk-progress { display: grid; gap: 8px; }
.bk-progress__line {
  margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px;
  font: 500 13px/18px var(--bk-body); color: var(--bk-ink-2); font-variant-numeric: tabular-nums;
}
.bk-progress__line .bk-sep { margin: 0; }
.bk-progress__track { height: 2px; border-radius: 1px; background: var(--bk-track); overflow: hidden; }
.bk-progress__track > div {
  height: 100%; background: rgb(245 245 244 / .85); border-radius: 1px; transition: width .3s linear;
}
/* The audio scripts paint a running job teal or amber; keep it stone. A finished
   (green) or failed (red) job keeps its semantic colour. */
.bk #audioProgressBar:not(.bg-green-500):not(.bg-red-500),
.bk #exportProgressBar { background: var(--bk-ink-2); }
.bk #audioProgressPercent:not(.text-green-400):not(.text-red-400) { color: var(--bk-ink-2); }
.bk #audioProgressLabel { color: var(--bk-ink-1); }
.bk #voicePrepBanner .bk-progress__track > div { background: var(--bk-ink-2); }
/* Play follows its label, not the far edge of the bar. */
.bk-sample {
  display: flex; align-items: center; justify-content: flex-start; gap: 12px;
  font: 500 13px/18px var(--bk-body); color: var(--bk-ink-2);
}
.bk-sample__title { color: var(--bk-ink-1); font-weight: 600; }
.bk-sample__detail { color: var(--bk-ink-3); }
.bk #freeSamplePlay { height: 36px; min-height: 36px; padding: 0 14px; border-radius: 10px; }

/* ── Hero: the cover as an object in a pool of its own light ── */
.bk-hero { position: relative; isolation: isolate; padding: 56px 0 72px; }
/* An open menu in the hero must paint over the sections below it (which sit above the
   light's overhang the rest of the time). */
.bk-hero:has(.bk-menu:not([hidden]), .inline-select-menu, .cover-menu.is-open) { z-index: 3; }
.bk-hero__grid {
  --cover: clamp(280px, calc(100vh - 168px - var(--bk-manage-h, 0px)), 384px);
  display: grid; grid-template-columns: var(--cover) minmax(0, 1fr); column-gap: 56px; align-items: end;
}
@supports (height: 100svh) {
  .bk-hero__grid { --cover: clamp(280px, calc(100svh - 168px - var(--bk-manage-h, 0px)), 384px); }
}
.bk--owner { --bk-manage-h: 56px; }
.bk-stage { position: relative; width: var(--cover); }
.bk-pool {
  position: absolute; left: 50%; top: 50%; width: 1680px; height: 1180px; z-index: -1;
  transform: translate(-50%, -50%); pointer-events: none;
}
.bk-pool::before {
  content: ""; position: absolute; inset: 0; background: var(--amb) center / cover; opacity: var(--lo);
  --m: radial-gradient(closest-side, #000, rgb(0 0 0 / .92) 14%, rgb(0 0 0 / .76) 28%, rgb(0 0 0 / .54) 42%,
       rgb(0 0 0 / .32) 56%, rgb(0 0 0 / .15) 70%, rgb(0 0 0 / .05) 84%, transparent);
  -webkit-mask-image: var(--m); mask-image: var(--m);
}
.bk-pool::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(closest-side at 50% 44%, rgb(var(--lamp) / calc(.373 * var(--g))),
              rgb(var(--lamp) / calc(.133 * var(--g))) 45%, rgb(var(--lamp) / 0) 88%);
}
.bk-cover {
  position: relative; margin: 0; width: var(--cover); aspect-ratio: 1; border-radius: 6px; background: var(--tint);
  box-shadow: 0 1px 2px rgb(0 0 0 / .45), 0 8px 16px -4px rgb(0 0 0 / .35), 0 32px 64px -16px rgb(0 0 0 / .7);
}
.bk-cover picture, .bk-cover img { display: block; width: 100%; height: 100%; border-radius: inherit; }
.bk-cover img { object-fit: cover; }
.bk-cover::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .08), inset 0 1px 0 rgb(255 255 255 / .10);
}
/* Radiosity: the pre-blurred cover under the object, no CSS filter. */
.bk-bloom {
  position: absolute; inset: 2% -4% -10%; z-index: -1; pointer-events: none;
  background: var(--amb) center / cover; opacity: .6; transform: translateY(20px);
  -webkit-mask-image: radial-gradient(closest-side, #000 40%, rgb(0 0 0 / .5) 70%, transparent);
          mask-image: radial-gradient(closest-side, #000 40%, rgb(0 0 0 / .5) 70%, transparent);
}
/* No cover: a typeset jacket of the same size and radius. */
.bk-jacket {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  padding: 40px 32px; text-align: center; container-type: inline-size;
}
.bk-jacket::before {
  content: ""; position: absolute; inset: 16px; border-radius: 2px; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgb(245 245 244 / .10);
}
.bk-jacket__title {
  margin: 0; font: 400 9cqi/1.15 var(--bk-display); color: var(--bk-ink-1); text-wrap: balance;
  overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; overflow: hidden;
}
.bk-jacket__rule { width: 24px; height: 1px; background: rgb(var(--lamp) / .5); }
.bk-jacket__author {
  margin: 0; max-width: 100%; font: 600 11px/14px var(--bk-body); letter-spacing: .2em; text-transform: uppercase; color: var(--bk-ink-2);
  overflow-wrap: anywhere;                 /* a long username wraps inside the frame */
}
/* (.bk-cover img would otherwise stretch the mark to the cover's size) */
.bk-cover .bk-jacket__mark { position: absolute; bottom: 28px; left: 50%; width: 16px; height: 16px; margin-left: -8px; opacity: .5; }

/* Owner: the cover's change control, a 36px glass circle (the only blur in the hero
   is on this 36px button). Visible on hover / focus; always at 60% on touch. */
.bk .cover-edit { position: absolute; top: 12px; left: 12px; z-index: 6; }
.bk .cover-change-btn {
  width: 36px; height: 36px; border-radius: 50%; color: var(--bk-ink-1);
  background: rgb(9 9 11 / .6); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 0; box-shadow: inset 0 0 0 1px rgb(255 255 255 / .14);
}
@media (hover: hover) {
  .bk .cover-change-btn { opacity: 0; transition: opacity .15s ease, background-color .15s ease; }
  .bk-cover:hover .cover-change-btn, .bk .cover-edit:focus-within .cover-change-btn,
  .bk .cover-change-btn[aria-expanded="true"] { opacity: 1; }
  .bk .cover-change-btn:hover { background: rgb(9 9 11 / .8); }
}
@media (hover: none) { .bk .cover-change-btn { opacity: .6; } }
.bk .cover-edit-status { position: absolute; left: 12px; right: 12px; bottom: 12px; margin: 0; z-index: 6; }

/* The title block, bottom-aligned to the cover. */
.bk-head { position: relative; min-width: 0; container: bk-head / inline-size; }
/* The text's own shade: a bright cover's spill darkened behind the head column, just
   enough for #A8A29E text at 4.5:1 (book_page.text_scrim works the alpha out per
   cover; most covers need none). It starts inside the gap, never over the cover, and
   fades at every edge. It joins the hero's stacking context at z -1, after the pool. */
@media (min-width: 768px) {
  .bk-head::before {
    content: ""; position: absolute; z-index: -1; inset: -40px -96px -24px -32px; pointer-events: none;
    background: rgb(9 9 11 / var(--scrim-t, 0));
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 160px), transparent),
                        linear-gradient(transparent, #000 40px, #000 calc(100% - 24px), transparent);
    -webkit-mask-composite: source-in;
            mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 160px), transparent),
                        linear-gradient(transparent, #000 40px, #000 calc(100% - 24px), transparent);
            mask-composite: intersect;
  }
}
@media (min-width: 1280px) { .bk-head::before { background: rgb(9 9 11 / var(--scrim, 0)); } }
.bk-eyebrow {
  margin: 0 0 16px; font: 600 12px/16px var(--bk-body); letter-spacing: .08em; text-transform: uppercase;
  color: var(--bk-ink-2);
}
.bk-title {
  --t-fs: 60px; --t-lh: 62px;
  margin: 0; font-family: var(--bk-display); font-weight: 400; font-size: var(--t-fs); line-height: var(--t-lh);
  letter-spacing: -.012em; color: var(--bk-ink-1); text-wrap: balance; overflow-wrap: anywhere;
}
.bk-title.bk-t2 { --t-fs: 52px; --t-lh: 56px; }
.bk-title.bk-t3 { --t-fs: 40px; --t-lh: 46px; }
.bk-title.bk-t4 { --t-fs: 32px; --t-lh: 38px; }
.bk-tagline {
  margin: 12px 0 0; max-width: 36rem; font: italic 400 22px/30px var(--bk-display); color: var(--bk-ink-2);
  text-wrap: balance;
}
.bk-tagline--long { font-size: 18px; line-height: 28px; }
.bk-credit { margin: 16px 0 0; font: 400 15px/22px var(--bk-body); color: var(--bk-ink-2); }
.bk-credit a, .bk-credit b { color: var(--bk-ink-1); font-weight: 600; }
.bk-meta {
  margin: 6px 0 0; font: 500 14px/20px var(--bk-body); color: var(--bk-ink-3); font-variant-numeric: tabular-nums;
}
/* A segment never breaks inside; the line may break after its leading dot (the
   template strips the whitespace between segments, so the dot carries the only
   break opportunity, and a wrapped line ends on "·" the way it would on a comma). */
.bk-meta .bk-seg { white-space: nowrap; }
.bk-meta .bk-sep { opacity: .6; margin: 0 6px; white-space: normal; }
.bk-meta .bk-sep::after { content: "\200B"; }
.bk-meta .bk-seg:first-child > .bk-sep { display: none; }
.bk-free { color: var(--bk-ink-1); font-weight: 600; }
/* Icons that sit in a line of text (Tailwind's preflight makes every svg a block). */
.bk-check, .bk-star, .bk-dd-icon { display: inline-block; }
.bk-check { width: 12px; height: 12px; margin-right: 4px; vertical-align: -1px; color: var(--bk-ok); }
.bk-star { width: 12px; height: 12px; margin-right: 4px; vertical-align: -1px; color: var(--bk-ink-1); }
/* CJK titles: a few-KB Noto Serif subset (loaded only for these books), never a
   synthesized italic; sizes are 0.88x the Latin steps. */
.bk-title:lang(zh), .bk-tagline:lang(zh), .bk-lede:lang(zh), .bk-excerpt:lang(zh) p, .bk-jacket__title:lang(zh) {
  font-family: "Noto Serif SC", "Songti SC", "STSong", serif; font-weight: 600; font-style: normal;
}
.bk-title:lang(zh) { font-size: calc(var(--t-fs) * .88); line-height: 1.2; letter-spacing: .02em; }
.bk-tagline:lang(zh), .bk-lede:lang(zh) { font-size: 20px; line-height: 30px; font-weight: 400; }

/* ── Actions: one filled, then tonal, then icons ── */
.bk-actions { margin-top: 24px; display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
/* Play and Read are one pair: one height, one width (the wider label). */
.bk-pair { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 12px; flex: none; }
.bk-tools { display: flex; align-items: center; gap: 12px; }
.bk-btn {
  height: 52px; display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 0 24px 0 20px; border: 0; border-radius: 14px; white-space: nowrap;
  font: 600 16px/20px var(--bk-body); font-variant-numeric: tabular-nums;
  transition: background-color .15s ease, transform .09s ease;
}
.bk-btn > svg, .bk-btn__icon { width: 20px; height: 20px; flex: none; }
.bk-btn--teal { background: var(--bk-press); color: var(--bk-press-ink); }
.bk-btn--tonal { background: var(--bk-tonal); color: var(--bk-ink-1); }
.bk-btn--teal:active { transform: scale(.98); }
.bk-btn--tonal:active { transform: translateY(.5px); }
/* Save, Share, Download: a different control type, so their own width, but the
   pair's height and radius family. */
.bk-icon {
  width: 52px; height: 52px; flex: none; display: grid; place-items: center; padding: 0; border: 0;
  border-radius: 14px; background: var(--bk-icon-fill); box-shadow: inset 0 0 0 1px var(--bk-ring-line);
  color: var(--bk-ink-1); transition: background-color .15s ease, transform .09s ease;
}
.bk-icon svg { width: 20px; height: 20px; }
.bk-icon:active { transform: scale(.94); }
.bk-icon[aria-pressed="true"] svg, .bk-icon #bookmarkIcon[fill="currentColor"] { fill: currentColor; }
.bk-icon:disabled { opacity: .5; cursor: default; }
@media (hover: hover) {
  .bk-btn--teal:hover { background: var(--bk-press-hover); }
  .bk-btn--tonal:hover { background: var(--bk-tonal-hover); }
  .bk-icon:not(:disabled):hover { background: var(--bk-icon-hover); }
}

/* The Play icon follows the player (book-page.js sets data-state on every
   [data-inline-play] it mirrors): play at rest, a meter while playing, a ring while
   loading, retry after an error, an arrow once the chapter has ended. */
/* The label changes with the player ("Pause · Chapter 1"); a hidden copy of the
   resting label keeps the pair from shrinking under the reader's pointer. */
.bk-play__text { display: grid; }
.bk-play__text > span { grid-area: 1 / 1; }
.bk-play__sizer { visibility: hidden; }
.bk-play__icon { position: relative; width: 20px; height: 20px; flex: none; display: grid; place-items: center; }
.bk-play__icon > * { grid-area: 1 / 1; display: none; }
.bk-play__icon > .bk-g-play { display: block; width: 20px; height: 20px; }
.bk-g-retry, .bk-g-next { width: 18px; height: 18px; }
[data-state="playing"] > .bk-play__icon > .bk-g-play,
[data-state="loading"] > .bk-play__icon > .bk-g-play,
[data-state="error"] > .bk-play__icon > .bk-g-play,
[data-state="ended"] > .bk-play__icon > .bk-g-play { display: none; }
[data-state="playing"] > .bk-play__icon > .bk-meter { display: flex; }
[data-state="loading"] > .bk-play__icon > .bk-spin { display: block; }
[data-state="error"] > .bk-play__icon > .bk-g-retry { display: block; }
[data-state="ended"] > .bk-play__icon > .bk-g-next { display: block; }
.bk-meter { height: 14px; align-items: flex-end; gap: 2px; }
.bk-meter i { display: block; width: 3px; height: 6px; border-radius: 1px; background: currentColor; animation: bk-bar 900ms ease-in-out infinite alternate; }
.bk-meter i:nth-child(2) { height: 10px; animation-duration: 1100ms; animation-delay: -400ms; }
.bk-meter i:nth-child(3) { height: 8px; animation-duration: 800ms; animation-delay: -200ms; }
@keyframes bk-bar { from { height: 4px; } to { height: 14px; } }
.bk-spin {
  width: 16px; height: 16px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent;
  opacity: .9; animation: bk-turn .9s linear infinite;
}
@keyframes bk-turn { to { transform: rotate(360deg); } }

/* Menus (Share, Download, the owner's "…"): 240px, raised, equal-width rows. */
.bk-menu-wrap { position: relative; }
.bk-menu {
  position: absolute; z-index: 40; top: calc(100% + 8px); right: 0; width: 240px; padding: 6px;
  display: grid; gap: 2px; border-radius: 14px; background: var(--bk-raised);
  box-shadow: inset 0 0 0 1px var(--bk-ring-line), var(--shadow-overlay, 0 25px 60px rgb(0 0 0 / .55));
  text-align: left;
}
/* Opened upward where the screen has no room for it below (toggleExportOptions). */
.bk-menu.bk-menu--up { top: auto; bottom: calc(100% + 8px); }
.bk-menu__item {
  width: 100%; min-height: 44px; display: flex; align-items: center; gap: 12px; padding: 0 12px;
  border: 0; border-radius: 8px; background: transparent; text-align: left;
  font: 500 14px/20px var(--bk-body); color: var(--bk-ink-1); white-space: nowrap;
}
.bk-menu__item svg { width: 16px; height: 16px; flex: none; color: var(--bk-ink-2); }
.bk-menu__item:disabled { opacity: .5; cursor: default; }
.bk-menu__item:focus-visible { outline-offset: -2px; }
.bk-menu__sep { height: 1px; margin: 4px 6px; background: var(--bk-rule); }
@media (hover: hover) { .bk-menu__item:not(:disabled):hover { background: rgb(245 245 244 / .06); } }

/* Export progress: one line under the action row. */
.bk-head > #exportProgressCard { margin-top: 16px; max-width: 520px; }

/* ── Sections: hairline-separated, on the ground; the light fades out under the story ── */
.bk-body { position: relative; z-index: 1; }    /* above the light's overhang */
.bk-sec { width: var(--bk-wrap); margin-inline: auto; padding: 56px 0; }
.bk-sec + .bk-sec { box-shadow: inset 0 1px 0 var(--bk-rule); }
.bk-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 64px; row-gap: 40px; }
.bk-label {
  margin: 0 0 16px; font: 600 11px/16px var(--bk-body); letter-spacing: .08em; text-transform: uppercase;
  color: var(--bk-ink-3);
}
.bk-sechead { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; margin: 0 0 20px; }
.bk-h2 { margin: 0; font: 400 28px/32px var(--bk-display); letter-spacing: -.005em; color: var(--bk-ink-1); }
.bk-link {
  display: inline-flex; align-items: center; gap: 8px; padding: 0; border: 0; background: none;
  font: 600 14px/20px var(--bk-body); color: var(--bk-ink-1); font-variant-numeric: tabular-nums;
}
.bk-link svg { width: 14px; height: 14px; flex: none; }
@media (hover: hover) {
  .bk-link:not(:disabled):hover, .bk-credit a:hover, .bk-dd-link:hover {
    color: var(--bk-press); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px;
  }
}

/* The story */
.bk-story--solo { grid-template-columns: minmax(0, 1fr); }
.bk-lede { display: none; }
.bk-synopsis { margin: 0; max-width: 34em; font: 400 18px/30px var(--bk-body); color: var(--bk-ink-2); white-space: pre-line; }
.bk-subjects { margin: 20px 0 0; font: 500 14px/22px var(--bk-body); color: var(--bk-ink-3); }
/* Plain text, phrases wrap whole, and the line breaks after a "·" (the spans
   touch, so the separator's zero-width space is the break). The owner's editor
   rebuilds these spans with the chip classes (rebuildKeywordDisplay in
   novel-details.js); this outranks them. */
.bk .bk-subjects .keyword-tag {
  display: inline; padding: 0; border: 0; border-radius: 0; background: none;
  font: inherit; color: inherit; white-space: nowrap;
}
.bk .bk-subjects .keyword-tag + .keyword-tag::before {
  content: "·\200B"; content: "·\200B" / ""; opacity: .5; margin: 0 8px 0 6px; white-space: normal;
}
.bk-excerpt { margin: 0; }
.bk-excerpt p {
  margin: 0; text-indent: -.42em;          /* only the opening quote mark hangs */
  font: 400 24px/34px var(--bk-display); letter-spacing: -.005em; color: var(--bk-ink-2);
  text-wrap: pretty;
}
.bk-links { margin: 20px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; }
html:not(.js) .bk-hear { display: none; }

/* Chapters: a two-column contents page, every row server-rendered */
.bk-toc {
  list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 64px; column-rule: 1px solid var(--bk-rule);
}
.bk .chapter-list { max-height: none; overflow: visible; }   /* never a nested scroll (the legacy class is one) */
.bk-toc--one { columns: 1; max-width: 568px; }
.bk-toc > li { position: relative; break-inside: avoid; }
.bk-row__link {
  display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; column-gap: 16px; align-items: center;
  min-height: 48px; padding: 0 12px; margin: 0 -12px; border-radius: 8px;
  box-shadow: inset 0 -1px 0 var(--bk-rule-row); color: var(--bk-ink-2); transition: background-color .12s ease;
}
.bk-row__link:focus-visible { outline-offset: -2px; border-radius: 8px; }
.bk .bk-toc .chapter-number {
  min-width: 0; margin: 0; text-align: right; font: 500 14px/20px var(--bk-body); color: var(--bk-ink-3);
  font-variant-numeric: tabular-nums; transition: opacity .12s ease;
}
.bk .bk-toc .chapter-title {
  margin: 0; min-width: 0; font: 400 16px/24px var(--bk-body); color: var(--bk-ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bk-row__dur { font: 500 14px/20px var(--bk-body); color: var(--bk-ink-3); text-align: right; font-variant-numeric: tabular-nums; }
.bk-row__dur--text { font-size: 12px; line-height: 16px; }
/* The row's play control: a sibling of the link, over the number cell. Without
   JavaScript there is nothing for it to do, so it is not shown. */
.row-play {
  position: absolute; left: 0; top: 0; width: 28px; height: 47px; padding: 0; border: 0; border-radius: 6px;
  display: flex; align-items: center; justify-content: flex-end; background: transparent; color: var(--bk-ink-1);
  opacity: 0; transition: opacity .12s ease;
}
.row-play svg { width: 14px; height: 14px; }
.row-play .bk-g-pause, [data-state="playing"] > .row-play .bk-g-play { display: none; }
[data-state="playing"] > .row-play .bk-g-pause { display: block; }
html:not(.js) .row-play { display: none; }
.row-play:focus-visible { opacity: 1; }
.bk-toc > li:has(.row-play:focus-visible) .chapter-number { opacity: 0; }
@media (hover: hover) {
  .bk-row__link:hover, .bk-toc > li:has(.row-play:hover) .bk-row__link { background: var(--bk-row-hover); box-shadow: none; }
  .bk-row__link:hover .chapter-title, .bk-toc > li:has(.row-play:hover) .chapter-title { color: var(--bk-ink-1); }
  .bk-toc > li[data-has-audio="true"]:hover .row-play { opacity: 1; }
  .bk-toc > li[data-has-audio="true"]:hover .chapter-number { opacity: 0; }
}
/* Playing / paused (book-page.js): a teal meter where the number was, the title lit,
   the remaining time, and a 2px progress line at the played fraction (--p). */
.bk-toc > li[data-state] .chapter-title { color: var(--bk-ink-1); }
.bk-toc > li[data-state] .chapter-number { color: transparent; position: relative; }
.bk-toc > li[data-state] .chapter-number::after {
  content: ""; position: absolute; right: 0; top: 50%; width: 12px; height: 12px; margin-top: -6px;
  background:
    linear-gradient(var(--bk-press), var(--bk-press)) 0 100% / 2px 6px no-repeat,
    linear-gradient(var(--bk-press), var(--bk-press)) 5px 100% / 2px 12px no-repeat,
    linear-gradient(var(--bk-press), var(--bk-press)) 10px 100% / 2px 8px no-repeat;
  animation: bk-row-meter 1s ease-in-out infinite alternate;
}
.bk-toc > li[data-state="paused"] .chapter-number::after { animation-play-state: paused; }
@keyframes bk-row-meter {
  0% { background-size: 2px 4px, 2px 12px, 2px 7px; }
  50% { background-size: 2px 12px, 2px 5px, 2px 12px; }
  100% { background-size: 2px 7px, 2px 9px, 2px 4px; }
}
.bk-toc > li[data-state]::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 2px; border-radius: 1px; pointer-events: none;
  width: calc(clamp(0, var(--p, 0), 1) * 100%); background: var(--bk-press);
}
/* Show all: rows 25+ hide only when JavaScript can bring them back. */
html.js .bk-toc--long:not(.is-open) > li:nth-child(n+25) { display: none; }
html:not(.js) [data-toc-toggle] { display: none; }
.bk-toc__more { display: flex; margin: 24px auto 0; height: 44px; border-radius: 12px; padding: 0 20px; }
.bk-empty { margin: 0; font: 400 15px/22px var(--bk-body); color: var(--bk-ink-3); }

/* Ratings & reviews (only with at least one review) */
.bk-rating { margin: 0; display: flex; align-items: baseline; gap: 8px; font: 500 13px/20px var(--bk-body); color: var(--bk-ink-3); font-variant-numeric: tabular-nums; }
.bk-rating__n { font: 400 40px/40px var(--bk-display); color: var(--bk-ink-1); }
.bk-review-list { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }
.bk-review { padding: 20px; border-radius: 14px; background: rgb(245 245 244 / .04); }
.bk-review__stars { display: flex; gap: 2px; }
.bk-review__stars svg { width: 14px; height: 14px; color: rgb(245 245 244 / .25); }
.bk-review__stars svg.is-on { color: var(--bk-ink-1); }
.bk-review__text {
  margin: 10px 0 0; font: 400 15px/24px var(--bk-body); color: var(--bk-ink-2);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; overflow: hidden; white-space: pre-line;
}
.bk-review__by { margin: 12px 0 0; font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); }
.bk-more-reviews { margin-top: 24px; }
.bk-more-reviews > summary { list-style: none; cursor: pointer; }
.bk-more-reviews > summary::-webkit-details-marker { display: none; }
.bk-more-reviews[open] > summary { margin-bottom: 24px; }
/* updateReviewUI() writes its own (teal) button or link into #reviewButtonContainer;
   here it is a tonal 44px "Write a review" beside the heading. */
.bk #reviewButtonContainer:empty { display: none; }
.bk #reviewButtonContainer { margin: 0 0 20px; }
.bk #reviewButtonContainer > :is(button, a) {
  height: 44px; display: inline-flex; align-items: center; padding: 0 18px; border-radius: 12px;
  background: var(--bk-tonal); color: var(--bk-ink-1); font: 600 15px/20px var(--bk-body); text-decoration: none;
}
@media (hover: hover) { .bk #reviewButtonContainer > :is(button, a):hover { background: var(--bk-tonal-hover); color: var(--bk-ink-1); } }
.bk-review-form { margin: 0 0 24px; padding: 20px; border-radius: 14px; background: rgb(245 245 244 / .04); max-width: 640px; }
.bk-review-form h3 { margin: 0 0 16px; font: 600 16px/24px var(--bk-body); color: var(--bk-ink-1); }
.bk-review-form label { display: block; margin: 0 0 8px; font: 600 11px/16px var(--bk-body); letter-spacing: .08em; text-transform: uppercase; color: var(--bk-ink-3); }
.bk-review-form textarea {
  width: 100%; min-height: 112px; padding: 12px; border: 0; border-radius: 10px; resize: vertical;
  background: rgb(245 245 244 / .06); box-shadow: inset 0 0 0 1px var(--bk-ring-line); color: var(--bk-ink-1);
  font: 400 15px/22px var(--bk-body);
}
.bk-review-form textarea::placeholder { color: var(--bk-ink-3); }
.bk-review-form__stars { display: flex; gap: 4px; margin: 0 0 16px; }
/* Stars are stone, never yellow (setRating toggles text-yellow-400 for "selected"). */
.bk .star-btn {
  width: 36px; height: 36px; display: grid; place-items: center; padding: 0; border: 0; background: none;
  font-size: 24px; line-height: 1; color: rgb(245 245 244 / .25);
}
.bk .star-btn.text-yellow-400 { color: var(--bk-ink-1); }
.bk-review-form__actions { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 12px; margin-top: 16px; width: max-content; }
.bk-review-form__actions .bk-btn { height: 44px; border-radius: 12px; padding: 0 18px; }

/* Details: a dl in two columns, then the colophon */
.bk-dl { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 64px; }
.bk-dl__row {
  display: grid; grid-template-columns: 168px minmax(0, 1fr); column-gap: 16px; align-items: baseline; padding: 14px 0;
  box-shadow: inset 0 -1px 0 var(--bk-rule-row);
}
.bk-dl dt { font: 600 11px/16px var(--bk-body); letter-spacing: .08em; text-transform: uppercase; color: var(--bk-ink-3); }
.bk-dl dd { margin: 0; min-width: 0; font: 500 15px/22px var(--bk-body); color: var(--bk-ink-1); font-variant-numeric: tabular-nums; }
.bk-dl dd .bk-sep { opacity: .6; margin: 0 6px; }
.bk-dd-icon { width: 16px; height: 16px; margin-right: 8px; vertical-align: -3px; color: var(--bk-ink-3); }
.bk-formats { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.bk-formats .bk-link { font-size: 15px; line-height: 22px; font-weight: 500; }
.bk-formats .bk-link:disabled { opacity: .45; cursor: default; }   /* while an audio export runs */
.bk .field-empty { color: var(--bk-ink-3); font-style: italic; }
.bk-colophon { margin: 32px 0 0; max-width: 40em; font: italic 400 18px/28px var(--bk-display); color: var(--bk-ink-3); }
/* DM Serif Display's italic covers Latin only: a colophon in (or about a book in) a
   script it lacks is set upright, never slanted by the browser (the template adds the
   class for ja, zh, ko and hi pages, and for a Chinese book's title). */
.bk-colophon--upright { font-style: normal; }
/* Rate this book: logged-in readers, no reviews yet */
.bk-rate { margin: 24px 0 0; min-height: 56px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.bk-rate__label { font: 600 15px/20px var(--bk-body); color: var(--bk-ink-1); }
.bk-rate__stars { display: flex; gap: 4px; }
.bk-rate__star { width: 44px; height: 44px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 10px; background: none; color: var(--bk-ink-3); }
.bk-rate__star svg { width: 32px; height: 32px; }
@media (hover: hover) { .bk-rate__star:hover { color: var(--bk-ink-1); } }
.bk-details #reviewForm { margin-top: 24px; }

/* More like this: plain covers, no light, no listen discs */
.bk-shelf { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 24px; }
.bk-shelf__card { display: block; color: var(--bk-ink-1); }
.bk-shelf__card img {
  display: block; width: 100%; height: auto; aspect-ratio: 1; border-radius: 4px; background: var(--bk-raised);
  box-shadow: 0 1px 2px rgb(0 0 0 / .45), 0 18px 36px -14px rgb(0 0 0 / .75), inset 0 0 0 1px rgb(255 255 255 / .06);
  transition: transform .2s ease, box-shadow .2s ease;
}
.bk-shelf__title { display: block; margin: 14px 0 0; font: 400 18px/24px var(--bk-display); color: var(--bk-ink-1);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.bk-shelf__cap { display: block; margin: 4px 0 0; font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); font-variant-numeric: tabular-nums; }
.bk-shelf__card:focus-visible { outline: none; }
.bk-shelf__card:focus-visible img { outline: 2px solid var(--bk-ink-1); outline-offset: 3px; }
@media (hover: hover) {
  .bk-shelf__card:hover img { transform: translateY(-4px); box-shadow: 0 1px 2px rgb(0 0 0 / .45), 0 26px 44px -14px rgb(0 0 0 / .85), inset 0 0 0 1px rgb(255 255 255 / .06); }
  .bk-shelf__card:hover .bk-shelf__title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
}

/* The end mark */
.bk-end { display: flex; justify-content: center; padding: 24px 0 96px; }
.bk-end img { width: 20px; height: 20px; opacity: .4; }

/* ── Floating: the desktop running head and the mobile capsule (hidden until
   book-page.js shows them; both leave once the mini-player opens) ── */
.bk-runhead {
  position: fixed; top: var(--bk-nav-h); left: 0; right: 0; z-index: 30; height: 56px;
  background: rgb(9 9 11 / .78); -webkit-backdrop-filter: blur(20px) saturate(140%); backdrop-filter: blur(20px) saturate(140%);
  box-shadow: inset 0 -1px 0 rgb(255 255 255 / .08);
  transition: opacity .24s ease, transform .24s var(--bk-ease-out);
}
@starting-style { .bk-runhead { opacity: 0; transform: translateY(-8px); } }
.bk-runhead__in { height: 100%; display: flex; align-items: center; gap: 12px; }
.bk-runhead__art { width: 32px; height: 32px; flex: none; border-radius: 3px; object-fit: cover; background: var(--tint); }
.bk-runhead__title { margin: 0; flex: 1; min-width: 0; font: 400 18px/22px var(--bk-display); color: var(--bk-ink-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bk-runhead__by { margin-left: 8px; font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); }
.bk-runhead__meta { flex: none; font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bk-runhead .bk-btn { height: 36px; border-radius: 10px; padding: 0 14px 0 12px; gap: 8px; font-size: 14px; }
.bk-runhead .bk-play__icon, .bk-runhead .bk-play__icon > .bk-g-play { width: 16px; height: 16px; }
.bk-capsule {
  position: fixed; z-index: 45; left: 50%; transform: translateX(-50%);
  bottom: calc(16px + env(safe-area-inset-bottom) + var(--bk-lift, 0px));
  width: min(560px, 100% - 24px); height: 68px; padding: 0 12px;
  display: flex; align-items: center; gap: 12px; border-radius: 20px; overflow: hidden; isolation: isolate;
  background: rgb(24 24 27 / .86); -webkit-backdrop-filter: blur(24px) saturate(1.3); backdrop-filter: blur(24px) saturate(1.3);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / .1), 0 24px 60px rgb(0 0 0 / .6);
  transition: opacity .24s ease, transform .24s var(--bk-ease-out);
}
@starting-style { .bk-capsule { opacity: 0; transform: translate(-50%, 12px); } }
.bk-capsule::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(60% 140% at 0% 50%, rgb(var(--lamp) / .22), transparent 70%);
}
.bk-capsule__art { width: 44px; height: 44px; flex: none; border-radius: 4px; object-fit: cover; background: var(--tint); }
.bk-capsule__text { flex: 1; min-width: 0; }
.bk-capsule__title { margin: 0; font: 400 17px/21px var(--bk-display); color: var(--bk-ink-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bk-capsule__sub { margin: 2px 0 0; font: 500 13px/18px var(--bk-body); color: var(--bk-ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.bk-capsule__play { width: 44px; height: 44px; flex: none; display: grid; place-items: center; border-radius: 50%; background: var(--bk-press); color: var(--bk-press-ink); }
.bk-capsule__play .bk-play__icon, .bk-capsule__play .bk-play__icon > .bk-g-play { width: 18px; height: 18px; }
@media (hover: hover) { .bk-capsule__play:hover { background: var(--bk-press-hover); } }
/* book-page.js adds .is-shown a frame after it unhides a head and removes it 160ms
   before hiding it again: the transition runs both ways. */
.bk-runhead:not(.is-shown) { opacity: 0; transform: translateY(-8px); pointer-events: none; transition-duration: .16s; }
.bk-capsule:not(.is-shown) { opacity: 0; transform: translate(-50%, 12px); pointer-events: none; transition-duration: .16s; }
html.mini-open .bk-runhead, html.mini-open .bk-capsule { display: none; }
/* The navbar (a z-50 layer) drops a scroll veil 102px below itself, over where the
   running head sits. While the head shows, the veil stops at the bar: the head's
   own glass is the surface content slides under. */
@media (min-width: 1024px) {
  html:not(.mini-open) body:has(#bkRunHead:not([hidden])) .nh-nav__veil { bottom: 0; }
}
@media (max-width: 1023.98px) { .bk-runhead { display: none; } }
@media (min-width: 1024px) { .bk-capsule { display: none; } }

/* ── Entrance, once per load: the light fades in, the cover settles, the text block
   rises. The H1 never animates (it may be the LCP element), nor does anything below
   the hero. Only with JavaScript, and only without a reduced-motion preference.
   Fill backwards, never both: a finished animation must leave no transform behind, or
   each block keeps a stacking context and covers the owner's genre menu. ── */
@media (prefers-reduced-motion: no-preference) {
  html.js .bk-pool { animation: bk-fade 600ms ease-out backwards; }
  html.js .bk-cover { animation: bk-settle 480ms var(--bk-ease-out) backwards; }
  html.js .bk-bloom { animation: bk-fade 600ms ease-out 120ms backwards; }
  html.js :is(.bk-eyebrow, .bk-head > .bk-tagline, .bk-credit, .bk-meta, .bk-actions) {
    animation: bk-rise 320ms ease-out backwards;
  }
  html.js .bk-eyebrow { animation-delay: 80ms; }
  html.js .bk-head > .bk-tagline { animation-delay: 130ms; }
  html.js .bk-credit { animation-delay: 180ms; }
  html.js .bk-meta { animation-delay: 230ms; }
  html.js .bk-actions { animation-delay: 280ms; }
}
@keyframes bk-fade { from { opacity: 0; } }
@keyframes bk-settle { from { transform: translateY(8px); } }
@keyframes bk-rise { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) {
  .bk *, .bk *::before, .bk *::after { transition-duration: .12s !important; }
  .bk-meter i, .bk-spin, .bk-toc > li[data-state] .chapter-number::after { animation: none; }
  .bk-meter i:nth-child(1) { height: 6px; }
  .bk-meter i:nth-child(3) { height: 8px; }
  .bk-btn:active, .bk-icon:active, .bk-shelf__card:hover img { transform: none; }
  .bk-runhead, .bk-capsule { transition: opacity .12s ease; }
  @starting-style { .bk-runhead { transform: none; } .bk-capsule { transform: translateX(-50%); } }
  .bk-runhead:not(.is-shown) { transform: none; }
  .bk-capsule:not(.is-shown) { transform: translateX(-50%); }
}

/* ── Responsive ── */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  .bk-hero__grid { --cover: min(320px, clamp(280px, calc(100vh - 168px - var(--bk-manage-h, 0px)), 384px)); column-gap: 48px; }
  .bk-title { --t-fs: 52px; --t-lh: 56px; }
}
/* The action row follows the head column's own width (1440: 760px; 1280: 712px).
   Play, Read and three icons need ~714px at 12px gaps: a column a little short of
   that tightens the row; one that cannot hold it gives Play a row of its own, then
   Read and the icons share one cluster. */
@container bk-head (max-width: 759.98px) {
  .bk-actions, .bk-pair, .bk-tools { gap: 8px; }
  .bk-btn { padding: 0 20px 0 16px; }
}
/* A long Play label (novel_details.html: bk-actions--long) or one measured too wide
   for the row (book-page.js: bk-actions--wrap) takes this layout at every width. */
.bk-actions:is(.bk-actions--long, .bk-actions--wrap):not(.bk-actions--single) { gap: 8px; }
@media (min-width: 1024px) {
  .bk-actions:is(.bk-actions--long, .bk-actions--wrap):not(.bk-actions--single) { max-width: 560px; }   /* not a 760px bar */
}
.bk-actions:is(.bk-actions--long, .bk-actions--wrap):not(.bk-actions--single) :is(.bk-pair, .bk-tools) { display: contents; }
.bk-actions:is(.bk-actions--long, .bk-actions--wrap):not(.bk-actions--single) .bk-pair > :first-child { flex: 1 0 100%; }
.bk-actions:is(.bk-actions--long, .bk-actions--wrap):not(.bk-actions--single) .bk-pair > .bk-read:not(:first-child) { flex: 1; height: 48px; border-radius: 12px; }
.bk-actions:is(.bk-actions--long, .bk-actions--wrap):not(.bk-actions--single) .bk-tools .bk-icon { width: 48px; height: 48px; border-radius: 12px; }
@container bk-head (max-width: 679.98px) {
  .bk-pair, .bk-tools { display: contents; }
  .bk-pair > :first-child { flex: 1 0 100%; }
  .bk-pair > .bk-read:not(:first-child) { flex: 1; height: 48px; border-radius: 12px; }
  .bk-tools .bk-icon { width: 48px; height: 48px; border-radius: 12px; }
  .bk-actions--single .bk-tools .bk-icon, .bk-actions--single .bk-tools .bk-menu-wrap { flex: 1; width: auto; }
  .bk-actions--single .bk-menu-wrap > .bk-icon { width: 100%; }
}
@media (min-width: 768px) and (max-width: 1023.98px) {
  .bk-hero__grid { --cover: 280px; column-gap: 40px; }
  .bk-title { --t-fs: 44px; --t-lh: 48px; }
  .bk-title.bk-t2 { --t-fs: 38px; --t-lh: 42px; }
  .bk-title.bk-t3 { --t-fs: 32px; --t-lh: 38px; }
  .bk-title.bk-t4 { --t-fs: 28px; --t-lh: 34px; }
}
@media (max-width: 1023.98px) {
  .bk-two, .bk-dl, .bk-review-list { grid-template-columns: minmax(0, 1fr); }
  .bk-toc { columns: 1; }
  .bk-shelf { display: flex; overflow-x: auto; gap: 16px; margin: 0 -16px; padding: 0 16px 8px;
    scroll-snap-type: x mandatory; scroll-padding-inline: 16px; scrollbar-width: none; }
  .bk-shelf::-webkit-scrollbar { display: none; }
  .bk-shelf > li { flex: 0 0 144px; scroll-snap-align: start; }
  .bk-shelf__title { font-size: 16px; line-height: 22px; }
}
/* Touch (any width): the row's play control is a visible trailing button. */
@media (max-width: 767.98px), (hover: none) {
  .bk-row__link { min-height: 56px; }
  .bk-toc > li[data-has-audio="true"] .bk-row__link { padding-right: 56px; }
  .row-play { left: auto; right: -6px; top: 6px; width: 44px; height: 44px; justify-content: center; opacity: 1; border-radius: 50%; }
  .row-play::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgb(245 245 244 / .16); }
  .row-play svg { width: 12px; height: 12px; }
  .bk-toc > li[data-has-audio="true"]:hover .chapter-number { opacity: 1; }
}
@media (max-width: 767.98px) {
  .bk-only-d { display: none; }
  .bk-only-m { display: inline; }
  .bk-hero { padding: 24px 0 40px; }
  .bk-hero__grid {
    --cover: clamp(200px, calc(100vh - 392px - var(--bk-manage-h, 0px)), min(72vw, 288px));
    grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center;
  }
  @supports (height: 100svh) {
    .bk-hero__grid { --cover: clamp(200px, calc(100svh - 392px - var(--bk-manage-h, 0px)), min(72vw, 288px)); }
  }
  .bk-pool { width: 760px; height: 900px; }
  .bk-head { width: 100%; margin-top: 24px; }
  .bk-eyebrow { margin-bottom: 8px; font-size: 11px; line-height: 14px; }
  .bk-title { --t-fs: 36px; --t-lh: 40px; }
  .bk-title.bk-t2 { --t-fs: 30px; --t-lh: 34px; }
  .bk-title.bk-t3 { --t-fs: 26px; --t-lh: 32px; }
  .bk-title.bk-t4 { --t-fs: 22px; --t-lh: 28px; }
  .bk-head > .bk-tagline:not(.editable-field):not([data-field-display]) { display: none; }
  .bk-tagline { margin-inline: auto; }
  .bk-credit { margin-top: 8px; font-size: 14px; line-height: 20px; }
  .bk-meta { margin-top: 4px; font-size: 13px; line-height: 18px; }
  .bk-actions { margin-top: 20px; }
  .bk-head > #exportProgressCard { margin-inline: auto; text-align: left; }
  .bk-sec { padding: 40px 0; }
  .bk-two { row-gap: 40px; }
  .bk-lede { display: block; margin: 0 0 16px; font: italic 400 20px/28px var(--bk-display); color: var(--bk-ink-1); }
  .bk-synopsis { font-size: 16px; line-height: 26px; }
  .bk-excerpt p { text-indent: 0; font-size: 20px; line-height: 28px; }
  .bk-links { margin-top: 8px; gap: 0 24px; }
  .bk-links .bk-link { min-height: 44px; }
  .bk-sechead { margin-bottom: 12px; }
  .bk-h2 { font-size: 24px; line-height: 28px; }
  .bk-dl__row { grid-template-columns: 120px minmax(0, 1fr); column-gap: 12px; }
  .bk-dl dt { letter-spacing: .04em; hyphens: manual; }
  .bk-colophon { font-size: 17px; line-height: 26px; }
  .bk-toc__more { width: 100%; }
  html.js .bk-toc--long:not(.is-open) > li:nth-child(n+11) { display: none; }
  .bk-end { padding-bottom: calc(96px + 84px + env(safe-area-inset-bottom)); }
  .bk-menu { right: 0; }
  .bk-review-form__actions { width: 100%; }
}

/* ── Owner inline editing on this page's type ── */
.bk .editable-field { position: relative; }
.bk .editable-block { display: flex; align-items: flex-end; gap: 8px; }
.bk .editable-block > [data-field-display] { flex: 1; min-width: 0; }
.bk-head .editable-block { justify-content: inherit; }
.bk .field-edit-btn {
  position: relative; flex: none; width: 28px; height: 28px; padding: 0; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: var(--bk-icon-fill); color: var(--bk-ink-2);
  transition: opacity .15s ease, background-color .15s ease;
}
.bk .field-edit-btn::before { content: ""; position: absolute; inset: -2px; border-radius: 50%; }   /* 32px target */
.bk .field-edit-btn svg { width: 14px; height: 14px; }
@media (hover: hover) {
  .bk .editable-field .field-edit-btn { opacity: 0; }
  .bk .editable-field:hover .field-edit-btn, .bk .editable-field:focus-within .field-edit-btn,
  .bk .field-edit-btn[aria-expanded="true"] { opacity: 1; }
  .bk .field-edit-btn:hover { background: var(--bk-icon-hover); color: var(--bk-ink-1); }
}
.bk-eyebrow .editable-field { display: inline-flex; align-items: center; gap: 6px; }
.bk-eyebrow .field-edit-btn { width: 24px; height: 24px; }
.bk-eyebrow .inline-edit { position: absolute; left: 0; top: 100%; width: max-content; z-index: 30;
  text-transform: none; letter-spacing: normal; font: 500 14px/20px var(--bk-body); }
.bk-eyebrow .inline-select-menu { left: 0; right: auto; }
.bk .bk-subjects .field-edit-btn { display: inline-grid; vertical-align: middle; margin-left: 8px; width: 24px; height: 24px; }
.bk .inline-edit { text-align: left; }
.bk .inline-edit-input, .bk .inline-edit textarea { color: var(--bk-ink-1); font-family: var(--bk-body); }
