/*
  Comic reader (reader.html only). Single full-height layout, independent
  of the .stage/.sidebar/.main-card shell in style.css (which this page
  also loads, but only for design tokens + .logo).

  Structure, top to bottom:
    .reader-header        fixed-height bar: logo, title, fullscreen toggle
    .reader-body-content  flex row: left sidebar / stage / right sidebar
      .reader-sidebar-left    page nav (collapsible)
      .reader-stage           the actual page image + prev/next zones
      .reader-sidebar-right   related characters, data-driven (collapsible)

  All interactivity (page turning, sidebar collapse/expand, etc.) lives in
  js/reader.js — this file is layout/visuals only.
*/

.reader-body {
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* A grid, not a flex row, so the comic title sits in the MIDDLE with the
   previous-chapter banner to its left and next-chapter to its right —
   whichever of those two actually exist.

   Columns: logo, previous slot, title, next slot, tools. Only the title
   column flexes, and the title is centred inside it. With the two chapter
   slots reserving equal width (see .has-chapter-nav below), the two sides
   come out near enough identical that the title reads as page-centred. */
.reader-header {
  min-height: 74px;
  display: grid;
  grid-template-columns: auto auto 1fr auto auto;
  grid-template-areas: "logo prev title next tools";
  align-items: center;
  gap: 10px 16px;
  padding: 14px 4%;
  color: #fff;
  background: rgba(30, 27, 24, .92);
  box-shadow: 0 2px 12px #0006;
  z-index: 60;
}

.reader-logo   { grid-area: logo; }
.reader-title  { grid-area: title; justify-self: center; }
.reader-tools  { grid-area: tools; }
.chapter-slot-prev { grid-area: prev; justify-self: start; }
.chapter-slot-next { grid-area: next; justify-self: end; }

.reader-logo { flex-shrink: 0; }
.reader-logo img { width: 46px; height: auto; display: block; }

.reader-title {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
  /* max-width IS THE ONE THAT MAKES THE ELLIPSIS BELOW WORK, and its
     absence was a bug for as long as this header has existed — found by
     a test written for something else entirely, and measured against the
     pre-credit markup to be sure the credit had not caused it.

     `justify-self: center` sizes this item to its content rather than
     stretching it, and min-width: 0 only says it MAY shrink — nothing
     said it must. So a long comic title made this box 2888px wide inside
     a 1141px grid track, the whole header overflowed the window, and the
     h1's `text-overflow: ellipsis` never fired because it was never
     short of room. Clamping to the grid area is what gives it something
     to truncate against.

     Invisible until now only because every real title is short. There
     are 250 comics waiting to be imported; some of them will not be. */
  max-width: 100%;
}

.reader-back {
  color: var(--gold);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid rgba(211, 155, 85, .5);
  padding: 6px 10px;
  border-radius: 3px;
  transition: background .15s;
}
.reader-back:hover { background: rgba(211, 155, 85, .12); }

/* The title and its credit line, stacked. min-width: 0 is load-bearing:
   without it this flex item refuses to shrink below its content and the
   h1's ellipsis below never triggers — a long comic title would push the
   header wide instead of truncating. */
.reader-title-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.reader-title h1 {
  font-family: 'Pirata One', serif;
  font-weight: 400;
  font-size: 20px;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The artwork credit. Quiet enough not to compete with the comic's name
   directly above it, legible enough to actually be read — it is the only
   notice on the one page with no sidebar to carry one. Both halves are
   links and both are underlined rather than merely tinted: on a dark
   header a colour shift alone is not a signal. */
.reader-credit {
  margin: 0;
  font-size: 11px;
  line-height: 1.35;
  letter-spacing: .2px;
  color: rgba(255, 255, 255, .6);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.reader-credit a {
  color: rgba(255, 255, 255, .82);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .26);
}
.reader-credit a:hover,
.reader-credit a:focus-visible {
  color: #fff;
  border-bottom-color: rgba(255, 255, 255, .65);
}

.reader-tools {
  display: flex;
  align-items: center;
  gap: 8px;
}

.reader-btn {
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .18);
  color: #fff;
  font-size: 15px;
  line-height: 1;
  padding: 9px 12px;
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: background .15s, border-color .15s;
}
.reader-btn:hover { background: rgba(255, 255, 255, .14); }

/* Shown in place of the page image when a comic has no pages yet
   (page_count 0). Deliberately visible rather than a blank stage: the
   failure it replaces looked like a broken renderer. */
.reader-empty {
  color: rgba(255, 255, 255, .75);
  font-size: 16px;
  text-align: center;
  margin: 0;
  padding: 40px 20px;
}

/* ---- Previous / next chapter banners ----

   Built by renderChapterNav() in js/reader.js, which appends nothing at
   all when the current comic has no numbered neighbour in its series —
   so this container is empty (and, having no padding or background of
   its own, invisible) most of the time.

   The two assets are mirror images: Previous_Chapter.png carries its wax
   seal on the right and its torn tail on the left, Next_Chapter.png the
   other way round. Placed side by side in that order the seals meet in
   the middle, which is why they are NOT given a separator or a border —
   the artwork already reads as one symmetric block.

   Each asset is 3800x1000, and the text is baked into the image, so only
   the height is set and the width follows. No text label is added
   alongside: the banner already says "Previous Chapter" / "Next
   Chapter". */
.chapter-slot {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

/* Reserve each slot's width, but only while this comic actually has a
   chapter to link to. A first chapter shows only "next" and a last
   chapter only "previous", so without a reservation the title would be
   centred differently on each and appear to jump when you move between
   them. A comic with no chapters at all gets no reservation — two empty
   gutters would be dead space for no reason. Matches the banner's own
   rendered width (42px tall at 3.8:1). */
.has-chapter-nav .chapter-slot { min-width: 160px; }

.chapter-link {
  display: block;
  line-height: 0;
  transition: transform .15s, filter .15s;
}

/* 42px is about the ceiling: .reader-header is min-height 74px with 14px
   of vertical padding, so 46px is the usable band. The text is baked into
   the artwork at a small size relative to the banner, so going much below
   this makes it hard to read. */
.chapter-link img {
  height: 42px;
  width: auto;
  display: block;
}

/* Lifts slightly and brightens rather than changing color: these are
   fixed artwork, so any tint would fight the illustration. */
.chapter-link:hover { transform: translateY(-2px); filter: brightness(1.12); }
.chapter-link:active { transform: translateY(0); }

/* Keyboard focus needs to be visible on artwork that has no background
   of its own to tint. */
.chapter-link:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

@media (max-width: 700px) {
  .reader-title h1 { font-size: 15px; }
  /* Smaller, never hidden. A copyright notice that disappears on the
     device most people read comics on is not a notice. */
  .reader-credit { font-size: 10px; }

  /* Two 122px banners plus the logo, title and tools do not fit one
     narrow row, so the header becomes two: logo/title/tools on top, the
     chapter banners underneath, still previous-left and next-right. The
     width reservation is dropped here — space is too tight to spend on
     an empty gutter. */
  .reader-header {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "logo title tools"
      "prev prev  next";
  }
  .has-chapter-nav .chapter-slot { min-width: 0; }
  .chapter-link img { height: 32px; }
}

/* ---- Body layout: sidebar (left) + stage (right) ---- */

.reader-body-content {
  flex: 1;
  min-height: 0;
  display: flex;
}

/* ---- Sidebar: page indicator, slider, thumbnail list (left) /
   related-content placeholder (right). Both are collapsible. ---- */

.reader-sidebar {
  flex-shrink: 0;
  width: 180px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 40px 12px 16px;
  background: rgba(30, 27, 24, .92);
  z-index: 60;
  overflow-y: auto;
  position: relative;
  transition: width .2s ease, padding .2s ease;
}

.reader-sidebar-left { box-shadow: 2px 0 12px #0006; }
.reader-sidebar-right { box-shadow: -2px 0 12px #0006; }

.reader-sidebar.collapsed {
  width: 0;
  padding-left: 0;
  padding-right: 0;
  overflow: hidden;
  box-shadow: none;
}
.reader-sidebar.collapsed > * { opacity: 0; }

.sidebar-close-btn {
  position: absolute;
  top: 10px;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .18);
  color: #fff;
  font-size: 12px;
  line-height: 1;
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .15s;
}
.sidebar-close-btn:hover { background: rgba(255, 255, 255, .14); }
.reader-sidebar-left .sidebar-close-btn { right: 10px; }
.reader-sidebar-right .sidebar-close-btn { left: 10px; }

.sidebar-heading {
  font-family: 'Pirata One', serif;
  font-weight: 400;
  font-size: 17px;
  color: var(--gold);
  margin: 0;
}

.sidebar-placeholder {
  font-size: 13px;
  line-height: 1.6;
  color: rgba(255, 255, 255, .55);
  margin: 0;
}

/* Right sidebar's real content once a comic has related characters (see
   renderRelated() in js/reader.js) — one row per character, thumbnail +
   name, linking to character.html?id=<id>. Mirrors .thumb-strip's layout
   rhythm on the left sidebar so both sides feel like the same component. */
.related-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.related-character {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #fff;
  text-decoration: none;
  padding: 6px;
  border-radius: 3px;
  transition: background .15s;
}
.related-character:hover { background: rgba(255, 255, 255, .08); }
.related-character img {
  width: 40px;
  height: 50px;
  object-fit: cover;
  border-radius: 2px;
  flex-shrink: 0;
  /* No background fill, no border: assets/Cube.png (the missing-image
     placeholder, see js/reader.js) is itself transparent, and a filled/
     bordered box around it looked like a dull frame instead of it just
     floating — see the same note on .comic-cover in css/style.css. */
}
.related-character span {
  font-size: 13px;
  line-height: 1.3;
}

/* A related character with no character.html page yet (see the
   ch/idToDisplayName branch in renderRelated(), js/reader.js) — same
   layout as .related-character above, just not clickable (it's a <span>,
   not an <a>) and visually dimmed, same "coming soon" idea as
   .sidebar-link-disabled in css/style.css. */
.related-character-disabled {
  cursor: default;
  color: rgba(255, 255, 255, .55);
}
.related-character-disabled:hover { background: none; }
.related-character-disabled img { opacity: .6; }

/* Collapsed-state tab: hidden by default, shown only when its matching
   sidebar carries .collapsed (adjacent-sibling selector — the button
   must immediately follow the <aside> in the HTML). Horizontal text,
   centered on the edge (not stretched full-height). */
.sidebar-open-btn {
  display: none;
  flex-shrink: 0;
  align-self: center;
  background: rgba(30, 27, 24, .92);
  color: var(--gold);
  border: 1px solid rgba(211, 155, 85, .4);
  font-family: 'EB Garamond', serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .5px;
  padding: 10px 16px;
  cursor: pointer;
  z-index: 60;
  transition: background .15s;
}
.sidebar-open-btn:hover { background: rgba(255, 255, 255, .08); }
.sidebar-open-left { border-radius: 0 4px 4px 0; box-shadow: 2px 0 12px #0006; }
.sidebar-open-right { border-radius: 4px 0 0 4px; box-shadow: -2px 0 12px #0006; }

.reader-sidebar-left.collapsed + .sidebar-open-left,
.reader-sidebar-right.collapsed + .sidebar-open-right {
  display: block;
}

.page-indicator {
  color: var(--gold);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
}

.page-slider {
  width: 100%;
  accent-color: var(--gold);
  height: 4px;
  cursor: pointer;
}

.thumb-strip {
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  scrollbar-width: thin;
}

.thumb {
  width: 100%;
  height: auto;
  display: block;
  border: 2px solid transparent;
  opacity: .55;
  cursor: pointer;
  border-radius: 2px;
  transition: opacity .15s, border-color .15s;
  background: #8c7b66;
}
.thumb:hover { opacity: .85; }
.thumb.active {
  opacity: 1;
  border-color: var(--gold);
}

@media (max-width: 700px) {
  .reader-sidebar { width: 110px; padding: 36px 8px 10px; gap: 8px; }
  .page-indicator { font-size: 11px; }
  .sidebar-open-btn { font-size: 11px; padding: 8px 10px; }
}

/* ---- Stage ---- */

.reader-stage {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* No background of its own — the shared blurred/darkened site
     background (body's background-image in style.css) shows through
     instead of a separate dark panel behind the page. */
  background: transparent;
  padding: 20px;
}

.spread {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  max-width: min(1400px, 96%);
  opacity: 1;
  transition: opacity .15s ease;
}
.spread.fade-out { opacity: 0; }

/* page-wrap is a full-size, invisible layout box (needed so the
   percentage max-width/max-height below have a definite box to resolve
   against). The visible "paper" — background, shadow, radius — lives on
   the image itself, so it always hugs the image's actual rendered size
   (correct aspect ratio) instead of leaving letterbox bars around it. */
.page-wrap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.page-img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
  background: #fff;
  box-shadow: 0 8px 30px #000a;
  border-radius: 3px;
  user-select: none;
  -webkit-user-drag: none;
}

/* ---- Prev / next click zones ---- */

.nav-zone {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 14%;
  min-width: 48px;
  max-width: 110px;
  border: none;
  background: linear-gradient(to var(--fade-dir, right), #0000004d, transparent);
  color: #fff;
  font-size: 34px;
  cursor: pointer;
  display: flex;
  align-items: center;
  opacity: 0;
  transition: opacity .15s;
  z-index: 20;
}
.reader-stage:hover .nav-zone { opacity: .55; }
.nav-zone:hover { opacity: 1 !important; }
.nav-zone:disabled { opacity: 0 !important; cursor: default; pointer-events: none; }

.nav-prev { left: 0; justify-content: flex-start; padding-left: 10px; --fade-dir: right; }
.nav-next { right: 0; justify-content: flex-end; padding-right: 10px; --fade-dir: left; }
.nav-arrow { line-height: 1; }

@media (hover: none) {
  .nav-zone { opacity: .35; }
}
