:root {
  color-scheme: light;

  /* Surfaces, lightest to darkest */
  --bg: #eceff1;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --surface-3: #fafbfc;
  --hover: #f0f9fa;

  /* Text, strongest to faintest */
  --text: #1e293b;
  --text-2: #334155;
  --text-3: #475569;
  --text-4: #64748b;
  --text-faint: #94a3b8;

  --border: #e2e8f0;
  --border-subtle: #f1f5f9;

  --brand-teal: #00616d;
  --brand-teal-dark: #004a54;
  --brand-panel: #0d3d45;
  --brand-panel-accent: #c69e66;
  --brand-teal-light: #e6f4f5;
  --brand-gold: #c69e66;
  --brand-gold-light: #f5ede3;
  --brand-gold-dark: #a8844f;

  --danger: #b91c1c;
  --danger-bg: #fef2f2;
  --danger-border: #fecaca;

  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.04);

  /* Logo art has a white background, so on dark surfaces it sits on a chip. */
  --logo-chip: transparent;
  --logo-chip-pad: 0;

  /* Legacy aliases, kept so older rules keep resolving */
  --background: var(--bg);
  --foreground: var(--text);
  --slate-200: var(--border);
  --slate-500: var(--text-4);
  --slate-800: var(--text);
}

/* Dark palette. Applied when the OS asks for it, unless the viewer has
   explicitly chosen light, and again for an explicit dark choice so the
   toggle wins in both directions. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg: #0f141a;
    --surface: #171f27;
    --surface-2: #1d262f;
    --surface-3: #1a232b;
    --hover: #16323a;

    --text: #e6edf3;
    --text-2: #cbd5e1;
    --text-3: #a9b8c4;
    --text-4: #8b9aa8;
    --text-faint: #6b7a88;

    --border: #2a3742;
    --border-subtle: #222c35;

    --brand-teal: #4fc3ce;
    --brand-teal-dark: #7ad3dc;
    --brand-panel: #0a2d33;
    --brand-panel-accent: #d4a96f;
    --brand-teal-light: #14333a;
    --brand-gold: #d4a96f;
    --brand-gold-light: #33281a;
    --brand-gold-dark: #e0bc8a;

    --danger: #ff8a7e;
    --danger-bg: #3a1a17;
    --danger-border: #5c2a24;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);

    --logo-chip: #ffffff;
    --logo-chip-pad: 0.3rem 0.5rem;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0f141a;
  --surface: #171f27;
  --surface-2: #1d262f;
  --surface-3: #1a232b;
  --hover: #16323a;

  --text: #e6edf3;
  --text-2: #cbd5e1;
  --text-3: #a9b8c4;
  --text-4: #8b9aa8;
  --text-faint: #6b7a88;

  --border: #2a3742;
  --border-subtle: #222c35;

  --brand-teal: #4fc3ce;
  --brand-teal-dark: #7ad3dc;
  --brand-panel: #0a2d33;
  --brand-panel-accent: #d4a96f;
  --brand-teal-light: #14333a;
  --brand-gold: #d4a96f;
  --brand-gold-light: #33281a;
  --brand-gold-dark: #e0bc8a;

  --danger: #ff8a7e;
  --danger-bg: #3a1a17;
  --danger-border: #5c2a24;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);

  --logo-chip: #ffffff;
  --logo-chip-pad: 0.3rem 0.5rem;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--background);
  color: var(--foreground);
}

::selection {
  background: color-mix(in srgb, var(--brand-gold) 35%, white);
}

.layout-split {
  display: grid;
  min-height: 100vh;
}

@media (min-width: 1024px) {
  .layout-split { grid-template-columns: 1fr 1fr; }
}

.brand-panel {
  display: none;
  flex-direction: column;
  justify-content: space-between;
  background: var(--brand-panel);
  padding: 2.5rem 3.5rem;
}

@media (min-width: 1024px) {
  .brand-panel { display: flex; }
}

.brand-panel .logo {
  /* A flex child stretches across the cross axis by default, which made this
     white chip span the whole panel. Shrink it to the logo it contains. */
  align-self: flex-start;
  display: inline-block;
  width: fit-content;
  padding: 0.5rem 0.9rem;
  border-radius: 0.5rem;
  background: #ffffff;
}

.brand-panel .logo img {
  height: 3rem;
  width: auto;
  display: block;
}

.brand-kicker {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brand-panel-accent);
  margin: 0 0 1rem;
}

.brand-title {
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--surface);
  margin: 0 0 1rem;
}

.brand-copy {
  font-size: 0.875rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.7);
  margin: 0;
  max-width: 28rem;
}

.brand-footer {
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.4);
}

.content-panel {
  display: flex;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--background);
}

.content-panel.app-mode {
  display: block;
  min-height: 100vh;
  padding: 0;
}

.card {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--slate-200);
  border-radius: 0.5rem;
  padding: 2rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
}

.logo-mobile {
  margin-bottom: 1.5rem;
}

.logo-mobile img {
  height: 2.5rem;
  width: auto;
}

@media (min-width: 1024px) {
  .logo-mobile { display: none; }
}

h1, h2 {
  margin: 0;
  color: var(--slate-800);
}

h1 { font-size: 1.25rem; font-weight: 600; }
h2 { font-size: 1.125rem; font-weight: 600; margin-bottom: 0.75rem; }

.subtitle {
  margin: 0.25rem 0 0;
  font-size: 0.875rem;
  color: var(--slate-500);
}

label {
  display: block;
  margin-top: 1rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-2);
}

input {
  width: 100%;
  margin-top: 0.375rem;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--slate-200);
  border-radius: 0.375rem;
  font-size: 0.9375rem;
}

input:focus {
  outline: 2px solid color-mix(in srgb, var(--brand-teal) 25%, white);
  border-color: var(--brand-teal);
}

/* The rules above are written for text fields. Without this, a checkbox
   inherits width:100% and stretches across its container, pushing its
   label away from it. */
input[type="checkbox"],
input[type="radio"] {
  width: auto;
  padding: 0;
  margin-top: 0;
  accent-color: var(--brand-teal);
  cursor: pointer;
}

.btn, button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 0.375rem;
  padding: 0.625rem 1rem;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
}

.btn-primary, button[type="submit"] {
  background: var(--brand-teal);
  color: var(--surface);
}

.btn-primary:hover, button[type="submit"]:hover {
  background: var(--brand-teal-dark);
}

.btn-outline {
  background: var(--surface);
  color: var(--slate-800);
  border: 1px solid var(--slate-200);
}

.btn-secondary {
  background: var(--text-3);
  color: var(--surface);
}

.btn-danger {
  background: var(--danger);
  color: var(--surface);
}

.btn-full { width: 100%; margin-top: 1.25rem; }

.row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

.divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  color: var(--text-faint);
  font-size: 0.75rem;
}

.divider::before, .divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--slate-200);
}

.error {
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid var(--danger-border);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: 0.875rem;
}

.hidden { display: none !important; }

.app-header {
  border-bottom: 1px solid var(--slate-200);
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.app-header-inner {
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 1rem;
  height: 4rem;
  padding: 0 1.5rem;
}

.app-header .logo img {
  height: 2rem;
  width: auto;
}

.page-header {
  border-bottom: 1px solid var(--slate-200);
  background: var(--surface);
}

.page-header-inner {
  max-width: 1400px;
  margin: 0 auto;
  padding: 1rem 1.5rem;
}

.page-header h1 {
  font-size: 1.25rem;
}

.app-main {
  max-width: 1400px;
  margin: 0 auto;
  padding: 1.25rem 1.5rem 2rem;
}

.panel-card {
  background: var(--surface);
  border: 1px solid var(--slate-200);
  border-radius: 0.5rem;
  padding: 1.5rem;
  margin-bottom: 1rem;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

.metric-item {
  background: var(--surface-2);
  border-radius: 0.5rem;
  padding: 0.875rem;
}

.metric-item strong {
  display: block;
  font-size: 0.8125rem;
  color: var(--text-3);
  margin-bottom: 0.25rem;
}

code {
  background: var(--brand-teal-light);
  color: var(--brand-teal-dark);
  padding: 0.125rem 0.375rem;
  border-radius: 0.25rem;
  word-break: break-all;
}

table.clean {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

table.clean thead th {
  border-bottom: 1px solid var(--slate-200);
  padding: 0.75rem 1rem;
  text-align: left;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-3);
  background: var(--surface-2);
}

table.clean tbody td {
  border-bottom: 1px solid var(--border-subtle);
  padding: 0.75rem 1rem;
  color: var(--text-2);
}

table.clean tbody tr:nth-child(even) {
  background: var(--surface-3);
}

table.clean tbody tr:hover {
  background: var(--hover);
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: 1rem;
}

.modal {
  background: var(--surface);
  border-radius: 0.5rem;
  width: 100%;
  max-width: 32rem;
  max-height: 90vh;
  overflow-y: auto;
  padding: 1.5rem;
  box-shadow: 0 20px 40px rgba(15, 23, 42, 0.15);
}

.modal h3 {
  margin: 0 0 1rem;
  font-size: 1.125rem;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

/* Each cell is a column with its control pinned to the bottom, so a label
   that wraps to two lines ("Monthly budget (USD)") does not push its input
   below the one beside it. */
.form-grid > div {
  display: flex;
  flex-direction: column;
}

.form-grid > div > :is(input, select) {
  margin-top: auto;
}

/* Field labels only. An option row is a label too, but it lays itself out -
   and this rule would beat its own class on specificity. */
.form-grid label:not(.picker-option):not(.check-row) {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-3);
  /* The global label rule adds margin-top: 1rem, which is meant for stacked
     forms and throws the grid rows out of alignment. */
  margin-top: 0;
  margin-bottom: 0.25rem;
}

/* A secondary note inside a field label, e.g. "default $50.00". Kept on the
   label line so it cannot make one grid column taller than its neighbour. */
/* Labels can wrap; align every control to the bottom of its row so a
   two-line label does not drop its input below the one beside it. */
.form-grid > div > :is(input, select) {
  margin-top: auto;
}

.form-grid input:not([type="checkbox"]):not([type="radio"]), .form-grid select {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--slate-200);
  border-radius: 0.375rem;
  font-size: 0.875rem;
}

.form-grid .full-width {
  grid-column: 1 / -1;
}

/* Role → model permission matrix.
   Roles are rows because roles grow without limit; models are columns because
   a company settles on a handful of tiers. Both axes stay usable: the header
   row and the role column are sticky inside a scrolling container. */
.matrix-scroll {
  overflow: auto;
  max-height: 34rem;
  border: 1px solid var(--slate-200);
  border-radius: 0.5rem;
  background: var(--surface);
}

table.matrix {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.875rem;
}

table.matrix th,
table.matrix td {
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--border-subtle);
}

table.matrix thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-2);
  border-bottom: 1px solid var(--slate-200);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-3);
  text-align: center;
  white-space: nowrap;
  vertical-align: bottom;
}

table.matrix thead th.matrix-role-head {
  left: 0;
  z-index: 3;
  text-align: left;
  min-width: 11rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Sticky cells need their own background or rows show through when scrolling. */
table.matrix th.matrix-role {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  text-align: left;
  font-weight: 600;
  color: var(--slate-800);
  text-transform: capitalize;
}

table.matrix tbody tr:hover th.matrix-role,
table.matrix tbody tr:hover td {
  background: var(--hover);
}

.matrix-model-name {
  display: block;
  font-weight: 600;
  color: var(--slate-800);
}

.matrix-upstream {
  display: block;
  margin-top: 0.15rem;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.6875rem;
  font-weight: normal;
  text-transform: none;
  letter-spacing: 0;
  color: var(--slate-500);
}

.matrix-granted {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.75rem;
  font-weight: normal;
  color: var(--slate-500);
  text-transform: none;
}

table.matrix td.matrix-cell {
  text-align: center;
  background: var(--surface);
}

/* A role with no models cannot chat at all - worth flagging, not hiding. */
.badge-admin {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 0.25rem;
  background: var(--brand-gold-light);
  color: var(--brand-gold-dark);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.2;
}

.muted {
  color: var(--slate-500);
}

/* A checkbox reads as one control with its label, so they share a row. */
.check-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 500;
  cursor: pointer;
}

.check-row input {
  width: auto;
  margin: 0;
}

.field-note {
  margin: 0.3rem 0 0;
  font-size: 0.8rem;
  color: var(--slate-500);
}

/* The role name and its delete control share a line, inside the sticky
   column - a far-right action would scroll out of reach as models are added. */
.matrix-role-top {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.matrix-delete {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: 0.3rem;
  background: none;
  color: var(--slate-500);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.matrix-delete svg {
  width: 0.9rem;
  height: 0.9rem;
}

.matrix-delete:hover,
.matrix-delete:focus-visible {
  background: var(--danger-bg);
  color: var(--danger);
}

tr.matrix-orphan th.matrix-role {
  color: var(--brand-gold-dark);
}

.matrix-orphan-flag {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border-radius: 0.25rem;
  background: var(--brand-gold-light);
  color: var(--brand-gold-dark);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  vertical-align: middle;
}

.matrix-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.matrix-search {
  flex: 1 1 14rem;
  max-width: 22rem;
  margin-top: 0;
  padding: 0.5rem 0.7rem;
  font-size: 0.875rem;
}

.matrix-count {
  font-size: 0.8125rem;
  color: var(--slate-500);
  white-space: nowrap;
}

.matrix-empty {
  padding: 1.5rem 0.9rem;
  text-align: center;
  color: var(--slate-500);
  font-size: 0.875rem;
}

.matrix-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.9rem;
}

.matrix-status {
  font-size: 0.8125rem;
  color: var(--slate-500);
}

.matrix-status.dirty {
  color: var(--brand-gold-dark);
  font-weight: 600;
}

.matrix-status.saved {
  color: var(--brand-teal);
  font-weight: 600;
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Embedded chat shell */
.chat-body {
  overflow: hidden;
  height: 100vh;
}

.chat-shell {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: var(--surface);
  position: relative;
}

/* Chat is a full-height flex column, so the shared header has to hold its
   height rather than being compressed by the iframe below it. */
.chat-shell > .app-header {
  flex-shrink: 0;
  z-index: 10;
}

.app-nav,
.app-nav-link {
  padding: 0.375rem 0.75rem;
  border-radius: 0.375rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--slate-500);
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.app-nav-link:hover {
  background: var(--brand-teal-light);
  color: var(--brand-teal-dark);
}

.app-nav-link.active {
  background: var(--brand-teal-light);
  color: var(--brand-teal);
  font-weight: 600;
}

.chat-frame {
  flex: 1;
  width: 100%;
  border: none;
  background: var(--surface);
}

.chat-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  gap: 1rem;
  color: var(--slate-500);
}

.chat-loading-logo {
  height: 3rem;
  width: auto;
  opacity: 0.85;
}

@media (max-width: 768px) {
  .app-nav-link { padding: 0.375rem 0.5rem; font-size: 0.75rem; }
}

/* Panel heading with an action on the right (e.g. Users / Add user). */
.panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.panel-head h2 {
  margin: 0;
}

.modal .subtitle {
  margin-bottom: 0.25rem;
}

/* Model chooser inside the Add role dialog. */
.role-model-picker {
  display: grid;
  gap: 0.4rem;
  margin-top: 0.375rem;
  max-height: 13rem;
  overflow-y: auto;
  padding: 0.5rem;
  border: 1px solid var(--slate-200);
  border-radius: 0.375rem;
  background: var(--surface-3);
}

.picker-option {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin: 0;
  padding: 0.35rem 0.4rem;
  border-radius: 0.25rem;
  font-weight: normal;
  cursor: pointer;
}

.picker-option:hover {
  background: var(--brand-teal-light);
}

.picker-name {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--slate-800);
}

.picker-sub {
  display: block;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.6875rem;
  color: var(--slate-500);
}

/* Row actions: keep the destructive one visually distinct from the rest.
   Note this class is on a <td>. `display: flex` there stops it being a
   table-cell, so it leaves the row's layout and its border stops lining up
   with the other columns. The buttons are inline-flex already, so spacing
   them with a margin keeps the cell a cell. */
.row-actions {
  white-space: nowrap;
}

.row-actions .btn + .btn {
  margin-left: 0.35rem;
}

.row-actions .btn {
  padding: 0.4rem 0.7rem;
  font-size: 0.8125rem;
}

.row-actions .btn-danger {
  background: var(--surface);
  color: var(--danger);
  border: 1px solid var(--danger-border);
}

.row-actions .btn-danger:hover {
  background: var(--danger-bg);
}

.status-on { color: var(--brand-teal); font-weight: 600; }
.status-off { color: var(--slate-500); }


/* Shared app header: logo, primary nav, then who you are on the right. */
.app-header-inner {
  gap: 0.5rem;
}

.app-header-right {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-left: auto;
}

.app-user {
  text-align: right;
  line-height: 1.25;
}

.app-user .name {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--slate-800);
}

.app-user .role {
  display: block;
  font-size: 0.6875rem;
  text-transform: capitalize;
  color: var(--brand-teal);
}

@media (max-width: 720px) {
  .app-header-inner { flex-wrap: wrap; height: auto; padding-block: 0.75rem; }
  .app-nav { order: 3; width: 100%; }
}


/* The logo artwork carries its own white background, so on dark surfaces it
   gets a matching chip rather than floating as a bright rectangle. */
.app-header .logo {
  display: inline-flex;
  align-items: center;
  background: var(--logo-chip);
  padding: var(--logo-chip-pad);
  border-radius: 0.375rem;
}

/* Theme switch */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  background: var(--surface);
  color: var(--text-3);
  cursor: pointer;
  line-height: 1;
}

.theme-toggle:hover {
  background: var(--brand-teal-light);
  color: var(--brand-teal);
  border-color: var(--brand-teal);
}

.theme-toggle svg {
  width: 1.05rem;
  height: 1.05rem;
}

/* Only one icon shows, depending on the resolved theme. */
.theme-toggle .icon-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-light { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon-dark { display: block; }
}
:root[data-theme="dark"] .theme-toggle .icon-light { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-dark { display: block; }
:root[data-theme="light"] .theme-toggle .icon-light { display: block; }
:root[data-theme="light"] .theme-toggle .icon-dark { display: none; }


/* Theme switch on the sign-in screen, before any header exists. */
.login-theme-toggle {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 10;
}

/* Sign-in card: a touch more presence than a plain panel. */
.card {
  box-shadow: var(--shadow-sm), 0 12px 32px rgba(15, 23, 42, 0.08);
}

:root[data-theme="dark"] .card {
  box-shadow: var(--shadow-sm), 0 12px 32px rgba(0, 0, 0, 0.5);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card {
    box-shadow: var(--shadow-sm), 0 12px 32px rgba(0, 0, 0, 0.5);
  }
}

/* Brand panel text is always light, because the panel is always dark. */
.brand-panel .brand-title { color: #ffffff; }
.brand-panel .brand-copy { color: rgba(255, 255, 255, 0.72); }
.brand-panel .brand-footer { color: rgba(255, 255, 255, 0.45); }

/* ---- usage column ------------------------------------------------------ */

.usage-cell {
  min-width: 7.5rem;
}

.usage-amount {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text-2);
}

.usage-bar {
  display: block;
  height: 4px;
  margin: 0.3125rem 0 0.1875rem;
  border-radius: 999px;
  background: var(--border-subtle);
  overflow: hidden;
}

.usage-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width 0.2s ease;
}

/* Colour only once it means something, so a normal row stays quiet. */
.usage-ok   { background: var(--brand-teal, #4fb3a7); }
.usage-warn { background: var(--brand-gold, #d9a441); }
.usage-over { background: var(--danger, #d9534f); }

.usage-pct,
.usage-none {
  font-size: 0.75rem;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* ---- confirmation dialog ---------------------------------------------- */

.modal-narrow {
  max-width: 26rem;
}

/* The consequence that is easy to miss, set apart from the main sentence. */
.confirm-note {
  margin: 0.75rem 0 0;
  padding: 0.625rem 0.75rem;
  border-left: 2px solid var(--border-subtle);
  background: var(--surface-3);
  border-radius: 0 6px 6px 0;
  font-size: 0.8125rem;
  color: var(--text-3);
}

/* ---- chat: role has no models ------------------------------------------ */

/* A strip above the chat, not a replacement for it. The chat still opens so
   the person can look around; the notice explains why sending will fail. */
.chat-notice {
  flex-shrink: 0;
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  padding: 0.75rem 1.25rem;
  background: var(--brand-gold-light, var(--surface-3));
  border-bottom: 1px solid var(--border-subtle);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--text-2);
}

.chat-notice svg {
  width: 1.05rem;
  height: 1.05rem;
  flex-shrink: 0;
  margin-top: 0.05rem;
  color: var(--brand-gold, var(--text-3));
}

.chat-notice strong {
  color: var(--text);
  font-weight: 600;
}

/* ---- per-user usage view ------------------------------------------------ */

/* Chart colours. Mid-tones, so the same set stays legible on both themes -
   these are solid fills rather than text, which is what makes that work. */
:root {
  --chart-3: #7c6bd1;
  --chart-4: #4a9ec9;
  --chart-5: #c98b5e;
  --chart-6: #6aa87e;
}

/* A column with a fixed head and a scrolling body, rather than one long
   scrolling box. The title, date fields and tabs stay put while the request
   log scrolls - previously they scrolled away and you lost the tabs partway
   down the table. */
.modal-wide {
  max-width: 62rem;
  width: calc(100vw - 3rem);
  max-height: calc(100vh - 4rem);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* The head keeps its height; only the panel below it scrolls. */
.modal-wide > .panel-head,
.modal-wide > .tabs,
.modal-wide > .error,
.modal-wide > .matrix-empty {
  flex-shrink: 0;
}

/* min-height:0 is what actually lets a flex child scroll - without it the
   panel grows to fit its content and the modal scrolls instead. */
.modal-wide > .tab-panel {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.activity-head {
  align-items: flex-start;
  gap: 1rem;
}

.activity-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* The two date inputs. Was shared with a range <select>, which the custom
   fields replaced. */
.act-range {
  padding: 0.375rem 0.5rem;
  border: 1px solid var(--border-subtle);
  border-radius: 0.375rem;
  background: var(--surface);
  color: var(--text-2);
  font-size: 0.8125rem;
}

/* --- tabs --- */

.tabs {
  display: flex;
  gap: 0.25rem;
  margin: 1rem 0 0;
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface);
}

.tab {
  padding: 0.5rem 0.875rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--text-3);
  cursor: pointer;
  /* Sits on the container's border so the active tab joins its panel. */
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.tab:hover { color: var(--text-2); }

.tab.active {
  color: var(--brand-teal);
  font-weight: 600;
  border-bottom-color: var(--brand-teal);
}

.tab-panel { padding-top: 0.5rem; }

.activity-totals { margin: 1rem 0 0; }

.activity-subhead {
  margin: 1.75rem 0 0.75rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* --- chart ---
   The axis sits behind the bars as a stack of labelled gridlines, so the
   columns can be read as quantities rather than only compared to each other. */

.act-plot {
  position: relative;
  height: 13rem;
  padding-left: 2.75rem;
}

.act-axis {
  position: absolute;
  inset: 0 0 1.25rem 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  pointer-events: none;
}

.act-gridline {
  position: relative;
  border-top: 1px solid var(--border-subtle);
  opacity: 0.6;
}

.act-gridline span {
  position: absolute;
  left: 0;
  top: -0.55rem;
  width: 2.5rem;
  text-align: right;
  font-size: 0.625rem;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

.act-chart {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 100%;
}

/* Past roughly six weeks the gaps would be wider than the bars. */
.act-chart.dense { gap: 1px; }
.act-chart.dense .act-stack { border-radius: 1px; }

/* Columns share the width rather than each claiming a minimum: at 90 days a
   fixed width made the chart ~2200px wide, so it scrolled and opened on the
   empty start of the range - the data was off-screen to the right and the
   chart looked broken. Thinner bars as the range grows is the right trade. */
.act-col {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 0.375rem;
  cursor: default;
}

.act-col:hover .act-stack { filter: brightness(1.12); }

.act-stack {
  width: 100%;
  min-height: 2px;
  display: flex;
  flex-direction: column-reverse;
  border-radius: 3px;
  overflow: hidden;
  transition: filter 0.1s;
}

.act-seg { width: 100%; min-height: 1px; }

.act-day {
  font-size: 0.625rem;
  color: var(--text-3);
  white-space: nowrap;
  height: 1.25rem;
  line-height: 1.25rem;
}

/* --- legend and per-model dots --- */

.act-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
  margin-top: 0.75rem;
  font-size: 0.75rem;
  color: var(--text-2);
}

.act-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.act-legend-item i {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 2px;
  display: inline-block;
  flex-shrink: 0;
}

/* The colour dot sits in the cell's left padding rather than in the text
 * flow. Inline, it pushed every model name right of the "Model" heading
 * above it, so the column read as misaligned. */
.act-dot {
  position: absolute;
  left: 1rem;
  top: 50%;
  transform: translateY(-50%);
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 2px;
}

.activity-table tbody td:first-child {
  position: relative;
  /* Cell padding, plus room for the dot and a gap after it. */
  padding-left: calc(1rem + 0.625rem + 0.5rem);
}

/* The heading matches that indent, so text lines up with text. */
.activity-table thead th:first-child {
  padding-left: calc(1rem + 0.625rem + 0.5rem);
}

/* --- tooltip ---
   Follows the cursor and is clamped to the viewport by the script. */

.act-tooltip {
  position: fixed;
  z-index: 60;
  min-width: 13rem;
  padding: 0.625rem 0.75rem;
  border-radius: 0.5rem;
  border: 1px solid var(--border-subtle);
  background: var(--surface);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
  font-size: 0.75rem;
  color: var(--text-2);
  pointer-events: none;
}

.act-tip-head {
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.375rem;
}

.act-tip-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.125rem 0;
}

.act-tip-row i {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 2px;
}

.act-tip-row strong { font-variant-numeric: tabular-nums; }
.act-tip-row em { font-style: normal; color: var(--text-3); }

.act-tip-total {
  margin-top: 0.375rem;
  padding-top: 0.375rem;
  border-top: 1px solid var(--border-subtle);
  color: var(--text-3);
}

.activity-table tbody td:first-child { white-space: nowrap; }

/* Visible to screen readers only - labels a control that has a visual cue. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Wide tables scroll in their own box rather than pushing the page sideways. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.table-scroll > table {
  width: max-content;
  min-width: 100%;
}

/* Figures only line up if the digits share a width.
 *
 * The header needs the full `table.clean thead th` prefix to win: that rule
 * sets text-align:left at specificity (0,1,2), so a bare `th.num` at (0,1,1)
 * lost to it and the headings stayed left while the values went right.
 */
.num,
table.clean tbody td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

table.clean thead th.num {
  text-align: right;
}

/* --- custom date range --- */

.act-custom {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.act-dash {
  color: var(--text-3);
  font-size: 0.8125rem;
}

/* A date input is taller than a select by default; match them so the control
   row does not jump when the custom range appears. */
.act-custom input[type="date"] {
  min-width: 8.5rem;
}
