/* las-story-ny.css — Läs (library) and Story (reader). Load AFTER app.css.
   Nothing here invents a colour: everything is an app.css token, plus the few
   steps app.css does not have yet, declared here WITH dark values.

   THE ONE RULE that cost the most rounds: a token used as INK on a surface that
   flips with the colour scheme must itself flip. --blue/--ok/--bad are FILLS
   (solid buttons, badges, progress bars); the -ink variants below are the only
   ones allowed in color:, stroke:, borders and underlines. */

:root {
  --card: #fff;            /* a raised surface above --paper */
  --sunk: #eae7de;         /* a recessed surface below --paper */
  --faint: #6f6a5f;        /* tertiary ink — 4.7:1 on --paper */
  --ok-soft: #e8ece8;
  --blue-line: #dccbe3;
  --blue-ink: #743f8e;     /* 6.1:1 on --blue-soft, 6.8:1 on --paper */
  --ok-ink: #256540;       /* 5.84:1 on --ok-soft */
  --bad-ink: #b4342c;      /* 5.09:1 on --blue-soft */
  --scrim: rgba(20, 22, 26, .62); /* see "cover glyphs" below */
}
@media (prefers-color-scheme: dark) {
  :root {
    --card: #1b1e23; --sunk: #22262c; --faint: #7d8590;
    --ok-soft: #1c2a22; --blue-line: #43304f;
    --blue-ink: #d9b8ec;   /* 9.0:1 on --blue-soft, 9.6:1 on --card */
    --ok-ink: #6fc08d;     /* 6.84:1 on --ok-soft */
    --bad-ink: #f08a80;    /* 5.84:1 on --blue-soft */
  }
}

/* ============================================================ Läs: library */

/* Continue reading. st.current already knows the episode, so this costs no new
   state — and it is the one thing a returning reader wants. */
.resume { display: flex; gap: 13px; align-items: stretch; width: 100%; padding: 0;
  border: 0; border-radius: 16px; overflow: hidden; background: var(--blue); color: var(--on-blue); text-align: left; }
.resume .art { width: 74px; flex: none; display: grid; place-items: center; }
.resume .body { flex: 1; min-width: 0; padding: 13px 14px 13px 0; }
.resume .kicker { display: block; font-size: .68rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; opacity: .75; }
.resume .titel { display: block; font-family: var(--serif); font-weight: 500; font-size: 1.18rem; line-height: 1.2; margin-top: 5px; }
.resume .var { display: block; font-size: .82rem; font-weight: 500; opacity: .82; margin-top: 5px; }
.resume .chev { align-self: center; padding-right: 14px; }

/* Cover glyphs need a scrim, and this is a PRE-EXISTING app bug, not one this
   design introduced: coverHtml pins lightness (42% / 58%) and lets hue run
   free, so NO flat ink clears 3:1 on both stops — swept over all 360 hues,
   white bottoms out at 1.74:1 and dark ink at 1.83:1, and 190 of 720 stops
   fail. White on --scrim is hue-independent: worst case 7.15:1.
   Applies to every glyph over generated art — .initial, .emoji and .resume. */
.ncover .initial, .ncover .emoji, .resume .art > * {
  display: grid; place-items: center; width: 2.1em; height: 2.1em;
  border-radius: 12px; background: var(--scrim); color: #fff;
}
.ncover .emoji { filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .25)); }

/* Cards: one fact per line. The old meta string concatenated level, episodes,
   finished and current, then the bar restated "finished" underneath. */
.novels.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.ncard { border: 1px solid var(--line); border-radius: 15px; overflow: hidden;
  background: var(--card); display: flex; flex-direction: column; padding: 0; text-align: left; }
.ncard:focus-visible { outline: 3px solid var(--yellow); outline-offset: 2px; }
.ncard .nbody { padding: 9px 10px 10px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.ncard .ntitle { font-family: var(--serif); font-weight: 500; font-size: .98rem; line-height: 1.2; }
.nmeta { display: flex; align-items: center; gap: 5px; }
/* The prepared path's level on a library card (docs/architecture/library-index.md). */
.nsteg { padding: 2px 6px; border-radius: 6px; background: var(--blue-soft); color: var(--blue-ink, var(--blue));
  font-size: .64rem; font-weight: 700; line-height: 1.5; letter-spacing: .05em; }
.nlevel { padding: 2px 6px; border-radius: 6px; background: var(--sunk);
  font-size: .64rem; font-weight: 700; line-height: 1.5; letter-spacing: .05em; color: var(--granite); }
.neps { font-size: .74rem; font-weight: 500; line-height: 1.3; color: var(--granite); }
.nprog { margin-top: auto; display: flex; align-items: center; gap: 6px; }
.nprog .track { flex: 1; height: 4px; border-radius: 2px; background: var(--sunk); overflow: hidden; }
.nprog .track i { display: block; height: 100%; border-radius: 2px; background: var(--blue); }
.nprog .track.klar i { background: var(--ok); }
.nprog .count { flex: none; font-size: .68rem; font-weight: 700; color: var(--blue-ink); }
.nprog .count.tom { color: var(--granite); }
/* the personal-story marker, was 👤 */
.nprivate { position: absolute; right: 7px; top: 7px; z-index: 2; width: 22px; height: 22px;
  border-radius: 7px; background: var(--card); display: grid; place-items: center; color: var(--granite); }

/* Adding a story belongs IN the grid, where you look for it. */
.nadd { border: 1.5px dashed var(--line); border-radius: 15px; background: transparent;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 18px 10px; min-height: 150px; color: var(--granite); font-size: .82rem; font-weight: 600; text-align: center; }

/* ============================================================ Story: reader */

/* Two bar rows, not three: the tempo slider moves behind the settings button. */
.rhead { padding: 11px 14px 0; border-bottom: 1px solid var(--line); }
.rtitlerow { display: flex; align-items: center; gap: 10px; }
.rtitlerow .who { flex: 1; min-width: 0; }
.rtitlerow .novel { font-size: .92rem; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* the story title reads as a title (Linh, 2026-09-18) */
.rtitlerow .novel .by { margin-left: .5em; font-size: .7rem; font-weight: 500; color: var(--faint); }
.rtitlerow .ep { font-family: var(--serif); font-weight: 500; font-size: 1.06rem; line-height: 1.2;
  margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.riconbtn { width: 30px; height: 30px; flex: none; border: 0; border-radius: 9px;
  background: var(--sunk); color: var(--ink); display: grid; place-items: center; padding: 0; }

.rtransport { display: flex; align-items: center; gap: 9px; padding: 11px 0 9px; }
.rtransport .step { width: 36px; height: 36px; flex: none; border: 0; border-radius: 50%;
  background: var(--sunk); color: var(--ink); display: grid; place-items: center; padding: 0; }
.rtransport .play { width: 46px; height: 46px; flex: none; border: 0; border-radius: 50%;
  background: var(--blue); color: var(--on-blue); display: grid; place-items: center; padding: 0;
  box-shadow: 0 2px 8px rgba(116, 63, 142, .3); }
.rtransport .seek { flex: 1; min-width: 0; }
.rtransport .seek input { width: 100%; accent-color: var(--blue); }
.rtransport .seek .nums { display: flex; justify-content: space-between; margin-top: 1px;
  font-size: .7rem; font-weight: 500; color: var(--faint); }
/* loop: was 🔁 plus a near-invisible <span class="lp">. The label names what it
   repeats, so the state is legible without decoding an icon. */
.rloop { flex: none; display: flex; align-items: center; gap: 5px; height: 36px; padding: 0 10px;
  border: 1.5px solid var(--line); border-radius: 11px; background: transparent;
  color: var(--granite); font-size: .72rem; font-weight: 700; }
.rloop[aria-pressed="true"] { border-color: var(--blue-ink); background: var(--blue-soft); color: var(--blue-ink); }

/* Text mode was one button cycling three states, so .story.mode-0 could hide
   the text with nothing on screen saying why. Use the app's own .seg. */
.rmodes { display: flex; padding: 0 0 11px; }
.rmodes .seg { flex: 1; }
.rmodes .seg button { flex: 1; }

/* The episode line keeps drawLine's numbers: they are the only label a reader
   has for jumping back, and title= does not exist on touch. */
.line .stop { flex: none; height: 30px; display: grid; place-items: center;
  border-radius: 9px; font-size: .82rem; font-weight: 700; }
.line .stop.klar { position: relative; width: 30px; background: var(--ok-soft); color: var(--ok-ink); }
.line .stop.klar .tick { position: absolute; right: -3px; bottom: -3px; width: 14px; height: 14px;
  border-radius: 50%; background: var(--ok); display: grid; place-items: center; border: 1.5px solid var(--paper); }
.line .stop.nu { width: 34px; background: var(--blue); color: var(--on-blue); font-size: .86rem;
  box-shadow: 0 0 0 3px var(--blue-soft); }
.line .stop.last { display: flex; align-items: center; gap: 3px; padding: 0 8px;
  border: 1.5px dashed var(--line); color: var(--faint); font-size: .78rem; font-weight: 600; }

/* Unlock conditions: a goal card with a count, not a ✅/⬜ list. */
.unlock { margin: 13px 14px 0; padding: 13px 14px; border-radius: 14px;
  background: var(--blue-soft); border: 1px solid var(--blue-line); }
.unlock .rubrik { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 9px; }
.unlock .rubrik .vad { font-size: .68rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--blue-ink); }
.unlock .rubrik .av { font-size: .74rem; font-weight: 700; color: var(--blue-ink); }
.unlock ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.unlock li { display: flex; align-items: center; gap: 9px; font-size: .84rem; font-weight: 500; line-height: 1.3; color: var(--ink); }
.unlock li.vantar { color: var(--granite); }
.unlock li b { color: var(--bad-ink); }
.unlock li .liknapp { margin-left: auto; flex: none; padding: .3em .75em; font-size: .82rem; } /* the test, straight from the card */

/* The story itself. Dialogue drops the left-border accent for a speaker label. */
.story { padding: 18px 16px 6px; }
.story p { max-width: 34em; margin: 0 0 1.05em; }
.story p:last-child { margin-bottom: 0; }
.story .nu { background: var(--blue-soft); border-radius: 5px; box-shadow: 0 0 0 4px var(--blue-soft); }
.story .w.saved { text-decoration: underline dotted var(--blue-ink) 1.5px; text-underline-offset: 3px; }
.story .said { display: flex; gap: 9px; }
.story .said .who { flex: none; font-family: var(--sans); font-size: .74rem; font-weight: 600;
  line-height: 1.9; letter-spacing: .04em; color: var(--granite); }
.story .said .what { flex: 1; }

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

/* The library's section for situation scenes (docs/product/stories/nivaer.md section 5). */
.libsek { margin-top: 1.4em; }
.libsekrubrik { font-size: .66rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--faint); margin: 0; }
.libsektip { margin: .25em 0 0; font-size: .82rem; }
/* The reader's back button says where it goes (2026-09-28). */
.riconbtn.tillbaka { width: auto; padding: 0 10px 0 6px; gap: 3px; display: inline-flex; align-items: center; font-size: .85rem; font-weight: 700; flex: none; }
