/* =========================================================================
   Wales High School — Flipbook Library
   A sleek, modern, dark-first design system.
   ========================================================================= */

:root {
  /* Surfaces */
  --bg:            #0b0e14;
  --bg-elev:       #11151f;
  --surface:       #161b27;
  --surface-2:     #1c2230;
  --surface-hover: #222a3a;
  --border:        #262e3e;
  --border-soft:   #1d2433;

  /* Text */
  --text:      #e8ecf4;
  --text-soft: #aab2c5;
  --text-dim:  #6b7488;

  /* Brand — Wales High School blue/gold */
  --accent:        #4f8cff;
  --accent-hover:  #6aa0ff;
  --accent-soft:   rgba(79, 140, 255, 0.12);
  --gold:          #f5c451;

  /* Feedback */
  --danger:  #ff5d6c;
  --success: #43d39e;

  /* Shape & motion */
  --radius:    14px;
  --radius-sm: 9px;
  --radius-lg: 22px;
  --shadow:    0 10px 30px -12px rgba(0, 0, 0, 0.7);
  --shadow-lg: 0 24px 60px -18px rgba(0, 0, 0, 0.8);
  --ease:      cubic-bezier(0.16, 1, 0.3, 1);

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Always show the scrollbar track so switching between short and tall admin
     tabs never changes the page width. overflow-y:scroll is the cross-browser
     guarantee; scrollbar-gutter is the modern, no-extra-track version. */
  overflow-y: scroll;
  scrollbar-gutter: stable;
}
/* The fixed-overlay viewer manages its own scrolling — no page scrollbar there. */
html:has(body.viewer) { overflow: hidden; }

body {
  margin: 0;
  font-family: var(--font);
  background:
    radial-gradient(1200px 700px at 80% -10%, rgba(79, 140, 255, 0.10), transparent 60%),
    radial-gradient(1000px 600px at -10% 10%, rgba(245, 196, 81, 0.05), transparent 55%),
    var(--bg);
  color: var(--text);
  line-height: 1.55;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body > main { flex: 1 0 auto; }

a { color: inherit; text-decoration: none; }

h1, h2, h3 { margin: 0; line-height: 1.2; letter-spacing: -0.02em; font-weight: 700; }

.icon { width: 20px; height: 20px; stroke-width: 2; flex: none; }
.icon-sm { width: 16px; height: 16px; }

/* ---------- Layout ---------- */
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 24px; }

.site-header {
  position: sticky; top: 0; z-index: 50;
  backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom: 1px solid var(--border-soft);
}
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  height: 70px; gap: 20px;
}
.brand { display: flex; align-items: center; gap: 13px; }
/* Logo used in place of the title/tagline text */
.brand-logo-full { height: 46px; width: auto; max-width: 300px; object-fit: contain; display: block; }
@media (max-width: 720px) { .brand-logo-full { height: 38px; max-width: 200px; } }
.brand-mark {
  width: 42px; height: 42px; border-radius: 12px;
  display: grid; place-items: center;
  background: linear-gradient(145deg, var(--accent), #2f6bdd);
  color: #fff; box-shadow: 0 6px 18px -6px var(--accent);
}
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-text .name { font-weight: 700; font-size: 1.02rem; letter-spacing: -0.01em; }
.brand-text .tag  { font-size: 0.76rem; color: var(--text-dim); font-weight: 500; }

.nav-actions { display: flex; align-items: center; gap: 10px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px; border-radius: var(--radius-sm);
  font-size: 0.9rem; font-weight: 600; font-family: inherit;
  border: 1px solid transparent; cursor: pointer;
  transition: all 0.18s var(--ease); white-space: nowrap;
  background: var(--surface-2); color: var(--text); border-color: var(--border);
}
.btn:hover { background: var(--surface-hover); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary {
  background: linear-gradient(145deg, var(--accent), #3573e8);
  color: #fff; border-color: transparent;
  box-shadow: 0 8px 20px -10px var(--accent);
}
.btn-primary:hover { background: linear-gradient(145deg, var(--accent-hover), #4f8cff); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-soft); }
.btn-ghost:hover { background: var(--surface); color: var(--text); }
.btn-danger { background: transparent; color: var(--danger); border-color: transparent; }
.btn-danger:hover { background: rgba(255, 93, 108, 0.12); }
.btn-icon { padding: 10px; }
.btn-block { width: 100%; justify-content: center; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* ---------- Hero ---------- */
.hero { padding: 64px 0 40px; }
.hero h1 {
  font-size: clamp(2rem, 4vw, 3.1rem);
  background: linear-gradient(120deg, #fff 20%, var(--text-soft));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-title { width: 100%; max-width: none; display: block; }
.hero p { color: var(--text-soft); font-size: 1.08rem; max-width: 560px; margin: 14px 0 0; }
.hero-meta {
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 18px;
  padding: 6px 13px; border-radius: 100px; font-size: 0.8rem; font-weight: 600;
  color: var(--accent); background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
}
.hero-meta .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }

/* ---------- Gallery grid ---------- */
.grid {
  display: grid; gap: 28px; padding-bottom: 80px;
  grid-template-columns: repeat(3, 1fr);   /* a tidy row of three */
}
@media (max-width: 920px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .grid { grid-template-columns: 1fr; } }
.section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin: 8px 0 24px;
}
.section-head-left { display: flex; align-items: baseline; gap: 12px; }
.section-head h2 { font-size: 1.35rem; }
.section-head .count { color: var(--text-dim); font-size: 0.9rem; font-weight: 500; }

/* ---------- Search ---------- */
.search {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 16px; border-radius: 100px; min-width: 260px;
  background: var(--surface); border: 1px solid var(--border);
  transition: border-color 0.18s, box-shadow 0.18s;
}
.search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.search .icon { color: var(--text-dim); flex: none; }
.search input {
  border: none; background: transparent; color: var(--text);
  font: inherit; font-size: 0.92rem; outline: none; width: 100%;
}
.search input::placeholder { color: var(--text-dim); }
.search input::-webkit-search-cancel-button { filter: invert(0.6); cursor: pointer; }

/* ---------- Ghost placeholder cards ---------- */
.book-card.ghost {
  border-style: dashed; border-color: color-mix(in srgb, var(--border) 55%, transparent);
  background: color-mix(in srgb, var(--surface) 18%, transparent);
  pointer-events: none; cursor: default; opacity: 0.5;
}
.book-card.ghost:hover { transform: none; box-shadow: none; }
.book-card.ghost .book-cover {
  background: color-mix(in srgb, var(--surface-2) 28%, transparent);
  color: var(--text-dim);
}
.book-card.ghost .book-cover .icon { width: 34px; height: 34px; opacity: 0.14; stroke-width: 1.5; }
.ghost-line {
  display: block; height: 11px; border-radius: 6px;
  background: var(--surface-2); opacity: 0.45;
}
.ghost-line.short { width: 55%; height: 9px; margin-top: 9px; opacity: 0.28; }

.book-card {
  position: relative;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  overflow: hidden;
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease),
              box-shadow 0.3s var(--ease);
  display: flex; flex-direction: column;
}
.book-card:hover {
  transform: translateY(-6px);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
  box-shadow: var(--shadow-lg);
}
.book-cover {
  position: relative; aspect-ratio: 3 / 4; overflow: hidden;
  background: linear-gradient(160deg, var(--surface-2), var(--bg-elev));
  display: grid; place-items: center;
}
.book-cover canvas, .book-cover img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.book-cover .spinner { position: absolute; }
.book-card:hover .book-cover::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(79, 140, 255, 0.18), transparent 55%);
}
/* Featured issue */
.book-card.featured {
  border-color: color-mix(in srgb, var(--gold) 55%, var(--border));
}
.book-card.featured:hover {
  border-color: var(--gold);
  box-shadow: 0 24px 60px -18px rgba(245, 196, 81, 0.25);
}
.featured-badge {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px; border-radius: 100px;
  background: linear-gradient(145deg, var(--gold), #d9a32e);
  color: #221a04; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.02em;
  box-shadow: 0 4px 14px -4px rgba(245, 196, 81, 0.6);
}
.featured-badge .icon-sm { width: 13px; height: 13px; fill: #221a04; }

.book-cover .play-badge {
  position: absolute; bottom: 14px; right: 14px; z-index: 2;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(11, 14, 20, 0.7); backdrop-filter: blur(6px);
  color: #fff; border: 1px solid rgba(255,255,255,0.12);
  opacity: 0; transform: scale(0.85) translateY(6px);
  transition: all 0.3s var(--ease);
}
.book-card:hover .play-badge { opacity: 1; transform: scale(1) translateY(0); }
.book-info { padding: 15px 16px 17px; }
.book-info h3 {
  font-size: 1rem; font-weight: 650;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.book-info .meta {
  display: flex; align-items: center; gap: 7px;
  margin-top: 6px; font-size: 0.8rem; color: var(--text-dim);
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--border);
  margin-top: auto;            /* pin to the bottom of the page */
  background: var(--bg-elev);
}
.site-footer .wrap {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 22px 24px; font-size: 0.82rem; color: var(--text-soft); font-weight: 500;
}
.site-footer .muted { color: var(--text-dim); opacity: 0.8; }

/* ---------- Empty state ---------- */
.empty {
  text-align: center; padding: 80px 24px; color: var(--text-dim);
  border: 1px dashed var(--border); border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--surface) 40%, transparent);
}
.empty .icon { width: 48px; height: 48px; margin-bottom: 16px; color: var(--text-dim); stroke-width: 1.5; }
.empty h3 { color: var(--text-soft); margin-bottom: 6px; }

/* ---------- Spinner ---------- */
.spinner {
  width: 28px; height: 28px; border-radius: 50%;
  border: 3px solid var(--border); border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Auth / Admin cards ---------- */
.center-page { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.auth-card { width: 100%; max-width: 410px; padding: 38px 34px; }
.auth-card .brand { justify-content: center; margin-bottom: 22px; }
.auth-card h1 { font-size: 1.5rem; text-align: center; }
.auth-card .sub { text-align: center; color: var(--text-dim); margin: 8px 0 26px; font-size: 0.92rem; }

.field { margin-bottom: 16px; }
.field label { display: block; font-size: 0.84rem; font-weight: 600; color: var(--text-soft); margin-bottom: 7px; }
.input, textarea.input {
  width: 100%; padding: 12px 14px; font-size: 0.95rem; font-family: inherit;
  color: var(--text); background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  transition: border-color 0.18s, box-shadow 0.18s;
}
.input:focus, textarea.input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea.input { resize: vertical; min-height: 84px; }

.alert {
  padding: 11px 14px; border-radius: var(--radius-sm); font-size: 0.88rem;
  margin-bottom: 18px; display: flex; align-items: center; gap: 9px;
}
.alert-error   { background: rgba(255, 93, 108, 0.12); color: #ff8b96; border: 1px solid rgba(255,93,108,0.25); }
.alert-success { background: rgba(67, 211, 158, 0.12); color: var(--success); border: 1px solid rgba(67,211,158,0.25); }

/* ---------- Admin dashboard ---------- */
.admin-head { padding: 40px 0 18px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; }
.admin-head h1 { font-size: 1.8rem; }
.admin-head p { color: var(--text-dim); margin: 6px 0 0; font-size: 0.92rem; }

/* Brand logo (header + auth + settings preview) */
.brand-mark img.brand-logo { width: 100%; height: 100%; object-fit: contain; }
.brand-mark:has(img.brand-logo) { background: none; box-shadow: none; }

/* Tabs */
.tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  margin: 8px 0 24px; border-bottom: 1px solid var(--border-soft);
}
.tab {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 16px; border: none; background: transparent;
  color: var(--text-soft); font: inherit; font-weight: 600; font-size: 0.92rem;
  cursor: pointer; border-radius: 10px 10px 0 0;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.tab:hover { color: var(--text); background: var(--surface); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-count {
  font-size: 0.72rem; background: var(--surface-2); color: var(--text-dim);
  padding: 1px 8px; border-radius: 100px; font-weight: 700;
}
.tab.active .tab-count { background: var(--accent-soft); color: var(--accent); }
.tab-panel { display: none; width: 100%; }
.tab-panel.active { display: block; animation: rise 0.35s var(--ease) both; }
/* Every tab's content is the SAME fixed-width column — no per-tab variation.
   Keep the normal gap between stacked cards; only drop the trailing margin. */
.tab-panel > .panel { width: 100%; box-sizing: border-box; }
.tab-panel > .panel:last-child { margin-bottom: 0; }

/* Admin content is a FIXED width so it never shrinks or varies between tabs.
   (The public pages keep the responsive .wrap.) On windows narrower than this
   the admin area scrolls horizontally rather than squashing the content. */
.admin-wrap { width: 1180px; max-width: 1180px; min-width: 1180px; }

/* Drag-to-reorder */
.book-row .row-grip {
  flex: none; display: grid; place-items: center;
  width: 26px; height: 38px; color: var(--text-dim);
  cursor: grab; border-radius: 7px; touch-action: none;
}
.book-row .row-grip:hover { color: var(--text-soft); background: var(--surface-2); }
.book-row.dragging { opacity: 0.55; border-color: var(--accent); box-shadow: var(--shadow); }

/* Settings form — fills the panel like every other tab (no narrower cap). */
.settings-form { width: 100%; }
.logo-row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.logo-preview {
  width: 64px; height: 64px; border-radius: 14px; flex: none; overflow: hidden;
  display: grid; place-items: center; color: #fff;
  background: linear-gradient(145deg, var(--accent), #2f6bdd);
}
.logo-preview img.brand-logo { width: 100%; height: 100%; object-fit: contain; }
.logo-preview:has(img.brand-logo) { background: var(--surface-2); }
.logo-controls { display: flex; flex-direction: column; gap: 9px; align-items: flex-start; }
.logo-controls .field-help { margin: 0; }
.checkbox { display: inline-flex; align-items: center; gap: 8px; font-size: 0.86rem; color: var(--text-soft); cursor: pointer; }
.checkbox input { width: 16px; height: 16px; accent-color: var(--accent); }

.panel { padding: 26px; margin-bottom: 28px; }
.panel-title { display: flex; align-items: center; gap: 10px; font-size: 1.1rem; margin-bottom: 4px; }
.panel-title .icon { color: var(--accent); }
.panel-sub { color: var(--text-dim); font-size: 0.88rem; margin: 0 0 20px; }

/* Dropzone — note this is a <label>, so it MUST be a block (an inline label
   only partially wraps its block children, leaving a broken-looking border). */
.dropzone {
  display: block; width: 100%;
  border: 2px dashed var(--border); border-radius: var(--radius);
  padding: 36px 24px; text-align: center; cursor: pointer;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
  background: var(--bg-elev);
}
.dropzone:hover, .dropzone.drag {
  border-color: var(--accent); background: var(--accent-soft);
}
.dropzone.has-file { border-style: solid; border-color: var(--success); background: rgba(67,211,158,0.06); }
.dz-inner { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.dz-icon { display: grid; place-items: center; margin-bottom: 8px; color: var(--accent); }
.dz-icon .icon { width: 38px; height: 38px; }
.dz-icon.ok { color: var(--success); }
.dz-main { margin: 0; color: var(--text-soft); }
.dz-main strong { color: var(--text); }
.dz-hint { color: var(--text-dim); font-size: 0.82rem; }

/* Upload form layout */
.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 20px; }
.field-opt { color: var(--text-dim); font-weight: 500; }
.field-help { margin: 7px 0 0; font-size: 0.78rem; color: var(--text-dim); }
.field-help code, .row-slug, .slug-prefix {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.slug-input { display: flex; align-items: stretch; }
.slug-input .slug-prefix {
  display: grid; place-items: center; padding: 0 12px;
  background: var(--surface-2); color: var(--text-dim);
  border: 1px solid var(--border); border-right: none;
  border-radius: var(--radius-sm) 0 0 var(--radius-sm); font-size: 0.9rem;
}
.slug-input .input { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.form-foot { display: flex; align-items: center; gap: 14px; margin-top: 20px; flex-wrap: wrap; }
.upload-status { color: var(--text-dim); font-size: 0.88rem; }

.upload-progress { height: 6px; border-radius: 100px; background: var(--border); overflow: hidden; margin-top: 16px; display: none; }
.upload-progress .bar { height: 100%; width: 0; background: linear-gradient(90deg, var(--accent), var(--gold)); transition: width 0.2s; }

@media (max-width: 560px) { .field-grid { grid-template-columns: 1fr; } }

.btn-sm { padding: 8px 12px; font-size: 0.84rem; }

/* Panel head (title left, search right) */
.panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.table-search { min-width: 240px; }

/* ---------- Published table ---------- */
.table-scroll { overflow-x: auto; margin: 0 -4px; }
.issues-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.issues-table th, .issues-table td { padding: 12px 8px; text-align: left; vertical-align: middle; }
.issues-table thead th {
  font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-dim); font-weight: 700; border-bottom: 1px solid var(--border);
  white-space: nowrap; user-select: none;
}
.issues-table th.sortable { cursor: pointer; transition: color 0.15s; }
.issues-table th.sortable:hover { color: var(--text-soft); }
.issues-table th.sortable::after { content: "↕"; opacity: 0.3; margin-left: 6px; font-size: 0.8em; }
.issues-table th.sorted-asc::after { content: "↑"; opacity: 1; color: var(--accent); }
.issues-table th.sorted-desc::after { content: "↓"; opacity: 1; color: var(--accent); }
.issues-table tbody tr { border-bottom: 1px solid var(--border-soft); transition: background 0.15s; }
.issues-table tbody tr:hover { background: var(--bg-elev); }
.issues-table tbody tr.dragging { opacity: 0.5; background: var(--surface-2); }

.col-grip { width: 26px; padding-right: 0 !important; }
.col-thumb { width: 46px; }
.col-date, .col-size { white-space: nowrap; color: var(--text-soft); }
.col-actions { width: 1%; white-space: nowrap; text-align: right !important; font-size: 0; }
.col-actions .btn { padding: 7px; }

.row-grip {
  display: none; place-items: center; width: 22px; height: 30px;
  color: var(--text-dim); cursor: grab; border-radius: 6px; touch-action: none;
}
body.reorderable .row-grip { display: grid; }
.row-grip:hover { color: var(--text-soft); background: var(--surface-2); }

.issues-table .thumb {
  width: 38px; height: 50px; border-radius: 6px; overflow: hidden;
  background: var(--surface-2); display: grid; place-items: center;
}
.issues-table .thumb canvas, .issues-table .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cell-title { font-weight: 650; color: var(--text); display: block; max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.issues-table .row-slug {
  display: inline-flex; align-items: center; gap: 5px; color: var(--accent);
  max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.issues-table .row-slug:hover { color: var(--accent-hover); text-decoration: underline; }

.table-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.table-pager { display: flex; gap: 4px; }
.pager-btn {
  min-width: 34px; height: 34px; padding: 0 8px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  font: inherit; font-weight: 600; cursor: pointer; transition: all 0.15s;
}
.pager-btn:hover:not(:disabled):not(.active) { background: var(--surface-hover); color: var(--text); }
.pager-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; cursor: default; }
.pager-btn:disabled { opacity: 0.4; cursor: not-allowed; }

@media (max-width: 720px) {
  .issues-table .col-slug, .issues-table .col-size { display: none; }
  .cell-title { max-width: 180px; }
}

/* ---------- Modals ---------- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: 20px;
  background: rgba(4, 6, 11, 0.6); backdrop-filter: blur(4px);
  opacity: 0; transition: opacity 0.2s var(--ease);
}
/* CRITICAL: the class rule above sets display:grid, which would otherwise beat
   the [hidden] attribute and leave an invisible full-screen overlay eating every
   click. Keep hidden overlays truly gone. */
.modal-overlay[hidden] { display: none; }
.modal-overlay.open { opacity: 1; }
.modal {
  width: 100%; max-width: 460px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  transform: translateY(12px) scale(0.98); transition: transform 0.2s var(--ease);
  max-height: calc(100vh - 40px); overflow: auto;
}
.modal-overlay.open .modal { transform: none; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 22px; border-bottom: 1px solid var(--border-soft);
}
.modal-head h3 { display: flex; align-items: center; gap: 9px; font-size: 1.1rem; }
.modal-head .icon, .modal-head .icon-sm { color: var(--accent); }
#delete-modal .modal-head .icon, #delete-modal .modal-head .icon-sm { color: var(--danger); }
.modal-close {
  width: 34px; height: 34px; border-radius: 8px; border: none; cursor: pointer;
  display: grid; place-items: center; background: transparent; color: var(--text-dim);
  transition: all 0.15s;
}
.modal-close:hover { background: var(--surface-2); color: var(--text); }
.modal-body { padding: 22px; }
.modal-text { margin: 0 0 4px; color: var(--text-soft); }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; }

/* Share modal */
.share-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 18px; }
.share-option {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 14px 6px 12px; border-radius: var(--radius);
  border: 1px solid var(--border-soft); background: var(--bg-elev);
  font-size: 0.78rem; font-weight: 600; color: var(--text-soft);
  transition: all 0.15s var(--ease);
}
.share-option:hover { transform: translateY(-2px); border-color: var(--border); color: var(--text); background: var(--surface-2); }
.share-bubble {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; color: #fff;
}
.share-bubble .icon { width: 21px; height: 21px; }
.share-bubble.fb { background: #1877f2; }
.share-bubble.tw { background: #111417; border: 1px solid #2c3340; }
.share-bubble.wa { background: #25d366; }
.share-bubble.em { background: linear-gradient(145deg, var(--accent), #2f6bdd); }
.copy-row { display: flex; gap: 8px; }
.copy-row .input { flex: 1; min-width: 0; font-size: 0.85rem; }
#share-native { margin-top: 12px; }
@media (max-width: 460px) { .share-grid { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Stats ---------- */
.col-views { white-space: nowrap; }
.views-pill { display: inline-flex; align-items: center; gap: 5px; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.views-pill .icon-sm { color: var(--text-dim); }

.tab-count-warn { background: rgba(255, 93, 108, 0.18) !important; color: var(--danger) !important; }

.stat-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 22px; }
.stat-card { padding: 20px 22px; }
.stat-label { display: flex; align-items: center; gap: 8px; font-size: 0.82rem; color: var(--text-dim); font-weight: 600; }
.stat-label .icon-sm { color: var(--accent); }
.stat-value { font-size: 2rem; font-weight: 700; letter-spacing: -0.02em; margin-top: 8px; font-variant-numeric: tabular-nums; }
.stat-value-sm { font-size: 1.05rem; font-weight: 650; margin-top: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-sub { font-size: 0.82rem; color: var(--text-dim); margin-top: 2px; }
@media (max-width: 760px) { .stat-cards { grid-template-columns: 1fr; } }

.stats-list { display: flex; flex-direction: column; }
.stat-row { display: flex; align-items: center; gap: 16px; padding: 12px 4px; border-bottom: 1px solid var(--border-soft); }
.stat-row:last-child { border-bottom: none; }
.stat-row .thumb { width: 38px; height: 50px; border-radius: 6px; flex: none; overflow: hidden; background: var(--surface-2); display: grid; place-items: center; }
.stat-row .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.stat-row-info { flex: 1; min-width: 0; }
.stat-row-title { font-weight: 650; color: var(--text); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-row-title:hover { color: var(--accent); }
.stat-row-info p { margin: 2px 0 0; font-size: 0.8rem; }
.stat-spark { color: var(--accent); flex: none; width: 96px; height: 28px; }
.stat-spark .sparkline { display: block; width: 100%; height: 100%; }
.stat-row-count { flex: none; text-align: right; min-width: 70px; }
.stat-row-count strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.stat-row-count span { display: block; font-size: 0.72rem; color: var(--text-dim); }
@media (max-width: 600px) { .stat-spark { display: none; } }

/* ---------- Audit ---------- */
.audit-flag { color: var(--danger); font-weight: 600; display: inline-flex; align-items: center; gap: 5px; }
.audit-table td { font-size: 0.86rem; }
.audit-table .audit-when { white-space: nowrap; color: var(--text-soft); font-variant-numeric: tabular-nums; }
.audit-table tr.audit-fail { background: rgba(255, 93, 108, 0.05); }
.badge { display: inline-block; padding: 2px 9px; border-radius: 100px; font-size: 0.74rem; font-weight: 700; }
.badge-ok { background: rgba(67, 211, 158, 0.14); color: var(--success); }
.badge-fail { background: rgba(255, 93, 108, 0.14); color: var(--danger); }

/* Half-vertical fade on the empty placeholder cards (homepage). */
.book-card.ghost {
  -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
}

/* ---------- Viewer ---------- */
body.viewer { overflow: hidden; background: #06080d; }
.viewer-stage {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  background:
    radial-gradient(1400px 800px at 50% -20%, rgba(79,140,255,0.08), transparent 60%),
    #06080d;
}
.viewer-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 22px; z-index: 30;
  background: linear-gradient(180deg, rgba(6,8,13,0.9), transparent);
}
.viewer-bar .title { display: flex; align-items: center; gap: 12px; min-width: 0; }
.viewer-bar .title h2 { font-size: 1rem; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viewer-bar .title .back { color: var(--text-soft); }
.viewer-bar .title .back:hover { color: var(--text); }

.flip-area { flex: 1; position: relative; display: grid; place-items: center; padding: 8px; min-height: 0; overflow: hidden; }
/* Take touch gestures away from the browser (whose pinch-zoom would snap back to
   maximum-scale) so our own zoom handles them and the zoom level persists.
   Touch EVENTS still fire, so single-finger swipe-to-flip keeps working. */
.flip-area, #flip-zoom, #flipbook, .flip-area canvas { touch-action: none; }
/* No `will-change: transform` here: it pins the layer to a fixed-resolution GPU
   texture, so zooming magnified a blurry snapshot instead of re-rendering the
   full-res page image at the zoomed size. Without it the browser re-rasterizes
   on zoom and the image stays crisp. */
#flip-zoom { transform-origin: center center; }

/* Clickable hotspots from the PDF's own link annotations */
/* Crisp full-resolution page overlay (shown at rest, above the flip canvas). */
.hires-layer { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.hires-layer.hide { display: none; }
.hires-page {
  position: absolute; top: 0; height: 100%;
  object-fit: fill; user-select: none; -webkit-user-drag: none;
}

.link-layer { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.link-layer.hide { display: none; }
.link-layer .page-link {
  position: absolute; pointer-events: auto; border-radius: 3px;
  transition: background 0.15s, box-shadow 0.15s;
}
.link-layer .page-link:hover {
  background: rgba(79, 140, 255, 0.16);
  box-shadow: 0 0 0 2px rgba(79, 140, 255, 0.45);
}

/* Thumbnail strip */
.thumb-strip { padding: 8px 14px 0; z-index: 25; }
.thumb-track {
  display: flex; gap: 8px; overflow-x: auto;
  padding: 6px 2px 8px;
  /* Firefox scrollbar — quiet, theme-matched */
  scrollbar-width: thin;
  scrollbar-color: #222a3a transparent;
}
/* Custom horizontal scrollbar (WebKit/Chromium) — subtle dark rail */
.thumb-track::-webkit-scrollbar { height: 4px; }
.thumb-track::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.03); border-radius: 100px; margin: 0 15%;
}
.thumb-track::-webkit-scrollbar-thumb {
  background: var(--surface-hover);            /* dark slate, barely-there */
  border-radius: 100px;
}
.thumb-track::-webkit-scrollbar-thumb:hover { background: #2e3950; }

.thumb-item {
  flex: none; position: relative; padding: 0; cursor: pointer;
  background: transparent; border: 2px solid transparent; border-radius: 9px;
  transition: border-color 0.15s;             /* transform/opacity are JS-driven */
  transform-origin: center bottom;
}
.thumb-item img { display: block; height: 82px; width: auto; border-radius: 6px; }
/* Page number: only on the page you're reading (and briefly on hover) */
.thumb-item span {
  position: absolute; bottom: 5px; right: 5px;
  font-size: 0.66rem; font-weight: 700; color: var(--text);
  background: rgba(8, 11, 18, 0.92); padding: 1px 7px; border-radius: 8px;
  border: 1px solid var(--border);
  opacity: 0; transition: opacity 0.15s;
}
.thumb-item:hover span { opacity: 1; }
.thumb-item.active span { opacity: 1; border-color: var(--accent); color: #fff; }
.thumb-item:hover { border-color: var(--border); }
.thumb-item.active { border-color: var(--accent); }

.dock button.on { color: var(--accent); background: var(--accent-soft); }
.dock button.muted { color: var(--text-dim); }

/* Featured star (admin table) */
.btn-star.on { color: var(--gold); }
.btn-star.on:hover { background: rgba(245, 196, 81, 0.12); }
.btn-star.on svg { fill: var(--gold); }

/* Fast-load "prepare" button (admin table): green when a set is ready,
   pulsing while it renders + uploads. */
.js-prepare.is-ready { color: var(--success); }
.js-prepare.is-ready:hover { background: rgba(67, 211, 158, 0.12); }
.js-prepare.is-busy { color: var(--accent); animation: prepare-pulse 1s ease-in-out infinite; }
.js-prepare:disabled { cursor: progress; opacity: 1; }
@keyframes prepare-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.featured-tag {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 8px;
  font-size: 0.68rem; font-weight: 700; color: var(--gold);
  vertical-align: 1px;
}
.featured-tag .icon-sm { width: 12px; height: 12px; fill: var(--gold); }
.flip-area.zoomed { cursor: grab; }
.flip-area.zoomed:active { cursor: grabbing; }
/* Shadow the actual page pixels, not the 2-page block. With the empty half of a
   lone cover now transparent, drop-shadow hugs the real content — so there's no
   ghost outline/shadow of the hidden page behind the front and back covers. */
.flip-area canvas { filter: drop-shadow(0 16px 26px rgba(0, 0, 0, 0.55)); }
#flipbook .page {
  background: #fff; overflow: hidden;
  display: grid; place-items: center;
}
#flipbook .page img { width: 100%; height: 100%; object-fit: contain; display: block; }
#flipbook .page.--hard { background: linear-gradient(135deg, #1c2230, #11151f); }

.flip-loading {
  position: absolute; inset: 0; display: grid; place-items: center;
  z-index: 5; gap: 16px; text-align: center;
}
.flip-loading .spinner { width: 40px; height: 40px; }
.flip-loading p { color: var(--text-soft); font-size: 0.9rem; }

/* Flying-dragon loader (landscape mascot, 204x169) */
.dragon-loader { position: relative; width: 156px; height: 150px; display: grid; place-items: center; }
.dragon-loader .dragon {
  width: 156px; height: auto; display: block;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.55));
  transform-origin: 50% 65%;
  animation: dragon-fly 1.9s ease-in-out infinite;
  user-select: none; -webkit-user-drag: none;
}
.dragon-loader .dragon-shadow {
  position: absolute; bottom: 0; left: 50%; width: 100px; height: 12px;
  margin-left: -50px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.5); filter: blur(6px);
  animation: dragon-shadow 1.9s ease-in-out infinite;
}
@keyframes dragon-fly {
  0%   { transform: translateY(2px) rotate(-3deg); }
  50%  { transform: translateY(-16px) rotate(3deg); }
  100% { transform: translateY(2px) rotate(-3deg); }
}
@keyframes dragon-shadow {
  0%   { transform: scale(1);   opacity: 0.45; }
  50%  { transform: scale(0.65); opacity: 0.22; }
  100% { transform: scale(1);   opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .dragon-loader .dragon, .dragon-loader .dragon-shadow { animation: none; }
}
.flip-loading .progress { width: 220px; height: 5px; border-radius: 100px; background: var(--border); overflow: hidden; }
.flip-loading .progress .bar { height: 100%; width: 0; background: linear-gradient(90deg, var(--accent), var(--gold)); transition: width 0.25s; }

/* Nav arrows */
.flip-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 20;
  width: 52px; height: 52px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(22, 27, 39, 0.7); backdrop-filter: blur(10px);
  border: 1px solid var(--border); color: var(--text);
  transition: all 0.2s var(--ease);
}
.flip-nav:hover { background: var(--accent); border-color: var(--accent); transform: translateY(-50%) scale(1.07); }
.flip-nav.prev { left: 24px; }
.flip-nav.next { right: 24px; }
.flip-nav:disabled { opacity: 0; pointer-events: none; }

/* Bottom control dock */
.viewer-dock {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 14px; z-index: 30;
}
.dock {
  display: flex; align-items: center; gap: 4px;
  padding: 7px; border-radius: 100px;
  background: rgba(22, 27, 39, 0.8); backdrop-filter: blur(14px);
  border: 1px solid var(--border); box-shadow: var(--shadow);
}
.dock button {
  width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer;
  display: grid; place-items: center; background: transparent; color: var(--text-soft);
  transition: all 0.18s var(--ease);
}
.dock button:hover { background: var(--surface-hover); color: var(--text); }
.dock button:disabled { opacity: 0.35; cursor: not-allowed; }
.dock .page-readout {
  font-size: 0.86rem; font-weight: 600; color: var(--text-soft);
  padding: 0 14px; min-width: 92px; text-align: center; font-variant-numeric: tabular-nums;
}
.dock .divider { width: 1px; height: 22px; background: var(--border); margin: 0 4px; }
.dock .zoom-readout {
  font-size: 0.76rem; font-weight: 600; color: var(--text-dim);
  min-width: 44px; text-align: center; font-variant-numeric: tabular-nums;
}
.dock button.ok { color: var(--success); }

/* CSS-only fullscreen fallback (iOS Safari can't fullscreen a div) */
body.pseudo-fs .viewer-bar { display: none; }

/* Page-slider scrubber */
.scrubber { display: flex; align-items: center; gap: 12px; padding: 0 10px; width: 220px; }
.scrubber input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 4px;
  border-radius: 100px; background: var(--border); cursor: pointer;
}
.scrubber input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 15px; height: 15px; border-radius: 50%;
  background: var(--accent); border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.4);
}
.scrubber input[type=range]::-moz-range-thumb {
  width: 15px; height: 15px; border-radius: 50%; background: var(--accent);
  border: 2px solid #fff;
}

/* ---------- Responsive ---------- */
@media (max-width: 720px) {
  .grid { gap: 18px; }
  .hero { padding: 40px 0 26px; }
  .section-head { align-items: stretch; }
  .search { width: 100%; min-width: 0; }
  .flip-nav { width: 42px; height: 42px; }
  .flip-nav.prev { left: 8px; } .flip-nav.next { right: 8px; }
  .scrubber { display: none; }
  .viewer-bar { padding: 12px 14px; }
  .brand-text .tag { display: none; }
  .hide-sm { display: none; }

  /* The per-frame drop-shadow filter flickers and is costly on phones — use a
     cheap static shadow instead (single-page portrait has no transparent half,
     so there's no ghost outline to worry about here). */
  .flip-area canvas { filter: none; }
  #flipbook { box-shadow: 0 12px 30px -8px rgba(0, 0, 0, 0.7); }

  /* Keep the bottom control dock from running off a narrow screen: drop the
     first/last + zoom buttons (pinch-zoom still works) and tighten spacing. */
  .viewer-dock { padding: 10px 8px; }
  .dock { gap: 2px; padding: 6px; max-width: calc(100vw - 24px); }
  .dock button { width: 38px; height: 38px; }
  .dock #first, .dock #last,
  .dock #zoom-in, .dock #zoom-out,
  .dock .zoom-readout, .dock .divider { display: none; }
  .dock .page-readout { min-width: 60px; padding: 0 8px; font-size: 0.82rem; }
  .thumb-item img { height: 64px; }
}
@media (max-width: 400px) {
  .dock #sound { display: none; }   /* keep the dock on-screen on tiny phones */
}

/* Fade-in on load */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.rise { animation: rise 0.5s var(--ease) both; }
