/* ============================================================================
   Watch Party — design system

   One dark theme, tuned for a room with the lights off. Surfaces step up in
   lightness with elevation rather than relying on borders alone, and the accent
   is reserved for things that are actionable so it keeps its meaning.
   ========================================================================= */

:root {
  color-scheme: dark;

  --bg:        #0b0d12;
  --surface-1: #12151d;
  --surface-2: #181c26;
  --surface-3: #1f2430;
  --line:      #262c3a;
  --line-soft: #1c2129;

  --text:      #e8eaf2;
  --text-dim:  #a2abc0;
  --text-faint:#6f7891;

  --accent:      #6d8cff;
  --accent-hover:#8aa2ff;
  --accent-ink:  #0a0d16;
  --good:  #4ade80;
  --warn:  #fbbf24;
  --bad:   #fb7185;

  --content-width: 1280px;
  --gutter:        24px;

  --radius:   14px;
  --radius-sm:9px;
  --shadow:   0 18px 45px rgba(0,0,0,.45);

  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
}

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.6 var(--font);
  -webkit-font-smoothing: antialiased;
}

/* A wash of colour behind the page so flat dark does not read as dead. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background:
    radial-gradient(1100px 620px at 12% -8%, rgba(109,140,255,.13), transparent 62%),
    radial-gradient(900px 520px at 92% 4%, rgba(168,109,255,.09), transparent 60%);
  pointer-events: none;
  z-index: 0;
}

body > * { position: relative; z-index: 1; }

h1, h2, h3 { margin: 0; line-height: 1.25; font-weight: 650; letter-spacing: -.015em; }
h1 { font-size: 26px; }
h2 { font-size: 19px; }
h3 { font-size: 15px; }
p  { margin: 0 0 12px; }
a  { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

.muted  { color: var(--text-dim); }
.faint  { color: var(--text-faint); }
.mono   { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
.tabular{ font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- layout */

/* The bar itself spans the window so its border and backdrop reach the edges. */
.topbar {
  border-bottom: 1px solid var(--line);
  background: rgba(11,13,18,.82);
  backdrop-filter: blur(14px);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* Its contents sit in the same column as the page below, so the logo lines up with the
   heading under it instead of hugging the window edge on a wide screen. */
.topbar-inner {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
  height: 62px;
}

.brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 680; letter-spacing: -.02em; color: var(--text);
  /* Separates the wordmark from the navigation, which the shared flex gap cannot do
     without spacing the nav items apart from each other by the same amount. */
  margin-right: 30px;
}
.brand svg { width: 24px; height: 24px; flex: none; }
.brand-mark { display: flex; }

/* Sits at the right of the bar, beside Sign out. */
.account { display: flex; align-items: center; gap: 9px; color: var(--text); }
.account .username { color: var(--text-dim); font-size: 13.5px; }
.account:hover .username { color: var(--text); }
.spacer { flex: 1; }

.shell { max-width: var(--content-width); margin: 0 auto; padding: 28px var(--gutter) 72px; }
.stack { display: flex; flex-direction: column; gap: 22px; }
.row   { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.between { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }

.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; margin-bottom: 14px; flex-wrap: wrap; }
.section-head .sub { color: var(--text-dim); font-size: 13.5px; }

/* ---------------------------------------------------------------- surfaces */

.card {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
}

.card.tight { padding: 14px 16px; }
.card.flush { padding: 0; overflow: hidden; }

.empty {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 44px 24px;
  text-align: center;
  color: var(--text-dim);
}
.empty strong { display: block; color: var(--text); margin-bottom: 6px; font-size: 15px; }

/* ---------------------------------------------------------------- controls */

button, .btn {
  font: inherit;
  font-weight: 570;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  padding: 9px 16px;
  cursor: pointer;
  background: var(--accent);
  color: var(--accent-ink);
  transition: background .14s ease, border-color .14s ease, opacity .14s ease, transform .06s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
button:hover, .btn:hover { background: var(--accent-hover); }
button:active, .btn:active { transform: translateY(1px); }
button:disabled { opacity: .45; cursor: not-allowed; transform: none; }

button.ghost, .btn.ghost {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--text);
}
button.ghost:hover, .btn.ghost:hover { background: var(--surface-3); border-color: #35405a; }

/* Every variant is defined for both <button> and .btn (used on links). Leaving one of them
   button-only means an anchor silently falls through to the filled base style — which is how
   the nav links ended up looking like primary actions. */
button.quiet, .btn.quiet { background: none; border-color: transparent; color: var(--text-dim); padding: 7px 10px; }
button.quiet:hover, .btn.quiet:hover { background: var(--surface-2); color: var(--text); }
/* The section you are already in, marked without shouting. */
.btn.quiet.current { background: var(--surface-2); color: var(--text); }

button.danger, .btn.danger { background: none; border-color: #4d2733; color: var(--bad); }
button.danger:hover, .btn.danger:hover { background: rgba(251,113,133,.11); border-color: var(--bad); }

button.small, .btn.small { padding: 6px 11px; font-size: 13px; }
button.block { width: 100%; justify-content: center; }

/* Focus is visible on every interactive element — keyboard users need to see where they are. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

input, select, textarea {
  font: inherit;
  width: 100%;
  padding: 10px 12px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  transition: border-color .14s ease, background .14s ease;
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); outline: none; background: var(--surface-3); }
input::placeholder { color: var(--text-faint); }
input[type=checkbox] { width: auto; accent-color: var(--accent); }

.field { margin-bottom: 15px; }
.field > label { display: block; font-size: 13px; font-weight: 560; color: var(--text-dim); margin-bottom: 6px; }
.field .help { font-size: 12.5px; color: var(--text-faint); margin-top: 6px; }
.field .error { font-size: 12.5px; color: var(--bad); margin-top: 6px; }

.code-input {
  font-family: var(--mono);
  font-size: 21px;
  letter-spacing: .3em;
  text-transform: uppercase;
  text-align: center;
  padding: 13px 12px;
}

/* ---------------------------------------------------------------- pills */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 560;
  padding: 3px 10px;
  border-radius: 99px;
  border: 1px solid var(--line);
  color: var(--text-dim);
  background: var(--surface-2);
  white-space: nowrap;
}
.pill.ok      { color: var(--good); border-color: rgba(74,222,128,.32); background: rgba(74,222,128,.09); }
.pill.working { color: var(--warn); border-color: rgba(251,191,36,.32); background: rgba(251,191,36,.09); }
.pill.bad     { color: var(--bad);  border-color: rgba(251,113,133,.32); background: rgba(251,113,133,.09); }
.pill.accent  { color: var(--accent); border-color: rgba(109,140,255,.34); background: rgba(109,140,255,.11); }

.dot { width: 7px; height: 7px; border-radius: 99px; background: currentColor; flex: none; }
.dot.pulse { animation: pulse 1.9s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* ---------------------------------------------------------------- library grid */

.grid-movies {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 20px;
}

.movie {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.movie:hover { border-color: #39435c; transform: translateY(-3px); box-shadow: var(--shadow); }

.movie .poster {
  aspect-ratio: 16 / 9;
  background: linear-gradient(140deg, var(--surface-3), var(--surface-2));
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.movie .poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.movie .poster .placeholder { color: var(--text-faint); font-size: 30px; }
.movie .poster .badge { position: absolute; top: 10px; right: 10px; }
.movie .poster .len {
  position: absolute; bottom: 10px; right: 10px;
  background: rgba(6,8,12,.82); color: #fff; font-size: 11.5px; font-weight: 560;
  padding: 2px 7px; border-radius: 5px; font-variant-numeric: tabular-nums;
}

.movie .body { padding: 13px 15px 15px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.movie .title { font-weight: 610; line-height: 1.35; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.movie .meta { font-size: 12.5px; color: var(--text-faint); display: flex; gap: 9px; flex-wrap: wrap; }
.movie .actions { margin-top: auto; display: flex; gap: 8px; }

/* Progress bar shown on a card while its video is still transcoding. */
.bar { height: 5px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--accent); transition: width .4s ease; }

/* ---------------------------------------------------------------- tables */

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; font-size: 12px; font-weight: 620; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-faint); padding: 10px 14px; border-bottom: 1px solid var(--line); white-space: nowrap;
}
td { padding: 11px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--surface-2); }

/* ---------------------------------------------------------------- toasts */

#toasts {
  position: fixed; right: 20px; bottom: 20px;
  display: flex; flex-direction: column; gap: 10px;
  z-index: 60; max-width: min(430px, calc(100vw - 40px));
}
.toast {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 12px 15px;
  box-shadow: var(--shadow);
  animation: slide-in .22s cubic-bezier(.2,.9,.3,1);
  font-size: 14px;
}
.toast.ok  { border-left-color: var(--good); }
.toast.err { border-left-color: var(--bad); }
.toast .t { font-weight: 600; margin-bottom: 2px; }
.toast .d { color: var(--text-dim); font-size: 13px; }
@keyframes slide-in { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }

/* ---------------------------------------------------------------- modal */

.modal-backdrop {
  position: fixed; inset: 0; background: rgba(5,7,11,.72);
  backdrop-filter: blur(3px); z-index: 50;
  display: grid; place-items: center; padding: 22px;
  animation: fade .16s ease;
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--surface-1); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  width: min(520px, 100%); max-height: 88vh; overflow-y: auto; padding: 24px;
}
.modal h2 { margin-bottom: 6px; }
.modal .modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 22px; }

/* ---------------------------------------------------------------- misc */

.avatar {
  width: 32px; height: 32px; border-radius: 99px; flex: none;
  display: grid; place-items: center;
  background: linear-gradient(140deg, var(--accent), #a86dff);
  color: #fff; font-weight: 640; font-size: 13px;
}
.avatar.sm { width: 26px; height: 26px; font-size: 11px; }

.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease infinite;
  border-radius: var(--radius-sm);
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

.divider { height: 1px; background: var(--line); margin: 20px 0; }

/* ============================================================================
   Mobile

   Treated as a target rather than a fallback: touch targets are sized for
   fingers, inputs are 16px so iOS does not zoom on focus, modals become bottom
   sheets, and the top bar keeps only what is useful on a small screen.
   ========================================================================= */

/* Respect notches and home indicators. */
body { padding-bottom: env(safe-area-inset-bottom); }
.topbar-inner { padding-left: max(var(--gutter), env(safe-area-inset-left)); padding-right: max(var(--gutter), env(safe-area-inset-right)); }

@media (hover: none) {
  /* Hover transforms feel broken on touch, where "hover" sticks after a tap. */
  .movie:hover { transform: none; box-shadow: none; }
  tbody tr:hover { background: none; }
}

@media (max-width: 900px) {
  .shell { padding: 20px 16px calc(64px + env(safe-area-inset-bottom)); }
  .topbar-inner {
    padding: 0 max(14px, env(safe-area-inset-right)) 0 max(14px, env(safe-area-inset-left));
    gap: 4px;
    height: 58px;
  }
  /* The wordmark is hidden on a phone, so the large gap after it would be dead space. */
  .brand { margin-right: 10px; }

  h1 { font-size: 21px; }
  h2 { font-size: 17px; }

  /* The brand wordmark is the first thing to go; the mark alone still identifies the app. */
  .topbar .brand span:last-child { display: none; }
  .topbar .username { display: none; }

  .card { padding: 16px; border-radius: 12px; }

  /* Fingers need roughly 44px; 15px text in a 9px padding button is not that. */
  button, .btn { padding: 11px 16px; min-height: 44px; }
  button.small, .btn.small { padding: 8px 12px; min-height: 38px; }
  button.quiet, .btn.quiet { min-height: 40px; }

  /* 16px prevents iOS Safari zooming the viewport when a field takes focus. */
  input, select, textarea { font-size: 16px; padding: 12px 13px; }
  .code-input { font-size: 22px; }

  .grid-movies { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 13px; }
  .movie .body { padding: 11px 12px 13px; gap: 7px; }
  .movie .title { font-size: 14px; }

  /* Full-width action buttons read better than a cramped row on a narrow card. */
  .movie .actions { flex-direction: column; }
  .movie .actions > * { width: 100%; justify-content: center; }

  .section-head { margin-bottom: 12px; }
  .between { gap: 10px; }

  /* Toasts span the width at the bottom, out of the way of the thumb. */
  #toasts { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); max-width: none; }

  /* Modals become bottom sheets — closer to the thumb and a familiar pattern. */
  .modal-backdrop { place-items: end center; padding: 0; }
  .modal {
    width: 100%;
    max-height: 90vh;
    border-radius: 18px 18px 0 0;
    padding: 22px 18px calc(22px + env(safe-area-inset-bottom));
    animation: sheet-up .22s cubic-bezier(.2,.9,.3,1);
  }
  .modal .modal-actions { flex-direction: column-reverse; }
  .modal .modal-actions > * { width: 100%; justify-content: center; }
}

@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }

@media (max-width: 560px) {
  .grid-movies { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }

  /* Wide tables stop being tables and become stacked records, so nothing is
     hidden behind a horizontal scroll the user may never discover. */
  table.stack-mobile thead { display: none; }
  table.stack-mobile, table.stack-mobile tbody, table.stack-mobile tr, table.stack-mobile td { display: block; width: 100%; }
  table.stack-mobile tr {
    border: 1px solid var(--line);
    border-radius: 12px;
    margin-bottom: 11px;
    padding: 6px 2px;
    background: var(--surface-1);
  }
  table.stack-mobile td { border: 0; padding: 7px 13px; display: flex; justify-content: space-between; gap: 14px; align-items: center; }
  table.stack-mobile td::before {
    content: attr(data-label);
    color: var(--text-faint);
    font-size: 12px;
    font-weight: 620;
    text-transform: uppercase;
    letter-spacing: .04em;
    flex: none;
  }
  table.stack-mobile td:empty { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
