/*
 * The Kitchen — Out Sauce Portal
 * Design System: Clean flat + batch colour accent
 */

/* CSS Variables - Design System */
:root {
  /* Batch Colours */
  --os-aqua: #00F5D4;
  --os-lilac: #C4A8FF;
  --os-peach: #FFBE98;
  --os-blue: #6B8CFF;
  --os-coral: #FF6B6B;

  /* Active batch colour (set by JS) */
  --batch: var(--os-aqua);
  --batch-subtle: color-mix(in srgb, var(--batch) 15%, transparent);
  --batch-hover: color-mix(in srgb, var(--batch) 25%, transparent);

  /* Backgrounds */
  --bg-primary: #F5F5F5;
  --bg-card: #FFFFFF;
  --bg-sidebar: #0A0A0A;
  --bg-sidebar-hover: #1A1A1A;

  /* Text */
  --text-primary: #0A0A0A;
  --text-body: #4A4E5A;
  --text-secondary: #888888;
  --text-muted: #9CA3AF;
  --text-on-sidebar: #FFFFFF;
  --text-on-sidebar-muted: #888888;

  /* Borders */
  --border-default: #E5E7EB;
  --border-strong: #D1D5DB;
  --border-weight: 2px;

  /* Semantic */
  --color-success: #34D399;
  --color-danger: #EF4444;
  --color-warning: #FBBF24;
  --color-info: #94A3B8;

  /* Typography */
  --font-display: 'Archivo Black', 'Arial Black', Impact, sans-serif;
  --font-mono: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;

  /* Spacing */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;

  /* Sizing */
  --button-height: 40px;
  --button-height-lg: 48px;
  --icon-button-size: 40px;
  --header-height: 60px;
  --sidebar-width: 260px;
  --sidebar-collapsed-width: 72px;

  /* Borders */
  --border-radius-sm: 6px;
  --border-radius-md: 8px;
  --border-radius-lg: 12px;
  --border-radius-xl: 20px;

  /* Effects — flat only, no glows */
  --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.06);
  --shadow-elevated: 0 4px 12px rgba(0, 0, 0, 0.08);
  --transition-fast: 150ms ease-out;
  --transition-medium: 300ms ease-out;

  /* POC token aliases (used by dashboard + shared components) */
  --block-bg: #0A0A0A;
  --block-text: #FFFFFF;
  --block-muted: #555555;
  --block-tag: #888888;
  --block-surface: rgba(255,255,255,0.06);
  --content-bg: #FFFFFF;
  --content-text: #1A1D26;
  --content-secondary: #4A4E5A;
  --content-muted: #6B7085;
  --content-border: #E5E7EB;
  --content-surface: #F7F7F8;
  --table-stripe: #FAFBFC;
  --success: #34D399;
  --danger: #EF4444;
  --warning: #FBBF24;
  --info: #94A3B8;
}

/* Base Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: var(--font-body);
  background: var(--bg-primary);
  color: var(--text-body);
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Monospace class for data elements */
.mono {
  font-family: var(--font-mono);
}

/* App Shell Layout */
.app-shell {
  display: flex;
  min-height: 100vh;
}

.app-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  margin-left: var(--sidebar-width);
  transition: margin-left var(--transition-medium);
  min-width: 0;
  /* `clip` (not `hidden`) so this does NOT become a scroll container: `hidden`
     makes the computed overflow-y `auto`, which hijacks `position: sticky` for
     descendants (e.g. the chaptered TOC) and traps their internal scroll. `clip`
     still suppresses horizontal bleed but keeps the viewport as the scroll root. */
  overflow-x: clip;
}

.app-main {
  flex: 1;
  padding: var(--spacing-xl);
}

/* Buttons — `.btn-primary` / `.btn-secondary` evicted in D7.45 (CQ-23
   §6.4 task 3 — closes Phase 3). All authenticated-app call-sites now
   use `brand-btn brand-btn--{primary,secondary}` from brand.css. The
   sole survivor (`survey_responses/show.html.erb` on the public survey
   layout, which does not load brand.css) carries an inline `<style>`
   block that fully overrides any base `.btn-primary` cascade — safe. */

/* Cards */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border-default);
  border-radius: var(--border-radius-lg);
  padding: var(--spacing-lg);
}

/* Form Inputs */
input, textarea, select {
  width: 100%;
  height: var(--button-height);
  padding: 0 var(--spacing-md);
  background: var(--bg-card);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: var(--border-radius-sm);
  font-family: var(--font-body);
  transition: all var(--transition-fast);
}

input:hover, textarea:hover, select:hover {
  border-color: var(--border-strong);
}

input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--batch);
}

input::placeholder, textarea::placeholder {
  color: var(--text-muted);
}

/* Full-bleed: break out of .app-main padding */
.body-content {
  margin-left: calc(-1 * var(--spacing-xl));
  margin-right: calc(-1 * var(--spacing-xl));
}

/* ══════════════════════════════════════
   BODY CONTENT
   ══════════════════════════════════════ */
.body-content {
  padding: 36px 48px 60px;
  background: var(--content-surface);
}

.section-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding-top: 4px;
}

.section-header-accent {
  width: 4px;
  height: 22px;
  background: var(--batch);
  border-radius: 2px;
  flex-shrink: 0;
  transition: background-color 0.5s ease;
}

.section-header-text {
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--content-text);
  letter-spacing: 0.01em;
}

.section-description {
  font-size: 14px;
  color: var(--content-secondary);
  margin-bottom: 20px;
  line-height: 1.6;
}

.section-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--content-muted);
}

.divider {
  height: 1px;
  background: var(--content-border);
  margin: 36px 0;
}

/* ══════════════════════════════════════
   TABLES
   ══════════════════════════════════════ */
.table-wrap {
  border: 1px solid var(--content-border);
  overflow-x: auto;
  background: var(--content-bg);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
}

.data-table thead tr {
  background: var(--block-bg);
}

.data-table thead th {
  padding: 12px 16px;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--block-tag);
  white-space: nowrap;
}

.data-table tbody tr {
  border-bottom: 1px solid var(--content-border);
  border-left: 3px solid transparent;
  transition: background-color 0.15s, border-color 0.15s;
}

.data-table tbody tr:last-child { border-bottom: none; }
.data-table tbody tr:nth-child(even) { background: var(--table-stripe); }
.data-table tbody tr:hover {
  background: color-mix(in srgb, var(--batch) 6%, transparent);
  border-left-color: var(--batch);
}

.data-table tbody td {
  padding: 14px 16px;
  font-size: 14px;
  color: var(--content-secondary);
  vertical-align: middle;
}

.data-table .col-name {
  font-weight: 600;
  color: var(--content-text);
}

/* ══════════════════════════════════════
   BADGES
   ══════════════════════════════════════ */
.badge {
  display: inline-block;
  padding: 4px 10px;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.badge-success { background: #E8F5E9; color: #2E7D32; }
.badge-batch { background: var(--batch); color: #0A0A0A; transition: background-color 0.5s ease; }

/* ══════════════════════════════════════
   DARK BLOCKS & ACTION CARDS
   ══════════════════════════════════════ */
.dark-block {
  background: var(--block-bg);
  padding: 24px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 32px;
  gap: 16px;
}

.block-title {
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--batch);
  margin-bottom: 4px;
  transition: color 0.5s ease;
}

.block-body {
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(255,255,255,0.55);
}

.action-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

.action-card {
  background: var(--block-bg);
  padding: 32px 28px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid transparent;
  text-decoration: none;
  display: block;
}

.action-card:hover {
  border-color: var(--batch);
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
}

.action-card-icon {
  font-size: 28px;
  margin-bottom: 16px;
  display: block;
  color: var(--batch);
  transition: color 0.5s ease;
}

.action-card-title {
  font-family: var(--font-display);
  font-size: 15px;
  color: #FFFFFF;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  margin-bottom: 8px;
}

.action-card-desc {
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(255,255,255,0.5);
  line-height: 1.5;
}

/* ══════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════ */
@media (max-width: 900px) {
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .action-cards { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  .body-content { padding: 24px; }
  .kpi-grid { grid-template-columns: 1fr; }
  .dark-block { flex-direction: column; align-items: flex-start; }
}

/* ══════════════════════════════════════
   CONVERSATION LAYOUT
   ══════════════════════════════════════ */
.conversation-layout {
  display: flex;
  flex-direction: column;
  /* viewport - app-header - app-main padding (top+bottom) - page hero
     box (~210px hero + 32px margin-bottom). Hero now lives in
     content_for(:hero) above the layout (D8 alignment with the
     dm-layout pattern), so the math mirrors .dm-layout. */
  height: calc(100vh - var(--header-height) - var(--spacing-xl) * 2 - 210px);
  min-height: 500px;
  background: var(--content-bg, var(--bg-card));
  border: 1px solid var(--content-border, var(--border-default));
  /* Full-bleed to the content edges, aligning with the full-bleed
     brand-compact-hero above (which breaks out of app-main padding). */
  margin-left: calc(-1 * var(--spacing-xl));
  margin-right: calc(-1 * var(--spacing-xl));
  overflow: hidden;
}

/* Embedded variant — for thread chrome that lives inside an already-sized
   flex parent (e.g. .dm-conversation-pane inside .dm-layout). Drops the
   standalone box (viewport-height, side margins, border) so the parent
   pane provides the bounds. Locked as part of CQ-23 §10.3 #1 (thread
   chrome design candidate). */
.conversation-layout--embedded {
  height: 100%;
  min-height: 0;
  margin-left: 0;
  margin-right: 0;
  border: none;
  background: transparent;
}

/* <turbo-frame> is inline by default — without this, the embedded
   .conversation-layout's height:100% has nothing to resolve against
   and the composer floats to natural-content height. */
.dm-conversation-pane > turbo-frame {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Thread chrome — D8 messaging unification. The bespoke dark
   .conversation-header was replaced by a page-level brand-compact-hero
   rendered via content_for(:hero), identical to every other rebranded
   page. The message stream / composer live in .conversation-layout
   below it. */

/* DM identity bar — per-thread chrome inside dm-conversation-pane.
   Lighter than the page hero (which sits above the whole dm-layout);
   mono eyebrow + display-font name. */
.dm-identity-bar {
  padding: 14px 24px;
  background: var(--content-bg, var(--bg-card));
  border-bottom: 1px solid var(--content-border, var(--border-default));
  flex-shrink: 0;
}

.dm-identity-bar-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--content-muted, var(--text-muted));
  margin-bottom: 4px;
}

.dm-identity-bar-title {
  font-family: var(--font-display);
  font-size: 18px;
  color: var(--content-text, var(--text-primary));
  letter-spacing: -0.01em;
  line-height: 1.1;
}

/* ══════════════════════════════════════
   PINNED ANNOUNCEMENTS
   ══════════════════════════════════════
   D7.5: .pinned-banner/.pinned-header/.pinned-icon/.pinned-body/
   .pinned-footer/.pinned-meta/.pinned-unpin removed — broadcasts/
   _broadcast_banner now renders a brand-kit `_status_card`.
   .pinned-area kept for conversations/show wrapper border.        */
.pinned-area {
  flex-shrink: 0;
  border-bottom: 1px solid var(--content-border, var(--border-default));
}

/* ══════════════════════════════════════
   MESSAGE STREAM
   ══════════════════════════════════════ */
.message-stream {
  flex: 1;
  overflow-y: auto;
  padding: 0 24px;
  display: flex;
  flex-direction: column;
  background: var(--content-bg, var(--bg-card));
}

.date-separator {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 0 8px;
}

.date-separator-line {
  flex: 1;
  height: 1px;
  background: var(--content-border, var(--border-default));
}

.date-separator-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--content-muted, var(--text-muted));
  flex-shrink: 0;
}

.message-group {
  display: flex;
  gap: 12px;
  padding: 10px 12px;
  border-left: 3px solid transparent;
  transition: background-color 0.12s ease, border-color 0.12s ease;
  /* #21 — positioning context for the hover-revealed admin delete control. */
  position: relative;
}

.message-group:hover {
  background: var(--content-surface, var(--bg-primary));
  border-left-color: var(--batch);
}

.message-group + .message-group {
  border-top: 1px solid var(--content-border, var(--border-default));
}

.message-group.consecutive {
  padding-top: 2px;
  padding-left: 63px;
  border-top: none;
}

.message-group.consecutive:hover {
  border-left-color: var(--batch);
}

.avatar-circle {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--batch);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 12px;
  color: #0A0A0A;
  flex-shrink: 0;
  transition: background-color 0.5s ease;
}

.avatar-circle.sm {
  width: 34px;
  height: 34px;
  font-size: 11px;
}

/* #35 — per-speaker colour ("Bright Spectrum" palette, operator pick).
   speaker_colour_class hashes author_id -> one of 8 slots and stamps a
   .speaker-N class on the .message-group of human-author kinds
   (_text/_file_link/_kb_card). Avatar fill + author name then read the
   slot's custom props, giving each person a stable differentiator.
   Deliberately distinct from the 5 batch/system colours so the speaker
   palette and the batch theme never get confused. System kinds
   (hold/complete/kb_announce) carry no .speaker-* class and keep their
   semantic avatar colours. Name tints are the darker, saturated variants
   for contrast on the white (.conversation-layout) thread. */
.message-group.speaker-0 { --speaker-bg: #EF476F; --speaker-fg: #0A0A0A; --speaker-name: #C42852; }
.message-group.speaker-1 { --speaker-bg: #06D6A0; --speaker-fg: #0A0A0A; --speaker-name: #067D5E; }
.message-group.speaker-2 { --speaker-bg: #FFD166; --speaker-fg: #0A0A0A; --speaker-name: #9A7B1E; }
.message-group.speaker-3 { --speaker-bg: #118AB2; --speaker-fg: #0A0A0A; --speaker-name: #0C6486; }
.message-group.speaker-4 { --speaker-bg: #F78C6B; --speaker-fg: #0A0A0A; --speaker-name: #C25638; }
.message-group.speaker-5 { --speaker-bg: #9B5DE5; --speaker-fg: #0A0A0A; --speaker-name: #6E37AE; }
.message-group.speaker-6 { --speaker-bg: #83E377; --speaker-fg: #0A0A0A; --speaker-name: #3E8A33; }
.message-group.speaker-7 { --speaker-bg: #4CC9F0; --speaker-fg: #0A0A0A; --speaker-name: #1A7C9C; }

.message-group[class*="speaker-"] .avatar-circle {
  background: var(--speaker-bg);
  color: var(--speaker-fg);
}

.message-group[class*="speaker-"] .message-author {
  color: var(--speaker-name);
}

/* #21 — admin delete control. Hidden until the message-group is hovered (or
   the control itself is focused, for keyboard users). button_to wraps the
   button in a <form>, so reset that form's box. */
.message-delete-control {
  position: absolute;
  top: 8px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--content-border, #E5E7EB);
  border-radius: 50%;
  background: var(--content-bg, #FFFFFF);
  color: var(--content-muted, #6B7085);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.message-group:hover .message-delete-control,
.message-delete-control:focus-visible {
  opacity: 1;
}

.message-delete-control:hover {
  color: var(--danger, #EF4444);
  border-color: var(--danger, #EF4444);
}

/* #21 — soft-delete tombstone. Muted, italic, no per-speaker colour. */
.message-group--tombstone .tombstone-avatar {
  background: var(--content-surface, #F7F7F8);
  color: var(--content-muted, #6B7085);
}

.message-group--tombstone .tombstone-text {
  color: var(--content-muted, #6B7085);
  font-style: italic;
  font-weight: 500;
}

.message-content {
  flex: 1;
  min-width: 0;
}

.message-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}

.message-author {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--content-text, var(--text-primary));
}

.message-timestamp {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--content-muted, var(--text-muted));
}

.message-body {
  font-family: var(--font-body);
  font-size: 13.5px;
  color: var(--content-secondary, var(--text-body));
  line-height: 1.6;
}

.message-body p { margin-bottom: 0; }
.message-body p + p { margin-top: 8px; }

.mention-highlight {
  background: var(--batch-subtle);
  color: var(--content-text, var(--text-primary));
  font-weight: 600;
  padding: 1px 6px;
  font-size: 13px;
  transition: background-color 0.5s ease;
}

/* File attachment cards */
.attachment-file {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--content-border, var(--border-default));
  background: var(--content-bg, var(--bg-card));
  padding: 8px 12px;
  margin-top: 6px;
  max-width: 300px;
  cursor: pointer;
  transition: border-color 0.5s ease;
  text-decoration: none;
}

.attachment-file:hover { border-color: var(--batch); }

.attachment-icon {
  width: 28px;
  height: 28px;
  background: var(--batch-subtle);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 700;
  color: var(--content-text, var(--text-primary));
  letter-spacing: 0.06em;
  flex-shrink: 0;
  transition: background-color 0.5s ease;
}

.attachment-info { min-width: 0; }

.attachment-name {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  color: var(--content-text, var(--text-primary));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.attachment-size {
  font-family: var(--font-mono);
  font-size: 8px;
  color: var(--content-muted, var(--text-muted));
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.attachment-download {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--batch);
  margin-left: auto;
  flex-shrink: 0;
  transition: color 0.5s ease;
  text-decoration: none;
}

.attachment-image {
  margin-top: 6px;
  display: block;
}

.attachment-image img {
  max-width: 280px;
  max-height: 180px;
  display: block;
  border: 1px solid var(--content-border, var(--border-default));
  object-fit: cover;
}

/* Load older messages */
.load-older {
  display: flex;
  justify-content: center;
  padding: 14px 0 6px;
}

.load-older-btn {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--content-muted, var(--text-muted));
  background: var(--content-surface, var(--bg-primary));
  border: 1px solid var(--content-border, var(--border-default));
  padding: 6px 18px;
  cursor: pointer;
  text-decoration: none;
  transition: border-color 0.5s ease, color 0.15s, background 0.15s;
}

.load-older-btn:hover { border-color: var(--batch); color: var(--content-text, var(--text-primary)); background: var(--batch-subtle); }

/* Typing indicator */
.typing-indicator {
  padding: 4px 24px;
  font-family: var(--font-body);
  font-size: 12px;
  font-style: italic;
  color: var(--content-muted, var(--text-muted));
  min-height: 24px;
  flex-shrink: 0;
  background: var(--content-bg, var(--bg-card));
}

/* New messages indicator */
.new-messages-indicator {
  display: flex;
  justify-content: center;
  padding: 6px 0;
  flex-shrink: 0;
  background: var(--content-bg, var(--bg-card));
}

.new-messages-pill {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #0A0A0A;
  background: var(--batch);
  border: none;
  padding: 4px 14px;
  cursor: pointer;
  transition: background-color 0.5s ease;
}

.new-messages-pill:hover { opacity: 0.85; }

/* ══════════════════════════════════════
   MESSAGE COMPOSER
   ══════════════════════════════════════ */
.message-composer {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 10px 24px 12px;
  background: var(--block-bg);
  flex-shrink: 0;
}

.message-textarea {
  flex: 1;
  width: auto;
  height: auto;
  font-family: var(--font-body);
  font-size: 13.5px;
  color: #1A1A1A;
  background: #FFFFFF;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 0;
  padding: 9px 14px;
  resize: none;
  outline: none;
  line-height: 1.5;
  min-height: 40px;
  max-height: 120px;
  transition: border-color 0.5s ease;
}

.message-textarea:focus { border-color: var(--batch); }
.message-textarea::placeholder { color: rgba(26, 26, 26, 0.45); }

.composer-btn {
  width: 38px;
  min-width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.15);
  border-radius: 0;
  color: rgba(255,255,255,0.45);
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.5s ease, color 0.15s;
}

.composer-btn:hover { border-color: var(--batch); color: var(--block-text, #FFFFFF); }

.composer-send {
  width: auto;
  height: 38px;
  padding: 0 20px;
  background: var(--batch);
  border: none;
  border-radius: 0;
  font-family: var(--font-display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #0A0A0A;
  cursor: pointer;
  flex-shrink: 0;
  transition: background-color 0.5s ease;
}

.composer-send:hover { opacity: 0.9; }

/* ══════════════════════════════════════
   DM SPLIT-PANE
   ══════════════════════════════════════ */
.dm-layout {
  display: flex;
  /* viewport - app-header - app-main padding (top+bottom) - page hero
     box (~210px hero + 32px margin-bottom). The page-level compact-hero
     anchors /messages now; the layout fills the rest of the viewport.
     Full-bleed to the content edges, aligning with the full-bleed
     brand-compact-hero above. */
  height: calc(100vh - var(--header-height) - var(--spacing-xl) * 2 - 210px);
  min-height: 500px;
  margin-left: calc(-1 * var(--spacing-xl));
  margin-right: calc(-1 * var(--spacing-xl));
  border: 1px solid var(--content-border, var(--border-default));
  background: var(--content-bg, var(--bg-card));
  overflow: hidden;
}

.dm-conversation-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-right: 1px solid var(--content-border, var(--border-default));
}

/* ══════════════════════════════════════
   THREAD LIST SIDEBAR
   ══════════════════════════════════════ */
.thread-list-sidebar {
  width: 320px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

/* D8 — page hero owns "+ New Message"; the rail just labels the list.
   No dark band; clean mono section label flush with brand typography. */
.thread-list-rail-head {
  padding: 18px 20px 12px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--content-border, var(--border-default));
  background: var(--content-bg, var(--bg-card));
}

.thread-list-rail-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--content-muted, var(--text-muted));
}

.thread-list {
  flex: 1;
  overflow-y: auto;
  background: var(--content-bg, var(--bg-card));
}

.thread-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--content-border, var(--border-default));
  cursor: pointer;
  border-left: 3px solid transparent;
  text-decoration: none;
  color: inherit;
  transition: background-color 0.15s, border-color 0.5s ease;
}

.thread-item:hover { background: var(--content-surface, var(--bg-primary)); }

.thread-item.active {
  background: var(--batch-subtle);
  border-left-color: var(--batch);
}

.thread-item.unread .thread-item-name { font-weight: 700; }

.thread-item-body { flex: 1; min-width: 0; }

.thread-item-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 2px;
}

.thread-item-name {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--content-text, var(--text-primary));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.thread-item-time {
  font-family: var(--font-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--content-muted, var(--text-muted));
  flex-shrink: 0;
  margin-left: 8px;
}

.thread-item-preview {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--content-muted, var(--text-muted));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.thread-unread-badge {
  background: var(--batch);
  color: #0A0A0A;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  padding: 2px 7px;
  flex-shrink: 0;
  align-self: center;
  margin-left: 6px;
  transition: background-color 0.5s ease;
}

/* D7.9 — Flex-fill wrapper that centers the shared _empty_state primitive
   inside the .dm-conversation-pane when no thread is active. Replaces the
   bespoke .dm-empty-state + .dm-empty-icon + .dm-empty-title + .dm-empty-body
   + .dm-empty-btn family (CQ-23 §6.1). */
.dm-empty-state-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

/* D7.9 — Sidebar's "No conversations yet" fallback. Tiny class-based
   replacement for the previous inline-style block; _empty_state would be
   visually heavy in the 320px sidebar column. */
.thread-list-empty {
  padding: 32px 20px;
  text-align: center;
  color: var(--content-muted, var(--text-muted));
}

.thread-list-empty-text {
  font-family: var(--font-body);
  font-size: 13px;
  margin: 0 0 8px;
}

.thread-list-empty-link {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--batch);
  text-decoration: none;
}

.thread-list-empty-link:hover { text-decoration: underline; }

/* ══════════════════════════════════════
   NEW REQUEST FORM
   ══════════════════════════════════════ */
.request-layout {
  max-width: 680px;
  margin: 0 auto;
  padding: 32px 0 48px;
}

.request-hero {
  background: var(--block-bg);
  padding: 24px 28px;
  margin-bottom: 24px;
  border-left: 4px solid var(--batch);
  transition: border-color 0.5s ease;
}

.request-hero-label {
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--batch);
  margin-bottom: 6px;
  transition: color 0.5s ease;
}

.request-hero-title {
  font-family: var(--font-display);
  font-size: 24px;
  color: var(--block-text, #FFFFFF);
  letter-spacing: -0.02em;
  text-transform: uppercase;
  margin-bottom: 6px;
}

.request-hero-subtitle {
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(255,255,255,0.55);
  line-height: 1.5;
}

.request-error-box {
  border: 1px solid var(--danger, var(--color-danger));
  border-left: 4px solid var(--danger, var(--color-danger));
  background: rgba(239,68,68,0.04);
  padding: 12px 16px;
  margin-bottom: 20px;
}

.request-error-title {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--danger, var(--color-danger));
  margin-bottom: 4px;
}

.request-error-list {
  list-style: none;
  padding: 0;
}

.request-error-list li {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--danger, var(--color-danger));
  padding: 1px 0;
}

.request-error-list li::before { content: "\2022  "; }

.request-card {
  background: var(--content-bg, var(--bg-card));
  border: 1px solid var(--content-border, var(--border-default));
  padding: 28px;
}

.request-section-label {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--content-border, var(--border-default));
}

.request-section-label::before {
  content: '';
  width: 4px;
  height: 22px;
  background: var(--batch);
  border-radius: 2px;
  flex-shrink: 0;
  transition: background-color 0.5s ease;
}

.request-section-label-text {
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--content-text, var(--text-primary));
  letter-spacing: 0.01em;
}

.form-field { margin-bottom: 22px; }

.form-label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--content-text, var(--text-primary));
  margin-bottom: 6px;
}

.form-required { color: var(--danger, var(--color-danger)); font-size: 12px; }

.form-hint {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--content-muted, var(--text-muted));
  margin-top: 4px;
}

.form-input,
.form-select,
.form-textarea {
  width: 100%;
  height: auto;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--content-text, var(--text-primary));
  background: var(--content-bg, var(--bg-card));
  border: 1px solid var(--content-border, var(--border-default));
  border-radius: 0;
  padding: 10px 14px;
  outline: none;
  transition: border-color 0.5s ease;
  appearance: none;
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus { border-color: var(--batch); }

.form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%236B7085' d='M0 0l6 8 6-8z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 36px;
  cursor: pointer;
}

.form-textarea { resize: vertical; line-height: 1.6; }

.form-file-zone {
  width: 100%;
  border: 2px dashed var(--content-border, var(--border-default));
  background: var(--content-surface, var(--bg-primary));
  padding: 24px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.5s ease, background 0.15s;
  position: relative;
}

.form-file-zone:hover { border-color: var(--batch); background: var(--batch-subtle); }

.form-file-zone-icon {
  font-size: 24px;
  color: var(--content-muted, var(--text-muted));
  margin-bottom: 6px;
}

.form-file-zone-text {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--content-muted, var(--text-muted));
}

.form-file-zone-text strong {
  color: var(--content-text, var(--text-primary));
  font-weight: 600;
}

.form-file-zone input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  width: 100%;
  height: 100%;
}

.request-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 8px;
  padding-top: 24px;
  border-top: 1px solid var(--content-border, var(--border-default));
}

.btn-cancel {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--content-muted, var(--text-muted));
  background: transparent;
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: color 0.15s;
}

.btn-cancel:hover { color: var(--content-text, var(--text-primary)); }

/* ══════════════════════════════════════
   NEW DM FORM
   ══════════════════════════════════════ */
.dm-new-page {
  max-width: 680px;
  margin: 0 auto;
  padding: 32px 0 48px;
}

/* Scrollbar */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: var(--bg-primary);
}

::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

/* Animations */
@keyframes fadeSlideIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes expandIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Utility Classes */
.text-muted {
  color: var(--text-muted);
}

.text-secondary {
  color: var(--text-secondary);
}

.coming-soon {
  opacity: 0.5;
  position: relative;
}

.coming-soon::after {
  content: "Coming Soon";
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-left: var(--spacing-sm);
}

/* Flash Messages — branded flat banners (D5.3) */
.brand-flash {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  margin-bottom: var(--spacing-lg);
  background: var(--content-bg);
  border: 1px solid var(--content-border);
  border-left-width: 4px;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  color: var(--content-text);
}

.brand-flash::before {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 4px 9px;
}

.brand-flash-notice {
  border-left-color: var(--color-success);
}

.brand-flash-notice::before {
  content: "Notice";
  background: color-mix(in srgb, var(--color-success) 16%, transparent);
  color: #047857;
}

.brand-flash-alert,
.brand-flash-error {
  border-left-color: var(--color-danger);
}

.brand-flash-alert::before {
  content: "Alert";
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
  color: var(--color-danger);
}

.brand-flash-error::before {
  content: "Error";
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
  color: var(--color-danger);
}

/* Pagination — branded pagy series-nav chrome (D5.3) */
.pagination-wrapper {
  margin-top: var(--spacing-lg);
  padding: var(--spacing-md);
  display: flex;
  justify-content: center;
}

.pagination-wrapper nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--spacing-xs);
}

.pagination-wrapper nav a,
.pagination-wrapper nav span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--content-border);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--content-secondary);
  text-decoration: none;
  transition: all var(--transition-fast);
}

.pagination-wrapper nav a:not([aria-disabled="true"]):hover {
  border-color: var(--batch);
  background: var(--batch-subtle);
  color: var(--content-text);
}

.pagination-wrapper nav a.current,
.pagination-wrapper nav span.current,
.pagination-wrapper nav [aria-current="page"] {
  background: var(--block-bg);
  border-color: var(--block-bg);
  color: var(--batch);
}

.pagination-wrapper nav a[aria-disabled="true"]:not([aria-current="page"]) {
  color: var(--text-muted);
  cursor: default;
}

.pagination-wrapper nav .gap {
  border-color: transparent;
  color: var(--text-muted);
}

/* Empty states — branded placeholder for empty listings (D5.3) */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 56px 32px;
  background: var(--content-surface);
  border: 1px solid var(--content-border);
}

.empty-state-title {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--content-text);
}

.empty-state-body {
  margin: 10px auto 0;
  max-width: 440px;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.6;
  color: var(--content-muted);
}

.empty-state .brand-btn--primary {
  margin-top: 20px;
}

/* Toast Notifications */
.toast-container {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 9999;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  pointer-events: none;
}

.toast-notification {
  background: var(--bg-card);
  border: var(--border-weight) solid var(--batch);
  border-radius: 8px;
  padding: 12px 16px;
  min-width: 300px;
  max-width: 400px;
  opacity: 0;
  transform: translateX(100%);
  transition: all 0.3s ease;
  pointer-events: auto;
  box-shadow: var(--shadow-elevated);
}

.toast-visible {
  opacity: 1;
  transform: translateX(0);
}

.toast-hiding {
  opacity: 0;
  transform: translateX(100%);
}

.toast-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}

.toast-title {
  color: var(--batch);
  font-weight: 600;
  font-size: 0.9375rem;
}

.toast-close {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color var(--transition-fast);
}

.toast-close:hover {
  color: var(--text-primary);
}

.toast-body {
  color: var(--text-secondary);
  font-size: 0.875rem;
  line-height: 1.4;
}

.toast-warning { border-color: var(--warning, #FBBF24); }
.toast-warning .toast-title { color: var(--warning, #FBBF24); }
.toast-error { border-color: var(--danger, #EF4444); }
.toast-error .toast-title { color: var(--danger, #EF4444); }

/* ══════════════════════════════════════
   Auth pages — page-local chrome only (CQ-23 closeout).
   Inputs, labels, buttons, errors all live on brand-kit primitives
   (brand-form-*, brand-btn--*). What remains here is the per-page
   header (title + subtitle outside the card), the "or" divider that
   splits the email/password form from the SSO button, the SSO
   button's row layout, and the footer link rhythm.
   ══════════════════════════════════════ */
.auth-page {
  width: 100%;
}

.auth-page-header {
  margin-bottom: 24px;
}

.auth-page-title {
  font-family: var(--font-display, 'Archivo Black', 'Arial Black', Impact, sans-serif);
  font-size: 22px;
  color: var(--content-text, #0A0A0A);
  margin-bottom: 8px;
}

.auth-page-subtitle {
  font-size: 14px;
  color: var(--content-secondary, #4A4E5A);
  margin: 0;
}

.auth-divider {
  text-align: center;
  padding: 16px 0;
  color: var(--content-muted, #6B7085);
  font-size: 13px;
  position: relative;
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 40%;
  height: 1px;
  background: var(--content-border, #E5E7EB);
}

.auth-divider::before { left: 0; }
.auth-divider::after { right: 0; }

/* Auth pages keep prominent full-width submit + SSO buttons — the
   form lives inside a narrow 448px right-panel column. */
.auth-page .brand-form-actions {
  display: block;
}

.auth-page .brand-form-actions .brand-btn {
  width: 100%;
}

.auth-sso-btn {
  width: 100%;
}

.auth-hint {
  text-align: center;
  font-size: 12px;
  color: var(--content-muted, #9CA3AF);
  margin-top: 8px;
}

.auth-link {
  text-align: center;
  margin-top: 16px;
  font-size: 13px;
  color: var(--content-muted, #6B7085);
}

.auth-link a {
  color: var(--batch, #00F5D4);
  text-decoration: none;
  font-weight: 500;
  transition: color 0.5s ease;
}

/* ══════════════════════════════════════
   Surveys — Out Sauce
   ══════════════════════════════════════ */

.surveys-page .page-header h1 {
  font-family: var(--font-display, 'Archivo Black', sans-serif);
  color: #0A0A0A;
}

.surveys-page .data-table th {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6B7280;
}

.surveys-page .data-table td {
  font-family: var(--font-body, 'Inter', sans-serif);
  font-size: 13px;
  color: #0A0A0A;
}

.surveys-page .data-table tbody tr:hover {
  border-left: 3px solid var(--batch, #00F5D4);
}

.surveys-page .surveys-table-card {
  background: #FFFFFF;
  border: 1px solid #E5E7EB;
}

.survey-show-page .survey-form-card {
  background: #FFFFFF;
  border: 1px solid #E5E7EB;
}

.survey-banner {
  background: #0A0A0A;
  border-bottom: 3px solid var(--batch, #00F5D4);
}

.survey-banner-text h3 {
  font-family: var(--font-display, 'Archivo Black', sans-serif);
  color: rgba(255, 255, 255, 0.9);
}

.survey-banner-text p {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.5);
}

.survey-card {
  background: #FFFFFF;
  border: 1px solid #E5E7EB;
}

.survey-card .meta-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6B7280;
}

/* W4-3 message kind components — file_link, kb_card, system_kb_announce */

/* T13 — file_link kind: subtle <hr> + paperclip + filename hyperlink */
.message-file-link {
  display: inline-flex;
  align-items: center;
  color: var(--batch, #00F5D4);
  font-size: 13px;
  text-decoration: none;
  padding: 2px 0;
}

.message-file-link:hover {
  text-decoration: underline;
}

.message-file-link--unavailable {
  color: rgba(255, 255, 255, 0.4);
  font-style: italic;
  pointer-events: none;
}

.message-file-link-name {
  font-family: var(--font-mono);
  font-size: 12px;
}

.message-file-link-status {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* T26/T27 — kb_card and system_kb_announce card. Renders inside the (light,
   theme-stable) message thread, so it uses content-* surface tokens. Sub-
   element selectors are scoped under .kb-card to avoid colliding with the
   identically-named .kb-card-title used by the KB index article card. */
.kb-card {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--content-surface, #F7F7F8);
  border: 1px solid var(--content-border, #E5E7EB);
  color: var(--content-text, #1A1D26);
  text-decoration: none;
  max-width: 480px;
}

.kb-card:hover {
  background: color-mix(in srgb, var(--batch) 8%, var(--content-surface, #F7F7F8));
  border-color: var(--batch, #00F5D4);
}

.kb-card--unavailable {
  pointer-events: none;
  opacity: 0.5;
}

.kb-card .kb-card-icon {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--content-secondary, #4A4E5A);
}

.kb-card .kb-card-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.kb-card .kb-card-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--content-text, #1A1D26);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kb-card .kb-card-scope {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--content-muted, #6B7085);
}

.kb-card .kb-card-scope--firm { color: var(--content-secondary, #4A4E5A); }
.kb-card .kb-card-scope--shared { color: var(--content-secondary, #4A4E5A); }
.kb-card .kb-card-scope--os_internal { color: var(--danger, #EF4444); }

/* KE-05 system_kb_announce — standard .message-group shape with a square book
   "avatar" so a new-article post sits in the thread like a normal message
   (mirrors the KE-04 system_hold treatment). */
/* Two-class specificity so the square system look wins over the single-class
   .avatar-circle redefined in jobs.css on job-thread conversations. Size is
   left to inherit so it matches the thread's other avatars. */
.message-group--kb-announce .avatar-circle.kb-announce-avatar {
  border-radius: 0;
  background: var(--content-text, #1A1D26);
  color: var(--batch, #00F5D4);
}

.kb-announce-author {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--content-secondary, #4A4E5A);
}

/* ══════════════════════════════════════
   System-hold message (KE-04) — renders in the standard .message-group
   shape (avatar + meta + body) so it inherits the conversation's row
   dividers and hover affordances. Only the avatar + author label are
   re-skinned with semantic colour (warning for placed, success for
   resumed). Styles live here (not inline in the partial) so the partial
   doesn't insert a <style> sibling that breaks the .message-group +
   .message-group adjacency selector.
   ══════════════════════════════════════ */
.hold-avatar {
  border-radius: 0;
  background: var(--content-text);
  color: var(--content-bg, #FFFFFF);
}

.message-group--hold-placed  .hold-avatar { background: var(--warning); color: #0A0A0A; }
.message-group--hold-resumed .hold-avatar { background: var(--success); color: #0A0A0A; }

.hold-author {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.message-group--hold-placed  .hold-author { color: var(--warning); }
.message-group--hold-resumed .hold-author { color: var(--success); }

.hold-body { font-family: var(--font-body); }

.hold-body-headline {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--content-text);
  text-transform: capitalize;
  line-height: 1.4;
}

.hold-body-detail {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--content-secondary);
  line-height: 1.5;
}

/* #47 — system_complete message treatment. Parallels the hold block:
   square semantic-tinted avatar + mono label, but a "done" success
   green with a check glyph so completion reads distinctly from a
   hold-resume. */
.complete-avatar {
  border-radius: 0;
  background: var(--success);
  color: #0A0A0A;
}

.complete-author {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--success);
}

.complete-body {
  font-family: var(--font-body);
  font-size: 13.5px;
  color: var(--content-secondary);
  line-height: 1.6;
}

.complete-body p { margin: 0; }
.complete-body p + p { margin-top: 8px; }

/* ══════════════════════════════════════
   File-upload preview list (REG-03 — shared by message composer +
   new-request form). Lifted from app/views/messages/_form.html.erb so
   the new-request file picker can reuse the same Stimulus controller
   (file_upload_controller.js). Form-specific blocks (.composer-input-row,
   .preview-category for T13) stay inline at messages/_form.html.erb.
   ══════════════════════════════════════ */
.file-preview-area {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 8px;
}

.file-preview-area:empty { margin-bottom: 0; }

.file-preview-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
}

.preview-image {
  width: 48px;
  height: 48px;
  object-fit: cover;
  flex-shrink: 0;
}

.preview-icon {
  font-size: 1.5rem;
  flex-shrink: 0;
  width: 48px;
  text-align: center;
  color: rgba(255, 255, 255, 0.6);
}

.preview-icon.pdf { color: #e74c3c; }

.preview-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.preview-name {
  color: #FFFFFF;
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.preview-size {
  color: rgba(255, 255, 255, 0.4);
  font-size: 10px;
  font-family: var(--font-mono);
}

.preview-remove {
  width: 24px;
  height: 24px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
}

.preview-remove:hover {
  border-color: var(--batch);
  color: var(--batch);
}

/* ══════════════════════════════════════
   #31 — Horizontal file cards (new-job "Attach Files" only).
   Opted into via .file-preview-area--cards + the controller's
   card-style value; the dark message composer keeps the row layout
   above. Each staged file is a bordered card with a coloured
   file-extension badge (or image thumbnail), filename, and size.
   ══════════════════════════════════════ */
.file-preview-area--cards {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 12px;
}

.file-card {
  position: relative;
  width: 130px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px 14px;
  background: #FFFFFF;
  border: 1px solid var(--content-border);
  border-radius: 8px;
  text-align: center;
}

.file-card-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  overflow: hidden;
  flex-shrink: 0;
}

.file-card-badge img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.file-card--pdf   .file-card-badge { color: #DC2626; background: color-mix(in srgb, #DC2626 12%, transparent); }
.file-card--sheet .file-card-badge { color: #16A34A; background: color-mix(in srgb, #16A34A 12%, transparent); }
.file-card--doc   .file-card-badge { color: #2563EB; background: color-mix(in srgb, #2563EB 12%, transparent); }
.file-card--image .file-card-badge { color: var(--text-muted); background: var(--content-border); }
.file-card--default .file-card-badge { color: #6B7280; background: color-mix(in srgb, #6B7280 12%, transparent); }

.file-card-name {
  width: 100%;
  font-size: 12px;
  font-weight: 500;
  color: var(--content-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-card-size {
  font-size: 11px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}

.file-card-remove {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--text-muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.file-card-remove:hover {
  color: #DC2626;
  background: color-mix(in srgb, #DC2626 10%, transparent);
}

/* New-request form-specific dropzone wrapper (REG-03) — visible "Choose
   Files" affordance + drag-and-drop hint. Composer reuses .composer-input-row
   for its own dropzone and is unaffected. */
.file-upload-dropzone {
  /* #30 — match the form inputs above (1.5px solid var(--content-border)) so the
     drop area reads as clearly present; kept dashed for the drop-zone affordance. */
  border: 1.5px dashed var(--content-border);
  padding: var(--spacing-md);
  background: var(--bg-card);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.file-upload-dropzone.drag-over {
  border-color: var(--batch);
  background: var(--batch-subtle);
}

.file-upload-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-sm) var(--spacing-md);
  cursor: pointer;
  color: var(--text-primary);
  font-weight: 500;
}

.file-upload-trigger:hover { color: var(--batch); }

.file-upload-hint {
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 400;
}
