/*
 * F10P base + component styles. Plain CSS, token-driven (see tokens.css).
 * Organised top-down: reset -> layout chrome -> discover surface -> cards ->
 * detail page. Class names follow a light BEM-ish convention (block__element).
 */

/* --- Reset & base --------------------------------------------------------- */

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

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

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
  transition: opacity var(--transition);
}

a:hover {
  opacity: 0.82;
}

:focus-visible {
  outline: 2px solid var(--accent-brand);
  outline-offset: 2px;
}



h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
}

img {
  max-width: 100%;
  display: block;
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--space-6);
}

.muted {
  color: var(--ink-muted);
}

/* --- Site chrome (navbar — ported from the old Navbar.js) ----------------- */
/* The header is page-coloured and borderless ON PURPOSE (not a card surface):
   it dissolves into the page exactly like the old app. Tokens map old→new
   (--background→--bg, --foreground→--ink, --text-secondary→--ink-muted,
   --accent-foreground→--accent-ink, --border-light→--border). */

.navbar {
  background: var(--bg);
  padding: var(--space-5) 0;          /* 1.5rem top/bottom, like the old */
  position: sticky;
  top: 0;
  z-index: 100;
}

.navbar-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}

.logo-link { text-decoration: none; color: inherit; display: inline-flex; align-items: center; }
.logo-link:hover { opacity: 0.85; }

/* F10P mark in ink colour (adapts to light/dark themes via currentColor). */
.logo-wrapper {
  display: inline-flex;
  align-items: center;
  color: var(--ink);
  line-height: 1;
}

.site-logo {
  height: 28px;
  width: auto;
  max-width: 100%;
  display: block;
}

/* Global search pill + live dropdown. */
.search-bar {
  flex: 1;
  max-width: 480px;
  position: relative;
  display: flex;
  align-items: center;
  /* Intentionally a CONSTANT light pill in both themes (the old hardcodes
     #F0F0F0); it is not a theme surface, so it deliberately avoids --surface-*. */
  background: #f0f0f0;
  border-radius: var(--radius-md);
  padding: 0 var(--space-4);
  gap: var(--space-3);
  border: 1px solid transparent;
  transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
}
.search-bar:focus-within {
  background: #ffffff;
  border-color: var(--border);
  box-shadow: var(--shadow-sm);
}
.search-bar .search-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  padding: var(--space-3) 0;
  font: inherit;
  font-size: 0.95rem;
  height: 48px;
  color: #111111;                     /* constant dark text on the constant light pill */
  outline: none;
}
.search-bar .search-input::placeholder { color: var(--ink-muted); }
.search-icon { color: var(--ink-muted); opacity: 0.7; flex-shrink: 0; }

.clear-search-btn {
  background: transparent;
  border: none;
  color: #9ca3af;
  cursor: pointer;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background var(--transition), color var(--transition);
}
.clear-search-btn:hover { background: #e5e7eb; color: #4b5563; }

/* Live results dropdown — a white floating card under the pill. */
.search-dropdown {
  position: absolute;
  top: calc(100% + 16px);
  left: 0;
  width: 100%;
  background: #ffffff;
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.12);
  border: 1px solid #e5e7eb;
  overflow: hidden;
  z-index: 150;
  padding: var(--space-2);
}
.results-list { list-style: none; display: flex; flex-direction: column; gap: var(--space-1); }
.result-link {
  display: flex;
  align-items: center;
  padding: 0.85rem 1rem;
  text-decoration: none;
  border-radius: var(--radius-md);
  transition: background var(--transition);
}
.result-link:hover { background: #f3f4f6; opacity: 1; }
.result-thumbnail {
  width: 40px;
  height: 60px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #e5e7eb;
  margin-right: 1.25rem;
  flex-shrink: 0;
}
.result-thumbnail img { width: 100%; height: 100%; object-fit: cover; }
.result-info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.result-title {
  font-weight: 700;
  color: #111827;
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.result-meta {
  font-size: var(--text-xs);
  color: #6b7280;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.no-results {
  padding: var(--space-5);
  text-align: center;
  color: #6b7280;
  font-style: italic;
  font-size: 0.9rem;
}

/* Right-side nav actions. */
.nav-actions { display: flex; align-items: center; gap: var(--space-6); }
.nav-link {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color var(--transition);
}
.nav-link:hover { color: var(--ink); opacity: 1; }
/* The logout control is a <button> in a POST form (LogoutView rejects GET) —
   strip the browser button chrome so it reads exactly like the sibling links. */
.nav-logout { display: inline-flex; }
.nav-link--button { background: none; border: none; padding: 0; font: inherit; cursor: pointer; }

/* Black primary button (white text on --accent); used by the Upload action. */
.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.6rem 1.25rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: 0.9rem;
  border: none;
  cursor: pointer;
  font-family: inherit;
  display: inline-block;
  transition: transform 0.1s ease, opacity var(--transition);
}
.btn-primary:hover { opacity: 0.9; transform: translateY(-1px); }

.nav-user-area { display: flex; align-items: center; gap: var(--space-5); }
/* Gold Pro Center link (constant gold across themes). */
.pro-link, .pro-link:hover { color: var(--gold); font-weight: 700; }

.user-profile {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  overflow: hidden;
  flex-shrink: 0;
  transition: border-color var(--transition), transform var(--transition);
}
.user-profile:hover { border-color: var(--ink-muted); transform: scale(1.04); opacity: 1; }
.user-profile img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Mobile Menu Toggle (hidden on desktop) */
.mobile-menu-toggle {
  display: none;
  background: transparent;
  border: none;
  color: var(--ink);
  cursor: pointer;
  padding: var(--space-1);
}

@media (max-width: 768px) {
  .navbar-content {
    flex-wrap: wrap;
    gap: var(--space-4);
  }
  .logo-link { order: 1; margin-right: auto; }
  .mobile-menu-toggle { display: block; order: 2; }
  .search-bar { order: 3; width: 100%; max-width: none; }
  
  /* The mobile drawer */
  .nav-actions {
    display: none;
    order: 4;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    background: var(--surface);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    box-shadow: var(--shadow-sm);
    border: 1px solid var(--border);
    gap: var(--space-4);
  }
  .nav-actions.is-open { display: flex; }
  .nav-link, .btn-primary { padding: 0.75rem 0; width: 100%; text-align: left; }
  .btn-primary { text-align: center; }
  .nav-user-area { flex-direction: column; align-items: flex-start; width: 100%; gap: var(--space-3); }
}

/* .site-footer lives in components.css now (the full ported footer). */

/* --- Discover surface (ported from the old discover page) ----------------- */
.discover-page { padding: var(--space-6) 0; }

.discover-header { text-align: center; margin-bottom: 2.5rem; }
.page-title { font-size: 2.5rem; font-weight: 800; letter-spacing: -0.03em; margin-bottom: var(--space-2); }
.page-subtitle { color: var(--ink-muted); font-size: 1.1rem; }

.controls-bar { display: flex; flex-direction: column; gap: var(--space-5); margin-bottom: var(--space-6); }

/* Centered search bar with a left magnifier icon. */
.search-wrapper { position: relative; width: 100%; max-width: 600px; margin: 0 auto; }
.search-wrapper input {
  width: 100%;
  padding: 1rem 1rem 1rem 3rem;
  border-radius: 12px;
  /* Forced-white search pill, ported verbatim from the old discover page: the
     old hardcodes background:#fff + a faint black border regardless of theme, so
     on this dark page the pill stays white with dark text. Deliberate constant,
     not a token — do NOT remap to --surface/--ink (that renders it dark). */
  border: 1px solid rgba(0, 0, 0, 0.1);
  background: #fff;
  color: #111;
  font: inherit;
  font-size: 1rem;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.search-wrapper input:focus { outline: none; border-color: var(--accent); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); }
.search-icon-container { position: absolute; left: 1rem; top: 50%; transform: translateY(-50%); color: var(--ink-muted); display: flex; pointer-events: none; }

/* Genre scroll row + sort control, fenced by hairlines top and bottom. */
.filters-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-4) 0;
  /* Ported verbatim from the old discover page: a faint black hairline that the
     old hardcodes regardless of theme. On this dark page it renders effectively
     invisible (black at 5% over near-black) — so the fence reads as no fence,
     exactly as the old does. Deliberate constant, not --border (which would show
     a visible grey line the old never has). */
  border-top: 1px solid rgba(0, 0, 0, 0.05);
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.genre-scroll { display: flex; gap: var(--space-2); overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.genre-scroll::-webkit-scrollbar { display: none; }
.genre-pill {
  padding: 0.4rem 1rem;
  border-radius: var(--radius-pill);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--ink-muted);
  font-size: 0.9rem;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.genre-pill:hover { background: var(--surface-2); color: var(--ink); }
.genre-pill--active { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }

.sort-wrapper { display: flex; align-items: center; gap: var(--space-3); }
.sort-label { color: var(--ink-muted); font-size: 0.9rem; white-space: nowrap; }
.custom-select { position: relative; display: inline-flex; align-items: center; }
.custom-select select {
  appearance: none;
  background: transparent;
  border: none;
  padding-right: 1.5rem;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}
.custom-select select:focus { outline: none; }
.select-icon { position: absolute; right: 0; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--ink); }

/* Discover grid: a fixed 4-up that steps down responsively. Scoped to
   .discover-page so the shared .scripts-grid used by other pages is untouched. */
.discover-page .scripts-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-6); }
@media (max-width: 1200px) { .discover-page .scripts-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 900px) { .discover-page .scripts-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .discover-page .scripts-grid { grid-template-columns: 1fr; } }

/* Discover empty state — an icon medallion above the message. */
.empty-state { grid-column: 1 / -1; text-align: center; padding: 4rem 1rem; color: var(--ink-muted); }
.empty-icon { width: 80px; height: 80px; background: var(--surface-2); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto var(--space-5); color: var(--ink-muted); }
.empty-state h3 { margin-bottom: var(--space-2); color: var(--ink); }

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.filters__search,
.filters__select {
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.filters__search {
  flex: 1 1 280px;
}

.filters__search:focus,
.filters__select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

/* --- Card grid ------------------------------------------------------------ */

.scripts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-5);
}

/* Script card (ported from the old <ScriptCard>): a framed card with the cover
   on top, a frosted-white genre pill top-right, and title / writer / 3-line
   logline beneath. The cover zooms on hover; the whole card lifts. */
.card {
  display: block;
  height: 100%;
  /* Frameless on purpose: the old card has NO surface/border/shadow — it is a
     rounded cover + text sitting straight on the page (the page shows through). */
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  transition: transform var(--transition);
}
/* No lift on hover — only the cover zooms gently (the text stays put). */
.card:hover { opacity: 1; }

.card__media {
  position: relative;
  width: 100%;
  /* ~1:1.4 vertical poster (the old uses padding-top: 140%). */
  aspect-ratio: 1 / 1.4;
  /* Dark placeholder, NOT the old's light #f0f0f0: that light grey was a
     light-theme-first leftover, and on this dark page it flashed a thin light
     ring around the rounded corners as the cover scaled on hover (the
     antialiased clip briefly reveals the wrapper bg). A dark placeholder keeps
     any residual seam invisible against the page. */
  background: var(--surface-2);
  overflow: hidden;
  border-radius: 12px;
  /* Promote the clipper to its own layer so the rounded overflow clip is
     rasterised together with the scaling cover — without this, Chrome reclips
     per frame during the zoom and leaks a 1px seam at the corners. */
  transform: translateZ(0);
}
.card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}
.card:hover .card__img { transform: scale(1.05); }

/* Private script locked badge — top-LEFT, frosted dark with lock icon */
.card__lock-badge {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: rgba(17, 17, 17, 0.85);
  backdrop-filter: blur(4px);
  padding: 4px 0.65rem 3px;
  border-radius: var(--radius-pill);
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #ffffff;
  z-index: 2;
  box-shadow: var(--shadow-sm);
}

/* Genre pill — top-RIGHT, frosted-white, dark text (kept dark in both themes
   because the badge background is always near-white). */
.card__genre {

  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  display: inline-flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(4px);
  /* line-height fits the font box (so glyphs aren't clipped/shoved high) and the
     top padding carries 1px more than the bottom to optically centre the all-caps
     label (px here on purpose — it's a sub-token optical nudge). */
  padding: 4px 0.75rem 3px;
  border-radius: var(--radius-pill);
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #111;
}

/* Saved-library card variant: a frosted bookmark where the genre pill would sit,
   but top-LEFT (ported from the old ScriptCard's showBookmark). The circle is
   always near-white, so the glyph stays DARK in both themes (same reasoning as
   .card__genre). The old themed the glyph with var(--foreground), which on this
   dark page resolves to near-white and renders it invisible on the white circle —
   so we use the light-theme intent the white circle was designed for. */
.card__bookmark {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(4px);
  color: #111;
  cursor: pointer;
  z-index: 10;
  transition: transform var(--transition), background var(--transition);
}
.card__bookmark:hover { transform: scale(1.1); background: #fff; }
.card__bookmark--active { background: #fff; }

.card__body { padding: var(--space-5); }
.card__title {
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
  margin-bottom: var(--space-1);
}
.card__writer {
  font-size: 0.85rem;
  color: var(--ink-muted);
  margin-bottom: var(--space-3);
}
.card__logline {
  font-size: 0.85rem;
  color: var(--ink-muted);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Rating glyph + meta row — retained for the marketplace reviewer card and the
   detail page (the script card itself no longer carries a rating overlay). */
.card__rating {
  position: absolute;
  bottom: var(--space-3);
  right: var(--space-3);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  font-size: var(--text-xs);
  font-weight: 700;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  backdrop-filter: blur(4px);
}
.card__rating-star { color: var(--star); }

.card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
  margin-top: var(--space-2);
  /* Wrap whole items to a new line in narrow columns instead of squeezing. */
  flex-wrap: wrap;
}
.rating { color: var(--star); font-weight: 600; }

/* --- Genre cards (image-background, overlaid name + count) ---------------- */
.genre-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-5);
}
.genre-card {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #111;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}
.genre-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); opacity: 1; }
.genre-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.78;
  transition: transform var(--transition-slow), opacity var(--transition);
}
.genre-card:hover .genre-card__img { transform: scale(1.08); opacity: 1; }
.genre-card__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  text-align: center;
  padding: var(--space-6) var(--space-4);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.92) 0%, rgba(0, 0, 0, 0.2) 45%, rgba(0, 0, 0, 0) 100%);
  color: #fff;
}
.genre-card__name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-shadow: 0 6px 16px rgba(0, 0, 0, 0.5);
  color: #fff;
}
.genre-card__count {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.65);
  transition: color var(--transition);
}
.genre-card:hover .genre-card__count { color: var(--accent-brand); }

.empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--space-8) 0;
}

/* --- Saved library (ported from the old SavedLibrary page) ------------------ */
/* A normal themed page — no hardcoded light constants — so every value is a token
   and it just follows the theme. Selectors are scoped to .saved-library-page so
   its .custom-select / .hidden-select never collide with the discover bar's
   same-named classes. Off-scale literals (4rem/6rem/0.75rem) match the old's
   exact values, consistent with the literals already used in the card rules. */
.saved-library-page { padding: 4rem 0; min-height: 80vh; }

.library-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 4rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-5);
}
.header-left h1 {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: var(--space-2);
  color: var(--ink);
}
.script-count { font-size: var(--text-lg); color: var(--ink-muted); font-weight: 500; }

.header-right { display: flex; align-items: center; gap: var(--space-6); margin-bottom: var(--space-2); }
.filter-group { display: flex; align-items: center; gap: var(--space-3); }
.filter-label { font-size: 0.75rem; font-weight: 800; color: var(--ink-muted); letter-spacing: 0.1em; }

/* Value + icon display with an invisible <select> overlaid (.hidden-select), so
   the whole pill is the native dropdown — exactly like the old. */
.saved-library-page .custom-select {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink);
  cursor: pointer;
}
.saved-library-page .custom-select--static { cursor: default; }
.hidden-select { position: absolute; inset: 0; width: 100%; opacity: 0; cursor: pointer; }

.divider { width: 1px; height: 24px; background: var(--border); }

/* Fixed 4-up (row gap 3rem, col gap 2rem), stepping down responsively. */
.library-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-8) var(--space-6); }
.card-wrapper { display: flex; flex-direction: column; gap: var(--space-4); }
.saved-meta { font-size: 0.75rem; color: var(--ink-muted); font-style: italic; padding-left: var(--space-2); }

/* Empty state — folder emoji + message + a real primary CTA. (The old marked the
   CTA "btn-primary" but that class is unscoped there, so it rendered as plain
   text; we render the intended button.) Spans the grid so it stays centred. */
.saved-empty { grid-column: 1 / -1; max-width: 400px; margin: 0 auto; padding: 6rem 0; text-align: center; }
.saved-empty__icon { font-size: 4rem; margin-bottom: var(--space-5); }
.saved-empty h2 { font-size: 1.5rem; margin-bottom: var(--space-4); color: var(--ink); }
.saved-empty p { color: var(--ink-muted); margin-bottom: var(--space-6); }

@media (max-width: 1024px) {
  .library-grid { grid-template-columns: repeat(2, 1fr); }
  .library-header { flex-direction: column; align-items: flex-start; gap: var(--space-6); }
}
@media (max-width: 600px) {
  .library-grid { grid-template-columns: 1fr; }
}

/* --- Writers directory (ported from the old WritersPage + WriterCard) ------ */
/* The old renders this page on the DARK body but hardcodes two LIGHT constants
   it never themes: the search pill and the WriterCards are forced white. Those
   are replicated verbatim. Where the old's dark-theme tokens then LEAK onto
   those forced-white surfaces and render content near-invisible — the writer
   name (var(--foreground) = #ededed) and the genre pill (var(--accent) = a
   white pill) — we instead render the LIGHT-theme intent the white card was
   designed for (a dark name, a black pill), so nothing is invisible. The page
   chrome (headline, subtitle, sort toggles) sits on the page itself, so it
   uses the normal theme tokens and reads light on the dark body. */

.writers-page { min-height: 100vh; padding-bottom: var(--space-8); }

/* Filter band: count + subtitle left, search pill centre, sort toggles right. */
.writers-filters { padding: var(--space-6) 0; margin-bottom: var(--space-4); }
.writers-filters__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-6);
}
.writers-filters__heading { flex-shrink: 0; }
/* Plain Inter (body) bold — the old's headline is NOT the display/serif face. */
.writers-title {
  font-family: var(--font-body);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-bottom: var(--space-1);
}
.writers-subtitle { font-size: 0.9rem; color: var(--ink-muted); }

/* Forced-white search pill — a light constant on the dark page. */
.writers-search {
  flex: 1;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 500px;
  height: 48px;
  padding: 0 var(--space-4);
  background: #ffffff;
  border: 1px solid #e5e5e5;
  border-radius: var(--radius-pill);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.writers-search:focus-within {
  border-color: var(--accent-brand);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
/* The icon stays grey — the old declares #9CA3AF, but without pinning it the
   dark body colour leaks in and the glyph vanishes on the white pill. */
.writers-search__icon { color: #9ca3af; flex-shrink: 0; }
.writers-search input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  outline: none;
  font: inherit;
  font-size: 0.9rem;
  color: #111111; /* dark text on the white pill (the old renders black) */
}
.writers-search input::placeholder { color: #9ca3af; }

/* Sort toggles — text buttons; active = accent text + accent underline. */
.writers-sort { display: flex; gap: var(--space-5); flex-shrink: 0; }
.writers-sort__btn {
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  color: #9ca3af; /* inactive, on the page */
  padding-bottom: var(--space-1);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
}
.writers-sort__btn:hover { color: var(--accent); }
.writers-sort__btn--active { color: var(--accent); border-bottom-color: var(--accent); }

/* Grid: a fixed 4-up stepping down responsively (the old's breakpoints). */
.writers-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
@media (max-width: 1024px) { .writers-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px) { .writers-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-4); } }
@media (max-width: 768px) {
  .writers-filters__row { flex-direction: column; align-items: flex-start; gap: var(--space-5); }
  .writers-search { width: 100%; max-width: 100%; }
  .writers-sort { width: 100%; justify-content: flex-start; }
}

/* Forced-white WriterCard: image on top, name + role + (genre pill / location)
   below. Lifts and zooms its image on hover; the page shows through the gaps. */
.writer-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
  transition: box-shadow 0.3s ease, border-color 0.3s ease;
}
/* No vertical lift on hover (per request) — the card stays put; the cover zooms
   and the border/shadow firm up gently to signal it's interactive. */
.writer-card:hover {
  border-color: #d1d5db;
  box-shadow: 0 8px 18px -8px rgba(0, 0, 0, 0.14);
  opacity: 1; /* override the global a:hover dim — the card highlights, it doesn't fade */
}
.writer-card__media { position: relative; width: 100%; padding-bottom: 100%; background: #f0f0f0; overflow: hidden; }
.writer-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  transition: transform 0.5s ease;
}
.writer-card:hover .writer-card__img { transform: scale(1.05); }

.writer-card__body { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); }
/* DEVIATION: the old declares var(--foreground) → #ededed in dark mode, which is
   near-invisible on the white card. Render the light intent (#111) instead. */
.writer-card__name {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  color: #111111;
  margin-bottom: var(--space-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.writer-card__role {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent-brand); /* the old's #00B5FF cyan role label */
  text-transform: uppercase;
  letter-spacing: 0.025em;
  margin-top: calc(-1 * var(--space-1));
  margin-bottom: var(--space-2);
}
.writer-card__meta { display: flex; align-items: center; justify-content: space-between; width: 100%; }
/* DEVIATION: the old declares var(--accent)/var(--accent-foreground), which in
   dark mode is a WHITE pill with dark text — invisible on the white card. Render
   the light intent: a solid black pill with white text. */
.writer-card__genre {
  background: #111111;
  color: #ffffff;
  font-size: 0.65rem;
  font-weight: 700;
  padding: 0.25rem 0.75rem;
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.writer-card__location {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 0.75rem;
  font-weight: 500;
  color: #666666;
}
.writer-card__pin { color: #9ca3af; flex-shrink: 0; }

/* Empty state — message + a Clear Filters button that resets the search. */
.writers-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) 0;
  color: var(--ink-muted);
}
.writers-empty__clear {
  margin-top: var(--space-4);
  padding: 0.5rem 1.5rem;
  background: var(--accent);
  color: var(--accent-ink);
  border: none;
  border-radius: var(--radius-pill);
  font-weight: 500;
  font-size: 0.9rem;
  cursor: pointer;
}

/* --- Script detail -------------------------------------------------------- */

.detail {
  padding-top: var(--space-8);
  padding-bottom: 16rem;
  min-height: calc(100vh - 200px);
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: var(--space-8);
}

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

.detail__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.detail__cover {
  aspect-ratio: var(--cover-ratio);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: var(--shadow-md);
}

.detail__read-btn {
  font-weight: 700;
  letter-spacing: -0.01em;
  box-shadow: 0 4px 14px rgba(0, 181, 255, 0.25);
  text-decoration: none;
}

.detail__read-btn:hover {
  box-shadow: 0 6px 20px rgba(0, 181, 255, 0.38);
}


.detail__cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.detail__genre {
  display: inline-block;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.detail__title {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--text-2xl);
  margin: var(--space-2) 0 var(--space-3);
}

.detail__section {
  margin-top: var(--space-6);
}

.detail__section h2 {
  font-size: var(--text-lg);
  margin-bottom: var(--space-3);
}
