/* ==========================================================================
   Alabama Ladder — Clips Stylesheet (Production Phase 5)
   ========================================================================== */

:root {
  --control-h: 38px;
  --bracket: 10px;
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-7: 32px;
  --s-8: 48px;

  --ok: #5bd6a0;
  --info: #7fc4ff;
  --warn: #f0c250;
  --danger: #e0637f;

  --surface-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);

}

/* ----------------------------------------------------------------- layout */

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* The page shell (flex column, min-height: 100dvh, a growing main) is the
   shared one in style.css now; only this page's zero main padding stays,
   because the sections carry their own spacing and .wrap the measure. */
main {
  padding: 0;
}

.section {
  margin-block: var(--s-8);
}

/* ------------------------------------------------------------------- boot */

/*
 * Boot gate. Until the session resolves, the member gallery waits out of
 * sight behind html.boot-pending — a class the inline script in clips.html
 * adds before first paint and js/clips/page.js removes on every exit from
 * initialization. The inline script's own timer drops the gate if the module
 * never boots.
 */
html.boot-pending #galleryPanel {
  display: none;
}

.boot-loading {
  display: none;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  padding: var(--s-8) 0;
}

.boot-loading__gem {
  width: 10px;
  height: 10px;
  flex: 0 0 auto;
  background: var(--crown-gold);
  transform: rotate(45deg);
  box-shadow: 0 0 10px rgba(240, 194, 80, 0.45);
  animation: working-pulse 1.6s ease-in-out infinite;
}

.boot-loading__label {
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

html.boot-pending .boot-loading {
  display: flex;
  /* Grace period: a session that resolves near-instantly must not see the
     spinner flash, so it only fades in once boot has taken 250ms. */
  visibility: hidden;
  animation: boot-loading-appear 0s linear 250ms forwards;
}

@keyframes boot-loading-appear {
  to { visibility: visible; }
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2) var(--s-4);
  margin-bottom: var(--s-5);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--hairline);
}

.section-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #ffffff;
}

.section-subtitle {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
}

.section--showcase {
  /* The wrap widened for the gallery's sake. The showcase is a form, and a
     form read across 1768px is worse, not better, so the panel takes a
     measure of its own and the wall alone spends the rest of the width. */
  max-width: 1440px;
  background: linear-gradient(180deg, #111624 0%, #0a0d15 100%);
  border: 1px solid rgba(240, 194, 80, 0.28);
  border-radius: var(--r-xl);
  padding: var(--s-6);
  margin-bottom: 0;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  position: relative;
}

body.showcase-modal-open {
  overflow: hidden;
}

dialog.showcase-dialog {
  width: min(1440px, calc(100vw - 64px));
  max-width: 1440px;
  max-height: calc(100dvh - 64px);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  overflow: auto;
}

dialog.showcase-dialog::backdrop {
  background: rgba(3, 6, 12, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.showcase-dialog .section--showcase {
  box-sizing: border-box;
  width: 100%;
  margin: 0;
}

.showcase-dialog .section-head {
  justify-content: space-between;
}

.showcase-dialog__close {
  flex: 0 0 auto;
}

.section--showcase::before,
.section--showcase::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: var(--bracket);
  height: var(--bracket);
  border-color: var(--crown-gold);
  border-style: solid;
  border-width: 0;
}

.section--showcase::before {
  top: -1px;
  left: -1px;
  border-top-width: 2px;
  border-left-width: 2px;
}

.section--showcase::after {
  right: -1px;
  bottom: -1px;
  border-right-width: 2px;
  border-bottom-width: 2px;
}

.section--gallery {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
  position: relative;
}

/* ------------------------------------------------------------------- hero */

.hero {
  padding: clamp(32px, 5vw, 56px) 0 clamp(16px, 3vw, 28px);
  text-align: center;
}

.hero-title {
  margin: 0 0 var(--s-2);
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #ffffff;
}

.hero-kicker {
  margin: 0 auto;
  max-width: 580px;
  color: var(--muted);
  font-size: clamp(0.92rem, 1.8vw, 1.05rem);
}

/* ----------------------------------------------------------------- limits */

.limits {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-6);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-5);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-family: var(--numeric);
  font-size: 0.74rem;
  color: var(--muted);
}

.limits-item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

.limits-item svg {
  color: var(--crown-gold);
  flex: 0 0 auto;
}

.limits-item b {
  color: #dbe0e8;
  font-weight: 600;
}

.picker-error {
  margin-bottom: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border: 1px solid rgba(224, 99, 127, 0.35);
  border-radius: var(--r-md);
  background: rgba(224, 99, 127, 0.06);
}

.picker-error.hidden {
  display: none;
}

.picker-error__message {
  margin: 0;
  color: #f0d4dc;
  font-size: 0.92rem;
}

.picker-error__detail {
  margin: var(--s-2) 0 0;
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.78rem;
}

.picker-error__dismiss {
  margin-top: var(--s-3);
}

/* The one error treatment: a showcase row's inline failure and the report
   dialog's refused submission share it, so they cannot drift apart. */
.showcase-row__error,
.report-error {
  padding: var(--s-3);
  border: 1px solid rgba(224, 99, 127, 0.35);
  border-radius: var(--r-sm);
  background: rgba(224, 99, 127, 0.06);
}

.showcase-row__error-message,
.report-error-message {
  margin: 0;
  color: #f0d4dc;
  font-size: 0.88rem;
}

.showcase-row__error-detail {
  margin: var(--s-2) 0 0;
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.76rem;
}

.showcase-row__error-dismiss {
  margin-top: var(--s-3);
}

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--control-h);
  padding: 0 14px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: linear-gradient(180deg, #1f2737, #131924);
  color: #e6e9ee;
  font-family: var(--font-display);
  font-size: 0.84rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 2px 4px rgba(0, 0, 0, 0.35);
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease, transform 120ms var(--ease), box-shadow 150ms ease;
  text-decoration: none;
}

.btn:hover:not(:disabled) {
  border-color: rgba(255, 255, 255, 0.22);
  background: linear-gradient(180deg, #273247, #18202e);
  color: #ffffff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 3px 8px rgba(0, 0, 0, 0.45);
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5);
}

.btn svg {
  flex: 0 0 auto;
}

.btn--primary {
  border-color: rgba(240, 194, 80, 0.55);
  background: linear-gradient(180deg, rgba(240, 194, 80, 0.18), rgba(184, 138, 48, 0.1));
  color: var(--crown-gold);
  box-shadow: inset 0 1px 0 rgba(240, 194, 80, 0.2), 0 2px 6px rgba(0, 0, 0, 0.4);
}

.btn--primary:hover:not(:disabled) {
  border-color: var(--crown-gold);
  background: linear-gradient(180deg, rgba(240, 194, 80, 0.28), rgba(184, 138, 48, 0.18));
  color: #fff4d1;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 14px rgba(240, 194, 80, 0.28);
}

.btn--danger {
  border-color: rgba(224, 99, 127, 0.45);
  background: linear-gradient(180deg, rgba(224, 99, 127, 0.14), rgba(160, 48, 72, 0.08));
  color: #ff9eb3;
  box-shadow: inset 0 1px 0 rgba(224, 99, 127, 0.15), 0 2px 4px rgba(0, 0, 0, 0.35);
}

.btn--danger:hover:not(:disabled) {
  border-color: var(--danger);
  background: linear-gradient(180deg, rgba(224, 99, 127, 0.24), rgba(160, 48, 72, 0.16));
  color: #ffe4ea;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 12px rgba(224, 99, 127, 0.25);
}

.btn--quiet {
  border-color: transparent;
  background: transparent;
  color: var(--muted);
  box-shadow: none;
}

.btn--quiet:hover:not(:disabled) {
  color: var(--text);
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.08);
  box-shadow: none;
}

.btn--sm {
  min-height: 32px;
  padding: 0 10px;
  font-size: 0.78rem;
}

.btn--block {
  width: 100%;
}

.btn:disabled {
  opacity: 0.42;
  cursor: not-allowed;
  box-shadow: none;
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 44px;
  min-height: 44px;
  padding: 0 6px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 0.76rem;
  cursor: pointer;
  transition: color 150ms ease, background 150ms ease, border-color 150ms ease;
}

.icon-btn:hover:not(:disabled) {
  color: var(--text);
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.08);
}

.icon-btn[data-reported="true"],
.icon-btn:disabled[data-reported="true"] {
  color: var(--crown-gold);
  opacity: 0.85;
  cursor: default;
  background: transparent;
  border-color: transparent;
}

/* ------------------------------------------------------------- 16:9 media */

.media {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #05070b;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline);
}

.media-thumb {
  position: absolute;
  inset: 0;
  background: linear-gradient(145deg, #18202d, #090d13 70%);
  background-size: cover;
  background-position: center;
}

.media-play {
  position: relative;
  z-index: 2;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid rgba(240, 194, 80, 0.6);
  background: rgba(18, 23, 34, 0.82);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: var(--crown-gold);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
  transition: transform 150ms var(--ease), background 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}

.media-play:hover {
  transform: scale(1.08);
  background: rgba(240, 194, 80, 0.2);
  border-color: var(--crown-gold);
  box-shadow: 0 0 20px rgba(240, 194, 80, 0.4);
  color: #ffffff;
}

.media-play:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.media-duration {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 2;
  padding: 2px 6px;
  border-radius: var(--r-xs);
  background: rgba(4, 7, 12, 0.82);
  color: #dbe0e8;
  font-family: var(--numeric);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
}

.media-state {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3);
  text-align: center;
}

.media-state-text {
  font-size: 0.8rem;
  font-weight: 600;
  color: #e2e6ed;
}

.media-state-sub {
  font-size: 0.68rem;
  color: var(--muted);
  font-family: var(--numeric);
}

.media-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ------------------------------------------------------- micro-animations */

.media-anim {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
}

/* 1. Uploading uplink crystal */
.anim-uplink {
  position: relative;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
}

.anim-uplink-core {
  width: 14px;
  height: 14px;
  background: var(--crown-gold);
  transform: rotate(45deg);
  border-radius: 2px;
  box-shadow: 0 0 12px rgba(240, 194, 80, 0.55);
  animation: uplink-pulse 1.4s ease-in-out infinite;
}

.anim-uplink-shards {
  position: absolute;
  inset: -10px;
  pointer-events: none;
}

.anim-shard {
  position: absolute;
  width: 4px;
  height: 4px;
  background: var(--crown-gold);
  transform: rotate(45deg);
  opacity: 0;
}

.anim-shard:nth-child(1) { left: 4px; bottom: -2px; animation: shard-rise 1.6s ease-in infinite; }
.anim-shard:nth-child(2) { right: 5px; bottom: 0; animation: shard-rise 1.6s ease-in infinite 0.53s; }
.anim-shard:nth-child(3) { left: 50%; margin-left: -2px; bottom: -6px; animation: shard-rise 1.6s ease-in infinite 1.06s; }

@keyframes uplink-pulse {
  0%, 100% { transform: rotate(45deg) scale(0.92); box-shadow: 0 0 6px rgba(240, 194, 80, 0.4); }
  50% { transform: rotate(45deg) scale(1.18); box-shadow: 0 0 16px rgba(240, 194, 80, 0.9); }
}

@keyframes shard-rise {
  0% { transform: translateY(6px) rotate(45deg) scale(0.4); opacity: 0; }
  35% { opacity: 0.9; }
  85% { opacity: 0.8; transform: translateY(-14px) rotate(45deg) scale(1); }
  100% { transform: translateY(-22px) rotate(45deg) scale(0.2); opacity: 0; }
}

/* 2. Processing rhomboid matrix */
.anim-matrix {
  position: relative;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
}

.matrix-ring {
  position: absolute;
  inset: 0;
  border: 1.5px solid rgba(127, 196, 255, 0.55);
  border-radius: 3px;
  transform: rotate(45deg);
  animation: matrix-spin 4s linear infinite;
}

.matrix-ring--inner {
  inset: 6px;
  border-color: rgba(240, 194, 80, 0.65);
  animation: matrix-spin-rev 3s linear infinite;
}

.matrix-core {
  width: 8px;
  height: 8px;
  background: var(--crown-gold);
  transform: rotate(45deg);
  box-shadow: 0 0 10px rgba(240, 194, 80, 0.85);
  animation: core-glow 2s ease-in-out infinite;
}

@keyframes matrix-spin {
  from { transform: rotate(45deg); }
  to { transform: rotate(405deg); }
}

@keyframes matrix-spin-rev {
  from { transform: rotate(45deg); }
  to { transform: rotate(-315deg); }
}

@keyframes core-glow {
  0%, 100% { opacity: 0.6; transform: rotate(45deg) scale(0.85); }
  50% { opacity: 1; transform: rotate(45deg) scale(1.2); box-shadow: 0 0 14px rgba(240, 194, 80, 1); }
}

.shimmer::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(127, 196, 255, 0.1) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: shimmer 1900ms linear infinite;
}

@keyframes shimmer {
  to { transform: translateX(100%); }
}

/* ------------------------------------------------------------------ chips */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 9px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.chip i {
  width: 5px;
  height: 5px;
  background: currentColor;
  transform: rotate(45deg);
  flex: 0 0 auto;
}

.chip[data-tone="live"] {
  color: var(--ok);
  border-color: rgba(91, 214, 160, 0.4);
  background: rgba(91, 214, 160, 0.1);
}

.chip[data-tone="working"] {
  color: var(--info);
  border-color: rgba(127, 196, 255, 0.4);
  background: rgba(127, 196, 255, 0.1);
}

.chip[data-tone="working"] i {
  animation: working-pulse 1.6s ease-in-out infinite;
}

@keyframes working-pulse {
  0%, 100% { opacity: 1; transform: rotate(45deg) scale(1); }
  50% { opacity: 0.35; transform: rotate(45deg) scale(0.72); }
}

.chip[data-tone="warn"] {
  color: var(--warn);
  border-color: rgba(240, 194, 80, 0.4);
  background: rgba(240, 194, 80, 0.1);
}

.chip[data-tone="danger"] {
  color: #ff8ea3;
  border-color: rgba(224, 99, 127, 0.4);
  background: rgba(224, 99, 127, 0.1);
}

/* ---------------------------------------------------------------- notices */

.notice {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-raised);
}

.notice > svg {
  margin-top: 3px;
  color: var(--muted);
  flex: 0 0 auto;
}

.notice h3 {
  margin: 0 0 2px;
  font-size: 0.94rem;
  font-weight: 700;
}

.notice p {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
}

.notice p + p {
  margin-top: var(--s-2);
}

.notice-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-3);
}

.notice[data-tone="info"] {
  border-color: rgba(127, 196, 255, 0.35);
  background: rgba(127, 196, 255, 0.06);
}
.notice[data-tone="info"] > svg { color: var(--info); }

.notice[data-tone="warn"] {
  border-color: rgba(240, 194, 80, 0.35);
  background: rgba(240, 194, 80, 0.06);
}
.notice[data-tone="warn"] > svg { color: var(--warn); }

.notice[data-tone="danger"] {
  border-color: rgba(224, 99, 127, 0.35);
  background: rgba(224, 99, 127, 0.06);
}
.notice[data-tone="danger"] > svg { color: var(--danger); }

.notice[data-tone="ok"] {
  border-color: rgba(91, 214, 160, 0.35);
  background: rgba(91, 214, 160, 0.06);
}
.notice[data-tone="ok"] > svg { color: var(--ok); }

/* ------------------------------------------------------ showcase control panel */

.showcase-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  /* The panel frame spans the showcase's own 1200px cap; the interactive rows
     inside read at a tighter form measure so a row's two halves and the
     progress track stay one composition instead of drifting to the panel
     edges. */
  max-width: min(1080px, 100%);
}

.showcase-row {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-4);
  background: var(--surface-raised);
  border: 1px solid var(--surface-border);
  border-radius: var(--r-md);
}

.showcase-row--focus {
  border-color: rgba(240, 194, 80, 0.35);
  box-shadow: inset 0 0 0 1px rgba(240, 194, 80, 0.12);
}

.showcase-row--danger {
  border-color: rgba(224, 99, 127, 0.35);
}

.showcase-row__main {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr) auto;
  align-items: flex-start;
  gap: var(--s-4);
  min-width: 0;
}

.showcase-row__thumb {
  position: relative;
  flex: 0 0 auto;
  width: 128px;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface-sunken);
  border: 1px solid var(--hairline);
}

.showcase-row__thumb-surface {
  width: 100%;
  height: 100%;
  background: linear-gradient(145deg, #18202d, #090d13 70%);
  background-size: cover;
  background-position: center;
}

.showcase-row__thumb-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.showcase-row__thumb-shimmer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.showcase-row__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 0;
  background: rgba(8, 10, 14, 0.42);
  color: #fff;
  cursor: pointer;
  transition: background 150ms ease;
}

.showcase-row__play:hover {
  background: rgba(8, 10, 14, 0.58);
}

.showcase-row__play:focus-visible {
  outline: 2px solid var(--crown-gold);
  outline-offset: 2px;
}

.showcase-row__duration {
  position: absolute;
  right: 4px;
  bottom: 4px;
  padding: 1px 5px;
  border-radius: var(--r-xs);
  background: rgba(8, 10, 14, 0.82);
  color: #e8ebf0;
  font-family: var(--numeric);
  font-size: 0.62rem;
  font-weight: 600;
  line-height: 1.3;
}

.showcase-row__duration--danger {
  color: var(--danger);
}

.showcase-row__info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-3);
  min-width: 0;
  flex: 1 1 auto;
}

.showcase-row__title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
  word-break: normal;
  overflow-wrap: break-word;
}

.showcase-row__title--muted {
  color: var(--muted);
  font-style: italic;
  font-weight: 500;
}

.showcase-row__status {
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.35;
}

.showcase-row__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  justify-content: flex-end;
  flex: 0 0 auto;
  margin-left: auto;
  align-self: center;
}

.showcase-row__detail {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding-top: var(--s-1);
  border-top: 1px solid var(--hairline);
}

.showcase-row__detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

/* Destructive controls must not out-shout the row they sit in: the filled
   danger treatment is reserved for the confirm dialog, and here the colour
   alone carries the warning until the pointer finds them. */
.showcase-row__actions .btn--danger,
.showcase-row__detail-actions .btn--danger {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--danger);
}

.showcase-row__actions .btn--danger:hover:not(:disabled),
.showcase-row__detail-actions .btn--danger:hover:not(:disabled) {
  border-color: rgba(224, 99, 127, 0.45);
  background: rgba(224, 99, 127, 0.08);
  color: #ff9eb3;
  box-shadow: none;
}

.showcase-add {
  margin-top: var(--s-1);
}

.showcase-add__btn {
  /* Inline-width on purpose: with rows above it, a full-measure button read
     as a banner. Only the solo drop-target variant spans the measure. */
  min-height: 48px;
  justify-content: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}

.showcase-add__btn--solo {
  width: 100%;
  min-height: 72px;
  flex-direction: column;
  padding: var(--s-4);
  border-style: dashed;
  border-color: rgba(240, 194, 80, 0.35);
  background: rgba(240, 194, 80, 0.05);
}

.showcase-add__hint {
  display: block;
  width: 100%;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.01em;
}

/* --------------------------------------------------------- showcase cards (legacy gallery card parts) */

.showcase-grid {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface-raised);
  border: 1px solid var(--surface-border);
  border-radius: var(--r-lg);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  transition: border-color 180ms ease, transform 180ms var(--ease);
}

.card::before,
.card::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: var(--bracket);
  height: var(--bracket);
  border-color: var(--gold-dim);
  border-style: solid;
  border-width: 0;
  transition: border-color 180ms ease;
}

.card::before { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }
.card::after { right: -1px; bottom: -1px; border-right-width: 1px; border-bottom-width: 1px; }

.card--focus { border-color: rgba(240, 194, 80, 0.4); }
.card--focus::before, .card--focus::after { border-color: rgba(240, 194, 80, 0.65); }

.card--danger { border-color: rgba(224, 99, 127, 0.4); }
.card--danger::before, .card--danger::after { border-color: rgba(224, 99, 127, 0.6); }

.card-head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  justify-content: space-between;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--hairline);
}

.card-title {
  margin: 0;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.card-media {
  padding: var(--s-3) var(--s-3) 0;
}

.card-body {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4) var(--s-4);
  flex: 1;
}

.card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: auto;
  padding-top: var(--s-1);
}

.caption {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.45;
  color: #d3d8e1;
  word-break: normal;
  overflow-wrap: break-word;
  text-wrap: pretty;
}

.caption--empty {
  color: var(--muted);
  font-style: italic;
}

.meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-3);
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ form fields */

.field {
  display: grid;
  gap: 6px;
}

.field > label {
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--muted);
}

.field textarea,
.field input[type="text"],
.field select {
  width: 100%;
  padding: 9px 11px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 0.86rem;
  resize: vertical;
  box-sizing: border-box;
}

.field textarea:focus-visible,
.field input:focus-visible,
.field select:focus-visible {
  outline: 2px solid var(--crown-gold);
  outline-offset: 1px;
}

.field-hint {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.66rem;
  margin: 0;
}

.field-hint b {
  font-weight: 600;
  color: #cfd5df;
}

.field-hint b[data-over="true"] {
  color: #ff8ea3;
}

.picked-file {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-3);
  align-items: center;
  padding: var(--s-3);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
}

.picked-file svg {
  color: var(--crown-gold);
}

.picked-file b {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  word-break: normal;
  overflow-wrap: break-word;
}

.picked-file span {
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.68rem;
}

/* --------------------------------------------------------------- progress */

.progress {
  display: grid;
  gap: 6px;
}

.progress-track {
  height: 5px;
  border-radius: 2px;
  background: #080c14;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: 1px;
  background: linear-gradient(90deg, #c49539, #f0c250);
  box-shadow: 0 0 10px rgba(240, 194, 80, 0.45);
  transition: width 240ms var(--ease);
}

.progress-fill--indeterminate {
  width: 35%;
  background: linear-gradient(90deg, transparent, #f0c250 50%, transparent);
  box-shadow: 0 0 12px rgba(240, 194, 80, 0.6);
  animation: indeterminate 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes indeterminate {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(280%); }
}

.progress-figures {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
}

.progress-figures b {
  color: var(--crown-gold);
  font-weight: 600;
}

/* ---------------------------------------------------------------- gallery */

.gallery-filter {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-6);
  position: relative;
  z-index: 10;
}

.gallery-filter__label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.gallery-filter__control {
  position: relative;
  display: inline-block;
}

.gallery-filter__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 12px;
  background: var(--surface-sunken);
  border: 1px solid var(--surface-border);
  border-radius: var(--r-md);
  color: var(--text);
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}

.gallery-filter__trigger:hover {
  border-color: var(--gold-dim);
  background: var(--surface-raised);
}

.gallery-filter__trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.gallery-filter__avatar {
  width: 20px;
  height: 20px;
  font-size: 0.6rem;
  flex: 0 0 auto;
}

.gallery-filter__avatar--all {
  background: var(--surface-sunken);
  color: var(--crown-gold);
}

.gallery-filter__trigger-text {
  white-space: nowrap;
}

.gallery-filter__chevron {
  color: var(--muted);
  margin-left: var(--s-1);
}

.gallery-filter__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 220px;
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: #0f131c;
  border: 1px solid var(--gold-line);
  border-radius: var(--r-md);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
  z-index: 20;
}

.gallery-filter__menu:focus {
  outline: none;
}

.gallery-filter__option {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 10px;
  border-radius: var(--r-sm);
  font-size: 0.82rem;
  color: var(--text);
  cursor: pointer;
  outline: none;
  transition: background 120ms ease;
}

.gallery-filter__option:hover,
.gallery-filter__option.is-focused {
  background: rgba(240, 194, 80, 0.12);
  color: #ffffff;
}

.gallery-filter__option.is-selected {
  color: var(--crown-gold);
  font-weight: 600;
}

.gallery-filter__option-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gallery-filter__option-count {
  font-family: var(--numeric);
  font-size: 0.72rem;
  color: var(--muted);
}

.gallery-wall {
  display: flex;
  flex-direction: column;
  gap: var(--s-7);
}

.gallery-group {
  display: grid;
  /* The rail takes what the identity needs (140-180px), not a fixed fifth of
     the wall; long names cap and ellipsis like the name rule already does. */
  grid-template-columns: minmax(140px, 180px) 1fr;
  gap: var(--s-6);
  align-items: start;
  padding-bottom: var(--s-7);
  border-bottom: 1px solid var(--hairline);
}

.gallery-group:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.gallery-group__sidebar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  position: sticky;
  top: 80px;
}

.gallery-group__avatar {
  width: 44px;
  height: 44px;
  font-size: 0.95rem;
  flex: 0 0 auto;
}

.gallery-group__info {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 2px;
}

.gallery-group__name {
  margin: 0;
  font-size: 0.96rem;
  font-weight: 700;
  color: #ffffff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gallery-group__count {
  font-family: var(--numeric);
  font-size: 0.72rem;
  color: var(--muted);
}

.gallery-group__grid {
  display: grid;
  gap: var(--s-4);
  /* Auto-fill, not a fixed three tracks: one clip then owns a full-sized
     first cell instead of stranding in a third-width column, and a dozen
     clips fill the same rows. minmax floor keeps a lone card a real card.
     The floor is 260px, not 300px, and the number is bounded on both sides.
     From 1920 up the wrap reaches --wall-max, the grid measures 1564px, and
     anything at or below 247px would break that into six columns instead of
     the five the cap was derived for. At 1440 -- the narrowest common
     desktop, where the viewport caps the wrap well below --wall-max -- the
     grid measures around 1135-1150px depending on whether a scrollbar is
     showing, and anything above 271px falls back to three columns blown up
     to 367px each. 260px sits in the middle of that window: five 300px
     tracks at 1920 and up, four ~275px tracks at 1440. */
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  /* Cards are uniform: every card in the wall is the same height, so a row
     has one flat bottom edge instead of a ragged one. That is safe to ask for
     only because card height is now a function of card width alone -- a 16/9
     media box over a footer of fixed height (see .clip-card .card-footer) --
     so stretching finds nothing left to stretch and cannot open the band of
     empty space that sizing-to-content was avoiding. */
  align-items: stretch;
}

@media (max-width: 768px) {
  .gallery-group {
    grid-template-columns: 1fr;
    gap: var(--s-3);
  }
}

.clip-card {
  /* One source for the caption's metrics: the slot the footer reserves is
     computed from the same numbers the caption itself renders with, so the
     reserved strip is exactly two lines of this text and no other height. */
  --caption-size: 0.86rem;
  --caption-leading: 1.35;
  --caption-lines: 2;
  --caption-slot: calc(var(--caption-lines) * var(--caption-size) * var(--caption-leading));
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface-raised);
  border: 1px solid var(--surface-border);
  border-radius: var(--r-lg);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  transition: border-color 180ms ease, transform 180ms var(--ease);
}

.clip-card::before,
.clip-card::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: var(--bracket);
  height: var(--bracket);
  border-color: var(--gold-dim);
  border-style: solid;
  border-width: 0;
  transition: border-color 180ms ease;
}

.clip-card::before { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }
.clip-card::after { right: -1px; bottom: -1px; border-right-width: 1px; border-bottom-width: 1px; }

.clip-card:hover {
  border-color: rgba(240, 194, 80, 0.22);
  transform: translateY(-2px);
}

.clip-card:hover::before,
.clip-card:hover::after {
  border-color: var(--crown-gold);
}

.clip-card:focus-within {
  border-color: rgba(10, 200, 185, 0.5);
}

.clip-card:focus-within::before,
.clip-card:focus-within::after {
  border-color: var(--accent);
}

.clip-card .card-media {
  /* Full bleed: the 16/9 media is the card's first box and every card in a
     row is the same width, so every thumbnail in a row starts and ends at
     the same height. The caption renders below it, inside the footer band. */
  padding: 0;
}

.clip-card .card-media .media {
  border: 0;
  border-radius: 0;
}

.clip-card .card-footer {
  /* The caption is what used to make one card taller than its neighbours, so
     the footer reserves the caption's full two clamped lines in every card --
     whether the clip has no caption, one line, or two. The reserved strip is
     the caption area itself, always in the same place at the same size, not
     slack opened up under a shorter card to match a taller one: it is there
     even when every card in the wall is caption-less, so it reads as the
     card's own structure rather than as a gap chasing a neighbour.

     Grid, not flex, because a grid row exists whether or not an element
     occupies it -- and a caption-less card renders no caption node at all
     (the row invariant test pins that), so there is nothing for a flex
     column to size. */
  display: grid;
  grid-template-rows: var(--caption-slot) auto;
  gap: var(--s-1);
  padding: var(--s-2) var(--s-3) var(--s-3);
}

.card-caption {
  grid-row: 1;
  margin: 0;
  font-size: var(--caption-size);
  font-weight: 600;
  line-height: var(--caption-leading);
  color: var(--text);
  word-break: normal;
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-line-clamp: var(--caption-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-footer__meta {
  grid-row: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  /* Locked to the height of the action buttons this row may or may not carry:
     a member's own clip offers neither vote nor report, and without a floor
     that card's footer would come up short of its neighbours'. */
  min-height: 32px;
  min-width: 0;
}

.card-time {
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.68rem;
  white-space: nowrap;
}

.card-footer .icon-btn {
  flex: 0 0 auto;
  /* The global 44x44 hit target turns this footer into a tall band with the
     date floating in invisible padding; the card footer is pointer-only. */
  min-width: 32px;
  min-height: 32px;
  margin-left: auto;
  margin-right: -6px;
}

.avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #2b3345, #141a24);
  border: 1px solid var(--border);
  color: var(--crown-gold);
  font-family: var(--numeric);
  font-size: 0.74rem;
  font-weight: 700;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  overflow: hidden;
  text-transform: uppercase;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --------------------------------------------------------- viewer dialog */

dialog.viewer {
  padding: 0;
  border: 0;
  background: transparent;
  /* The first term is only a ceiling; the two viewport terms do the real
     work — the width term keeps 16px gutters, the height term caps a 16/9
     stage at 100dvh - 120px so the dialog never needs a scrollbar. 1600px
     reads as framed on a 1920 display (160px side margins) and is inert on
     1440, where the width term binds first. */
  max-width: min(1600px, calc(100vw - 32px), calc((100dvh - 120px) * 16 / 9 + 32px));
  max-height: calc(100dvh - 32px);
  width: 100%;
  color: var(--text);
  overflow: visible;
  margin: auto;
}

dialog.viewer::backdrop {
  /* Dim enough to sit the player forward, sheer enough that the page behind is
     still legibly there. The blur carries the separation the alpha gives up. */
  background: rgba(3, 6, 12, 0.62);
  backdrop-filter: blur(16px) saturate(120%);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
}

.viewer-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-3);
  background: rgba(13, 17, 26, 0.72);
  backdrop-filter: blur(20px) saturate(115%);
  -webkit-backdrop-filter: blur(20px) saturate(115%);
  border: 1px solid var(--gold-line);
  border-radius: var(--r-lg);
  box-shadow: 0 20px 56px rgba(0, 0, 0, 0.8);
  box-sizing: border-box;
  margin: 0 auto;
}

.viewer-panel::before,
.viewer-panel::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: 24px;
  height: 24px;
  border-color: var(--crown-gold);
  border-style: solid;
  border-width: 0;
}

.viewer-panel::before { top: -1px; left: -1px; border-top-width: 2px; border-left-width: 2px; }
.viewer-panel::after { right: -1px; bottom: -1px; border-right-width: 2px; border-bottom-width: 2px; }

.viewer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-width: 0;
  padding-bottom: 2px;
}

.viewer-creator {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
  flex: 1 1 auto;
}

.viewer-creator .avatar {
  width: 36px;
  height: 36px;
  font-size: 0.82rem;
}

.viewer-heading {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 1px;
}

.viewer-title {
  margin: 0;
  font-size: 0.96rem;
  font-weight: 700;
  color: #ffffff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.viewer-subline {
  margin: 0;
  font-size: 0.74rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}

.viewer-subline b {
  color: #dbe0e8;
  font-weight: 600;
}

.viewer-subline span {
  font-family: var(--numeric);
}

.viewer-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}

.viewer-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-md);
  overflow: hidden;
  /* Transparent, not black: a clip whose aspect does not match the stage shows
     the panel and the page through its bars rather than a hard black slab. */
  background: transparent;
  display: grid;
  place-items: center;
  border: 0;
  margin: 0 auto;
}

.viewer-thumb {
  position: absolute;
  inset: 0;
  background: #000000;
  background-size: cover;
  background-position: center;
}

.viewer-video-container {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  z-index: 1;
  background-color: transparent;
}

.viewer-unplayable {
  position: relative;
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 0.9rem;
  text-align: center;
  padding: var(--s-4);
  max-width: 320px;
}

.viewer-unplayable p {
  margin: 0;
}

.viewer-video-container video {
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: contain;
  background-color: transparent;
  color-scheme: dark;
}

.viewer-quality {
  position: absolute;
  top: var(--s-3);
  right: var(--s-3);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 4px 6px 4px 8px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  background: rgba(8, 10, 14, 0.82);
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.68rem;
  line-height: 1;
  opacity: 1;
  transition: opacity 180ms ease;
}

.viewer-quality.is-idle-hidden {
  opacity: 0;
  pointer-events: none;
}

.viewer-quality__control {
  position: relative;
}

.viewer-quality__trigger {
  min-height: 24px;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  cursor: pointer;
}

.viewer-quality__chevron {
  color: var(--muted);
}

.viewer-quality__menu {
  position: absolute;
  right: -6px;
  top: calc(100% + var(--s-2));
  min-width: 96px;
  margin: 0;
  padding: var(--s-1);
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--gold-line);
  border-radius: var(--r-sm);
  box-shadow: var(--surface-shadow);
}

.viewer-quality__option {
  padding: 6px var(--s-2);
  border-radius: var(--r-sm);
  color: var(--text);
  cursor: pointer;
  outline: none;
  text-align: right;
}

.viewer-quality__option:hover,
.viewer-quality__option.is-focused {
  background: var(--gold-soft);
}

.viewer-quality__option.is-selected {
  color: var(--crown-gold);
  font-weight: 700;
}

.viewer-quality:focus-within {
  outline: 2px solid var(--crown-gold);
  outline-offset: 2px;
}

/* --------------------------------------------------------- report dialog */

dialog.report,
dialog.confirm-dialog,
dialog.caption-dialog {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: min(440px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  width: 100%;
  color: var(--text);
  overflow: visible;
}

dialog::backdrop {
  background: rgba(3, 6, 12, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.report-panel,
.confirm-panel,
.caption-panel {
  position: relative;
  display: grid;
  gap: var(--s-4);
  padding: var(--s-5);
  border: 1px solid var(--gold-dim);
  border-radius: var(--r-lg);
  background: #12161f;
  box-shadow: var(--surface-shadow);
  color: var(--text);
  box-sizing: border-box;
}

.report-panel::before,
.report-panel::after,
.confirm-panel::before,
.confirm-panel::after,
.caption-panel::before,
.caption-panel::after {
  content: "";
  position: absolute;
  pointer-events: none;
  width: 20px;
  height: 20px;
  border-color: var(--gold-line);
  border-style: solid;
  border-width: 0;
}

.report-panel::before,
.confirm-panel::before,
.caption-panel::before { top: -1px; left: -1px; border-top-width: 1px; border-left-width: 1px; }

.report-panel::after,
.confirm-panel::after,
.caption-panel::after { right: -1px; bottom: -1px; border-right-width: 1px; border-bottom-width: 1px; }

.report-panel h3,
.confirm-panel h3,
.caption-panel h3 {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 700;
  color: #ffffff;
}

.report-lead {
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.45;
}

.report-subject {
  margin: 0;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  font-size: 0.78rem;
  color: var(--muted);
}

.report-subject b {
  color: #ffffff;
}

.report-categories {
  display: grid;
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  border: 0;
}

.report-categories legend {
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: var(--s-1);
  padding: 0;
}

.radio {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--panel);
  font-size: 0.84rem;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}

.radio:has(input:checked) {
  border-color: var(--crown-gold);
  background: rgba(240, 194, 80, 0.08);
  color: #ffffff;
}

.radio input {
  accent-color: var(--crown-gold);
}

.report-actions,
.confirm-actions,
.caption-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--hairline);
}

/* ------------------------------------------------------------- utilities */

.hidden {
  display: none !important;
}

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}



/* The Riot footer is the shared treatment in style.css; this file declares
   nothing for it. */



/* ----------------------------------------------------------- responsive */

@media (max-width: 640px) {
  .showcase-row__main {
    grid-template-columns: 88px minmax(0, 1fr);
  }

  .showcase-row__actions {
    grid-column: 1 / -1;
    width: 100%;
    margin-left: 0;
    justify-content: flex-start;
  }

  .gallery-grid { grid-template-columns: 1fr; }
  .limits { flex-direction: column; gap: var(--s-2); }
  .viewer-panel { padding: var(--s-3); gap: var(--s-2); }
  .viewer-creator .avatar { width: 28px; height: 28px; font-size: 0.64rem; }
  .viewer-actions .icon-btn { min-width: 38px; min-height: 38px; }
}

@media (max-width: 420px) {
  .btn--sm { padding: 0 8px; font-size: 0.74rem; }
}

@media (max-height: 520px) {
  .viewer-panel {
    max-height: calc(100dvh - 16px);
    overflow-y: auto;
    gap: var(--s-2);
    padding: var(--s-2);
  }
  .viewer-stage {
    max-height: calc(100dvh - 76px);
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .clip-card:hover { transform: none; }
  .shimmer::before { display: none; }
  .anim-uplink-core, .anim-shard, .matrix-ring, .matrix-core, .boot-loading__gem {
    animation: none !important;
  }
  .anim-shard { display: none; }
  .matrix-ring { transform: rotate(45deg) !important; }
}

/* A stalled upload: no animation, because there is nothing to animate. */
.showcase-row__stalled {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--surface-border);
  border-radius: var(--r-md);
  background: var(--surface-sunken);
}

.showcase-row__stalled p {
  flex: 1 1 240px;
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.5;
}

/* ---- sign-in return notice (rendered by js/clips/page.js into the gate) ---- */

.notice--auth {
  position: relative;
  margin-bottom: var(--s-5);
}

.notice--auth .notice-dismiss {
  position: absolute;
  top: var(--s-2);
  right: var(--s-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.notice--auth .notice-dismiss:hover,
.notice--auth .notice-dismiss:focus-visible {
  color: var(--text);
  border-color: var(--surface-border);
}

/* Keep text clear of the corner button on narrow screens. */
.notice--auth > div {
  padding-right: var(--s-6);
}

/* ------------------------------------------------------------ best-clip vote
 *
 * One vote per member, cast from the gallery while the event is live. The
 * confirmation is a brief checkmark toast; the card holding the vote wears
 * the gold corners every other card only earns on hover, and keeps them
 * after voting closes. Off the live phase the controls stay rendered but
 * inert. Existing tokens only: gold line/dim/soft, the --s-* scale.
 */

/* The transient confirmation: absolutely positioned, so it never shifts the
   gallery's layout when it appears or leaves. */
.vote-toast {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: var(--s-2);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  border: 1px solid rgba(240, 194, 80, 0.5);
  border-radius: var(--r-lg);
  background: var(--surface-raised);
  color: var(--crown-gold);
  font-family: var(--numeric);
  font-size: 0.8rem;
  font-weight: 600;
  box-shadow: var(--surface-shadow, 0 8px 24px rgba(0, 0, 0, 0.4));
  animation: vote-toast-in 180ms ease-out;
}

.vote-toast__label {
  white-space: nowrap;
}

@keyframes vote-toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(calc(-1 * var(--s-1))); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* The gallery container is the toast's positioning context. */
#galleryContainer {
  position: relative;
}

/* Cards: the voted clip keeps the hover gold permanently, in every phase. */
.clip-card.is-voted {
  border-color: rgba(240, 194, 80, 0.4);
}

.clip-card.is-voted::before,
.clip-card.is-voted::after {
  border-color: var(--crown-gold);
}

.card-actions-cluster {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  margin-left: auto;
}

.card-vote .card-vote__label {
  font-size: 0.76rem;
  font-weight: 600;
}

.card-vote:not(:disabled):hover {
  color: var(--crown-gold);
}

/* The clip already holding the vote is a state, not an action. */
.card-vote[data-voted="true"],
.card-vote:disabled[data-voted="true"] {
  color: var(--crown-gold);
  opacity: 0.95;
  cursor: default;
  background: transparent;
  border-color: transparent;
}

/* Off the live phase the control is a rendered state, inert on purpose. */
.card-vote:disabled[data-vote-closed="true"] {
  color: var(--muted);
  cursor: default;
  opacity: 0.7;
}

/* A refused vote sits above the wall, not floating midway. */
.gallery-vote-error {
  margin-top: calc(-1 * var(--s-3));
  margin-bottom: var(--s-5);
}

/* ---- gallery refusal and unavailable states (finding 5) -------------------
 *
 * The gallery panel's two failure states. The refused state is the shared
 * member gate (.gate in styles/style.css); the unavailable state is the shared
 * .notice with its actions row. No new colour, spacing, or type tokens — both
 * reuse the existing surfaces.
 */

/* The unavailable notice's actions row keeps the retry inside the notice
   rather than dangling beneath it. */
.notice-actions {
  grid-column: 1 / -1;
}

@media (prefers-reduced-motion: reduce) {
  .vote-toast {
    animation: none;
  }
}
