:root {
  --p:#7042F3;          /* brand purple: same in both themes */
  --bg:#f6f6fb;         /* page */
  --ink:#222;           /* body text */
  --card:#fff;          /* rows, inputs, panels */
  --card-2:#faf8ff;     /* nested/soft panels */
  --line:var(--line);       /* borders */
  --dim:#555;           /* secondary text */
  --soft:#efeaff;       /* purple-tinted chips */
  --soft-line:var(--soft-line);
  --danger:#c0392b;
  --danger-bg:#fdf4f3;
  --danger-line:#f0c9c4;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
body { margin:0; font-family: system-ui, sans-serif; background:var(--bg); color:var(--ink); }
#topbar { background:var(--p); color:#fff; padding:12px 18px; display:flex; align-items:center;
  justify-content:space-between; position:sticky; top:0; z-index:10; }
#topbar h1 { margin:0; font-size:18px; cursor:pointer; }
/* sits under the world list, so it reads as a page action rather than a topbar chip */
#world-btn { display:block; width:100%; margin:14px 0 0; background:var(--p); color:#fff;
  border:0; border-radius:10px; padding:12px 18px; font-weight:700; font-size:15px;
  cursor:pointer; }
main { max-width:860px; margin:18px auto; padding:0 16px; }
.link { display:inline-block; color:var(--p); cursor:pointer; font-size:13px; margin-bottom:10px;
  text-decoration:none; }
.muted { color:#888; } .err { color:#c0392b; font-weight:600; }

/* library list */
.book-row { display:flex; gap:12px; align-items:center; background:var(--card); border:1px solid var(--line);
  border-radius:10px; padding:10px; margin-bottom:10px; cursor:pointer; }
.book-row:hover { border-color:#cdb4f6; }
.book-row .cov { width:64px; height:48px; border-radius:6px; flex:none;
  background:linear-gradient(135deg,#cdb4f6,#a29bfe); background-size:cover; background-position:center; }
.book-row .bk-title { font-weight:700; }
.book-row .bk-sub { color:#999; font-size:12px; }

/* create form */
form label { display:block; font-weight:600; margin:10px 0 4px; font-size:14px; }
form .row { display:flex; gap:14px; } form .row label { flex:1; }
/* the full-width rule is for text fields; a stretched checkbox pushes its own label
   halfway across the row, which is how "Cast narration" ended up adrift on a phone */
input[type=checkbox], input[type=radio] { width:auto; flex:none; }
input, select, textarea { width:100%; padding:8px 10px; border:1px solid #ccd; border-radius:8px;
  font:inherit; background:var(--card); }
button[type=submit] { margin-top:16px; background:var(--p); color:#fff; border:0; border-radius:10px;
  padding:11px 18px; font-weight:700; font-size:15px; cursor:pointer; }

/* generating + result */
.spinner { width:42px; height:42px; border:5px solid #ddd; border-top-color:var(--p);
  border-radius:50%; animation:spin 1s linear infinite; margin:30px auto; }
@keyframes spin { to { transform:rotate(360deg); } }
#generating { text-align:center; }
.dl { display:inline-block; margin:4px 8px 10px 0; background:#eee; color:#333; border-radius:14px;
  padding:5px 12px; text-decoration:none; font-size:13px; }
details { margin-top:14px; } pre { white-space:pre-wrap; background:var(--card); padding:12px;
  border-radius:8px; overflow:auto; max-height:340px; font-size:12px; }
.ai-fill { display:flex; gap:8px; margin:4px 0 8px; }
.ai-fill input { flex:1; }
.ai-fill button { margin:0; background:var(--soft); color:var(--p); font-weight:700;
  border:1px solid var(--soft-line); border-radius:8px; padding:8px 12px; cursor:pointer; white-space:nowrap; }
#ai-status { margin:0 0 8px; }
.voice-pick { display:flex; gap:6px; align-items:center; }
.voice-pick select { flex:1; }
#voice-sample { margin:0; background:var(--soft); color:var(--p); border:1px solid var(--soft-line);
  border-radius:8px; padding:8px 12px; cursor:pointer; font-weight:700; line-height:1; }
#sequel-btn { margin: 8px 0; background: var(--soft); color: var(--p); border: 1px solid var(--soft-line);
  border-radius: 8px; padding: 8px 12px; cursor: pointer; font-weight: 700; }
#sequel-banner { background: #eef; border-radius: 8px; padding: 8px 10px; }
#sequel-characters { display: flex; flex-direction: column; gap: 8px; margin: 6px 0; }
#sequel-characters h3 { margin: 0; font-size: 1rem; }
.seq-char { display: flex; gap: 6px; align-items: flex-start; }
.seq-char .seq-name { flex: 0 0 32%; }
.seq-char .seq-desc { flex: 1; }
.seq-remove { background: #fee; color: #b00; border: 1px solid #fbb; border-radius: 8px;
  padding: 6px 9px; cursor: pointer; }
#retry-btn { margin: 8px 0; background: var(--soft); color: var(--p); border: 1px solid var(--soft-line);
  border-radius: 8px; padding: 8px 14px; cursor: pointer; font-weight: 700; }
.series-row .bk-title { font-weight: 700; }
#series-parts { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
#series-sequel-btn { margin: 8px 0; background: var(--soft); color: var(--p); border: 1px solid var(--soft-line);
  border-radius: 8px; padding: 8px 14px; cursor: pointer; font-weight: 700; }
#premises, #batch-episodes { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
#premises h3 { margin: 0; font-size: 1rem; }
.premise { display: flex; gap: 6px; align-items: flex-start; }
.premise .pr-title { flex: 0 0 32%; }
.premise .pr-sum { flex: 1; }
.premise .pr-remove { background: #fee; color: #b00; border: 1px solid #fbb; border-radius: 8px;
  padding: 6px 9px; cursor: pointer; }
.batch-ep { padding: 6px 8px; background: #faf8ff; border-radius: 8px; }
#plan-btn-go, #batch-go-btn, #series-plan-btn, #batch-cancel-btn, #batch-retry-btn {
  margin: 8px 6px 8px 0; background: var(--soft); color: var(--p); border: 1px solid var(--soft-line);
  border-radius: 8px; padding: 8px 14px; cursor: pointer; font-weight: 700; }
#quota-badge { margin-left: auto; font-size: 0.9rem; white-space: nowrap; }
#quota-badge.quota-low { color: #e5484d; font-weight: 600; }

/* ---- worlds ---- */
.world-row .bk-title { font-weight: 600; }
.chg { border-left: 3px solid #cbd5e1; margin: .5em 0; padding: .1em 0 .1em .6em; }
.chg .muted { font-size: .85em; }
#world-chars .seq-char, #wf-chars .seq-char { margin-bottom: .4em; }
#world-elab-idea { width: 100%; margin: .3em 0 .6em; }
.badge-pending { color: #b45309; font-weight: 600; }
/* Buttons in the world screens are styled by WHERE THEY ARE, not by a list of ids kept
   up to date by hand — that list is how three separate buttons shipped unstyled. The
   exceptions carry a class: .danger has its own look, .lang-sample is a tiny play
   button inside a row. */
#world-edit button:not(.danger):not(.lang-sample),
#worldform button:not(.danger):not(.lang-sample),
#series-adopt-btn, #book-adopt-btn, #series-adopt-go, #book-adopt-go,
#world-plan-btn, #world-new-story-btn, #world-save-btn, #world-elab-btn,
#world-resync-btn, #world-add-char, #wf-elab-btn, #wf-random-btn,
#wf-add-char, #wf-save-btn, #world-edit-btn, #world-cancel-btn,
#world-next-btn, #world-title-btn, #wf-title-btn, #plan-add-char {
  margin: 8px 6px 8px 0; background: var(--soft); color: var(--p); border: 1px solid var(--soft-line);
  border-radius: 8px; padding: 8px 14px; cursor: pointer; font-weight: 700; }
#wf-save-btn, #world-save-btn, #world-next-btn {
  background: var(--p); color: #fff; border: 1px solid var(--p); }
#series-adopt, #book-adopt { display: flex; gap: 6px; align-items: center; margin: 8px 0; }
#series-adopt select, #book-adopt select { flex: 1; }
#world-cancel-btn { background: #eee; color: var(--dim); border-color: #ddd; }
#world-view h3 { margin: 14px 0 6px; }
#world-view-desc { background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; white-space: pre-wrap; }
#world-view-facts { margin: 4px 0; padding-left: 22px; }

/* ---- reader ---- */
#reader-page { text-align: center; }
#reader-page img { max-width: 100%; max-height: 62vh; border-radius: 12px; }
#reader-text { font-size: 1.35rem; line-height: 1.5; max-width: 640px; margin: 14px auto; }
/* Three groups — navigation, read-aloud, options — laid out in one row on a
   desktop and stacked into thumb-sized rows on a phone. */
#reader-controls { display: flex; gap: 10px 14px; align-items: center; justify-content: center;
  flex-wrap: wrap; position: sticky; bottom: 0; background: var(--bg);
  padding: 10px 0 calc(10px + env(safe-area-inset-bottom)); }
.rc-nav { display: flex; gap: 10px; align-items: center; }
.rc-opts { display: flex; gap: 8px 14px; align-items: center; flex-wrap: wrap;
  justify-content: center; }
.rc-toggles { display: flex; gap: 8px 18px; align-items: center; flex-wrap: wrap;
  justify-content: center; }
.rc-toggles label { display: inline-flex; align-items: center; gap: 6px; font-size: 14px;
  color: var(--dim); margin: 0; }
.rc-opts label { display: inline-flex; align-items: center; gap: 6px; font-size: 14px;
  color: var(--dim); margin: 0; }
.rc-opts select { width: auto; padding: 6px 8px; }
#reader-pos { min-width: 62px; text-align: center; }
#reader-prev, #reader-next, #reader-aloud { background: var(--soft); color: var(--p);
  border: 1px solid var(--soft-line); border-radius: 8px; padding: 10px 16px; cursor: pointer;
  font-weight: 700; font-size: 15px; }
#reader-prev:disabled, #reader-next:disabled, #reader-aloud:disabled { opacity: .4; cursor: default; }

@media (max-width: 560px) {
  /* stack the groups; each row is full width so the targets stay big */
  #reader-controls { flex-direction: column; align-items: stretch; gap: 8px; }
  .rc-nav { justify-content: space-between; }
  .rc-nav button { flex: 1; }
  #reader-aloud { width: 100%; padding: 12px 16px; }
  .rc-opts { justify-content: space-between; gap: 8px 10px; }
  .rc-toggles { justify-content: space-between; gap: 8px 10px; width: 100%; }
  #reader-text { font-size: 1.2rem; margin: 10px auto; }
  #reader-page img { max-height: 46vh; }   /* leave room for the stacked controls */
}

/* ---- world page: stories first ---- */
#world-entries { margin: 10px 0 4px; }
.series-group { border: 1px solid #e4e0f6; border-radius: 12px; padding: 8px 10px 2px;
  margin-bottom: 12px; background: #faf8ff; }
.series-group-head { display: flex; gap: 10px; align-items: baseline; margin: 2px 2px 8px; }
.series-group-head .sg-title { font-weight: 700; }
.series-group-head .sg-open { margin: 0 0 0 auto; }
.series-group .book-row { background: var(--card); }
#world-detail, #world-log { margin: 14px 0; background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: 8px 12px; }
#world-detail > summary, #world-log > summary { cursor: pointer; font-weight: 700;
  color: var(--p); }

/* world story-defaults readout: label/value grid */
#world-view-settings { display:grid; grid-template-columns:auto 1fr; gap:2px 12px; margin:0 0 12px; }
#world-view-settings dt { color:#666; font-size:.9em; }
#world-view-settings dd { margin:0; }

/* danger zone: destructive actions, set apart at the foot of a page */
.danger-zone { margin:28px 0 4px; padding:14px; border:1px solid #f0c9c4;
  border-radius:10px; background:#fdf4f3; display:flex; flex-direction:column;
  align-items:center; text-align:center; gap:10px; }
button.danger { margin:0; background:var(--card); color:#c0392b; border:1px solid #c0392b;
  border-radius:8px; padding:8px 14px; font-weight:700; font-size:14px; cursor:pointer; }
button.danger:hover { background:#c0392b; color:#fff; }

/* empty-world shortcut: the primary next step, so it leads the action row */
#world-pilot-btn { display:block; width:100%; margin:10px 0 0; background:var(--p);
  color:#fff; border:0; border-radius:10px; padding:12px 18px; font-weight:700;
  font-size:15px; cursor:pointer; }
#world-pilot-btn:disabled { opacity:.7; cursor:default; }

/* in-flight generation rows in a world's story list */
.job-row { opacity:.95; }
.job-cov { background:repeating-linear-gradient(45deg,#efeaff,#efeaff 6px,#e3dbff 6px,#e3dbff 12px); }
.job-row .bk-sub { color:var(--p); }
.job-failed .bk-sub { color:#c0392b; }

/* danger zone headline */
.danger-zone h3 { margin:0; font-size:14px; color:#c0392b; }

/* modal: matches the app's cards (same radius, shadow and accent) */
.modal-back { position:fixed; inset:0; background:rgba(20,16,40,.45); display:flex;
  align-items:center; justify-content:center; padding:20px; z-index:50; }
.modal-back[hidden] { display:none; }
.modal { background:var(--card); border-radius:14px; padding:20px; width:100%; max-width:420px;
  box-shadow:0 18px 50px rgba(0,0,0,.28); }
.modal h3 { margin:0 0 8px; font-size:17px; }
.modal .muted { margin:0 0 12px; font-size:14px; }
.modal input { margin-bottom:14px; }
.modal-actions { display:flex; gap:10px; justify-content:flex-end; }
.modal-actions button { margin:0; border:0; border-radius:8px; padding:9px 16px;
  font-weight:700; font-size:14px; cursor:pointer; background:#eee; color:#333; }
.modal-actions button.danger { background:#c0392b; color:#fff; border:0; }
.modal-actions button.danger:hover { background:#a93226; }

/* story screen extras, under the reader controls */
#reader-head { font-weight:700; font-size:17px; margin:0 0 10px; }
#reader-extras { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:14px; }

/* download section: same shape as the danger zone, neutral colours */
/* same frame as the download section, but its own class so a selector for one never
   picks up the other */
/* The two panels below a story — download and premium narration — are the same kind of
   thing and share one look, so their buttons cannot end up styled and unstyled side by
   side. */
.download-zone, .cast-zone { margin:22px 0 4px; padding:14px; border:1px solid #dfe0ee;
  border-radius:10px; background:#f7f7fc; display:flex; flex-direction:column;
  align-items:center; text-align:center; gap:10px; }
.download-zone h3, .cast-zone h3 { margin:0; font-size:14px; color:var(--dim); }
.cast-zone p { margin:0; }
.cast-zone audio { width:100%; margin-top:4px; }
.zone-actions { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }
.download-zone .dl, .cast-zone button { margin:0; background:var(--card); color:var(--p);
  border:1px solid var(--p); border-radius:8px; padding:8px 14px; font-weight:700;
  font-size:14px; cursor:pointer; text-decoration:none; display:inline-block; width:auto; }
.download-zone .dl:hover:not(:disabled), .cast-zone button:hover:not(:disabled) {
  background:var(--p); color:#fff; }
.download-zone .dl:disabled, .cast-zone button:disabled { color:#9a9aa8;
  border-color:#d5d5e0; background:#f0f0f5; cursor:not-allowed; }

/* "Also generate in" language checkboxes */
.lang-picks { display:flex; flex-wrap:wrap; gap:6px 14px; margin:6px 0; font-weight:400; }
.lang-pick { display:inline-flex; align-items:center; gap:5px; font-size:14px; }
.lang-pick input { width:auto; }
#modal-msg { white-space:pre-wrap; }   /* multi-line explanations keep their breaks */


/* ---- dark mode: follows the phone/system setting ---- */
@media (prefers-color-scheme: dark) {
  :root {
    --p:#9b7bff;              /* lifted so purple stays legible on dark */
    --bg:#14131a;
    --ink:#e9e8ef;
    --card:#1e1d26;
    --card-2:#232132;
    --line:#33313f;
    --dim:#a5a3b3;
    --soft:#2a2440;
    --soft-line:#4a3f70;
    --danger:#ff7a6b;
    --danger-bg:#2a1c1b;
    --danger-line:#5a3230;
  }
  #topbar { background:#241f37; }
  body, input, select, textarea, .book-row, .modal, details, .batch-ep,
  .series-group, #world-detail, #world-log { background:var(--card); color:var(--ink); }
  body { background:var(--bg); }
  input, select, textarea { border-color:var(--line); }
  .muted, .bk-sub, #world-view-settings dt, .download-zone h3, .cast-zone h3 {
    color:var(--dim); }
  .series-group { background:var(--card-2); }
  .book-row:hover { background:var(--card-2); }
  .modal { box-shadow:0 18px 50px rgba(0,0,0,.6); }
  .modal-actions button { background:#2f2d3b; color:var(--ink); }
  .modal-back { background:rgba(0,0,0,.6); }
  .danger-zone { background:var(--danger-bg); border-color:var(--danger-line); }
  .danger-zone h3, button.danger { color:var(--danger); border-color:var(--danger); }
  button.danger { background:transparent; }
  button.danger:hover, .modal-actions button.danger { background:var(--danger); color:#14131a; }
  .download-zone, .cast-zone { background:var(--card-2); border-color:var(--line); }
  .download-zone .dl, .cast-zone button { background:transparent; }
  .download-zone .dl:disabled, .cast-zone button:disabled { background:#26242f;
    border-color:var(--line); color:#6f6d7d; }
  .dl, #import-go { background:var(--soft); color:var(--ink); }
  #world-btn, #world-pilot-btn, button[type=submit],
  #wf-save-btn, #world-save-btn, #world-next-btn { color:#14131a; }
  .job-cov { background:repeating-linear-gradient(45deg,#2a2440,#2a2440 6px,#332a4d 6px,#332a4d 12px); }
  #quota-badge.quota-low { color:#ffd0c8; }
  #sidemenu { background:var(--card); box-shadow:-10px 0 40px rgba(0,0,0,.6); }
  #menu-backdrop { background:rgba(0,0,0,.6); }
  .read-done { color:#6ee7a8; }
}

#reader-autonext { width:auto; }
.read-done { color:#2e8b57; font-weight:600; }
.read-part { color:var(--p); font-weight:600; }

/* fullscreen page image: the picture follows the narration, nothing else on screen */
#reader-fs { position:fixed; inset:0; z-index:60; background:#000; display:flex;
  align-items:center; justify-content:center; cursor:zoom-out; }
#reader-fs[hidden] { display:none; }
#reader-fs img { max-width:100%; max-height:100%; object-fit:contain; }
#reader-fs-close { position:absolute; top:calc(12px + env(safe-area-inset-top)); right:12px;
  background:rgba(255,255,255,.15); color:#fff; border:0; border-radius:50%;
  width:40px; height:40px; font-size:18px; cursor:pointer; }
#reader-img { cursor:zoom-in; }
label.check { display:flex; align-items:center; gap:6px; font-weight:600; }
label.check input { width:auto; }
label.check .muted { font-weight:400; font-size:13px; }
.dl.is-busy { opacity:.6; pointer-events:none; }

/* inline spinner for buttons waiting on an AI call */
.spin { display:inline-block; width:12px; height:12px; margin-right:7px; vertical-align:-2px;
  border:2px solid currentColor; border-top-color:transparent; border-radius:50%;
  animation:spin .7s linear infinite; }
button:disabled .spin { opacity:.9; }
#reader-restart { margin:0; background:transparent; color:var(--dim); border:1px solid var(--line);
  border-radius:8px; padding:6px 10px; font-size:13px; font-weight:600; cursor:pointer; }
#reader-restart:hover { color:var(--p); border-color:var(--soft-line); }

/* sign-in */
#login { max-width:360px; margin:40px auto; }
#login h2 { margin:0 0 12px; }


#account-plans .book-row { cursor:default; }
#account-plans button { margin:0; background:var(--p); color:#fff; border:0; border-radius:8px;
  padding:8px 14px; font-weight:700; cursor:pointer; }

/* ---- side menu: words, not just icons ---- */
/* The hamburger is universal enough to stand alone — everything it opens is spelled
   out. It keeps an aria-label and title so it is never a mystery to a reader. */
#menu-btn { background:transparent; color:#fff; border:0; padding:4px 2px; cursor:pointer;
  font-size:24px; line-height:1; }
#menu-btn:hover { opacity:.85; }
#menu-backdrop { position:fixed; inset:0; background:rgba(20,16,40,.45); z-index:70; }
#menu-backdrop[hidden], #sidemenu[hidden] { display:none; }
#sidemenu { position:fixed; top:0; right:0; bottom:0; width:min(320px, 86vw); z-index:71;
  background:var(--card); color:var(--ink); box-shadow:-10px 0 40px rgba(0,0,0,.28);
  padding:18px 18px calc(18px + env(safe-area-inset-bottom)); overflow-y:auto;
  display:flex; flex-direction:column; gap:14px; }
#menu-close { align-self:flex-end; background:transparent; color:var(--dim); border:0;
  font-size:14px; cursor:pointer; padding:4px; }
#menu-email { margin:0; font-weight:600; color:var(--ink); word-break:break-all; }
#menu-usage { display:grid; grid-template-columns:auto 1fr; gap:4px 12px; margin:0;
  font-size:14px; }
#menu-usage dt { color:var(--dim); }
#menu-usage dd { margin:0; }
#sidemenu nav { display:flex; flex-direction:column; gap:8px; margin-top:6px; }
#sidemenu nav button { text-align:left; background:var(--soft); color:var(--p); border:1px solid
  var(--soft-line); border-radius:10px; padding:11px 14px; font-weight:700; font-size:15px;
  cursor:pointer; margin:0; }
#sidemenu nav button.danger { background:transparent; color:var(--danger);
  border-color:var(--danger); }
/* the badge is a glance; the menu has the detail, so drop it on narrow screens */
@media (max-width:560px) { #quota-badge { display:none; } }

/* ---- one row per language, each with its own voice ---- */
.lang-rows { display:flex; flex-direction:column; gap:8px; margin:8px 0 12px; }
.lang-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  background:var(--card-2); border:1px solid var(--line); border-radius:10px;
  padding:8px 10px; }
.lang-row.is-main { border-color:var(--soft-line); }
.lang-name { font-weight:700; min-width:7em; text-transform:capitalize; }
.lang-row select.lang-voice { width:auto; flex:1; min-width:9em; }
.lang-sample, .lang-main-btn, .lang-drop { margin:0; background:transparent;
  border:1px solid var(--line); border-radius:8px; padding:6px 10px; cursor:pointer;
  font-size:13px; color:var(--dim); }
.lang-main-btn:hover, .lang-sample:hover { color:var(--p); border-color:var(--soft-line); }
.lang-drop:hover { color:var(--danger); border-color:var(--danger); }
.lang-note { font-size:12px; }
@media (max-width:560px) { .lang-name { min-width:100%; } }
#whole-story-downloads { border-top:1px solid var(--line); margin-top:10px; padding-top:10px;
  width:100%; text-align:center; }
#whole-story-downloads h4 { margin:0 0 8px; font-size:13px; color:var(--dim); font-weight:600; }

/* A sentence that happens to be pressable: a button here would look like a control,
   and this is a remark about the story you are already reading. */
.linkish { background: none; border: 0; padding: 0; font: inherit;
  color: inherit; text-decoration: underline; cursor: pointer; }
