/* =====================================================================
   BookPilot AI — design system
   =====================================================================

   One stylesheet, three jobs: tokens, primitives, components. The app
   and the landing page both build on it so a button on the pricing
   table and a button in the campaign wizard are the same button.

   Typography reuses the self-hosted DM Sans / DM Serif Display already
   in this repository (/fonts/fonts.css) — no request ever leaves the
   visitor's browser for a font, which is both faster and one less
   third-party transfer to disclose.

   Colour: a restrained ink-and-indigo palette with a single warm accent.
   Deliberately not a gradient-heavy "AI product" look — the audience is
   authors deciding whether to trust software with their advertising
   budget, and calm reads as competent.
   ===================================================================== */

/* ------------------------------------------------------------------ */
/* Tokens — light                                                      */
/* ------------------------------------------------------------------ */

:root {
  color-scheme: light;

  /* Surfaces. `page` is the ground, `surface` is a card on it,
     `raised` is a card on a card (a modal, a popover). */
  --bp-page: #fbfaf8;
  --bp-surface: #ffffff;
  --bp-raised: #ffffff;
  --bp-sunken: #f5f4f1;
  --bp-border: #e6e3dd;
  --bp-border-strong: #d3cfc7;

  /* Ink */
  --bp-text: #1a1a1c;
  --bp-text-muted: #62615f;
  --bp-text-subtle: #8b8985;
  --bp-text-inverse: #ffffff;

  /* Brand */
  --bp-primary: #3f3aa8;
  --bp-primary-hover: #332e8f;
  --bp-primary-soft: #eeedfa;
  --bp-primary-border: #cfccf0;
  --bp-primary-text: #302b86;

  /* Warm accent — the "book" note in the palette. Used sparingly:
     highlights, the winner badge, the demo ribbon. */
  --bp-accent: #a9631a;
  --bp-accent-soft: #fdf3e6;
  --bp-accent-border: #f0dcbf;

  /* Status */
  --bp-success: #1c7355;
  --bp-success-soft: #e7f4ef;
  --bp-success-border: #bfe0d4;
  --bp-warning: #9a6414;
  --bp-warning-soft: #fdf3e2;
  --bp-warning-border: #f0ddb9;
  --bp-danger: #a32d3a;
  --bp-danger-soft: #fdeced;
  --bp-danger-border: #f3ccd0;
  --bp-info: #1f5c8b;
  --bp-info-soft: #ebf3f9;
  --bp-info-border: #c5dcec;

  /* Elevation. Soft and low — a premium interface casts small shadows. */
  --bp-shadow-sm: 0 1px 2px rgba(24, 22, 18, 0.05);
  --bp-shadow: 0 1px 3px rgba(24, 22, 18, 0.06), 0 6px 16px -6px rgba(24, 22, 18, 0.08);
  --bp-shadow-lg: 0 2px 6px rgba(24, 22, 18, 0.06), 0 20px 40px -16px rgba(24, 22, 18, 0.16);
  --bp-ring: 0 0 0 3px rgba(63, 58, 168, 0.18);

  /* Shape */
  --bp-radius-sm: 6px;
  --bp-radius: 10px;
  --bp-radius-lg: 14px;
  --bp-radius-xl: 20px;
  --bp-radius-pill: 999px;

  /* Space — 4px base */
  --bp-1: 4px;
  --bp-2: 8px;
  --bp-3: 12px;
  --bp-4: 16px;
  --bp-5: 20px;
  --bp-6: 24px;
  --bp-8: 32px;
  --bp-10: 40px;
  --bp-12: 48px;
  --bp-16: 64px;
  --bp-20: 80px;
  --bp-24: 96px;

  /* Type */
  --bp-font-sans: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --bp-font-serif: 'DM Serif Display', Georgia, 'Times New Roman', serif;
  --bp-font-mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;

  --bp-sidebar-width: 244px;
  --bp-topbar-height: 64px;
  --bp-content-max: 1180px;
}

/* ------------------------------------------------------------------ */
/* Tokens — dark                                                       */
/*                                                                     */
/* Dark mode is a real palette, not an inversion: the ground is a warm  */
/* near-black so book covers and creative previews don't look grey.     */
/* ------------------------------------------------------------------ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --bp-page: #131316;
    --bp-surface: #1b1b1f;
    --bp-raised: #232329;
    --bp-sunken: #17171a;
    --bp-border: #2e2e35;
    --bp-border-strong: #3d3d46;

    --bp-text: #f2f1ee;
    --bp-text-muted: #a9a7a2;
    --bp-text-subtle: #7d7b77;
    --bp-text-inverse: #16161a;

    --bp-primary: #9b96f0;
    --bp-primary-hover: #b0abf7;
    --bp-primary-soft: #22213a;
    --bp-primary-border: #3a3766;
    --bp-primary-text: #b8b4f8;

    --bp-accent: #e0a35c;
    --bp-accent-soft: #2b2118;
    --bp-accent-border: #4a3a26;

    --bp-success: #5cc79f;
    --bp-success-soft: #14241d;
    --bp-success-border: #27443a;
    --bp-warning: #e0b463;
    --bp-warning-soft: #262017;
    --bp-warning-border: #453a26;
    --bp-danger: #f08a95;
    --bp-danger-soft: #2a181b;
    --bp-danger-border: #4d2a2f;
    --bp-info: #7ab6e0;
    --bp-info-soft: #16222b;
    --bp-info-border: #2b4152;

    --bp-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --bp-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 6px 16px -6px rgba(0, 0, 0, 0.5);
    --bp-shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.45), 0 20px 40px -16px rgba(0, 0, 0, 0.6);
    --bp-ring: 0 0 0 3px rgba(155, 150, 240, 0.25);
  }
}

/* Explicit choice from the theme toggle wins over the system setting. */
:root[data-theme='dark'] {
  color-scheme: dark;
  --bp-page: #131316;
  --bp-surface: #1b1b1f;
  --bp-raised: #232329;
  --bp-sunken: #17171a;
  --bp-border: #2e2e35;
  --bp-border-strong: #3d3d46;
  --bp-text: #f2f1ee;
  --bp-text-muted: #a9a7a2;
  --bp-text-subtle: #7d7b77;
  --bp-text-inverse: #16161a;
  --bp-primary: #9b96f0;
  --bp-primary-hover: #b0abf7;
  --bp-primary-soft: #22213a;
  --bp-primary-border: #3a3766;
  --bp-primary-text: #b8b4f8;
  --bp-accent: #e0a35c;
  --bp-accent-soft: #2b2118;
  --bp-accent-border: #4a3a26;
  --bp-success: #5cc79f;
  --bp-success-soft: #14241d;
  --bp-success-border: #27443a;
  --bp-warning: #e0b463;
  --bp-warning-soft: #262017;
  --bp-warning-border: #453a26;
  --bp-danger: #f08a95;
  --bp-danger-soft: #2a181b;
  --bp-danger-border: #4d2a2f;
  --bp-info: #7ab6e0;
  --bp-info-soft: #16222b;
  --bp-info-border: #2b4152;
  --bp-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --bp-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), 0 6px 16px -6px rgba(0, 0, 0, 0.5);
  --bp-shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.45), 0 20px 40px -16px rgba(0, 0, 0, 0.6);
  --bp-ring: 0 0 0 3px rgba(155, 150, 240, 0.25);
}

/* ------------------------------------------------------------------ */
/* Base                                                                */
/* ------------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

/* The user-agent rule for [hidden] is a bare attribute selector, so any
   component rule that sets `display` outranks it — an element toggled
   with `el.hidden = true` then stays on screen. Every filter in the app
   uses that property, so make it win. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bp-page);
  color: var(--bp-text);
  font-family: var(--bp-font-sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5 {
  margin: 0;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--bp-text);
}

h1 { font-size: clamp(1.9rem, 1.4rem + 1.8vw, 2.8rem); }
h2 { font-size: clamp(1.5rem, 1.2rem + 1.1vw, 2.1rem); }
h3 { font-size: 1.24rem; }
h4 { font-size: 1.05rem; }

p { margin: 0 0 var(--bp-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--bp-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

img, svg { max-width: 100%; }

hr {
  border: 0;
  border-top: 1px solid var(--bp-border);
  margin: var(--bp-6) 0;
}

::selection { background: var(--bp-primary-soft); color: var(--bp-primary-text); }

:focus-visible {
  outline: 2px solid var(--bp-primary);
  outline-offset: 2px;
  border-radius: var(--bp-radius-sm);
}

/* The display face is reserved for editorial moments: the landing hero,
   section titles, a book title on its detail page. Using it for UI
   labels makes a dashboard look like a brochure. */
.bp-display {
  font-family: var(--bp-font-serif);
  font-weight: 400;
  letter-spacing: -0.01em;
}

.bp-eyebrow {
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bp-text-subtle);
}

.bp-lead { font-size: 1.08rem; color: var(--bp-text-muted); }
.bp-muted { color: var(--bp-text-muted); }
.bp-subtle { color: var(--bp-text-subtle); }
.bp-small { font-size: 0.85rem; }
.bp-tiny { font-size: 0.78rem; }
.bp-mono { font-family: var(--bp-font-mono); font-size: 0.85em; }

/* ------------------------------------------------------------------ */
/* Buttons                                                             */
/* ------------------------------------------------------------------ */

.bp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--bp-2);
  padding: 9px 16px;
  border: 1px solid transparent;
  border-radius: var(--bp-radius);
  background: var(--bp-surface);
  color: var(--bp-text);
  font: inherit;
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease, border-color 0.15s ease,
              color 0.15s ease, box-shadow 0.15s ease, transform 0.06s ease;
}
.bp-btn:hover { text-decoration: none; }
.bp-btn:active { transform: translateY(0.5px); }
.bp-btn:disabled, .bp-btn[aria-disabled='true'] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

.bp-btn--primary {
  background: var(--bp-primary);
  border-color: var(--bp-primary);
  color: var(--bp-text-inverse);
  box-shadow: var(--bp-shadow-sm);
}
.bp-btn--primary:hover:not(:disabled) { background: var(--bp-primary-hover); border-color: var(--bp-primary-hover); }

.bp-btn--secondary {
  background: var(--bp-surface);
  border-color: var(--bp-border-strong);
  color: var(--bp-text);
}
.bp-btn--secondary:hover:not(:disabled) { background: var(--bp-sunken); }

.bp-btn--ghost { background: transparent; color: var(--bp-text-muted); }
.bp-btn--ghost:hover:not(:disabled) { background: var(--bp-sunken); color: var(--bp-text); }

.bp-btn--danger {
  background: var(--bp-danger-soft);
  border-color: var(--bp-danger-border);
  color: var(--bp-danger);
}
.bp-btn--danger:hover:not(:disabled) { background: var(--bp-danger); color: var(--bp-text-inverse); border-color: var(--bp-danger); }

.bp-btn--lg { padding: 13px 24px; font-size: 1rem; border-radius: var(--bp-radius-lg); }
.bp-btn--sm { padding: 6px 11px; font-size: 0.82rem; border-radius: var(--bp-radius-sm); }
.bp-btn--block { width: 100%; }

/* ------------------------------------------------------------------ */
/* Cards and panels                                                    */
/* ------------------------------------------------------------------ */

.bp-card {
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius-lg);
  padding: var(--bp-6);
}
.bp-card--flush { padding: 0; overflow: hidden; }
.bp-card--raised { box-shadow: var(--bp-shadow); }
.bp-card--interactive { transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease; }
.bp-card--interactive:hover {
  border-color: var(--bp-border-strong);
  box-shadow: var(--bp-shadow);
  transform: translateY(-1px);
}

.bp-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--bp-4);
  margin-bottom: var(--bp-4);
}
.bp-card__title { font-size: 1.02rem; font-weight: 600; }

.bp-panel {
  background: var(--bp-sunken);
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius);
  padding: var(--bp-4);
}

/* ------------------------------------------------------------------ */
/* Forms                                                               */
/* ------------------------------------------------------------------ */

.bp-field { margin-bottom: var(--bp-5); }
.bp-field:last-child { margin-bottom: 0; }

.bp-label {
  display: block;
  margin-bottom: 6px;
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--bp-text);
}
.bp-hint { margin-top: 6px; font-size: 0.82rem; color: var(--bp-text-subtle); }
.bp-error-text { margin-top: 6px; font-size: 0.82rem; color: var(--bp-danger); }

.bp-input, .bp-select, .bp-textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--bp-border-strong);
  border-radius: var(--bp-radius);
  background: var(--bp-surface);
  color: var(--bp-text);
  font: inherit;
  font-size: 0.94rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.bp-textarea { min-height: 110px; resize: vertical; line-height: 1.55; }
.bp-input:focus, .bp-select:focus, .bp-textarea:focus {
  outline: none;
  border-color: var(--bp-primary);
  box-shadow: var(--bp-ring);
}
.bp-input::placeholder, .bp-textarea::placeholder { color: var(--bp-text-subtle); }
.bp-input:disabled, .bp-select:disabled, .bp-textarea:disabled {
  background: var(--bp-sunken);
  color: var(--bp-text-subtle);
  cursor: not-allowed;
}
.bp-input[aria-invalid='true'], .bp-textarea[aria-invalid='true'] { border-color: var(--bp-danger); }

.bp-select {
  appearance: none;
  padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%238b8985' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 12px;
}

.bp-checkbox, .bp-radio {
  display: flex;
  align-items: flex-start;
  gap: var(--bp-3);
  padding: var(--bp-3);
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.bp-checkbox:hover, .bp-radio:hover { border-color: var(--bp-border-strong); background: var(--bp-sunken); }
.bp-checkbox input, .bp-radio input { margin: 3px 0 0; accent-color: var(--bp-primary); flex: none; }
.bp-checkbox--selected, .bp-radio--selected {
  border-color: var(--bp-primary);
  background: var(--bp-primary-soft);
}

.bp-field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--bp-4);
}

/* ------------------------------------------------------------------ */
/* Badges, chips, pills                                                */
/* ------------------------------------------------------------------ */

.bp-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius-pill);
  background: var(--bp-sunken);
  color: var(--bp-text-muted);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.7;
  white-space: nowrap;
}
.bp-badge--primary { background: var(--bp-primary-soft); border-color: var(--bp-primary-border); color: var(--bp-primary-text); }
.bp-badge--success { background: var(--bp-success-soft); border-color: var(--bp-success-border); color: var(--bp-success); }
.bp-badge--warning { background: var(--bp-warning-soft); border-color: var(--bp-warning-border); color: var(--bp-warning); }
.bp-badge--danger  { background: var(--bp-danger-soft);  border-color: var(--bp-danger-border);  color: var(--bp-danger); }
.bp-badge--info    { background: var(--bp-info-soft);    border-color: var(--bp-info-border);    color: var(--bp-info); }
.bp-badge--accent  { background: var(--bp-accent-soft);  border-color: var(--bp-accent-border);  color: var(--bp-accent); }

/* The demo ribbon. It appears on every screen that renders sample data
   and is deliberately hard to miss — presenting simulated advertising
   results as real ones is the one thing this product must never do. */
.bp-demo-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px dashed var(--bp-accent-border);
  border-radius: var(--bp-radius-pill);
  background: var(--bp-accent-soft);
  color: var(--bp-accent);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.bp-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius-pill);
  background: var(--bp-surface);
  color: var(--bp-text-muted);
  font-size: 0.83rem;
  cursor: pointer;
  transition: all 0.15s ease;
}
.bp-chip:hover { border-color: var(--bp-border-strong); color: var(--bp-text); }
.bp-chip--active {
  background: var(--bp-primary-soft);
  border-color: var(--bp-primary-border);
  color: var(--bp-primary-text);
  font-weight: 500;
}

.bp-chips { display: flex; flex-wrap: wrap; gap: var(--bp-2); }

/* ------------------------------------------------------------------ */
/* Stats                                                               */
/* ------------------------------------------------------------------ */

.bp-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--bp-3);
}

/* The eight headline metrics are a fixed set, so give them a fixed
   shape: 4x2 reads as one block, where an auto-fit wrap leaves two
   orphans on the second row at most desktop widths. */
@media (min-width: 760px) {
  .bp-stat-grid--quad { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.bp-stat {
  padding: var(--bp-4);
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius);
}
.bp-stat__label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--bp-text-subtle);
}
.bp-stat__value {
  margin-top: 4px;
  font-size: 1.6rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
/* "N/A" is a legitimate value, not an error — it reads as unknown, not
   as zero. See js/core/metrics.js. */
.bp-stat__value--na { color: var(--bp-text-subtle); font-size: 1.1rem; font-weight: 400; }
.bp-stat__meta { margin-top: 4px; font-size: 0.8rem; color: var(--bp-text-muted); }

/* ------------------------------------------------------------------ */
/* Tables                                                              */
/* ------------------------------------------------------------------ */

.bp-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.bp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}
.bp-table th, .bp-table td {
  padding: 11px var(--bp-4);
  text-align: left;
  border-bottom: 1px solid var(--bp-border);
  vertical-align: middle;
}
.bp-table th {
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bp-text-subtle);
  white-space: nowrap;
  background: var(--bp-sunken);
}
.bp-table th[data-sortable] { cursor: pointer; user-select: none; }
.bp-table th[data-sortable]:hover { color: var(--bp-text); }
.bp-table tbody tr:last-child td { border-bottom: 0; }
.bp-table tbody tr:hover { background: var(--bp-sunken); }
.bp-table .bp-num { text-align: right; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ */
/* Empty states (spec §36)                                             */
/* ------------------------------------------------------------------ */

.bp-empty {
  padding: var(--bp-12) var(--bp-6);
  text-align: center;
  border: 1px dashed var(--bp-border-strong);
  border-radius: var(--bp-radius-lg);
  background: var(--bp-surface);
}
.bp-empty__icon { font-size: 1.9rem; line-height: 1; margin-bottom: var(--bp-3); opacity: 0.75; }
.bp-empty__title { font-family: var(--bp-font-serif); font-size: 1.32rem; margin-bottom: 6px; }
.bp-empty__text { color: var(--bp-text-muted); max-width: 44ch; margin: 0 auto var(--bp-5); }

/* ------------------------------------------------------------------ */
/* Alerts                                                              */
/* ------------------------------------------------------------------ */

.bp-alert {
  display: flex;
  gap: var(--bp-3);
  padding: var(--bp-4);
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius);
  background: var(--bp-sunken);
  font-size: 0.9rem;
}
.bp-alert__icon { flex: none; line-height: 1.5; }
.bp-alert__title { font-weight: 600; margin-bottom: 2px; }
.bp-alert--info    { background: var(--bp-info-soft);    border-color: var(--bp-info-border); }
.bp-alert--success { background: var(--bp-success-soft); border-color: var(--bp-success-border); }
.bp-alert--warning { background: var(--bp-warning-soft); border-color: var(--bp-warning-border); }
.bp-alert--danger  { background: var(--bp-danger-soft);  border-color: var(--bp-danger-border); }

/* ------------------------------------------------------------------ */
/* Progress, loading                                                   */
/* ------------------------------------------------------------------ */

.bp-progress {
  height: 6px;
  border-radius: var(--bp-radius-pill);
  background: var(--bp-sunken);
  overflow: hidden;
}
.bp-progress__bar {
  height: 100%;
  background: var(--bp-primary);
  border-radius: inherit;
  transition: width 0.3s ease;
}

.bp-skeleton {
  border-radius: var(--bp-radius-sm);
  background: linear-gradient(90deg, var(--bp-sunken) 25%, var(--bp-border) 50%, var(--bp-sunken) 75%);
  background-size: 200% 100%;
  animation: bp-shimmer 1.4s ease-in-out infinite;
}
@keyframes bp-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.bp-spinner {
  display: inline-block;
  width: 15px;
  height: 15px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: bp-spin 0.65s linear infinite;
  vertical-align: -2px;
}
@keyframes bp-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------------ */
/* Toasts                                                              */
/* ------------------------------------------------------------------ */

.bp-toasts {
  position: fixed;
  right: var(--bp-4);
  bottom: var(--bp-4);
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: var(--bp-2);
  max-width: min(380px, calc(100vw - 32px));
}
.bp-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--bp-3);
  padding: var(--bp-3) var(--bp-4);
  border: 1px solid var(--bp-border-strong);
  border-radius: var(--bp-radius);
  background: var(--bp-raised);
  box-shadow: var(--bp-shadow-lg);
  font-size: 0.89rem;
  animation: bp-toast-in 0.2s ease;
}
.bp-toast--success { border-left: 3px solid var(--bp-success); }
.bp-toast--error   { border-left: 3px solid var(--bp-danger); }
.bp-toast--info    { border-left: 3px solid var(--bp-info); }
@keyframes bp-toast-in { from { opacity: 0; transform: translateY(8px); } }

/* ------------------------------------------------------------------ */
/* Modal                                                               */
/* ------------------------------------------------------------------ */

.bp-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--bp-4);
  background: rgba(20, 18, 15, 0.42);
  backdrop-filter: blur(2px);
  animation: bp-fade 0.15s ease;
}
@keyframes bp-fade { from { opacity: 0; } }

.bp-modal {
  width: 100%;
  max-width: 560px;
  max-height: min(86vh, 780px);
  overflow-y: auto;
  background: var(--bp-raised);
  border: 1px solid var(--bp-border);
  border-radius: var(--bp-radius-xl);
  box-shadow: var(--bp-shadow-lg);
  padding: var(--bp-6);
}
.bp-modal--wide { max-width: 820px; }
.bp-modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--bp-4);
  margin-bottom: var(--bp-4);
}
.bp-modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--bp-2);
  margin-top: var(--bp-6);
}

/* ------------------------------------------------------------------ */
/* Tabs                                                                */
/* ------------------------------------------------------------------ */

.bp-tabs {
  display: flex;
  gap: var(--bp-1);
  border-bottom: 1px solid var(--bp-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.bp-tabs::-webkit-scrollbar { display: none; }
.bp-tab {
  padding: 9px 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--bp-text-muted);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.bp-tab:hover { color: var(--bp-text); }
.bp-tab--active { color: var(--bp-primary); border-bottom-color: var(--bp-primary); }

/* ------------------------------------------------------------------ */
/* Utilities                                                           */
/* ------------------------------------------------------------------ */

.bp-stack > * + * { margin-top: var(--bp-4); }
.bp-stack-sm > * + * { margin-top: var(--bp-2); }
.bp-stack-lg > * + * { margin-top: var(--bp-6); }

.bp-row { display: flex; align-items: center; gap: var(--bp-3); }
.bp-row--between { justify-content: space-between; }
.bp-row--wrap { flex-wrap: wrap; }
.bp-row--top { align-items: flex-start; }

.bp-grid { display: grid; gap: var(--bp-4); }
.bp-grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.bp-grid--3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.bp-grid--cards { grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }

.bp-flex-1 { flex: 1; min-width: 0; }
.bp-hidden { display: none !important; }
.bp-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bp-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bp-clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bp-center { text-align: center; }
.bp-right { text-align: right; }
.bp-nowrap { white-space: nowrap; }
.bp-pre-wrap { white-space: pre-wrap; }

.bp-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.bp-skip-link {
  position: absolute;
  left: -9999px;
  top: var(--bp-2);
  z-index: 400;
  padding: 10px 16px;
  background: var(--bp-primary);
  color: var(--bp-text-inverse);
  border-radius: var(--bp-radius);
}
.bp-skip-link:focus { left: var(--bp-2); }

.bp-divider { height: 1px; background: var(--bp-border); margin: var(--bp-5) 0; }

/* Book cover: consistent 2:3 with a graceful fallback when an author
   hasn't uploaded one yet. */
.bp-cover {
  aspect-ratio: 2 / 3;
  border-radius: var(--bp-radius-sm);
  background: var(--bp-sunken);
  border: 1px solid var(--bp-border);
  object-fit: cover;
  display: block;
  width: 100%;
}
.bp-cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Padding scales with the cover so the smallest one (the 76px hero
     thumbnail) is not mostly padding. */
  padding: 6%;
  text-align: center;
  font-family: var(--bp-font-serif);
  font-size: 0.78rem;
  color: var(--bp-text-subtle);
  line-height: 1.25;
  /* The title is author-supplied and the box is narrow, so a single long
     word can be wider than the cover. Break it rather than letting it
     spill over the artwork beside it, and clip whatever still will not
     fit — centred flex content overflows both edges, not just the end. */
  overflow: hidden;
  overflow-wrap: anywhere;
}
