/* ==========================================================================
   Components added alongside the security, compliance and automation work.

   A separate file rather than 700 more lines appended to style.css: these
   are admin and settings surfaces, not the chat canvas, and keeping them
   apart means a change here cannot accidentally shift the message pane.

   Every colour comes from the variables already declared in style.css, so
   the two files stay in step if the palette changes.
   ========================================================================== */

/* ---------------------------------------------------------------- layout */
.page-narrow {
  max-width: 780px;
}

.two-col {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 28px;
}

.table-scroll {
  overflow-x: auto;
  /* Wide tables scroll inside their own container; the page body must
     never scroll sideways. */
  max-width: 100%;
}

.mono {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-variant-numeric: tabular-nums;
}

.muted   { color: var(--text-muted); }
.danger-text { color: var(--busy); font-weight: 600; }

/* ---------------------------------------------------------------- banners */
.banner {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--text-dim);
  background: #f8fafc;
  color: var(--text-main);
  font-size: 13.5px;
  line-height: 1.55;
  margin-bottom: 18px;
}
.banner strong { font-weight: 600; }
.banner-warn  { border-left-color: var(--away);  background: #fffbeb; }
.banner-error { border-left-color: var(--busy);  background: #fef2f2; }
.banner-ok    { border-left-color: var(--online); background: #ecfdf5; }

.status-line {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  margin-bottom: 20px;
}
.status-ok   { background: #ecfdf5; color: #065f46; }
.status-warn { background: #fffbeb; color: #92400e; }

/* ----------------------------------------------------------------- chips */
.chip {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: #f1f5f9;
  color: var(--text-muted);
  white-space: nowrap;
  vertical-align: middle;
}
.chip-ok     { background: #d1fae5; color: #065f46; }
.chip-warn   { background: #fef3c7; color: #92400e; }
.chip-danger { background: #fee2e2; color: #991b1b; }
.chip-plain  { background: #f1f5f9; color: var(--text-muted); font-weight: 500; text-decoration: none; }
a.chip-plain:hover { background: #e2e8f0; }

.chip-list { display: flex; flex-wrap: wrap; gap: 6px; }

/* ------------------------------------------------------------ stat tiles */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
  margin-bottom: 30px;
}
.stat-tile {
  background: #fff;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* A tile that needs attention gets a form change as well as a number —
   a count alone doesn't read as "act on this" at a glance. */
.stat-tile.stat-alert { border-left: 3px solid var(--away); }
.stat-tile .stat-n {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--text-main);
  font-variant-numeric: tabular-nums;
}
.stat-tile .stat-l { font-size: 13px; color: var(--text-muted); }
.stat-tile .stat-s { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }

/* ------------------------------------------------------------- settings */
.settings-block {
  background: #fff;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  padding: 20px 22px 24px;
  margin-bottom: 22px;
}
.settings-block h2, .settings-block h3 { margin: 0 0 10px; }
.settings-block > p { color: var(--text-muted); font-size: 13.5px; margin: 0 0 14px; }
.settings-danger { border-color: #fecaca; }

.settings-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  font-size: 14px;
  cursor: pointer;
  flex-wrap: wrap;
}
.settings-check input { margin-top: 3px; flex: none; }
.settings-check small {
  flex-basis: 100%;
  padding-left: 26px;
  color: var(--text-muted);
  font-size: 12.5px;
}

.settings-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 14px;
  margin: 10px 0;
}
.settings-row { display: flex; gap: 20px; flex-wrap: wrap; }

/* ----------------------------------------------------------------- forms */
.stacked-form { display: flex; flex-direction: column; gap: 18px; max-width: 620px; }

.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field label { font-size: 13.5px; font-weight: 600; color: var(--text-main); }
.form-field input[type="text"],
.form-field input[type="url"],
.form-field input[type="email"],
.form-field input[type="number"],
.form-field input[type="password"],
.form-field input[type="datetime-local"],
.form-field input[type="time"],
.form-field select,
.form-field textarea {
  padding: 9px 12px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 14px;
  color: var(--text-main);
  background: #fff;
  width: 100%;
}
.form-field textarea { resize: vertical; }
.form-field .code-editor {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 13px;
  line-height: 1.5;
  background: #0f172a;
  color: #e2e8f0;
  border-color: #1e293b;
}
.form-field-error input,
.form-field-error select,
.form-field-error textarea { border-color: var(--busy); }
.form-help  { font-size: 12.5px; color: var(--text-muted); }
.form-error { font-size: 12.5px; color: var(--busy); font-weight: 500; }
.required-dot { color: var(--busy); margin-left: 2px; }

.inline-form { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.inline-form input, .inline-form select {
  padding: 6px 9px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 13px;
}

.filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 12px 0 16px;
  border-bottom: 1px solid var(--chat-pane-border);
  margin-bottom: 18px;
}
.filter-bar input[type="search"] {
  flex: 1 1 220px;
  min-width: 180px;
  padding: 8px 12px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 13.5px;
}
.filter-bar select {
  padding: 8px 10px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 13px;
  background: #fff;
}
.filter-check { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); }

/* ------------------------------------------------------------------ tabs */
.tab-row {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--chat-pane-border);
  margin-bottom: 20px;
}
.tab {
  padding: 9px 16px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  display: flex;
  align-items: center;
  gap: 6px;
}
.tab:hover { color: var(--text-main); }
.tab.active { color: var(--brand-orange); border-bottom-color: var(--brand-orange); font-weight: 600; }
.tab-count {
  background: var(--brand-orange-soft);
  color: var(--brand-orange);
  padding: 0 6px;
  border-radius: var(--radius-full);
  font-size: 11px;
  font-weight: 700;
}

/* ---------------------------------------------------------------- tables */
.data-table td.audit-meta { max-width: 260px; }
.audit-action {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  background: #f1f5f9;
  color: var(--text-main);
}
/* Category colour carries information the action name alone doesn't —
   an auth event and a compliance event read differently at a glance. */
.audit-auth       { background: #e0f2fe; color: #075985; }
.audit-user       { background: #ede9fe; color: #5b21b6; }
.audit-channel    { background: #d1fae5; color: #065f46; }
.audit-compliance { background: #fef3c7; color: #92400e; }
.audit-integration{ background: #fce7f3; color: #9d174d; }

.row-muted { opacity: 0.55; }

.pager {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 0;
  font-size: 13px;
}

/* ---------------------------------------------------------------- buttons */
.btn-ghost {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
}
.btn-ghost:hover { background: #f1f5f9; color: var(--text-main); }
.btn-block { width: 100%; justify-content: center; }
.link-button {
  background: none;
  border: none;
  padding: 0;
  color: var(--text-link);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}

/* -------------------------------------------------------------------- MFA */
.auth-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--header-bg);
  padding: 24px;
}
/* Scoped to .auth-shell (MFA verify). Unscoped it also hit the six
   .auth-wrap pages — login, signup, the four password-reset steps — which
   have their own .auth-card in style.css; this file loads second, so those
   six silently took the MFA geometry instead of their own. */
.auth-shell .auth-card {
  background: #fff;
  border-radius: var(--radius-lg);
  padding: 34px 32px;
  width: 100%;
  max-width: 400px;
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.5);
}
.auth-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--text-main);
  margin-bottom: 20px;
}
.auth-title { margin: 0 0 6px; font-size: 22px; }
.auth-sub { color: var(--text-muted); font-size: 14px; margin: 0 0 20px; }
.auth-form { display: flex; flex-direction: column; gap: 14px; }
.auth-help { margin-top: 18px; font-size: 13px; color: var(--text-muted); }
.auth-help summary { cursor: pointer; color: var(--text-link); }
.auth-alt { margin-top: 16px; text-align: center; font-size: 13px; }

.mfa-code-input {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 26px;
  letter-spacing: 0.35em;
  text-align: center;
  padding: 12px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  width: 100%;
}

.setup-steps { display: flex; flex-direction: column; gap: 26px; margin-top: 24px; }
.setup-step { display: grid; grid-template-columns: 34px 1fr; gap: 16px; align-items: start; }
.setup-step h3 { margin: 0 0 6px; font-size: 15.5px; }
.setup-step p { margin: 0; color: var(--text-muted); font-size: 13.5px; line-height: 1.6; }
.setup-step-num {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-full);
  background: var(--brand-orange-soft);
  color: var(--brand-orange);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 14px;
}
.mfa-qr { margin: 14px 0; padding: 14px; background: #fff; border: 1px solid var(--chat-pane-border);
          border-radius: var(--radius-md); display: inline-block; }
.mfa-manual { margin-top: 12px; font-size: 13px; }
.mfa-manual summary { cursor: pointer; color: var(--text-link); }
.mfa-secret {
  display: inline-block;
  margin-top: 10px;
  padding: 10px 14px;
  background: #f1f5f9;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 15px;
  letter-spacing: 0.08em;
  user-select: all;
}
.mfa-form { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 12px; }
.mfa-form .mfa-code-input { width: 190px; font-size: 20px; }

.recovery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 10px;
  margin: 22px 0;
}
.recovery-code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 14.5px;
  padding: 10px 12px;
  background: #f1f5f9;
  border-radius: var(--radius-sm);
  text-align: center;
  user-select: all;
  letter-spacing: 0.04em;
}

/* --------------------------------------------------------------- devices */
.device-list { display: flex; flex-direction: column; gap: 10px; }
.device-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  background: #fff;
  flex-wrap: wrap;
}
.device-current { border-color: var(--online); }
.device-main { display: flex; flex-direction: column; gap: 4px; }
.device-meta { font-size: 12.5px; color: var(--text-muted); }

/* -------------------------------------------------------------- reminders */
.reminder-quick {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.reminder-quick-text { flex: 1 1 320px; }
.reminder-quick-when { flex: 0 0 130px; }
.reminder-quick input {
  padding: 10px 13px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 14px;
}

.reminder-list { display: flex; flex-direction: column; gap: 8px; }
.reminder-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 16px;
  border: 1px solid var(--chat-pane-border);
  border-left: 3px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  background: #fff;
  flex-wrap: wrap;
}
/* An overdue reminder gets a colour AND a border weight change, so it is
   distinguishable without relying on colour alone. */
.reminder-overdue { border-left-color: var(--away); background: #fffdf7; }
.reminder-done { opacity: 0.6; }
.reminder-done .reminder-text { text-decoration: line-through; }
.reminder-main { flex: 1 1 320px; display: flex; flex-direction: column; gap: 4px; }
.reminder-text { font-size: 14.5px; color: var(--text-main); }
.reminder-meta { display: flex; gap: 10px; align-items: center; font-size: 12.5px;
                 color: var(--text-muted); flex-wrap: wrap; }
.reminder-link { color: var(--text-link); text-decoration: none; }
.reminder-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.reminder-snooze { padding: 5px 8px; border: 1px solid var(--chat-pane-border);
                   border-radius: var(--radius-sm); font-size: 12.5px; }

/* ------------------------------------------------------------ saved/drafts */
.saved-list { display: flex; flex-direction: column; gap: 12px; }
.saved-card {
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  padding: 15px 18px;
  background: #fff;
}
.saved-head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; font-size: 13px;
              margin-bottom: 8px; }
.saved-author { font-weight: 600; color: var(--text-main); }
.saved-where { color: var(--text-muted); }
.saved-where a { color: var(--text-link); text-decoration: none; }
.saved-time { margin-left: auto; color: var(--text-dim); font-size: 12px; }
.saved-body { font-size: 14.5px; line-height: 1.6; color: var(--text-main); }
.saved-files { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.saved-foot { display: flex; gap: 8px; margin-top: 12px; align-items: center; }

.draft-list { display: flex; flex-direction: column; gap: 8px; }
.draft-row {
  display: block;
  padding: 13px 16px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  background: #fff;
  text-decoration: none;
  color: inherit;
}
.draft-row:hover { border-color: var(--brand-orange); }
.draft-where { font-size: 13px; font-weight: 600; color: var(--text-main); display: flex;
               gap: 8px; align-items: center; }
.draft-body { font-size: 13.5px; color: var(--text-muted); margin-top: 4px; }
.draft-time { font-size: 11.5px; color: var(--text-dim); margin-top: 6px; }

/* ---------------------------------------------------------------- search */
.search-header { display: flex; gap: 10px; margin-bottom: 8px; }
.search-big {
  flex: 1;
  padding: 12px 16px;
  font-size: 16px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  font-family: inherit;
}
.search-summary { font-size: 13px; color: var(--text-muted); margin-bottom: 16px;
                  display: flex; gap: 8px; align-items: center; }
.search-columns { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 28px; }
.search-main { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.search-hit {
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  background: #fff;
}
.search-hit header { font-size: 13px; color: var(--text-muted); display: flex; gap: 6px;
                     flex-wrap: wrap; align-items: baseline; margin-bottom: 6px; }
.search-hit header strong { color: var(--text-main); }
.search-hit header a { color: var(--text-link); text-decoration: none; }
.search-time { margin-left: auto; color: var(--text-dim); font-size: 12px; }
.search-body { font-size: 14.5px; line-height: 1.6; word-break: break-word; }
.search-files { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.search-open { display: inline-block; margin-top: 10px; font-size: 12.5px;
               color: var(--text-link); text-decoration: none; }
.search-aside section { margin-bottom: 24px; }
.search-aside h3 { font-size: 12px; text-transform: uppercase; letter-spacing: 0.09em;
                   color: var(--text-dim); margin: 0 0 8px; }
.aside-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: inherit;
  font-size: 13.5px;
}
.aside-row:hover { background: #f1f5f9; }
.aside-row small { color: var(--text-muted); font-size: 12px; }

@media (max-width: 900px) {
  .search-columns { grid-template-columns: 1fr; }
}

/* ----------------------------------------------------------------- tokens */
.token-reveal {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 16px;
  background: #0f172a;
  border-radius: var(--radius-md);
  margin: 20px 0;
  flex-wrap: wrap;
}
.token-reveal code {
  flex: 1;
  color: #7dd3fc;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 14px;
  word-break: break-all;
  user-select: all;
}
.detail-list { display: grid; grid-template-columns: 140px 1fr; gap: 8px 16px; font-size: 14px;
               margin: 20px 0; }
.detail-list dt { color: var(--text-muted); }
.detail-list dd { margin: 0; color: var(--text-main); }
.code-block {
  background: #0f172a;
  color: #e2e8f0;
  padding: 16px;
  border-radius: var(--radius-md);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12.5px;
  line-height: 1.65;
  overflow-x: auto;
}

/* ------------------------------------------------------------------ push */
.push-status {
  font-size: 13px;
  color: var(--text-muted);
  padding: 9px 12px;
  background: #f1f5f9;
  border-radius: var(--radius-sm);
}
.push-status.ok   { background: #ecfdf5; color: #065f46; }
.push-status.warn { background: #fffbeb; color: #92400e; }

/* ----------------------------------------------------------------- toasts */
/* Replaces alert(). Fixed to the bottom-right so it never covers the
   composer, and it only ever appears after the server has confirmed —
   which is the whole point: it cannot report a success that didn't
   happen, the way the alert() stubs did. */
#toast-host {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 9000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(380px, calc(100vw - 40px));
  pointer-events: none;
}
.toast {
  background: #0f172a;
  color: #f8fafc;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  font-size: 13.5px;
  line-height: 1.5;
  box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  border-left: 3px solid var(--online);
  pointer-events: auto;
}
.toast.toast-in { opacity: 1; transform: translateY(0); }
.toast-error { border-left-color: var(--busy); }
.toast-warn  { border-left-color: var(--away); }

@media (prefers-reduced-motion: reduce) {
  .toast { transition: none; }
}

/* ----------------------------------------------------- message-action modal */
.ma-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  z-index: 8000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.ma-modal {
  background: #fff;
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 480px;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 70px -20px rgba(0, 0, 0, 0.5);
}
.ma-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--chat-pane-border);
}
.ma-modal-head h3 { margin: 0; font-size: 16px; }
.ma-close {
  background: none;
  border: none;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0 4px;
}
.ma-modal-body { padding: 18px 22px 22px; overflow-y: auto; display: flex;
                 flex-direction: column; gap: 12px; }
.ma-help { font-size: 13px; color: var(--text-muted); margin: 0; line-height: 1.55; }
.ma-label { display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; font-weight: 600; }
.ma-filter, .ma-comment, .ma-name, .ma-relative {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 14px;
  font-weight: 400;
}
.ma-picklist { max-height: 260px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.ma-pick-group {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-dim);
  padding: 10px 4px 4px;
}
.ma-pick {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  cursor: pointer;
}
.ma-pick:hover { background: #f1f5f9; }
.ma-pick-icon { width: 20px; text-align: center; color: var(--text-muted); }
.ma-empty { color: var(--text-muted); font-size: 13.5px; }
.ma-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }

.ma-preset-list { display: flex; flex-wrap: wrap; gap: 8px; }
.ma-preset {
  padding: 8px 14px;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-full);
  background: #fff;
  font-size: 13.5px;
  cursor: pointer;
  color: var(--text-main);
}
.ma-preset:hover { border-color: var(--brand-orange); color: var(--brand-orange); }

.ma-action-list { display: flex; flex-direction: column; gap: 4px; max-height: 340px; overflow-y: auto; }
.ma-action-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  text-align: left;
  cursor: pointer;
  font: inherit;
  width: 100%;
}
.ma-action-row:hover { background: #f8fafc; border-color: var(--chat-pane-border); }
.ma-action-row:disabled { opacity: 0.5; cursor: wait; }
.ma-action-icon { font-size: 18px; width: 24px; text-align: center; flex: none; }
.ma-action-text { display: flex; flex-direction: column; gap: 2px; }
.ma-action-text strong { font-size: 14px; color: var(--text-main); font-weight: 600; }
.ma-action-text small { font-size: 12.5px; color: var(--text-muted); }

/* ------------------------------------------------------- composer popover */
/* The @mention and /command picker. Positioned above the composer because
   the composer sits at the bottom of the viewport. */
.composer-popover {
  position: fixed;
  z-index: 7500;
  background: #fff;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px -12px rgba(15, 23, 42, 0.35);
  max-height: 280px;
  overflow-y: auto;
  padding: 4px;
}
.cp-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.cp-row.active, .cp-row:hover { background: var(--brand-orange-soft); }
.cp-avatar {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  background: #e2e8f0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  flex: none;
  overflow: hidden;
}
.cp-avatar img { width: 100%; height: 100%; object-fit: cover; }
.cp-broadcast { background: var(--brand-orange-soft); color: var(--brand-orange); }
.cp-command { background: #0f172a; color: #7dd3fc; font-size: 15px; }
.cp-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cp-text strong { font-size: 13.5px; color: var(--text-main); font-weight: 600;
                  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-text small { font-size: 12px; color: var(--text-muted);
                 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-flag { margin-left: auto; font-size: 10.5px; color: var(--text-dim); flex: none; }

/* ------------------------------------------------- composer quote strip */
.composer-quote-strip {
  display: none;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: #f1f5f9;
  border-left: 3px solid var(--brand-orange);
  border-radius: var(--radius-xs);
  font-size: 12.5px;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.composer-quote-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.composer-quote-cancel {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
}

/* ---------------------------------------------------- unread indicators */
/* A count AND a weight change: a bold row reads as "new" even to someone
   who cannot distinguish the badge colour. */
.sidebar-link.has-unread { font-weight: 700; color: var(--text-nav-bright); }
.unread-badge {
  margin-left: auto;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--brand-orange);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}
.unread-dot {
  margin-left: auto;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-full);
  background: var(--text-nav);
  flex: none;
}

/* A message that DLP masked, so the sender knows why their text changed. */
.msg-redacted-note {
  font-size: 11.5px;
  color: var(--away);
  margin-top: 3px;
}

/* -------------------------------------------------------------- printing */
@media print {
  .global-header, .rail, .sidebar, .btn, #toast-host { display: none !important; }
  .page, .page-narrow { max-width: none; padding: 0; }
  .recovery-code { border: 1px solid #999; }
}

/* ------------------------------------------------------------- message cards */
/* Namespaced `msg-card-*`. The bare `.card` name belongs to the page-level
   panel in style.css, which 40+ admin/settings templates rely on; defining
   `.card` here overrode it (this file loads second) and turned every one of
   those panels into a 520px-wide flex row. */
/* Structured, interactive messages posted by bots, commands and functions.
   Sits inside a message bubble, so it is deliberately quieter than a
   standalone panel — it should read as part of the conversation, not as a
   dialog dropped on top of it. */
.msg-card {
  display: flex;
  gap: 12px;
  margin-top: 8px;
  padding: 13px 15px;
  background: #fff;
  border: 1px solid var(--chat-pane-border);
  /* The accent rail is what makes a card scannable in a wall of messages.
     Its colour is the only thing the theme changes. */
  border-left: 3px solid var(--text-dim);
  border-radius: var(--radius-md);
  max-width: 520px;
}
.msg-card-default { border-left-color: var(--accent-2); }
.msg-card-success { border-left-color: var(--online); }
.msg-card-warning { border-left-color: var(--away); }
.msg-card-danger  { border-left-color: var(--busy); }
.msg-card-prompt  { border-left-color: var(--brand-orange); }
.msg-card-poll    { border-left-color: #7c3aed; }

.msg-card-thumb {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  flex: none;
}
.msg-card-main { flex: 1; min-width: 0; }

.msg-card-title {
  font-weight: 700;
  font-size: 14.5px;
  color: var(--text-main);
  margin-bottom: 3px;
}
.msg-card-text {
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-main);
  white-space: pre-wrap;
  word-break: break-word;
}

.msg-card-fields {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 3px 14px;
  margin: 10px 0 0;
  font-size: 12.5px;
}
.msg-card-fields dt { color: var(--text-muted); }
.msg-card-fields dd { margin: 0; color: var(--text-main); word-break: break-word; }

.msg-card-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
}
.msg-card-btn {
  padding: 6px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--chat-pane-border);
  background: #fff;
  color: var(--text-main);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  line-height: 1.4;
}
.msg-card-btn:hover:not(:disabled) { border-color: var(--brand-orange); color: var(--brand-orange); }
.msg-card-btn-primary {
  background: var(--brand-orange);
  border-color: var(--brand-orange);
  color: #fff;
}
.msg-card-btn-primary:hover:not(:disabled) { background: var(--brand-orange-hover); color: #fff; }
.msg-card-btn-danger { border-color: #fecaca; color: var(--busy); }
.msg-card-btn-danger:hover:not(:disabled) { background: #fef2f2; border-color: var(--busy); color: var(--busy); }

.msg-card-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.msg-card-btn-busy { opacity: 0.6; cursor: wait; }
/* A once-only button that has fired stays visible rather than vanishing —
   the label is the record of what was done. */
.msg-card-btn-spent { opacity: 0.45; text-decoration: line-through; }

.msg-card-status { font-size: 12px; margin-top: 8px; min-height: 1em; }
.msg-card-status-done    { color: var(--online); }
.msg-card-status-refused { color: var(--away); }

@media (max-width: 560px) {
  .msg-card { max-width: 100%; }
  .msg-card-buttons .msg-card-btn { flex: 1 1 auto; justify-content: center; }
}

/* Link previews (chat/unfurl.py). Deliberately its own class family, not a
   reuse of .msg-card above — that one is for bot/command-authored
   structured cards with buttons and fields; this is a plain unfurl of a
   URL someone pasted. Visually related (same border/radius language) but
   not the same component, so a future change to one doesn't silently
   reshape the other. */
.link-preview-card {
  display: flex;
  gap: 12px;
  margin-top: 8px;
  padding: 10px;
  max-width: 420px;
  background: #fff;
  border: 1px solid var(--chat-pane-border);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.link-preview-card:hover {
  border-color: var(--accent-2, var(--brand-orange));
  background: var(--panel-bg, #f8fafc);
}
.link-preview-thumb {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  flex: none;
  background: var(--panel-bg, #f1f5f9);
}
.link-preview-main { flex: 1; min-width: 0; }
.link-preview-title {
  font-weight: 700;
  font-size: 13.5px;
  color: var(--accent-2, #2563eb);
  margin-bottom: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.link-preview-desc {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.link-preview-site {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
  text-transform: lowercase;
}
@media (max-width: 560px) {
  .link-preview-card { max-width: 100%; }
}

/* ==========================================================================
   Classes referenced by templates that had no rule anywhere.

   Each of these was live markup rendering with browser defaults. They are
   collected here rather than scattered because they came out of one audit
   pass; the grouping is the record of that, not a category of its own.
   ========================================================================== */

/* -- form field messages ---------------------------------------------------
   `_form_page.html` and everything built on it use .form-help/.form-error.
   The hand-written forms that predate it use .helptext/.form-errors, so
   validation errors on signup, password reset and the adminpanel forms were
   rendering as plain body text — the same size and colour as the label above
   them. Aliased rather than renamed across 20 templates.
   .form-errors is also used as `class="form-errors alert alert-error"` on the
   password-reset pages; :not(.alert) keeps this off that case so the alert
   styling still owns it. */
.helptext {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-top: 4px;
}
.form-errors:not(.alert) {
  font-size: 12.5px;
  color: var(--busy);
  font-weight: 500;
  margin-top: 4px;
}

/* -- secondary button ------------------------------------------------------
   26 uses across MFA, sessions, and the report filters. With no rule it was
   indistinguishable from a bare .btn, so "Generate new codes" read with the
   same weight as "Cancel". */
.btn-secondary {
  background: #f1f5f9;
  border-color: #cbd5e1;
  color: var(--text-main);
  font-weight: 600;
}
.btn-secondary:hover:not(:disabled) {
  background: #e2e8f0;
  border-color: #94a3b8;
  color: #0f172a;
}

/* -- initials avatar -------------------------------------------------------
   Ten templates use .avatar-sm; most also carry an inline width/height, which
   is why the gap went unnoticed. The three that do not (chat/room.html twice,
   workspace/channel_members.html) rendered the initials as loose text with no
   tile behind them. Size is a default here so the inline overrides still win. */
.avatar-sm {
  width: 34px;
  height: 34px;
  border-radius: var(--radius-xs);
  background: #f1f5f9;
  border: 1px solid #e2e8f0;
  color: #334155;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  flex-shrink: 0;
  overflow: hidden;
  text-transform: uppercase;
  line-height: 1;
}
.avatar-sm img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}
.avatar-lg {
  width: 72px;
  height: 72px;
  font-size: 24px;
  border-radius: var(--radius-sm);
}

/* -- empty states ----------------------------------------------------------
   The icon is a single emoji; without a size it rendered at body size and the
   empty state read as a stray character above the heading. */
.empty-icon {
  font-size: 34px;
  line-height: 1;
  margin-bottom: 12px;
}

/* -- auth pages ------------------------------------------------------------ */
.text-center { text-align: center; }

/* The glow is absolutely positioned against .auth-logo-badge (already
   position:relative) and sits under the logo tile. It cannot use z-index:-1 —
   that would push it behind .auth-card's own white background and make it
   invisible — so the logo is lifted above it instead. */
.auth-logo-glow {
  position: absolute;
  left: 0;
  top: 0;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-xs);
  background: var(--brand-orange);
  filter: blur(18px);
  opacity: 0.55;
  pointer-events: none;
}
.auth-logo-badge .auth-logo {
  position: relative;
  z-index: 1;
}
.auth-notice {
  text-align: left;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-top: 18px;
}
.notice-badge {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--away);
  margin-bottom: 6px;
}
.notice-text {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-muted);
  margin: 0;
}

/* -- profile flyout status dot --------------------------------------------
   Takes its colour from the same status class the sidebar dots use, so the
   dot in the flyout and the dot in the conversation list cannot disagree. */
.rail-avatar-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--offline);
  flex-shrink: 0;
  display: inline-block;
}
.rail-avatar-dot.active,
.rail-avatar-dot.online  { background: var(--online); }
.rail-avatar-dot.away    { background: var(--away); }
.rail-avatar-dot.busy    { background: var(--busy); }
.rail-avatar-dot.offline { background: var(--offline); }

/* -- odds and ends --------------------------------------------------------- */
.settings-header-info { min-width: 0; }

/* The time is the one piece of data in the reminder meta row; the rest of the
   row is labels, so it gets the body colour and the row keeps the muted one. */
.reminder-when {
  font-weight: 500;
  color: var(--text-main);
}

/* Long channel names in the calendar detail modal wrapped the modal wider
   than its own box without this. */
.cal-detail-text {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.composer-reply-label {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-muted);
}
