/* ===========================================================================
   Tayfa — component layer
   Every value comes from tokens.css. No literal colours, no literal spacing.
   =========================================================================== */

/* ===========================================================================
   BRAND LOCKUP
   Gap is 24% of the mark height — the ratio holds at every size.
   The mark SVG is cropped to its ink (viewBox "4 4 56 56") so the flex gap
   is the true optical gap.
   =========================================================================== */
.brand {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--brand-size, 30px) * .24);
  color: var(--accent);
}
.brand__mark { width: var(--brand-size, 30px); height: var(--brand-size, 30px); flex: none; }
.brand__word {
  font-size: var(--brand-size, 30px);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1;
  color: var(--fg);
}
.brand--lg { --brand-size: 46px; }
.brand--md { --brand-size: 30px; }
.brand--sm { --brand-size: 24px; }
.brand--xs { --brand-size: 20px; }
.brand--mark-only .brand__word { display: none; }

/* ===========================================================================
   BUTTON
   =========================================================================== */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: -.005em;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition:
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    transform var(--dur-micro) var(--ease-out);
}
.btn:active:not(:disabled) { transform: scale(.98); }
.btn svg { width: var(--icon-sm); height: var(--icon-sm); flex: none; }

/* --- variants.  Text colour is derived from the variant: there is no
       colour prop, so white-on-orange cannot happen by accident. --------- */
.btn--primary   { background: var(--accent); color: var(--accent-fg); }
.btn--primary:hover:not(:disabled) { background: var(--accent-hover); }

.btn--secondary { background: var(--bg-overlay); color: var(--fg); border-color: var(--border-strong); }
.btn--secondary:hover:not(:disabled) { background: var(--bg-elevated); border-color: var(--fg-subtle); }

.btn--ghost     { background: transparent; color: var(--fg-muted); }
.btn--ghost:hover:not(:disabled) { background: var(--bg-elevated); color: var(--fg); }

.btn--outline   { background: transparent; color: var(--accent); border-color: var(--accent-ring); }
.btn--outline:hover:not(:disabled) { background: var(--accent-soft); border-color: var(--accent); }

.btn--live      { background: var(--live); color: #fff; }
.btn--live:hover:not(:disabled) { background: var(--live-hover); }

.btn--danger    { background: var(--danger); color: #fff; }
.btn--danger:hover:not(:disabled) { background: var(--danger-hover); }

/* --- sizes ------------------------------------------------------------- */
.btn--sm { height: var(--control-h-sm); padding: 0 var(--space-3); font-size: var(--fs-caption); }
.btn--lg { height: var(--control-h-lg); padding: 0 var(--space-5); font-size: var(--fs-body); }
.btn--lg svg { width: var(--icon-md); height: var(--icon-md); }
.btn--block { width: 100%; }

.btn--icon { width: var(--control-h); padding: 0; }
.btn--icon.btn--sm { width: var(--control-h-sm); }
.btn--icon.btn--lg { width: var(--control-h-lg); }

/* --- states ------------------------------------------------------------ */
.btn:disabled,
.btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; transform: none; }

.btn.is-loading { pointer-events: none; }
.btn.is-loading .btn__label { opacity: .55; }
.btn.is-loading::before {
  content: "";
  width: 14px; height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--radius-full);
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }

/* ===========================================================================
   BADGE / CHIP / TAG
   =========================================================================== */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-micro);
  line-height: var(--lh-micro);
  font-weight: 700;
  letter-spacing: .06em;
}
.badge--live     { background: var(--live); color: var(--live-fg); }
.badge--accent   { background: var(--accent); color: var(--accent-fg); }
.badge--team     { background: var(--bg-scrim); color: var(--accent); backdrop-filter: blur(4px); }
.badge--mature   { background: var(--bg-scrim); color: var(--warning); }
.badge--neutral  { background: var(--bg-overlay); color: var(--fg-muted); letter-spacing: 0; }
.badge--verified { background: var(--info); color: var(--info-fg, var(--live-fg)); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--bg-overlay);
  color: var(--fg-muted);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
a.chip:hover, button.chip:hover { background: var(--bg-elevated); color: var(--fg); }
.chip--active { background: var(--accent-soft); color: var(--accent); }
.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-1); }

/* A chip used as a control rather than a label. The base .chip is a static tag
   with no interaction states, so a clickable one needs them added explicitly —
   otherwise it looks identical whether it does something or not. */
.chip--button { cursor: pointer; border: 1px solid transparent; }
.chip--button:hover:not(:disabled) { background: var(--bg-elevated); color: var(--fg); }
.chip--button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chip--button:active:not(:disabled) { transform: scale(.97); }
.chip--button:disabled { opacity: .45; cursor: not-allowed; }
.chip--button.chip--active:hover:not(:disabled) {
  background: var(--accent);
  color: var(--accent-fg);
}

/* live dot — the same mark everywhere a stream is live */
.dot {
  width: 6px; height: 6px;
  border-radius: var(--radius-full);
  background: var(--live);
  flex: none;
}
.dot--pulse { animation: pulse 2s var(--ease-out) infinite; }
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .55; transform: scale(.82); }
}

/* ===========================================================================
   AVATAR
   =========================================================================== */
/* Two states in one box. The fallback is the brand mark, so a user who never
   uploads a photo still reads as one of ours instead of a grey silhouette.
   An <img> inside simply covers it — no conditional class, no JS. */
.avatar {
  position: relative;
  width: var(--avatar-md); height: var(--avatar-md);
  border-radius: var(--radius-full);
  background: var(--bg-elevated);
  flex: none;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.avatar__fallback {
  width: 58%; height: 58%;
  color: var(--avatar-tint, var(--accent));
}
.avatar__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* Placeholder for specimens where no real photo exists. */
.avatar--photo { background: linear-gradient(140deg, #3a4452, #1b2027); }
.avatar--photo .avatar__fallback { display: none; }
.avatar--xs { width: var(--avatar-xs); height: var(--avatar-xs); }
.avatar--sm { width: var(--avatar-sm); height: var(--avatar-sm); }
.avatar--lg { width: var(--avatar-lg); height: var(--avatar-lg); }
.avatar--xl { width: var(--avatar-xl); height: var(--avatar-xl); }

.avatar-ring { position: relative; display: inline-flex; flex: none; }
.avatar-ring--live { box-shadow: 0 0 0 2px var(--live), 0 0 0 4px var(--bg-surface); border-radius: var(--radius-full); }
.avatar-ring--offline { opacity: .55; }

/* ===========================================================================
   FORM FIELD
   =========================================================================== */
.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field__label { font-size: var(--fs-small); font-weight: 600; color: var(--fg); }
.field__hint  { font-size: var(--fs-caption); color: var(--fg-subtle); }
.field__error { font-size: var(--fs-caption); color: var(--danger); }

.input, .textarea, .select {
  height: var(--control-h);
  padding: 0 var(--space-3);
  background: var(--bg-overlay);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--fg);
  font-size: var(--fs-body);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.textarea { height: auto; min-height: 88px; padding: var(--space-3); line-height: var(--lh-body); resize: vertical; }
.input::placeholder, .textarea::placeholder { color: var(--fg-subtle); }
.input:hover, .textarea:hover, .select:hover { border-color: var(--border-strong); }
.input:focus, .textarea:focus, .select:focus { border-color: var(--accent); background: var(--bg-elevated); }
.input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--danger); }
.input:disabled, .textarea:disabled, .select:disabled { opacity: .5; cursor: not-allowed; }

.select {
  appearance: none;
  padding-right: var(--space-8);
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
                    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 16px, calc(100% - 13px) 16px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.search { position: relative; display: flex; align-items: center; }
.search .input { width: 100%; padding-left: var(--space-10); }
.search__icon {
  position: absolute; left: var(--space-3);
  width: var(--icon-sm); height: var(--icon-sm);
  color: var(--fg-subtle); pointer-events: none;
}
.search__kbd {
  position: absolute; right: var(--space-2);
  font-family: var(--font-mono); font-size: var(--fs-micro);
  color: var(--fg-subtle); background: var(--bg-elevated);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 2px 6px; pointer-events: none;
}

/* switch */
.switch { display: inline-flex; align-items: center; gap: var(--space-3); cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  width: 38px; height: 22px;
  background: var(--bg-overlay);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  position: relative;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.switch__track::after {
  content: "";
  position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px;
  background: var(--fg-muted);
  border-radius: var(--radius-full);
  transition: transform var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
}
.switch input:checked + .switch__track { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .switch__track::after { transform: translateX(16px); background: var(--accent-fg); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--accent); outline-offset: 2px; }
/* .btn and .input already carry this; without it a disabled switch reads as a
   live control — an orange "on" track that silently ignores clicks. */
.switch:has(input:disabled) { cursor: not-allowed; opacity: .5; }
.switch input:disabled + .switch__track { cursor: not-allowed; }

/* stream key field — value is masked until revealed */
.keyfield { display: flex; gap: var(--space-2); }
.keyfield .input {
  flex: 1;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: .02em;
}

/* ===========================================================================
   TABS
   =========================================================================== */
.tabs { display: flex; gap: var(--space-5); border-bottom: 1px solid var(--border); }
.tab {
  position: relative;
  padding: var(--space-3) 0;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--fg-muted);
  transition: color var(--dur-fast) var(--ease-out);
}
.tab:hover { color: var(--fg); }
.tab[aria-selected="true"] { color: var(--fg); }
.tab[aria-selected="true"]::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--accent); border-radius: 2px 2px 0 0;
}

/* ===========================================================================
   SEGMENTED CONTROL
   Two to four mutually exclusive options that must all stay visible — theme,
   player quality mode, team-stream layout, analytics date range.
   Use a <select> instead when there are five or more options.
   =========================================================================== */
.segmented {
  display: inline-flex;
  padding: 2px;
  background: var(--bg-overlay);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.segmented__opt {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: calc(var(--control-h) - 6px);
  padding: 0 var(--space-3);
  border-radius: calc(var(--radius-md) - 2px);
  font-size: var(--fs-caption);
  font-weight: 600;
  color: var(--fg-muted);
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.segmented__opt:hover { color: var(--fg); }
.segmented__opt[aria-pressed="true"],
.segmented__opt[aria-checked="true"] {
  background: var(--bg-elevated);
  color: var(--fg);
  box-shadow: var(--shadow-sm);
}
.segmented__opt svg { width: 14px; height: 14px; flex: none; }
.segmented--sm .segmented__opt { height: calc(var(--control-h-sm) - 6px); padding: 0 var(--space-2); }

/* filter pill row (browse page) */
.pillbar { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pill {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: var(--control-h-sm);
  padding: 0 var(--space-3);
  background: var(--bg-overlay);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  font-size: var(--fs-caption);
  font-weight: 600;
  color: var(--fg-muted);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.pill:hover { background: var(--bg-elevated); color: var(--fg); }
.pill[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent-ring); color: var(--accent); }

/* ===========================================================================
   CARDS
   =========================================================================== */
.grid-channels {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-4) var(--space-4);
}
.grid-categories {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: var(--space-4);
}

.card { display: flex; flex-direction: column; gap: var(--space-2); }

.thumb {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--border);
  background:
    radial-gradient(110% 90% at 22% 18%, var(--bg-overlay) 0%, transparent 58%),
    linear-gradient(145deg, var(--bg-elevated) 0%, var(--bg-base) 100%);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.thumb__tl { position: absolute; top: var(--space-2); left: var(--space-2); }
.thumb__tr { position: absolute; top: var(--space-2); right: var(--space-2); }
.thumb__bl { position: absolute; bottom: var(--space-2); left: var(--space-2); }
.thumb__br { position: absolute; bottom: var(--space-2); right: var(--space-2); }

/* overlay meta on a thumbnail always sits on a scrim, never on raw video */
.ovl {
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--bg-scrim);
  color: #fff;
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  backdrop-filter: blur(4px);
}

.card__body { display: flex; gap: var(--space-2); }
.card__text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.card__title { font-size: var(--fs-small); font-weight: 600; color: var(--fg); line-height: 1.35; }
.card__chan  { font-size: var(--fs-caption); color: var(--fg-muted); }
.card__cat   { font-size: var(--fs-caption); color: var(--fg-muted); transition: color var(--dur-fast) var(--ease-out); }
.card__cat:hover { color: var(--accent); }

.card:hover .thumb { border-color: var(--accent-ring); }
.card:hover .card__title { color: var(--accent); }

/* category card — 2:3 box art */
.card-cat { display: flex; flex-direction: column; gap: var(--space-2); }
.card-cat__art {
  aspect-ratio: 2 / 3;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: linear-gradient(160deg, var(--bg-overlay), var(--bg-base));
  transition: transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.card-cat:hover .card-cat__art { transform: translateY(-3px); border-color: var(--accent-ring); }

/* ===========================================================================
   SIDEBAR ROW
   =========================================================================== */
.side-row {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.side-row:hover { background: var(--bg-elevated); }
.side-row__text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.side-row__name { font-size: var(--fs-small); font-weight: 600; color: var(--fg); }
.side-row__cat  { font-size: var(--fs-caption); color: var(--fg-muted); }
.side-row__count {
  display: flex; align-items: center; gap: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.side-head {
  padding: var(--space-2) var(--space-2) var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  color: var(--fg-subtle);
}

/* ===========================================================================
   TOPBAR
   =========================================================================== */
.topbar {
  height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--space-5);
  padding: 0 var(--space-4);
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
}
.topbar__nav { display: flex; gap: var(--space-5); }
.topbar__link { font-size: var(--fs-body); font-weight: 600; color: var(--fg-muted); }
.topbar__link:hover { color: var(--fg); }
.topbar__link--active { color: var(--fg); }
.topbar__spacer { flex: 1; min-width: var(--space-4); }

/* ===========================================================================
   PANEL / SECTION
   =========================================================================== */
.panel {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
}
.panel__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.panel__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }

.section-head { display: flex; align-items: center; gap: var(--space-2); }
.section-head h2 { font-size: var(--fs-h3); font-weight: 700; }

/* ===========================================================================
   STAT
   =========================================================================== */
.stat {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-4);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.stat__label { font-size: var(--fs-caption); color: var(--fg-muted); }
.stat__value {
  font-size: var(--fs-h1); line-height: var(--lh-h1);
  font-weight: 700; letter-spacing: -.015em;
  font-variant-numeric: tabular-nums;
}
.stat__delta { font-size: var(--fs-caption); font-weight: 600; font-variant-numeric: tabular-nums; }
.stat__delta--up   { color: var(--success); }
.stat__delta--down { color: var(--danger); }

/* ===========================================================================
   TABLE (admin)
   =========================================================================== */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); }
.table { width: 100%; border-collapse: collapse; background: var(--bg-surface); }
.table th, .table td {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  /* Baseline is the default, and it aligns a single-line cell to the *first*
     line of a two-line neighbour — so a row with a title plus a subtitle
     leaves every other column floating above centre. */
  vertical-align: middle;
}
.table th {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--fg-subtle);
}
.table td { font-size: var(--fs-small); }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--bg-elevated); }
.table .num { text-align: right; font-family: var(--font-mono); }

/* ===========================================================================
   MENU / DROPDOWN
   =========================================================================== */
.menu {
  min-width: 200px;
  padding: var(--space-1);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.menu__item {
  display: flex; align-items: center; gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--fs-small);
  color: var(--fg);
  transition: background-color var(--dur-micro) var(--ease-out);
}
.menu__item:hover { background: var(--bg-overlay); color: var(--fg); }
.menu__item--danger { color: var(--danger); }
.menu__sep { height: 1px; background: var(--border); margin: var(--space-1) 0; }

/* ===========================================================================
   TOOLTIP
   =========================================================================== */
.tooltip {
  padding: var(--space-1) var(--space-2);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  font-size: var(--fs-caption);
  color: var(--fg);
  white-space: nowrap;
}

/* ===========================================================================
   DIALOG
   =========================================================================== */
.scrim {
  position: fixed; inset: 0;
  background: var(--bg-scrim);
  backdrop-filter: blur(3px);
  z-index: var(--z-scrim);
}
.dialog {
  width: min(480px, calc(100vw - var(--space-8)));
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.dialog__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5) var(--space-3);
}
.dialog__title { font-size: var(--fs-h3); font-weight: 700; }
.dialog__body { padding: 0 var(--space-5) var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }
.dialog__foot {
  display: flex; justify-content: flex-end; gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-surface);
  border-top: 1px solid var(--border);
}

/* ===========================================================================
   TOAST
   =========================================================================== */
.toast {
  display: flex; align-items: flex-start; gap: var(--space-3);
  min-width: 280px; max-width: 420px;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--fg-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  font-size: var(--fs-small);
}
.toast--success { border-left-color: var(--success); }
.toast--error   { border-left-color: var(--danger); }
.toast--live    { border-left-color: var(--live); }
.toast--accent  { border-left-color: var(--accent); }
.toast__title { font-weight: 600; color: var(--fg); }
.toast__text  { color: var(--fg-muted); }

/* ===========================================================================
   BANNER
   =========================================================================== */
.banner {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--bg-surface);
  font-size: var(--fs-small);
  color: var(--fg-muted);
}
.banner--warning { border-color: color-mix(in oklab, var(--warning) 40%, transparent); background: color-mix(in oklab, var(--warning) 8%, var(--bg-surface)); }
.banner--danger  { border-color: color-mix(in oklab, var(--danger) 40%, transparent);  background: color-mix(in oklab, var(--danger) 8%, var(--bg-surface)); }
.banner--accent  { border-color: var(--accent-ring); background: var(--accent-soft); }
.banner strong { color: var(--fg); font-weight: 600; }

/* ===========================================================================
   IMAGE UPLOAD
   ---------------------------------------------------------------------------
   The frame holds its aspect ratio whether or not there is a picture in it, so
   the panel does not jump as one loads. The ratio is part of the modifier
   rather than inline: each surface has one correct shape, and an upload
   control that previews a different shape than the page will show is a control
   that lies about the crop.
   =========================================================================== */
.imgdrop { display: flex; flex-direction: column; gap: var(--space-3); }

.imgdrop__frame {
  position: relative;
  display: grid; place-items: center;
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-elevated);
  /* A checkerboard behind the picture: transparency is preserved for PNG and
     GIF sources, and a flat background hides whether a corner is see-through
     until it lands on the real page. */
  background-image:
    linear-gradient(45deg, var(--bg-surface) 25%, transparent 25%),
    linear-gradient(-45deg, var(--bg-surface) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--bg-surface) 75%),
    linear-gradient(-45deg, transparent 75%, var(--bg-surface) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.imgdrop__frame--wide  { aspect-ratio: 4 / 1; }
.imgdrop__frame--video { aspect-ratio: 16 / 9; }

.imgdrop__frame img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
}

.imgdrop__empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  color: var(--fg-subtle);
  font-size: var(--fs-caption);
  text-align: center;
  padding: var(--space-4);
}
.imgdrop__empty svg { width: var(--icon-lg); height: var(--icon-lg); }

.imgdrop__actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* ===========================================================================
   PROGRESS / METER
   =========================================================================== */
/* display:block on both is load-bearing, not tidiness: these are written as
   <span> in markup, and height on an inline box is ignored — the track and the
   fill both collapse to nothing. */
.meter {
  display: block;
  height: 6px;
  background: var(--bg-overlay);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.meter__fill {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: var(--radius-full);
  transition: width var(--dur-base) var(--ease-out);
}
.meter__fill--warning { background: var(--warning); }
.meter__fill--danger  { background: var(--danger); }
.meter__fill--success { background: var(--success); }

/* ===========================================================================
   SKELETON
   =========================================================================== */
.sk {
  background: linear-gradient(90deg, var(--bg-overlay) 0%, var(--bg-elevated) 40%, var(--bg-overlay) 80%);
  background-size: 300% 100%;
  border-radius: var(--radius-sm);
  animation: shimmer 1.4s linear infinite;
}
.sk--thumb { aspect-ratio: 16 / 9; border-radius: var(--radius-lg); }
.sk--line  { height: 12px; }
.sk--line-sm { height: 10px; }
.sk--avatar { width: var(--avatar-md); height: var(--avatar-md); border-radius: var(--radius-full); }
@keyframes shimmer { to { background-position: -300% 0; } }

/* ===========================================================================
   EMPTY / ERROR STATE
   =========================================================================== */
.state {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-3);
  padding: var(--space-12) var(--space-5);
  text-align: center;
}
.state__icon {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: var(--radius-full);
  background: var(--bg-overlay);
  color: var(--fg-subtle);
}
.state__title { font-size: var(--fs-h3); font-weight: 700; }
.state__text { font-size: var(--fs-small); color: var(--fg-muted); max-width: 42ch; }
.state__actions { margin-top: var(--space-2); }

/* ===========================================================================
   CHAT
   =========================================================================== */
.chat {
  display: flex; flex-direction: column;
  width: var(--chat-w);
  background: var(--bg-surface);
  border-left: 1px solid var(--border);
}
.chat__head {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--topbar-h);
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-small);
  font-weight: 600;
}
.chat__body { flex: 1; overflow-y: auto; padding: var(--space-2) 0; }
.chat__foot { padding: var(--space-3); border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: var(--space-2); }

.msg {
  padding: 5px var(--space-3);
  font-size: var(--fs-small);
  line-height: 1.45;
  word-wrap: break-word;
}
.msg:hover { background: var(--bg-elevated); }
.msg__badges { display: inline-flex; gap: 2px; vertical-align: -3px; margin-right: var(--space-1); }
.msg__name { font-weight: 700; }
.msg--mention { background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }
.msg--deleted { color: var(--fg-subtle); font-style: italic; }

.cbadge {
  display: inline-grid; place-items: center;
  width: 18px; height: 18px;
  border-radius: var(--radius-sm);
  font-size: 9px; font-weight: 800;
  color: #fff;
}
.cbadge--broadcaster { background: var(--broadcaster); }
.cbadge--mod   { background: var(--mod); }
.cbadge--vip   { background: var(--vip); }
.cbadge--tier1 { background: var(--tier-1); color: #0d1014; }
.cbadge--tier2 { background: var(--tier-2); color: #0d1014; }
.cbadge--tier3 { background: var(--tier-3); color: #0d1014; }

.chat-event {
  margin: var(--space-2) var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--accent-soft);
  border: 1px solid var(--accent-ring);
  border-radius: var(--radius-md);
  font-size: var(--fs-small);
  color: var(--fg);
}
.chat-event strong { font-weight: 700; }
.chat-event--live { background: var(--live-soft); border-color: color-mix(in oklab, var(--live) 40%, transparent); }

.chat-pinned {
  display: flex; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--bg-overlay);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-caption);
  color: var(--fg-muted);
}

/* ===========================================================================
   PLAYER SHELL
   =========================================================================== */
.player {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.player__canvas {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 100% at 30% 25%, var(--bg-overlay) 0%, transparent 60%),
    linear-gradient(160deg, var(--bg-elevated) 0%, #05070a 100%);
}
.player__top { position: absolute; top: var(--space-3); left: var(--space-3); right: var(--space-3); display: flex; gap: var(--space-2); }
.player__bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--space-3);
  padding: 0 var(--space-3);
  background: linear-gradient(transparent, rgba(0, 0, 0, .85));
  color: #fff;
}
.player__btn {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: var(--radius-md);
  color: #fff;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.player__btn:hover { background: rgba(255, 255, 255, .14); }
.player__time {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  color: #fff;
}
.player__spacer { flex: 1; }

/* ===========================================================================
   APP SHELL
   sidebar · main column · chat. The three fixed widths come from tokens so a
   screen built here and a screen built in Next.js cannot drift apart.
   =========================================================================== */
.app {
  display: flex;
  background: var(--bg-base);
  overflow: hidden;
}
.app__side {
  width: var(--sidebar-w);
  flex: none;
  background: var(--bg-surface);
  border-right: 1px solid var(--border);
  padding: var(--space-2);
  overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-1);
}
.app__side--collapsed { width: var(--sidebar-w-collapsed); align-items: center; }
.app__main { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
.app__body { flex: 1; min-height: 0; display: flex; overflow: hidden; }
.app__content { flex: 1; min-width: 0; overflow-y: auto; }
.app__chat { width: var(--chat-w); flex: none; min-height: 0; }

/* ===========================================================================
   WATCH SCREEN
   =========================================================================== */
.watch { display: flex; flex-direction: column; }
.watch__player { background: #000; }
.watch__player .player { border-radius: 0; }
/* The channel banner, below the player and above the identity block. Its own
   ratio is fixed so the page does not reflow as it loads, and it is hidden
   entirely when a channel has not set one — an empty strip looks like a
   failure, while no strip looks like a choice. */
.watch__banner {
  width: 100%;
  aspect-ratio: 4 / 1;
  /* Capped, and cropped by object-fit rather than scaled. At full ratio a
     1500 px wide page gives a 375 px tall strip, which pushes the channel's
     name and the follow button below the fold — the banner would be the
     loudest thing on a page about a broadcast. */
  max-height: 220px;
  overflow: hidden;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border);
}
.watch__banner img { display: block; width: 100%; height: 100%; object-fit: cover; }

.watch__info {
  display: flex; flex-direction: column; gap: var(--space-4);
  padding: var(--space-4);
}
.watch__head { display: flex; align-items: flex-start; gap: var(--space-3); }
.watch__id { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; flex: 1; }
.watch__title { font-size: var(--fs-h3); line-height: 1.35; font-weight: 700; color: var(--fg); }
.watch__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.watch__chan { font-size: var(--fs-body); font-weight: 700; color: var(--fg); }
.watch__actions { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.watch__stats {
  display: flex; align-items: center; gap: var(--space-4);
  font-family: var(--font-mono); font-size: var(--fs-small);
  font-variant-numeric: tabular-nums; color: var(--fg-muted);
}
/* The team-stream strip: one tile per participant, below the player. */
.watch__team { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
/* Same height as a medium button so the participant row and the controls next
   to it sit on one line. */
.teamtile {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: var(--control-h);
  padding: 0 var(--space-3);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--fg-muted);
  white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.teamtile .avatar { width: 22px; height: 22px; }
.teamtile:hover { border-color: var(--accent-ring); color: var(--fg); }
.teamtile--active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }

/* Chat gate — a guest sees the whole conversation, only the input is swapped. */
.chatgate {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4);
  background: var(--bg-elevated);
  border-radius: var(--radius-md);
  text-align: center;
}
.chatgate__title { font-size: var(--fs-small); font-weight: 700; color: var(--fg); }
.chatgate__actions { display: flex; gap: var(--space-2); }
.chatgate__actions .btn { flex: 1; }
.chatgate__note { font-size: var(--fs-caption); color: var(--fg-subtle); }

/* ===========================================================================
   AUTH
   =========================================================================== */
.authcard {
  width: min(420px, 100%);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.authcard__head {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-3);
  padding: var(--space-6) var(--space-6) var(--space-4);
  text-align: center;
}
.authcard__title { font-size: var(--fs-h2); font-weight: 700; letter-spacing: -.012em; }
.authcard__sub { font-size: var(--fs-small); color: var(--fg-muted); max-width: 32ch; }
.authcard__body { padding: 0 var(--space-6) var(--space-6); display: flex; flex-direction: column; gap: var(--space-4); }
.authcard__foot {
  padding: var(--space-4) var(--space-6);
  background: var(--bg-surface);
  border-top: 1px solid var(--border);
  text-align: center;
  font-size: var(--fs-small);
  color: var(--fg-muted);
}
.authcard__foot a { color: var(--accent); font-weight: 600; }

.oauth { display: flex; flex-direction: column; gap: var(--space-2); }
.oauth-btn {
  display: flex; align-items: center; gap: var(--space-3);
  height: var(--control-h-lg);
  padding: 0 var(--space-4);
  background: var(--bg-overlay);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  color: var(--fg);
  font-size: var(--fs-body);
  font-weight: 600;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.oauth-btn:hover { background: var(--bg-elevated); border-color: var(--fg-subtle); color: var(--fg); }
.oauth-btn__icon { width: 20px; height: 20px; flex: none; }
/* Label centred in the remaining space so the icons stay in one column and the
   words stay optically centred — the pattern every provider's guidelines want. */
.oauth-btn__label { flex: 1; text-align: center; margin-right: 20px; }

.divider {
  display: flex; align-items: center; gap: var(--space-3);
  font-size: var(--fs-caption); color: var(--fg-subtle);
}
.divider::before, .divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}

.legalnote { font-size: var(--fs-caption); line-height: 1.5; color: var(--fg-subtle); text-align: center; }
.legalnote a { color: var(--fg-muted); text-decoration: underline; }

.strength { display: flex; gap: 3px; }
.strength span { flex: 1; height: 3px; border-radius: 99px; background: var(--bg-overlay); }
.strength span.on-weak   { background: var(--danger); }
.strength span.on-ok     { background: var(--warning); }
.strength span.on-strong { background: var(--success); }

/* ===========================================================================
   CREATOR DASHBOARD
   =========================================================================== */
.dash { display: flex; min-height: 0; }
.dash__nav {
  width: 208px; flex: none;
  background: var(--bg-surface);
  border-right: 1px solid var(--border);
  padding: var(--space-3) var(--space-2);
  display: flex; flex-direction: column; gap: 2px;
}
.dash__navhead {
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  color: var(--fg-subtle);
}
.dash__link {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--fs-small);
  font-weight: 600;
  color: var(--fg-muted);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.dash__link:hover { background: var(--bg-elevated); color: var(--fg); }
.dash__link--active { background: var(--accent-soft); color: var(--accent); }
.dash__main { flex: 1; min-width: 0; overflow-y: auto; padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-6); }
.dash__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-4); }

/* Live status strip at the top of the dashboard. */
.livestrip {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  padding: var(--space-4) var(--space-5);
  background: var(--live-soft);
  border: 1px solid color-mix(in oklab, var(--live) 40%, transparent);
  border-radius: var(--radius-lg);
}
.livestrip--offline {
  background: var(--bg-surface);
  border-color: var(--border);
}

/* ===========================================================================
   LAYOUT HELPERS
   =========================================================================== */
.stack  { display: flex; flex-direction: column; }
.row    { display: flex; align-items: center; }
.wrap   { flex-wrap: wrap; }
.between{ justify-content: space-between; }
.g-1 { gap: var(--space-1); } .g-2 { gap: var(--space-2); } .g-3 { gap: var(--space-3); }
.g-4 { gap: var(--space-4); } .g-5 { gap: var(--space-5); } .g-6 { gap: var(--space-6); }
.g-8 { gap: var(--space-8); } .g-12 { gap: var(--space-12); }
.flex-1 { flex: 1; min-width: 0; }
