/* ─── Library detail view (sidebar + PDF preview) ───────────────────────── */

/* When the detail view is open, collapse #site-main's vertical padding so the
   preview pane sits flush below the sticky header (its own height calc already
   reserves bottom slack via var(--preview-sticky-top) + 2rem). */
body:has(#lib-detail-view:not(.hidden)) #site-main {
  padding-top: 0;
  padding-bottom: 0;
}

#lib-detail-view:not(.hidden) {
  display: grid;
  grid-template-columns: 17rem minmax(0, 1fr);
  gap: 1rem;
  height: calc(100vh - var(--preview-sticky-top));   /* fixed height; the preview box's WIDTH tracks the
                                                         zoom factor and stays horizontally centred, the
                                                         PDF scrolls vertically inside the box */
  align-items: stretch;
}

@media (max-width: 767px) {
  /* :not(.hidden) so this beats the desktop #lib-detail-view:not(.hidden) rule
     (equal specificity → later source order wins). Plain #lib-detail-view loses
     the cascade and the desktop 2-col 17rem layout crushes the PDF to a sliver. */
  #lib-detail-view:not(.hidden) {
    grid-template-columns: minmax(0, 1fr);     /* single column (minmax(0,) lets it shrink) */
    grid-template-rows: auto minmax(0, 1fr);   /* compact sidebar, PDF fills the rest */
    align-items: stretch;                      /* override desktop align-items:start */
    gap: 0.6rem;
    height: calc(100vh - var(--preview-sticky-top));     /* fallback */
    height: calc(100dvh - var(--preview-sticky-top));    /* dvh: tracks mobile chrome */
    min-height: 0;
  }
}

/* ── Left sidebar ─────────────────────────────────────────────────────────── */

#lib-sidebar {
  position: sticky;            /* stays in view as the page scrolls; also anchors the download btn */
  top: var(--preview-sticky-top);
  align-self: start;
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--preview-sticky-top));
  min-height: 0;
  border-radius: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.07);
  background: rgba(8, 14, 30, 0.6);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

@media (max-width: 767px) {
  /* Roomy file selector. A DEFINITE height (not height:auto) is required so the
     flex:1 list fills it — with height:auto the flex-basis:0 list collapses to
     ~0 and only the header shows, which is why the selector looked tiny. */
  #lib-sidebar {
    height: clamp(9rem, 34vh, 18rem);
  }
}

/* Header wrapper (back button + subject strip). display:contents makes it
   transparent on desktop so its children stack as direct flex items exactly as
   before; phones turn it into one horizontal bar (see the mobile block below). */
#lib-sidebar-head { display: contents; }

/* Back button */
#lib-back-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.875rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: rgb(148 163 184);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 1rem 1rem 0 0;
  transition: color 0.15s, background 0.15s;
  width: 100%;
  text-align: left;
  cursor: pointer;
  flex-shrink: 0;
}
#lib-back-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.04); }
#lib-back-btn:focus-visible { outline: 2px solid rgba(34, 211, 238, 0.7); outline-offset: -2px; }

/* Subject header strip — sits between back btn and scroll list, stays visible */
.lib-sidebar-subject-hdr {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 0.875rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  flex-shrink: 0;
}
.lib-sidebar-subject-dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 9999px;
  flex-shrink: 0;
}
/* One dot class per CATEGORY hue (IGCSE sky / A-Level violet / AP rose /
   Morning Reading amber) — matches the picker's --tab-rgb palette. */
.lib-sidebar-subject-dot--sky     { background: rgb(56 189 248);  box-shadow: 0 0 5px rgba(56, 189, 248, 0.55);  }
.lib-sidebar-subject-dot--violet  { background: rgb(167 139 250); box-shadow: 0 0 5px rgba(167, 139, 250, 0.55); }
.lib-sidebar-subject-dot--rose    { background: rgb(251 113 133); box-shadow: 0 0 5px rgba(251, 113, 133, 0.55); }
.lib-sidebar-subject-dot--amber   { background: rgb(251 191 36);  box-shadow: 0 0 5px rgba(251, 191, 36, 0.55);  }
.lib-sidebar-subject-dot--orange  { background: rgb(251 146 60);  box-shadow: 0 0 5px rgba(251, 146, 60, 0.55);  }
/* The lanes' current hues (library.html --tab-rgb / library.js theme): IGCSE sky, A-Level
   cyan, AP violet, Languages indigo, Morning Reading blue — the landing's own ramp. */
.lib-sidebar-subject-dot--cyan    { background: rgb(34 211 238);  box-shadow: 0 0 5px rgba(34, 211, 238, 0.55);  }
.lib-sidebar-subject-dot--indigo  { background: rgb(129 140 248); box-shadow: 0 0 5px rgba(129, 140, 248, 0.55); }
.lib-sidebar-subject-dot--blue    { background: rgb(96 165 250);  box-shadow: 0 0 5px rgba(96, 165, 250, 0.55);  }
.lib-sidebar-subject-name {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: rgb(148 163 184);
}

/* Scrollable file list */
#lib-sidebar-list {
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  padding: 0.375rem 0.375rem 0.75rem;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: rgba(56, 189, 248, 0.22) transparent;
}

#lib-sidebar-list::-webkit-scrollbar { width: 8px; }
#lib-sidebar-list::-webkit-scrollbar-track { background: transparent; }
#lib-sidebar-list::-webkit-scrollbar-thumb {
  background: rgba(56, 189, 248, 0.22);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
#lib-sidebar-list::-webkit-scrollbar-thumb:hover {
  background: rgba(56, 189, 248, 0.38);
  background-clip: padding-box;
  border: 2px solid transparent;
}

/* Year row with gradient divider line */
.lib-sidebar-year-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.5rem 0.2rem;
  margin-top: 0.375rem;
}
#lib-sidebar-list > .lib-sidebar-year-row:first-child { margin-top: 0; }

.lib-sidebar-year-label {
  padding: 0;
  flex-shrink: 0;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgb(100 116 139);
}
.lib-sidebar-year-divider {
  height: 1px;
  flex: 1;
  background: linear-gradient(to right, rgba(255, 255, 255, 0.13), transparent);
}

/* Session badge row */
.lib-sidebar-session-row {
  padding: 0.1rem 0.5rem 0.1rem;
}
.lib-sidebar-session-badge {
  display: inline-flex;
  height: 1.15rem;
  min-width: 1.15rem;
  align-items: center;
  justify-content: center;
  border-radius: 0.25rem;
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: rgba(255, 255, 255, 0.04);
  padding: 0 0.25rem;
  font-size: 0.625rem;
  font-weight: 700;
  color: rgb(100 116 139);
  letter-spacing: 0.05em;
  cursor: default;
}

/* File buttons */
.lib-sidebar-item {
  display: block;
  width: 100%;
  padding: 0.4rem 0.6rem;
  border-radius: 0.5rem;
  font-size: 0.8rem;
  color: rgb(148 163 184);
  text-align: left;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, box-shadow 0.12s;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.35;
  box-shadow: inset 2px 0 0 transparent;
}
.lib-sidebar-item:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #e2e8f0;
  box-shadow: inset 2px 0 0 rgba(255, 255, 255, 0.10);
}
.lib-sidebar-item:focus-visible { outline: 2px solid rgba(34, 211, 238, 0.6); outline-offset: -2px; }

/* Active highlight per CATEGORY hue — background + color + left accent
   (same four-hue palette as the picker; sky doubles as the fallback). */
.lib-sidebar-item.is-active,
.lib-sidebar-item--sky.is-active     { background: rgba(56, 189, 248, 0.12);  color: rgb(125 211 252); box-shadow: inset 2px 0 0 rgba(56, 189, 248, 0.65);  }
.lib-sidebar-item--violet.is-active  { background: rgba(167, 139, 250, 0.12); color: rgb(196 181 253); box-shadow: inset 2px 0 0 rgba(167, 139, 250, 0.65); }
.lib-sidebar-item--rose.is-active    { background: rgba(251, 113, 133, 0.12); color: rgb(253 164 175); box-shadow: inset 2px 0 0 rgba(251, 113, 133, 0.65); }
.lib-sidebar-item--amber.is-active   { background: rgba(251, 191, 36, 0.12);  color: rgb(252 211 77);  box-shadow: inset 2px 0 0 rgba(251, 191, 36, 0.65);  }
.lib-sidebar-item--orange.is-active  { background: rgba(251, 146, 60, 0.12);  color: rgb(253 186 116); box-shadow: inset 2px 0 0 rgba(251, 146, 60, 0.65);  }
.lib-sidebar-item--cyan.is-active    { background: rgba(34, 211, 238, 0.12);  color: rgb(103 232 249); box-shadow: inset 2px 0 0 rgba(34, 211, 238, 0.65);  }
.lib-sidebar-item--indigo.is-active  { background: rgba(129, 140, 248, 0.12); color: rgb(165 180 252); box-shadow: inset 2px 0 0 rgba(129, 140, 248, 0.65); }
.lib-sidebar-item--blue.is-active    { background: rgba(96, 165, 250, 0.12);  color: rgb(147 197 253); box-shadow: inset 2px 0 0 rgba(96, 165, 250, 0.65);  }

/* ── PDF preview pane ────────────────────────────────────────────────────── */

#lib-detail-preview {
  position: relative;          /* anchors pdf-loading-overlay & pdf-empty-state */
  flex: none;                  /* width is strictly the JS-set width below (no flex grow/shrink) */
  width: 100%;                 /* default = full column until JS (libLayoutBox) sizes it */
  min-width: min(240px, 100%); /* avoid an absurd sliver at very low zoom; = full width on tiny screens */
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--preview-sticky-top));   /* fixed height; width tracks the zoom, the PDF scrolls inside */
  border-radius: 1rem;
  border: 1px solid rgba(255, 255, 255, 0.08);
  overflow: hidden;            /* clip to the rounded border; the inner scroll handles the PDF */
  background: var(--pane-bg);
  z-index: 3;                  /* paint over the sidebar when the box breaks out of its column on zoom */
  /* No transition: the box is re-laid-out by each render, which makes flex-basis/transform transitions
     stick at their start value — so width + position are applied instantly (correct end state). */
}

/* Centre each page within the stack (keeps a page narrower than the box centred). */
#lib-detail-preview .pdf-page-wrap {
  margin-left: auto;
  margin-right: auto;
}

/* When the box breaks out of its column and overlaps the sidebar (zoomed in), fade the file-list
   sidebar out so it doesn't peek behind the box; it returns on zoom-out. (JS toggles .lib-zoomed.)
   visibility is delayed so opacity can animate; the base #lib-sidebar transition fades it back in. */
#lib-sidebar { transition: opacity 0.15s ease; }
#lib-detail-view.lib-zoomed #lib-sidebar {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease, visibility 0s linear 0.15s;
}

@media (max-width: 767px) {
  #lib-detail-preview {       /* width stays JS-driven; don't force a flex-basis that overrides it */
    flex: none;
    min-height: 0;
  }
}

/* Centre the pages stack when JS sets an explicit px width narrower than container */
#lib-detail-preview .pdf-pages-stack {
  margin-left: auto;
  margin-right: auto;
}

/* Match the workspace preview-mode override: display:block allows the pages
   stack to centre via margin:auto (flex align-items:stretch would left-align it).
   Padding is zeroed so the rendered page can fill the full container height. */
#lib-detail-preview .pdf-viewport-scroll {
  display: block;
  flex: 1 1 0;                /* fill the bounded box */
  overflow-x: hidden;        /* the page is sized to fill the width exactly → never a horizontal slider */
  overflow-y: auto;          /* the PDF scrolls VERTICALLY inside the box */
  scrollbar-gutter: stable;  /* reserve the vertical-scrollbar gutter so the width can't jump */
  overscroll-behavior: contain;
  padding: 0;
  background: linear-gradient(180deg, rgba(8, 30, 52, 0.52) 0%, rgba(2, 8, 20, 0.5) 100%);
}

/* Top-right control cluster (zoom out / in, download), pinned to the sidebar's corner
   (on the back-button row). Absolute → it takes no space from the PDF pane and never
   overlaps the page. Shown only once a PDF has loaded (JS toggles [hidden]). The explicit
   [hidden] rule is required: this sheet's later `display` rule would otherwise outrank a
   plain `[hidden]` / Tailwind `.hidden` (the documented trap). */
.lib-detail-controls {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;                  /* above the back button it overlays */
  display: flex;
  align-items: center;
  gap: 0.3rem;
}
.lib-detail-controls[hidden] { display: none; }

.lib-ctrl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.4rem;
  border-radius: 0.55rem;
  color: rgb(165 243 252);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.10);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.lib-ctrl-btn:hover {
  background: rgba(56, 189, 248, 0.14);
  color: #fff;
  border-color: rgba(56, 189, 248, 0.40);
}
.lib-ctrl-btn:focus-visible {
  outline: 2px solid rgba(34, 211, 238, 0.7);
  outline-offset: 2px;
}
.lib-ctrl-btn svg { width: 1.05rem; height: 1.05rem; display: block; }

/* Preview column = the centring context for the PDF box. The box (JS-sized, flex:none) is
   horizontally centred; the zoom +/- rail is an absolute overlay positioned by JS. */
#lib-preview-col {
  position: relative;                 /* containing block for the absolute zoom rail */
  display: flex;
  justify-content: center;            /* horizontally centre the (JS-sized) box in the column */
  align-items: stretch;               /* box fills the column height */
  min-width: 0;
  min-height: 0;
}
/* Zoom +/- rail — an absolute overlay pinned to the vertical centre. JS (libLayoutBox) sets `left`
   so it rides the box's right edge, overlapping the box once it fills the column. The `right`
   default places it correctly during the first render, before JS runs (see libLayoutBox). */
.lib-zoom-controls {
  position: absolute;
  top: 0.6rem;                        /* TOP-right, beside the box (JS sets `left` to the box edge) */
  right: 0.4rem;                      /* default before JS sets `left` */
  z-index: 5;                         /* above the box content when it overlaps */
}
.lib-zoom-controls[hidden] { display: none; }
.lib-zoom-inner {
  display: flex;
  flex-direction: column;             /* + over - */
  gap: 0.3rem;
}

/* ─── Landscape phones: side-by-side detail layout ─────────────────────── */
/* Tablets in landscape are ≥ 768 px tall, so max-height: 500px excludes them. */
@media (orientation: landscape) and (max-height: 500px) {
  #lib-detail-view:not(.hidden) {
    grid-template-columns: 11rem minmax(0, 1fr);
    grid-template-rows: 1fr;
    height: calc(100vh - var(--preview-sticky-top));
  }
  #lib-sidebar {
    height: calc(100vh - var(--preview-sticky-top));
  }
  #lib-detail-preview {
    height: calc(100vh - var(--preview-sticky-top));
  }
}

/* ─── Portrait phones: roomier file selector, back button on its top row ──── */
@media (max-width: 767px) {
  /* Back button + subject label share one horizontal bar, freeing the row the
     full-width back button used to occupy so the file list gets more height. */
  #lib-sidebar-head {
    display: flex;
    align-items: stretch;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  }
  #lib-back-btn {
    width: auto;
    flex-shrink: 0;
    border-bottom: none;
    border-radius: 1rem 0 0 0;
  }
  #lib-sidebar-subject-hdr {
    flex: 1 1 auto;
    min-width: 0;
    border-bottom: none;
  }
  /* Bigger tap targets for picking a file. */
  .lib-sidebar-item {
    padding: 0.6rem 0.7rem;
    font-size: 0.875rem;
  }
}

/* ── Teacher-password lock badge ──────────────────────────────────────────────
   Small padlock beside a gated row's title (unit tests, weekly vocabulary tests —
   web/doc_lock.py). Purely an affordance: the real refusal is the server's 403, and
   whether THIS visitor is unlocked is never rendered here, because /library HTML is
   cached identity-free by the micro-cache and the service worker.
   Amber rather than red — this is "for teachers", not "error". */
.lib-lock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 0.5rem;
  color: rgb(251, 191, 36);
  background-color: rgba(251, 191, 36, 0.12);
}
