/* Arenos chat — layout on top of the Arenos design system.
   Every colour, space and radius comes from ds/styles.css tokens, so a theme
   can repaint the app by overriding them and nothing here needs to change.

   Two literals remain, both video-ground exceptions: white on the thumbnail
   clock and true black on the letterbox matte. The thumbnail is dark under
   every theme, so its foreground does not follow the page the way --color-bg
   would. The matte is the same argument at full strength: it is video, not a
   UI surface. Everywhere text sits on the accent fill instead now goes through
   --color-on-accent rather than a literal white — Arenos amber fails contrast
   outright under white (about 1.9:1) and needs ink, which a hardcoded #fff
   could not express. */

/* Structure, alongside the design system's colour and space tokens.

   Rule weight is a theme's business as much as its palette is: a system built
   on hairlines and small radii is a different object from one built on heavy
   rules and square corners, even reusing the same component classes. --rule
   and --rule-hair live here because ds/styles.css has no token for a border
   width — nothing else there names one either. */
:root {
  /* Arenos specifies one hairline weight, 1px, everywhere — no separate
     heavier structural rule. Both tokens carry the same value so nothing
     downstream has to change to ask for it, and a future theme that does want
     two weights only has to override one of them. */
  --rule: 1px;
  --rule-hair: 1px;
}

body {
  margin: 0;
  background: var(--color-bg);
  font-family: var(--font-body);
  color: var(--color-text);
}

a { color: var(--color-accent-700); text-decoration: none; }
a:hover { color: var(--color-accent); }
input, button, textarea { font-family: var(--font-body); }

.shell {
  height: 100vh;
  min-height: 620px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--color-bg);
}

/* ── Brand ──────────────────────────────────────────────────────────── */

/* The brand sits in the session rail's header, not in a bar of its own. With
   Settings and Sign out moved into the account menu at the foot of that rail,
   a full-width header had nothing left in it. */
.brand {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* The Arenos lockup (notag, horizontal) is a wide mark — artwork bounds
   815.912 x 211, roughly 3.87:1 — sitting in a 232px rail rather than a
   full-width header. At 35px tall it wants about 136px of width, and the rail
   leaves 172px once its 13px padding, the 8px gap and the 26px plus button are
   taken out, so it clears the control beside it. object-fit keeps the ratio;
   the cap is what stops a wider lockup from ever reaching the button. */
.brand-logo {
  height: 35px;
  width: auto;
  max-width: 172px;
  object-fit: contain;
  display: block;
}

/* The tagline cut (819.358 x 211, same ~3.87:1) at a legible sign-in size. */
.signin-logo { height: 34px; width: auto; margin-bottom: var(--space-4); }

.brand-name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ── Transcript ─────────────────────────────────────────────────────── */

.scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 32px 0 24px; }

.transcript {
  max-width: 860px;
  padding: 0 48px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* A user turn is a line in the margin; an agent turn is a card. The two are
   different kinds of thing and the transcript reads better for saying so: one
   is what somebody typed, the other is the reply the desk works from — and
   usually the frame around a moments, games or stage-strip list as well. */
.msg-user { border-left: var(--rule) solid var(--color-neutral-400); padding-left: 16px; }

.card {
  background: var(--color-surface);
  border: var(--rule-hair) solid var(--color-divider);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

/* Replies land at the foot of a scrolled column, so a card that fades up says
   a new one has arrived without shifting anything already read.
   It is not a decoration that can be left in the markup: the transcript is
   rewritten wholesale on every render, and an agent reply re-renders on every
   streamed token, so the class has to be applied once and then dropped — see
   the WeakSet in render(). */
@keyframes card-fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.fade-in { animation: card-fade-up 0.32s cubic-bezier(0.2, 0.7, 0.3, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .fade-in { animation: none; }
}

.msg-label {
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
  margin-bottom: 6px;
}
.msg-agent .msg-label { color: var(--color-accent-700); }

.msg-text {
  font-size: 14px;
  line-height: 1.6;
  text-wrap: pretty;
  white-space: pre-wrap;
  max-width: 640px;
}

.thinking-text { font-size: 13px; color: var(--color-neutral-600); }

/* ── Inline cards ───────────────────────────────────────────────────── */

.panel { margin-top: 14px; border: var(--rule) solid var(--color-text); max-width: 640px; }
.panel-light { margin-top: 14px; border: var(--rule-hair) solid var(--color-neutral-300); max-width: 640px; }

/* Inside a card the label's own spacing and the card's padding already do most
   of that work, so the panel's margin is trimmed to keep a card that answers
   with a list reading at the same rhythm as one that answers in a sentence. */
.card > .panel,
.card > .panel-light { margin-top: var(--space-3); }

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: var(--rule-hair) solid var(--color-neutral-300);
}

.panel-head-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.panel-head-meta {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  display: flex;
  gap: 10px;
}

/* The chosen sort. A pressed link-button reads as the current state rather
   than as somewhere to go, so it takes the text colour and loses the hand. */
.link-btn[aria-pressed="true"] {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: default;
}

.row { border-bottom: var(--rule-hair) solid var(--color-neutral-300); }
.row:last-child { border-bottom: 0; }

/* Moments */

.moment-row {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
}

.thumb {
  position: relative;
  height: 40px;
  background: var(--color-neutral-900);
  overflow: hidden;
  cursor: pointer;
  border: 0;
  padding: 0;
  width: 100%;
}
.thumb:hover { outline: 2px solid var(--color-accent); outline-offset: -2px; }

.thumb-stripes {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(115deg,
    color-mix(in srgb, var(--color-neutral-900) 80%, var(--color-neutral-700)) 0 7px,
    var(--color-neutral-900) 7px 15px);
}

.thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.thumb-clock {
  position: absolute;
  left: 4px;
  bottom: 3px;
  font-size: 8.5px;
  font-weight: 700;
  /* On the video ground, not on the page: the thumbnail is dark under every
     theme, so this is white rather than --color-bg, which follows the page. */
  color: #fff;
  z-index: 1;
  /* A timecode — the brand's own example of what the mono face exists for. */
  font-family: var(--font-mono);
}

.moment-label { font-size: 12.5px; font-weight: 700; line-height: 1.25; }

.moment-meta {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
  margin-top: 3px;
}

.rerank-why {
  font-size: 10.5px;
  color: var(--color-neutral-700);
  margin-top: 4px;
  font-style: italic;
  line-height: 1.4;
}

/* Buttons — flush left labels, radius from the theme's own tokens */

.btn-outline {
  border: var(--rule-hair) solid var(--color-text);
  background: transparent;
  color: var(--color-text);
  padding: 6px 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
}
.btn-outline:hover { background: var(--color-accent-100); }
.btn-outline:disabled { opacity: 0.45; cursor: not-allowed; }

.btn-solid {
  border: 0;
  background: var(--color-accent);
  /* On the accent, not on --color-bg (the page's own colour, and only
     readable here by luck of which theme is active). --color-on-accent is a
     fixed ink/white choice per theme — Arenos requires ink here because white
     on its amber fails contrast outright; the fallback covers any theme that
     does not define the token. */
  color: var(--color-on-accent, #fff);
  padding: 9px 14px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}
.btn-solid:hover { background: var(--color-accent-600); }
.btn-solid:active { background: var(--color-accent-700); }
.btn-solid:disabled { opacity: 0.45; cursor: not-allowed; }

.chip {
  border: var(--rule-hair) solid var(--color-neutral-400);
  background: transparent;
  color: var(--color-neutral-800);
  padding: 6px 10px;
  font-size: 11px;
  cursor: pointer;
}
.chip:hover { border-color: var(--color-accent); color: var(--color-accent-700); }
.chip[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: var(--color-accent-100);
  color: var(--color-accent-900);
}

.chip-row { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }

/* Inline player — opens in place, so a moment is reviewed without a timeline */

.inline-player {
  border-top: var(--rule-hair) solid var(--color-neutral-300);
  background: var(--color-neutral-900);
  position: relative;
}
/* Letterbox bars stay true black: this is video matte, not a UI surface, and
   a tinted ground would read as a rendering fault against the footage. */
.inline-player video { width: 100%; display: block; aspect-ratio: 16 / 9; background: #000; }

.player-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  background: var(--color-bg);
  border-top: var(--rule-hair) solid var(--color-neutral-300);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700);
}

/* Ingest */

.dropzone {
  border: var(--rule) dashed var(--color-neutral-500);
  background: var(--color-neutral-100);
  padding: 18px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.dropzone.is-over { border-color: var(--color-accent); background: var(--color-accent-100); }

.dz-thumb {
  width: 74px;
  height: 42px;
  background: var(--color-neutral-900);
  position: relative;
  overflow: hidden;
  flex: none;
}

.dz-name { font-size: 12.5px; font-weight: 700; overflow-wrap: anywhere; }
.dz-meta { font-size: 11px; color: var(--color-neutral-700); margin-top: 3px; }

.file-label {
  border: var(--rule-hair) solid var(--color-text);
  background: transparent;
  padding: 7px 11px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
}
.file-label:hover { background: var(--color-accent-100); }

.source-tabs { display: flex; border-bottom: var(--rule-hair) solid var(--color-neutral-300); }

.source-tab {
  flex: 1;
  border: 0;
  border-right: var(--rule-hair) solid var(--color-neutral-300);
  background: transparent;
  color: var(--color-text);
  padding: 9px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}
.source-tab:last-child { border-right: 0; }
.source-tab[aria-selected="true"] { background: var(--color-text); color: var(--color-bg); }
.source-tab:disabled { opacity: 0.45; cursor: not-allowed; }

.field-label {
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
}

/* Progress */

.meter { flex: 1; height: 4px; background: var(--color-neutral-300); }
.meter i { display: block; height: 4px; background: var(--color-accent); }
.meter-neutral i { background: var(--color-neutral-800); }

.meter-row { display: flex; align-items: center; gap: 9px; margin-top: 8px; }

/* Stage strip: one segment per pipeline stage, widths in proportion to how long
   each stage actually takes, so the bar moves at a roughly constant rate
   through a run rather than sitting still through the hour of analysis. */
.stage-strip { display: flex; gap: 4px; margin-top: 9px; }
.stage { flex-grow: 1; flex-basis: 0; }
.stage[data-state="todo"] { opacity: 0.45; }
.stage-meter { height: 4px; background: var(--color-neutral-300); }
.stage-meter i { display: block; height: 4px; background: var(--color-neutral-800); }
.stage[data-state="active"] .stage-meter i { background: var(--color-accent); }

.stage-label {
  margin-top: 4px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-neutral-700);
}

.stage[data-state="active"] .stage-label { color: var(--color-accent); }

.meter-pct {
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700);
}

/* Reel */

.reel-bars { display: flex; height: 30px; border-bottom: var(--rule-hair) solid var(--color-neutral-300); }
.reel-bar { border-right: var(--rule-hair) solid var(--color-bg); flex-basis: 0; }

.clip-row {
  display: grid;
  grid-template-columns: 20px 1fr auto auto;
  gap: 10px;
  align-items: center;
  padding: 9px 12px;
  border-bottom: var(--rule-hair) solid var(--color-neutral-300);
}

.clip-n {
  font-size: 10px;
  font-weight: 700;
  color: var(--color-neutral-600);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono);
}

.clip-label { font-size: 12px; font-weight: 700; line-height: 1.25; min-width: 0; }

.stepper { display: flex; align-items: center; gap: 6px; }

.step-btn {
  border: var(--rule-hair) solid var(--color-neutral-400);
  background: transparent;
  color: var(--color-text);
  width: 24px;
  height: 24px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  line-height: 1;
}
.step-btn:hover { border-color: var(--color-accent); }

.step-val {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 38px;
  text-align: center;
  font-family: var(--font-mono);
}

.link-btn {
  border: 0;
  background: transparent;
  color: var(--color-neutral-600);
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  padding: 4px 2px;
}
.link-btn:hover { color: var(--color-accent); }

.panel-actions { display: flex; gap: 8px; padding: 11px 12px; flex-wrap: wrap; }

/* Jobs */

.job { padding: 11px 12px; border-bottom: var(--rule-hair) solid var(--color-neutral-300); }
.job:last-child { border-bottom: 0; }

.job-top { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.job-name { font-size: 12px; font-weight: 700; overflow-wrap: anywhere; }

.job-status {
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--color-neutral-600);
}
.job-status[data-tone="running"] { color: var(--color-neutral-800); }
.job-status[data-tone="failed"] { color: var(--color-accent-2); }

.job-stage { font-size: 11px; color: var(--color-neutral-700); margin-top: 4px; line-height: 1.4; }

.job-error {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin-top: 7px;
  border-left: var(--rule) solid var(--color-accent-2);
  background: var(--color-accent-2-100);
  padding: 8px 10px;
}
.job-error p { font-size: 11px; line-height: 1.45; color: var(--color-accent-2-900); flex: 1; margin: 0; }

/* Publish */

.platform {
  width: 100%;
  text-align: left;
  display: grid;
  grid-template-columns: 18px 1fr auto;
  gap: 12px;
  align-items: center;
  border: 0;
  border-bottom: var(--rule-hair) solid var(--color-neutral-300);
  background: transparent;
  color: var(--color-text);
  padding: 11px 12px;
  cursor: pointer;
}
.platform:hover { background: var(--color-accent-100); }
.platform[aria-pressed="true"] { background: var(--color-accent-100); }

.checkmark { width: 14px; height: 14px; border: var(--rule) solid var(--color-neutral-600); }
.platform[aria-pressed="true"] .checkmark { border-color: var(--color-accent); background: var(--color-accent); }

.platform-name { font-size: 12.5px; font-weight: 700; }
.platform-spec { font-size: 10.5px; color: var(--color-neutral-700); margin-top: 2px; }

.platform-state {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
}

.caption-box {
  width: 100%;
  border: var(--rule-hair) solid var(--color-neutral-400);
  background: var(--color-neutral-100);
  padding: 9px;
  font-size: 12.5px;
  line-height: 1.5;
  outline: 0;
  resize: vertical;
  color: var(--color-text);
}
.caption-box:focus-visible { border-color: var(--color-accent); }

/* Composer */

.composer { flex: none; border-top: var(--rule) solid var(--color-text); }

.suggestions { padding: 12px 48px 8px; display: flex; flex-wrap: wrap; gap: 7px; }

.composer-inner { padding: 0 48px 18px; }

.composer-box {
  display: flex;
  border: var(--rule) solid var(--color-text);
  background: var(--color-neutral-100);
}

.composer-input {
  flex: 1;
  border: 0;
  outline: 0;
  background: transparent;
  padding: 13px 14px;
  font-size: 13.5px;
  color: var(--color-text);
  min-width: 0;
}

.composer-send {
  border: 0;
  border-left: var(--rule) solid var(--color-text);
  background: var(--color-accent);
  color: var(--color-on-accent, #fff);
  padding: 0 20px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
}
.composer-send:hover { background: var(--color-accent-600); }
.composer-send:disabled { opacity: 0.45; cursor: not-allowed; }

.footer-line {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
  margin-top: 7px;
}

/* Sign-in */

.signin {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--color-bg);
  z-index: 50;
}

.signin-card {
  width: min(420px, 92vw);
  border: var(--rule) solid var(--color-text);
  background: var(--color-neutral-100);
  padding: var(--space-8);
}

.signin-card h1 { font-size: 28px; margin: 0 0 var(--space-2); }

.signin-alt { display: flex; align-items: center; gap: 10px; margin: 16px 0 12px; }
.signin-alt > span:first-child,
.signin-alt > span:last-child { flex: 1; height: 1px; background: var(--color-neutral-300); }
.signin-card p { font-size: 14px; color: var(--color-neutral-800); margin-bottom: var(--space-6); }

.error-note {
  border-left: var(--rule) solid var(--color-accent-2);
  background: var(--color-accent-2-100);
  color: var(--color-accent-2-900);
  padding: 9px 11px;
  font-size: 12px;
  margin-top: var(--space-3);
}

.hidden { display: none !important; }

@media (max-width: 900px) {
  .transcript, .suggestions, .composer-inner { padding-left: 20px; padding-right: 20px; }
}

/* Slot the live player is re-parented into after each render. */
.player-slot:empty { display: none; }

/* Game details */
/* Two columns, not the moment row's three: a game has no thumbnail to play,
   so borrowing that grid would squeeze the headline into the 72px thumb slot. */
.game-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
}

.game-summary {
  padding: 0 12px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--color-neutral-800);
}

/* Aligned under the headline rather than the thumb column, so the outcome
   reads as part of the same statement. */
.game-outcome {
  margin-top: 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.header-select {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: var(--rule) solid var(--color-text);
  background: transparent;
  color: var(--color-text);
  padding: 6px 8px;
  margin-right: 8px;
  cursor: pointer;
}

/* Firebase restores a stored session asynchronously and reports null first.
   Painting nothing until that resolves stops every reload flashing the sign-in
   card, which reads as having been logged out. */
body:not([data-auth-resolved]) .signin,
body:not([data-auth-resolved]) .shell { visibility: hidden; }

/* Settings */
.modal {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--color-text) 45%, transparent);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 8vh 16px;
  z-index: 50;
}

.modal-card {
  width: min(520px, 100%);
  background: var(--color-neutral-100);
  border: var(--rule) solid var(--color-text);
  max-height: 84vh;
  overflow-y: auto;
}

.modal-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: var(--rule) solid var(--color-text);
}

.modal-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.setting { padding: 14px 16px; border-bottom: var(--rule-hair) solid var(--color-neutral-300); }
.setting:last-child { border-bottom: 0; }

.setting-hint {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--color-neutral-800);
  margin: 4px 0 9px;
}

/* Sessions panel */
.workspace { flex: 1; display: flex; min-height: 0; }

/* The content column: transcript above, composer pinned under it. The composer
   lives here rather than in the shell so it spans the content only — full
   width put a search bar under the session list, which is not what it
   searches. */
.main-area {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.sessions {
  width: 232px;
  flex: none;
  display: flex;
  flex-direction: column;
  border-right: var(--rule) solid var(--color-text);
  background: var(--color-neutral-100);
  min-height: 0;
}

/* The rail's own header: the brand, and one control. */
.sessions-header {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0 var(--space-4);
  min-height: 56px;
  border-bottom: var(--rule-hair) solid var(--color-neutral-300);
}

/* A plus, not a labelled bar. Starting a session is a frequent, low-stakes
   action; giving it the accent across the full width of the rail spent the
   one scarce colour in the system on the least important thing on screen. */
.sessions-new {
  flex: none;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--rule-hair) solid var(--color-neutral-300);
  border-radius: var(--radius-md);
  background: var(--color-neutral-200);
  color: var(--color-neutral-700);
  cursor: pointer;
  padding: 0;
}
.sessions-new:hover {
  background: var(--color-accent-100);
  border-color: var(--color-accent);
  color: var(--color-accent-700);
}

.sessions-list { flex: 1; overflow-y: auto; min-height: 0; }

/* Recency separator. Sessions are ordered newest first, so these split the
   list where the day does — one label per group, never a label with nothing
   under it. */
.session-group {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-neutral-600);
  padding: var(--space-4) var(--space-4) var(--space-2);
}
.session-group:first-child { padding-top: var(--space-3); }

/* ── Account ────────────────────────────────────────────────────────── */

.sessions-footer {
  flex: none;
  position: relative;
  border-top: var(--rule-hair) solid var(--color-neutral-300);
}

.account {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-body);
  text-align: left;
  color: var(--color-text);
}
.account:hover { background: var(--color-accent-100); }

.avatar {
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-md);
  border: var(--rule-hair) solid var(--color-neutral-300);
  background: var(--color-neutral-200);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 500;
  color: var(--color-neutral-700);
  text-transform: uppercase;
}

.account-name {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: var(--color-neutral-800);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-chevron { flex: none; color: var(--color-neutral-600); transition: transform 120ms; }
.account[aria-expanded="true"] .account-chevron { transform: rotate(180deg); }

/* Opens upward: the button is at the foot of the rail, so a menu below it
   would be off-screen. */
.account-menu {
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: calc(100% - var(--space-2));
  z-index: 5;
  display: flex;
  flex-direction: column;
  padding: var(--space-1);
  background: var(--color-neutral-100);
  border: var(--rule-hair) solid var(--color-neutral-300);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.account-menu-item {
  border: 0;
  background: transparent;
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--color-text);
  cursor: pointer;
}
.account-menu-item:hover { background: var(--color-accent-100); color: var(--color-accent-700); }

/* The row holds the session button and its delete control side by side; the
   delete only appears on hover or focus, so a list of matches is not a row of
   crosses inviting an accident. */
.session-row { display: flex; align-items: stretch; border-bottom: var(--rule-hair) solid var(--color-neutral-300); }
.session-row:hover { background: var(--color-accent-100); }

.session-delete {
  flex: none;
  width: 30px;
  border: 0;
  background: transparent;
  color: var(--color-neutral-700);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
}

.session-row:hover .session-delete,
.session-delete:focus-visible { opacity: 1; }
.session-delete:hover { color: var(--color-accent); }

.session {
  flex: 1;
  min-width: 0;
  display: block;
  text-align: left;
  border: 0;
  background: transparent;
  padding: 11px 14px;
  cursor: pointer;
  font-family: var(--font-body);
}

/* The open session is marked with a rule rather than a fill, so the list keeps
   reading as one column of equal items. */
.session[aria-current="true"] { border-left: 3px solid var(--color-accent); padding-left: 11px; }

.session-name {
  font-size: 12.5px;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.session-meta {
  margin-top: 3px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-neutral-700);
}

.session[data-tone="running"] .session-meta { color: var(--color-neutral-800); }
.session[data-tone="failed"] .session-meta { color: var(--color-accent-2); }

.sessions-empty {
  padding: 14px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--color-neutral-800);
}

@media (max-width: 720px) {
  /* Below this the transcript needs the whole width more than the list does. */
  .sessions { display: none; }
}

/* Details popup: the moment on the left, its record on the right.

   Opening the details of a play is the point at which someone wants to see it,
   so the two sit side by side rather than the facts replacing the footage. The
   card is wider than the settings dialog for that reason — 520px of video and
   a two-column table beside it is neither. */
.modal-card-wide { width: min(1180px, 100%); }

/* The video takes the larger share. The record beside it is a two-column table
   of short values, which reads fine narrow, while a 16:9 frame squeezed to
   half a dialog is the thing someone opened this to look at. */
.detail-split {
  display: grid;
  grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
}

.detail-player {
  border-right: var(--rule) solid var(--color-text);
  background: var(--color-neutral-900);
}

/* A game record has nothing to play, so it gets the whole width rather than a
   black column where a video would be. */
.detail-split.solo { grid-template-columns: 1fr; }
.detail-split.solo .detail-player { display: none; }

/* Sticky against the card's own scroll, so a long record scrolls past a video
   that stays where it is. The column stretches to the row height by default,
   which is what gives this somewhere to stick. */
.detail-player .player-slot { position: sticky; top: 0; }

/* Below this the two would each be too narrow to read, so they stack: the
   video first, because it is what was asked for. */
@media (max-width: 760px) {
  .detail-split { grid-template-columns: 1fr; }
  .detail-player {
    border-right: 0;
    border-bottom: var(--rule) solid var(--color-text);
  }
  .detail-player .player-slot { position: static; }
}

/* Moment details */
.moment-actions { display: flex; align-items: center; gap: 10px; flex: none; }

/* Two columns: the attribute name, then its value. The name column is sized to
   the longest label rather than a fraction of the width, so the values line up
   and stay readable when a description runs long. */
.detail-grid { display: grid; grid-template-columns: max-content 1fr; }

.detail-key,
.detail-value {
  padding: 9px 14px;
  border-bottom: var(--rule-hair) solid var(--color-neutral-300);
  font-size: 12px;
  line-height: 1.45;
}

.detail-key {
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 10px;
  color: var(--color-neutral-700);
  white-space: nowrap;
  border-right: var(--rule-hair) solid var(--color-neutral-300);
}

.detail-value { overflow-wrap: anywhere; }

/* Registering a source already in Cloud Storage. Its own block under the
   dropzone rather than beside it: they are two ways to do the same thing, and
   side by side they read as two halves of one. */
.gcs-row { margin-top: 14px; }

.gcs-input-row { display: flex; gap: 8px; margin-top: 6px; }
.gcs-input-row .composer-input {
  flex: 1;
  min-width: 0;
  border: var(--rule-hair) solid var(--color-neutral-400);
  padding: 8px 10px;
  font-size: 12px;
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
}
.gcs-input-row .btn-outline { flex: none; }
.gcs-row .setting-hint { margin-top: 6px; }

/* A game's record opened inside the list rather than in the popup. Indented
   and quieter than a row of its own, so the headline above it stays the thing
   being scanned. */
.detail-inline {
  border-top: var(--rule-hair) solid var(--color-neutral-300);
  margin-top: 8px;
  background: var(--color-neutral-100);
}
.detail-inline .detail-key,
.detail-inline .detail-value { padding: 6px 12px; font-size: 11px; }
.detail-inline > :nth-last-child(-n + 2) { border-bottom: 0; }

@media (max-width: 520px) {
  .detail-grid { grid-template-columns: 1fr; }
  .detail-key { border-right: 0; padding-bottom: 0; border-bottom: 0; }
}

/* Pager */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 12px;
  border-top: var(--rule-hair) solid var(--color-neutral-300);
}

.pager-count {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700);
  font-family: var(--font-mono);
}

.pager .link-btn[disabled] { opacity: 0.35; cursor: default; }


/* ── Rounding ───────────────────────────────────────────────────────────
   Arenos radii are small and deliberate (8px cards, 5px inputs/chips, 3px
   controls — see ds/styles.css) rather than zero, so these rules matter now;
   they stay written as tokens rather than literals so a future theme that
   wants a different radius scale only has to override the three variables.

   Containers that round also clip. A row's own background or bottom rule is
   square, so without overflow it draws over the corner it is supposed to sit
   inside — visible as a notch on exactly one row of a list. */

.panel,
.panel-light,
.modal-card,
.dropzone,
.signin-card,
.inline-player,
.detail-player,
.composer-box,
.stage-strip,
.source-tabs {
  border-radius: var(--radius-lg);
  overflow: hidden;
}

/* The popup's two columns share the card's corners rather than having their
   own, so the player rounds on the left only. */
.detail-player { border-radius: var(--radius-lg) 0 0 var(--radius-lg); }
@media (max-width: 760px) {
  .detail-player { border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
}

.btn-solid,
.btn-outline,
.chip,
.link-btn,
.file-label,
.platform,
.session,
.thumb,
.dz-thumb,
.step-btn,
.caption-box,
.composer-input,
.header-select {
  border-radius: var(--radius-md);
}

.meter,
.meter i,
.stage-meter,
.stage-meter i,
.reel-bar,
.checkmark {
  border-radius: var(--radius-sm);
}

/* The send button is flush against the input's edge, so it keeps the corners
   on that side square whatever the theme does. */
.composer-send { border-radius: 0 var(--radius-md) var(--radius-md) 0; }
