/* ===========================================================
   Layout — App Shell (sidebar + topbar + main) + responsive
   =========================================================== */

/* ---------- App Shell grid ---------- */
.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: 100vh;
  min-height: 100vh;
  background: var(--bg-app);
}

@media (max-width: 1023px) {
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
}

/* ---------- Sidebar ---------- */
.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border-right: 1px solid var(--border-subtle);
  padding: var(--sp-4) var(--sp-3);
  z-index: var(--z-sidebar);
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-4);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: background var(--t-fast) var(--easing);
}
.sidebar-brand:hover {
  background: var(--bg-elev);
}
.sidebar-brand-mark {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}
.sidebar-brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.15;
}
.sidebar-brand-name {
  font-size: var(--fs-15);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.sidebar-brand-tagline {
  margin-top: 2px;
  font-size: 11px;
  color: var(--text-muted);
  white-space: nowrap;
}

.sidebar-section {
  margin-top: var(--sp-2);
}
.sidebar-section-title {
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-1);
}

.sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sidebar-nav .nav-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0.5rem var(--sp-3);
  font-size: var(--fs-14);
  color: var(--text-secondary);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--t-fast) var(--easing),
              color var(--t-fast) var(--easing);
  text-decoration: none;
  position: relative;
}
.sidebar-nav .nav-item:hover {
  background: var(--bg-elev);
  color: var(--text-primary);
}
.sidebar-nav .nav-item.active {
  background: var(--bg-elev);
  color: var(--text-primary);
}
.sidebar-nav .nav-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5rem;
  bottom: 0.5rem;
  width: 2px;
  background: var(--accent);
  border-radius: var(--radius-full);
}
.sidebar-nav .nav-item.disabled {
  color: var(--text-muted);
  cursor: not-allowed;
}
.sidebar-nav .nav-item.disabled:hover {
  background: transparent;
  color: var(--text-muted);
}

.nav-item .nav-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: currentColor;
}

.nav-item .nav-soon {
  margin-left: auto;
  font-size: var(--fs-12);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  background: var(--bg-input);
  padding: 0.05rem 0.4rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-subtle);
}

.sidebar-spacer { flex: 1; }

.sidebar-footer {
  border-top: 1px solid var(--border-subtle);
  padding-top: var(--sp-3);
  margin-top: var(--sp-3);
}
.sidebar-account {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-md);
  font-size: var(--fs-13);
  color: var(--text-secondary);
  text-decoration: none;
}
/* Anonymous chip is a clickable link to /auth/google — make hover affordance
   match the auth nav-items above so the user immediately sees it as actionable. */
.sidebar-account.is-anon { cursor: pointer; transition: background var(--t-fast) var(--easing); }
.sidebar-account.is-anon:hover { background: var(--bg-hover, rgba(0,0,0,0.04)); }
.sidebar-account .avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--bg-elev);
  border: 1px solid var(--border-subtle);
  display: grid;
  place-items: center;
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  flex-shrink: 0;
}
.sidebar-account .avatar-img {
  /* Override the grid-based placement when we render an <img> instead of an
     initial-letter div, so the picture fills the 28×28 circle cleanly. */
  display: block;
  object-fit: cover;
  background: var(--bg-elev);
}
.sidebar-account .account-meta {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;     /* let the inner span ellipsis-clip when name is long */
  flex: 1 1 auto;
}
.sidebar-account .account-name {
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
}
.sidebar-account .account-status {
  color: var(--text-muted);
  font-size: var(--fs-12);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
}
.sidebar-account .account-logout {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm, 6px);
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--t-fast) var(--easing),
              background var(--t-fast) var(--easing);
}
.sidebar-account .account-logout:hover {
  color: var(--text-primary);
  background: var(--bg-hover, rgba(0,0,0,0.05));
}

/* ---------- Sidebar mobile drawer ---------- */
@media (max-width: 1023px) {
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--sidebar-w);
    height: 100vh;
    transform: translateX(-100%);
    transition: transform var(--t-base) var(--easing);
    z-index: var(--z-drawer);
  }
  .sidebar.open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }
}

/* Backdrop for mobile drawer */
.drawer-backdrop {
  position: fixed;
  inset: 0;
  background: var(--bg-overlay);
  backdrop-filter: blur(2px);
  z-index: calc(var(--z-drawer) - 1);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-base) var(--easing);
}
.drawer-backdrop.show {
  opacity: 1;
  pointer-events: auto;
}

/* ---------- Topbar ---------- */
.topbar {
  position: sticky;
  top: 0;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-5);
  background: var(--bg-app);
  border-bottom: 1px solid var(--border-subtle);
  z-index: var(--z-topbar);
}

.topbar-menu-btn {
  display: none;
  width: 32px; height: 32px;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  flex-shrink: 0;
}
.topbar-menu-btn:hover { color: var(--text-primary); }

@media (max-width: 1023px) {
  .topbar-menu-btn { display: inline-flex; }
}

.topbar-title {
  font-size: var(--fs-14);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.lang-switcher {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.lang-switcher .select {
  padding: 0.35rem 1.8rem 0.35rem 0.7rem;
  font-size: var(--fs-13);
  background-color: var(--bg-surface);
  background-position: right 0.55rem center;
  border-radius: var(--radius-md);
  width: auto;
  cursor: pointer;
}

.topbar-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 0.35rem 0.7rem;
  font-size: var(--fs-13);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  text-decoration: none;
  transition: color var(--t-fast) var(--easing),
              border-color var(--t-fast) var(--easing);
}
.topbar-cta:hover {
  color: var(--text-primary);
  border-color: var(--border-strong);
}

.user-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 0.2rem 0.5rem;
  font-size: var(--fs-13);
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  max-width: 220px;
}
.user-chip .user-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
  background: var(--bg-mute, #eee);
}
.user-chip .user-avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-primary);
}
.user-chip .user-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 120px;
}
.user-chip .user-logout {
  font-size: var(--fs-12);
  color: var(--text-secondary);
  text-decoration: none;
  padding-left: var(--sp-1);
  border-left: 1px solid var(--border-subtle);
  margin-left: var(--sp-1);
}
.user-chip .user-logout:hover {
  color: var(--text-primary);
}

@media (max-width: 600px) {
  .topbar { padding: 0 var(--sp-4); gap: var(--sp-2); }
  .topbar-title { font-size: var(--fs-13); }
  .topbar-cta .cta-text { display: none; }
  .user-chip .user-name { display: none; }
  .user-chip { max-width: none; }
}

/* ---------- Main / Content ---------- */
.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow-y: auto;
}

.content {
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

@media (max-width: 600px) {
  .content { padding: var(--sp-5) var(--sp-4); }
}

.page-header {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  margin-bottom: var(--sp-3);
}
.page-title {
  font-size: var(--fs-24);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.page-subtitle {
  font-size: var(--fs-14);
  color: var(--text-muted);
}

/* ---------- KB / Footer ---------- */
.kb-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  justify-content: center;
  font-size: var(--fs-12);
  color: var(--text-muted);
  margin-top: var(--sp-6);
  padding: var(--sp-5);
  border-top: 1px solid var(--border-subtle);
}
.kb-links a {
  color: var(--text-muted);
}
.kb-links a:hover {
  color: var(--text-secondary);
}

.app-footer {
  text-align: center;
  font-size: var(--fs-12);
  color: var(--text-muted);
  padding: var(--sp-4) var(--sp-5) var(--sp-8);
}

/* ---------- Status panel ---------- */
.status-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}

/* ===========================================================
   Task split — desktop side-by-side (form left, status right)
   ===========================================================
   Mobile / tablet (< 1024px): the wrapper is a no-op block. The two
   cards stack vertically and app.js's existing .hidden swap (form↔status)
   remains the right behavior for narrow viewports.
   =========================================================== */
@media (min-width: 1024px) {
  /* Widen the content well only on pages that mount the split, so KB /
     other long-form pages keep their 820px reading width. */
  .content:has(.task-split) { max-width: 1280px; }

  /* Same trick for the History page — the table now carries 8 columns
     (Created / Source / Narration / Lang / Mode / Duration / Status /
     Actions), and the longer header words in de/fr/ru/pt would otherwise
     push the table beyond the 820px reading well, forcing horizontal
     scroll. 1280px gives every locale enough room to render in one row. */
  .content:has(.history-card) { max-width: 1280px; }

  /* Showcase shares the same wide well so its left edge lines up exactly
     with History when the user toggles between the two pages from the
     sidebar — small thing but the eye notices an inch of left-edge jitter
     instantly on a desktop monitor. */
  .content:has(.showcase-card) { max-width: 1280px; }

  .task-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--sp-5);
    align-items: start;
  }

  /* Cancel the global `.card + .card { margin-top: var(--sp-5) }` rule
     (components.css) inside the split — it was meant for the old single-
     column stack. In the grid it would push the right card down by
     ~20px, breaking the top alignment with the left card. */
  .task-split > .card + .card { margin-top: 0; }

  /* Desktop never collapses either pane — app.js still toggles .hidden on
     formCard / statusCard, but here we pin them to display:block via a more
     specific selector that wins the !important duel against base.css's
     `.hidden { display:none !important }`. Specificity: (0,2,1) vs (0,1,0). */
  .task-split > .card.hidden { display: block !important; }

  /* Right pane sticks below the topbar so it stays in view while the user
     scrolls the (long) creation form on the left. */
  .task-split > #statusCard {
    position: sticky;
    top: calc(var(--topbar-h) + var(--sp-5));
    transition: opacity var(--t-base) var(--easing);
  }

  /* "Appear later" empty state: pre-submit, the right pane is invisible &
     non-interactive, but its grid track is preserved so the form keeps
     half-width (no jarring re-flow on first submit). app.js removes
     .is-pristine inside showStatus() to fade the pane in. */
  .task-split > #statusCard.is-pristine {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}

/* ===========================================================
   History page (templates/history.html + static/js/history.js)
   - Desktop:  proper data-table layout, hover rows, pill statuses.
   - Mobile (<720px): each <tr> collapses to a card; <th> labels are
     pulled in via data-label so the user still understands which
     value belongs to which column without a table header in view.
   =========================================================== */

.history-card {
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.history-table-wrap {
  width: 100%;
  overflow-x: auto;
}

.history-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-13);
  color: var(--text-primary);
}

.history-table thead th {
  text-align: left;
  font-weight: var(--fw-semibold);
  font-size: var(--fs-12);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--border-subtle);
  white-space: nowrap;
}

.history-table tbody td {
  padding: var(--sp-3);
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: middle;
}

.history-table tbody tr:hover {
  background: var(--bg-mute, rgba(0,0,0,0.03));
}

.history-table .col-created { white-space: nowrap; color: var(--text-secondary); }
.history-table .col-source { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-table .col-source a { color: var(--text-primary); text-decoration: none; border-bottom: 1px dashed var(--border-subtle); }
.history-table .col-source a:hover { color: var(--accent, #5e6ad2); }
.history-table .col-narration {
  /* Cap the column so a long narration cannot blow out the table grid; the
     line-clamp on .narration-text inside takes care of vertical bounding.
     Note these are HARD caps — the wider .content well (see the
     :has(.history-card) rule below) gives this column its breathing
     room rather than letting it grow unbounded and push the action
     buttons off-screen in long-word locales (de/fr/ru). */
  max-width: 280px;
  min-width: 140px;
  color: var(--text-secondary);
  font-size: var(--fs-12);
  line-height: 1.45;
}
.history-table .col-narration.is-empty {
  color: var(--text-muted);
  text-align: center;
}
.history-table .col-lang,
.history-table .col-mode { white-space: nowrap; }
.history-table .col-duration {
  white-space: nowrap;
  text-align: right;
  /* Tabular numerals keep "12:34" and "1:23:45" right-aligned in the
     same visual column so users can scan / sum durations at a glance. */
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.history-table .col-duration.is-empty {
  color: var(--text-muted);
  text-align: center;
}
.history-table .col-actions { white-space: nowrap; text-align: right; }

.narration-cell { display: block; }
.narration-text {
  white-space: pre-wrap;
  word-break: break-word;
}
.narration-cell.is-collapsed .narration-text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.narration-toggle {
  display: inline-block;
  margin-top: 4px;
  padding: 0;
  background: none;
  border: none;
  color: var(--accent, #5e6ad2);
  font-size: var(--fs-11, 11px);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.narration-toggle:hover { text-decoration: underline; }

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  text-transform: capitalize;
  border: 1px solid transparent;
  background: var(--bg-mute, #eee);
  color: var(--text-secondary);
}
.status-pill.status-queued     { background: rgba(120,120,120,0.12); color: #555; border-color: rgba(120,120,120,0.25); }
.status-pill.status-processing { background: rgba(70,120,255,0.12); color: #2552d8; border-color: rgba(70,120,255,0.25); }
.status-pill.status-done       { background: rgba(40,170,90,0.12); color: #1d7e3f; border-color: rgba(40,170,90,0.25); }
.status-pill.status-error      { background: rgba(220,70,70,0.12); color: #b32424; border-color: rgba(220,70,70,0.25); }

.history-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  justify-content: flex-end;
}
.history-actions .btn-sm {
  padding: 4px 10px;
  font-size: var(--fs-12);
  border-radius: var(--radius-sm, 6px);
}
.history-actions .btn-danger {
  background: transparent;
  color: #b32424;
  border: 1px solid rgba(179,36,36,0.35);
}
.history-actions .btn-danger:hover {
  background: rgba(179,36,36,0.08);
}

.history-status {
  font-size: var(--fs-12);
  color: var(--text-muted);
  min-height: 1em;
}

/* Footer summary — appears once the first page has rendered and grows
   as the user paginates. Kept visually quiet so it doesn't compete with
   the table content, but tabular-nums on the duration so "1h 23m" stays
   aligned across reflows. */
.history-summary {
  display: flex;
  gap: var(--sp-2);
  align-items: baseline;
  flex-wrap: wrap;
  margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-12);
  color: var(--text-secondary);
}
.history-summary-count { font-weight: var(--fw-semibold); }
.history-summary-sep { color: var(--text-muted); }
.history-summary-duration { font-variant-numeric: tabular-nums; }

.history-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-3);
  text-align: center;
}
.history-empty-title {
  font-size: var(--fs-16);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.history-empty-sub {
  font-size: var(--fs-13);
  color: var(--text-muted);
  margin-bottom: var(--sp-2);
}

@media (max-width: 720px) {
  .history-table thead { display: none; }
  .history-table,
  .history-table tbody,
  .history-table tr,
  .history-table td { display: block; width: 100%; }
  .history-table tr {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md, 10px);
    margin-bottom: var(--sp-3);
    padding: var(--sp-3);
    background: var(--bg-surface);
  }
  .history-table tbody td {
    border-bottom: none;
    padding: 4px 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-3);
  }
  .history-table tbody td.col-actions {
    margin-top: var(--sp-2);
    justify-content: flex-end;
  }
  .history-table .col-source { max-width: 100%; }
  .history-table .col-narration {
    max-width: 100%;
    /* Stack narration on its own line on mobile — a multi-line block of
       text doesn't fit in the "label : value" inline pattern the rest of
       the cells use. */
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }
}

/* Share-toggle button — uses pill-on/off semantics. The "is-public" state
   reads as a positive accent so the user can scan a long history list and
   see at a glance which rows are exposed in the showcase. */
.history-actions .js-share {
  border: 1px solid var(--border-subtle);
}
.history-actions .js-share.is-public {
  background: rgba(40,170,90,0.12);
  color: #1d7e3f;
  border-color: rgba(40,170,90,0.35);
}
.history-actions .js-share[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Tiny floating toast used by history.js. Kept independent of the create
   page's showToast() to avoid coupling the two bundles. */
.history-toast {
  position: fixed;
  left: 50%;
  bottom: var(--sp-6);
  transform: translateX(-50%) translateY(20px);
  background: var(--text-primary);
  color: #fff;
  padding: 10px 16px;
  border-radius: var(--radius-md, 10px);
  font-size: var(--fs-13);
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  opacity: 0;
  pointer-events: none;
  z-index: 9999;
  transition: opacity 180ms ease, transform 180ms ease;
  max-width: 90vw;
  white-space: pre-wrap;
}
.history-toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.history-toast[data-kind="err"] { background: #b32424; }
.history-toast[data-kind="ok"]  { background: #1d7e3f; }

/* ===========================================================
   Showcase page (templates/showcase.html + static/js/showcase.js)
   =========================================================== */

.showcase-card {
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.showcase-grid {
  display: grid;
  gap: var(--sp-4);
  /* Default tile sizing for narrow / medium viewports: auto-fill keeps the
     grid responsive between the small-screen 1-col rule below and the
     desktop 3-col rule in the @media (min-width:1024px) block. minmax's
     280px floor stops a 16:9 video from collapsing into an unreadable
     thumbnail when the viewport is around 700px wide. */
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.showcase-item {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
  background: var(--bg-surface);
  padding: var(--sp-3);
  transition: box-shadow var(--t-base, 180ms) var(--easing, ease);
}
.showcase-item:hover {
  box-shadow: 0 6px 18px rgba(0,0,0,0.08);
}

/* 16:9 video frame; the actual <video> stretches to fill it. We use
   aspect-ratio instead of padding-bottom so the controls stay glued to
   the bottom edge instead of overlapping a faux pseudo element. */
.showcase-video {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-sm, 8px);
  overflow: hidden;
}
.showcase-video video {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  background: #000;
}

.showcase-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fs-13);
}

.showcase-creator {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}
.showcase-creator-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-mute, #eee);
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-primary);
}
.showcase-creator-avatar-fallback {
  background: var(--bg-mute, #eee);
}
.showcase-creator-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.showcase-sub {
  color: var(--text-muted);
  font-size: var(--fs-12);
}

.showcase-source-link {
  font-size: var(--fs-12);
  color: var(--text-secondary);
  text-decoration: none;
  align-self: flex-start;
  border-bottom: 1px dashed var(--border-subtle);
}
.showcase-source-link:hover {
  color: var(--accent, #5e6ad2);
  border-bottom-color: currentColor;
}

.showcase-narration {
  margin-top: var(--sp-2);
  padding: var(--sp-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--bg-input);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.showcase-narration-label {
  font-size: var(--fs-12);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.showcase-narration-text {
  margin: 0;
  font-size: var(--fs-13);
  line-height: var(--lh-relaxed);
  color: var(--text-secondary);
  white-space: pre-wrap;
  word-break: break-word;
}
.showcase-narration.is-collapsed .showcase-narration-text {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.showcase-narration-toggle {
  align-self: flex-start;
  padding: 0;
  font-size: var(--fs-12);
  font-weight: var(--fw-medium);
  color: var(--accent);
  background: transparent;
  border: none;
  cursor: pointer;
}
.showcase-narration-toggle:hover {
  color: var(--accent-hover);
}

.showcase-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border-subtle);
}
.showcase-pager .btn-sm {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 0.4rem 0.85rem;
  font-size: var(--fs-13);
  border-radius: var(--radius-md);
}
.showcase-pager .btn-sm:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.showcase-pager-indicator {
  font-size: var(--fs-13);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  min-width: 4.5em;
  text-align: center;
}

.showcase-status {
  font-size: var(--fs-12);
  color: var(--text-muted);
  min-height: 1em;
}

.showcase-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-3);
  text-align: center;
}
.showcase-empty-title {
  font-size: var(--fs-16);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.showcase-empty-sub {
  font-size: var(--fs-13);
  color: var(--text-muted);
  margin-bottom: var(--sp-2);
}

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

/* Desktop: pin to exactly 3 cards per row regardless of card width. We
   pair this with `minmax(0, 1fr)` (NOT plain `1fr`) so that long
   creator names / narration excerpts inside the card can ellipsis or
   wrap properly — without the explicit 0-min, the grid track would
   inflate to fit the longest child and break the equal-width layout. */
@media (min-width: 1024px) {
  .showcase-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Trailing footnote under the platforms table on /<lang>/platforms/.
   Matches the muted body-copy spacing used by .page-subtitle so the
   table doesn't end with an abrupt edge against the card border. */
.platforms-tip {
  margin-top: var(--sp-3);
  color: var(--text-muted);
  font-size: var(--fs-13);
}

/* About page — long-form prose. We tighten the default heading rhythm so
   the content card reads as a single document rather than a sequence of
   isolated rows, while keeping the line length comfortable on wide
   monitors. */
.about-card {
  padding: var(--sp-5);
  font-size: var(--fs-14);
  color: var(--text-primary);
  max-width: 820px;
  margin: 0 auto;
}
.about-card h2 {
  font-size: var(--fs-18);
  font-weight: var(--fw-semibold);
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-2);
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.about-card h2:first-child { margin-top: 0; }
.about-card h3 {
  font-size: var(--fs-15, 15px);
  font-weight: var(--fw-semibold);
  margin-top: var(--sp-4);
  margin-bottom: var(--sp-1);
  color: var(--text-primary);
}
.about-card p {
  margin: var(--sp-2) 0;
  line-height: 1.65;
  color: var(--text-secondary);
}
.about-card ul,
.about-card ol {
  margin: var(--sp-2) 0 var(--sp-3) var(--sp-5);
  padding: 0;
}
.about-card li {
  margin: 4px 0;
  line-height: 1.65;
  color: var(--text-secondary);
}
.about-card a {
  color: var(--accent, #5e6ad2);
  text-decoration: none;
  border-bottom: 1px dashed currentColor;
}
.about-card a:hover { text-decoration: none; border-bottom-style: solid; }
.about-card blockquote {
  margin: var(--sp-3) 0;
  padding: var(--sp-3) var(--sp-4);
  border-left: 3px solid var(--accent, #5e6ad2);
  background: var(--bg-mute, rgba(0,0,0,0.03));
  border-radius: 0 var(--radius-sm, 8px) var(--radius-sm, 8px) 0;
  color: var(--text-primary);
}
.about-card blockquote p { margin: 4px 0; color: var(--text-primary); }
.about-card strong { color: var(--text-primary); }
