* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; height: 100vh; display: flex; }

/* Auth page */
.auth-container {
  margin: auto; width: 380px; background: #fff; border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.1); padding: 40px;
}
.auth-container h1 { font-size: 24px; margin-bottom: 8px; text-align: center; }
.auth-container p.subtitle { color: #666; text-align: center; margin-bottom: 24px; font-size: 14px; }
.auth-container input {
  width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 6px;
  font-size: 14px; margin-bottom: 12px; outline: none;
}
.auth-container input:focus { border-color: #4f46e5; }
.auth-container button {
  width: 100%; padding: 10px; background: #4f46e5; color: #fff; border: none;
  border-radius: 6px; font-size: 14px; cursor: pointer; margin-bottom: 12px;
}
.auth-container button:hover { background: #4338ca; }
.auth-container .toggle { text-align: center; font-size: 13px; color: #666; }
.auth-container .toggle a { color: #4f46e5; cursor: pointer; text-decoration: none; }
.auth-container .error { color: #dc2626; font-size: 13px; margin-bottom: 12px; display: none; }
.auth-container .notice { color: #16a34a; font-size: 13px; margin-bottom: 12px; display: none; }
.auth-container .resend { text-align: center; margin-bottom: 12px; display: none; }
/* Link-styled button: override the full-width .auth-container button rules. */
.auth-container .resend-btn {
  width: auto; padding: 0; margin: 0; background: none; color: #4f46e5;
  font-size: 13px; cursor: pointer; text-decoration: underline;
}
.auth-container .resend-btn:hover { background: none; color: #4338ca; }

/* Chat layout */
.chat-app { display: flex; width: 100%; height: 100vh; }

/* Sidebar */
.sidebar {
  width: 280px; background: #1e1e2e; color: #cdd6f4; display: flex; flex-direction: column;
  flex-shrink: 0;
}
.sidebar-header {
  padding: 16px; border-bottom: 1px solid #313244; display: flex;
  justify-content: space-between; align-items: center;
}
.sidebar-header h2 { font-size: 16px; color: #cdd6f4; }
.sidebar-header .user-info { font-size: 12px; color: #a6adc8; }
.new-chat-btn {
  margin: 12px 16px; padding: 10px; background: #4f46e5; color: #fff; border: none;
  border-radius: 6px; cursor: pointer; font-size: 13px;
}
.new-chat-btn:hover { background: #4338ca; }
.classify-nav-btn {
  margin: 0 16px 12px; padding: 10px; background: transparent; color: #cdd6f4;
  border: 1px solid #45475a; border-radius: 6px; cursor: pointer; font-size: 13px;
}
.classify-nav-btn:hover { background: #313244; }
.classify-nav-btn.active { background: #45475a; border-color: #4f46e5; color: #fff; }
.conversations-list { flex: 1; overflow-y: auto; padding: 8px; }
.conv-item {
  padding: 10px 12px; border-radius: 6px; cursor: pointer; font-size: 13px;
  margin-bottom: 4px; display: flex; align-items: center; gap: 8px;
}
.conv-item:hover { background: #313244; }
.conv-item.active { background: #45475a; }
.conv-item .conv-title {
  flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.conv-item .delete-btn {
  display: none; background: none; border: none; color: #a6adc8; cursor: pointer;
  font-size: 14px; padding: 2px 4px; border-radius: 4px; flex-shrink: 0;
}
.conv-item:hover .delete-btn { display: block; }
.conv-item .delete-btn:hover { color: #f38ba8; background: #45475a; }
.conv-item .conv-date { font-size: 11px; color: #6c7086; }
.logout-btn {
  margin: 12px 16px; padding: 8px; background: transparent; color: #a6adc8;
  border: 1px solid #45475a; border-radius: 6px; cursor: pointer; font-size: 13px;
}
.logout-btn:hover { background: #313244; }

/* Chat main area */
.chat-main { flex: 1; display: flex; flex-direction: column; background: #fff; }
.chat-thread {
  flex: 1; display: flex; flex-direction: column; min-height: 0;
}
.chat-header {
  padding: 16px 24px; border-bottom: 1px solid #e5e7eb; font-size: 16px; font-weight: 600;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
/* EB360 connection status pill (top-right of chat header) */
.eb360-status {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px;
  background: #f3f4f6; border: 1px solid #e5e7eb; border-radius: 999px;
  font-size: 13px; font-weight: 500; color: #6b7280; cursor: pointer;
}
.eb360-status:hover { background: #e5e7eb; }
.eb360-status .eb360-dot {
  width: 8px; height: 8px; border-radius: 50%; background: #9ca3af; flex-shrink: 0;
}
.eb360-status.connected { color: #166534; background: #f0fdf4; border-color: #bbf7d0; }
.eb360-status.connected:hover { background: #dcfce7; }
.eb360-status.connected .eb360-dot { background: #22c55e; }

/* Modal */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex;
  align-items: center; justify-content: center; z-index: 100;
}
.modal {
  width: 380px; background: #fff; border-radius: 8px; padding: 28px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.2);
}
.modal h2 { font-size: 18px; margin-bottom: 6px; }
.modal p.subtitle { color: #666; font-size: 13px; margin-bottom: 18px; }
.modal label { display: block; font-size: 12px; color: #374151; margin-bottom: 4px; font-weight: 500; }
.modal input {
  width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 6px;
  font-size: 14px; margin-bottom: 14px; outline: none;
}
.modal input:focus { border-color: #4f46e5; }
.modal .error { color: #dc2626; font-size: 13px; margin-bottom: 12px; display: none; }
.modal .modal-actions { display: flex; gap: 10px; margin-top: 4px; }
.modal button {
  flex: 1; padding: 10px; border-radius: 6px; font-size: 14px; cursor: pointer; border: none;
}
.modal .btn-primary { background: #4f46e5; color: #fff; }
.modal .btn-primary:hover { background: #4338ca; }
.modal .btn-primary:disabled { background: #9ca3af; cursor: not-allowed; }
.modal .btn-secondary { background: #f3f4f6; color: #374151; border: 1px solid #e5e7eb; }
.modal .btn-secondary:hover { background: #e5e7eb; }
.modal .btn-danger { background: #fff; color: #dc2626; border: 1px solid #fecaca; }
.modal .btn-danger:hover { background: #fef2f2; }
.messages {
  flex: 1; overflow-y: auto; padding: 24px; display: flex; flex-direction: column; gap: 16px;
}

/* Room for the steps to grow into while a run is live. The run only scrolls
   once this headroom is used up. */
.messages.running {
  padding-bottom: 160px;
}
.message { max-width: 720px; line-height: 1.6; font-size: 14px; }
.message.user {
  align-self: flex-end; background: #4f46e5; color: #fff; padding: 10px 16px;
  border-radius: 16px 16px 4px 16px;
}
.message.assistant {
  align-self: flex-start; background: #f3f4f6; color: #1f2937; padding: 10px 16px;
  border-radius: 16px 16px 16px 4px;
}
.message.assistant pre {
  background: #e5e7eb; padding: 8px 12px; border-radius: 4px; overflow-x: auto;
  margin: 8px 0; font-size: 13px;
}
.message.assistant code {
  background: #e5e7eb; padding: 2px 5px; border-radius: 3px; font-size: 13px;
}
.message.assistant pre code {
  background: none; padding: 0;
}
.message.assistant h1, .message.assistant h2, .message.assistant h3 {
  margin: 12px 0 6px 0; line-height: 1.3;
}
.message.assistant h1 { font-size: 18px; }
.message.assistant h2 { font-size: 16px; }
.message.assistant h3 { font-size: 15px; }
.message.assistant p { margin: 6px 0; }
.message.assistant ul, .message.assistant ol {
  margin: 6px 0; padding-left: 20px;
}
.message.assistant li { margin: 3px 0; }
.message.assistant table {
  border-collapse: collapse; margin: 8px 0; width: 100%; font-size: 13px;
}
.message.assistant th, .message.assistant td {
  border: 1px solid #d1d5db; padding: 6px 10px; text-align: left;
}
.message.assistant th {
  background: #e5e7eb; font-weight: 600;
}
.message.assistant strong { font-weight: 600; }
.message.assistant hr { border: none; border-top: 1px solid #d1d5db; margin: 10px 0; }
.message.assistant blockquote {
  border-left: 3px solid #d1d5db; padding-left: 12px; margin: 6px 0; color: #6b7280;
}
.empty-state {
  flex: 1; display: flex; align-items: center; justify-content: center;
  color: #9ca3af; font-size: 15px;
}

@keyframes typing {
  0%, 60%, 100% { opacity: 0.3; transform: scale(0.8); }
  30% { opacity: 1; transform: scale(1); }
}

/* Applied only to a freshly streamed answer, so loading a conversation's
   history does not animate every message at once. */
.message.arriving {
  animation: message-in 340ms ease-out;
}

@keyframes message-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Agent progress */
.progress {
  --row-gap: 6px;
  --twist: 14px;
  display: flex;
  align-items: flex-start;
  gap: var(--row-gap);
  padding: 8px 16px;
  max-width: 720px;
  align-self: stretch;
  font-size: 13px;
  color: #6b7280;
  font-variant-numeric: tabular-nums;
}

/* Pulls back most of the 16px .messages gap so the summary sits just under
   the answer it belongs to. */
.progress.collapsed {
  display: block;
  padding: 0;
  margin-top: -12px;
}

.progress-rail {
  display: flex;
  align-items: center;
  height: 25px;
}

/* Height is set from JS and glides between values as rows come and go. Hidden
   overflow so a row on its way out is clipped rather than spilling. */
.progress-stage {
  flex: 1;
  overflow: hidden;
  transition: height 240ms ease;
}

.progress-branch {
  display: flex;
  align-items: center;
  gap: var(--row-gap);
  padding: 2px 0;
  /* The connectors hang off this box, so 50% of it is the line the caret and
     the label are already centred on. */
  position: relative;
  animation: branch-in 220ms ease-out;
}

/* A step row is one line. A long URL has no break opportunities, so left to
   itself it overruns and carries the mark past the end of the row; trailing it
   off keeps the mark against the text it belongs to. The full text is on the
   row's title. */
.progress-branch .label {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.progress-branch .tick,
.progress-branch .dur,
.progress-branch .count {
  flex: 0 0 auto;
}

.progress-branch .dur {
  color: #9ca3af;
  font-size: 0.667em;
}

.progress-branch .tick.found {
  color: #d97706;
}

.progress-branch .tick {
  color: #059669;
}

.progress-branch .tick.failed {
  color: #b91c1c;
}

/* Only an admin's mark carries the error, so only theirs invites a hover. */
.progress-branch .tick.failed[title] {
  cursor: help;
}

/* A step that ran and returned, carrying a finding the reviewer refused.
   Distinct from failed: nothing went wrong with the call. */
.progress-branch .tick.rejected {
  color: #b45309;
}


.progress-branch.queued .label {
  color: #b0b6c0;
}

/* A finished step leaving the live block, with whatever it ran beneath it. The
   height is set from JS to the row's own, then to zero, so the collapse takes
   the whole 200ms rather than snapping at the end of it. */
.progress-node.leaving {
  overflow: hidden;
  opacity: 0;
  transition: height 200ms ease-in, opacity 140ms ease-in;
}

.progress-node {
  position: relative;
}

.progress-children {
  padding-left: 18px;
}

/* The trunk running down past this row to its siblings. Scaled from a fixed
   origin to stay off the layout path. */
.progress-children > .progress-node::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: #d1d5db;
  transform-origin: top center;
  animation: trunk-draw 200ms ease-out;
}

/* A last child closes the branch, so its trunk stops where the stub meets it.
   Both are drawn on the row rather than the node: the caret beside them is
   centred in the row by flexbox, and 50% of the row is that same line — a
   fixed offset only ever matches it by luck. */
.progress-children > .progress-node.last::before {
  display: none;
}

.progress-children > .progress-node.last > .progress-branch::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 0;
  height: 50%;
  width: 1px;
  background: #d1d5db;
  transform-origin: top center;
  animation: trunk-draw 200ms ease-out;
}

.progress-children > .progress-node > .progress-branch::after {
  content: '';
  position: absolute;
  left: -10px;
  top: 50%;
  width: 7px;
  height: 1px;
  background: #d1d5db;
  transform-origin: left center;
  /* `backwards` so it waits out the delay undrawn, not fully drawn. */
  animation: stub-draw 140ms ease-out 120ms backwards;
}

/* Withdrawn in the order they were drawn, inside BRANCH_OUT_MS (progress.js). */
.progress-children > .progress-node.leaving > .progress-branch::after {
  animation: stub-draw 90ms ease-in reverse forwards;
}

.progress-children > .progress-node.leaving::before,
.progress-children > .progress-node.leaving > .progress-branch::before {
  animation: trunk-draw 110ms ease-in 40ms reverse forwards;
}

/* Fixed width so a leaf's label lines up with a sibling that has a twist, and
   square so centring it is symmetric in both directions. */
.progress-twist {
  width: var(--twist);
  height: var(--twist);
  flex: 0 0 var(--twist);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #9ca3af;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Drawn rather than typed. A glyph sits on the font's baseline, so its ink
   centre is not the button's centre and the connector meets it only by luck of
   the font. This triangle is symmetric about its own box, and the box is
   centred on the row — the same 50% the stub is drawn at. */
.progress-twist::before {
  content: '';
  width: 0;
  height: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 5px solid currentColor;
  transition: transform 160ms ease;
}

.progress-twist[aria-expanded='true']::before {
  transform: rotate(90deg);
}

.progress-twist:hover {
  color: #374151;
}

.progress-node.leaf > .progress-branch {
  padding-left: calc(var(--twist) + var(--row-gap));
}

.progress-branch .count {
  color: #9ca3af;
  font-size: 0.667em;
}

.progress-dots {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.progress-dots span {
  width: 5px;
  height: 5px;
  background: #9ca3af;
  border-radius: 50%;
  animation: typing 1.4s infinite ease-in-out;
}

.progress-dots span:nth-child(2) {
  animation-delay: 0.2s;
}

.progress-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

/* A top-level step is the slow one — it is the whole of what is happening, and
   it outlives every substep under it. Substeps keep the quicker rate, and each
   row's animation runs from when it went pending, not from the last redraw. */
/* The gradient tiles — both ends are the base colour — and one cycle moves it
   by exactly one tile, so every cycle is a single even sweep. The old band ran
   off the end and left the text flat for half the cycle, which read as the
   shimmer stopping partway and starting again. */
.progress-branch.pending .label {
  background-image: linear-gradient(
    90deg,
    var(--shimmer-base) 0%,
    var(--shimmer-lift) 50%,
    var(--shimmer-base) 100%
  );
  background-size: 200% 100%;
  background-repeat: repeat-x;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shimmer var(--shimmer-rate) linear infinite;
}

.progress {
  --shimmer-base: #9ca3af;
  --shimmer-lift: #e5e7eb;
  --shimmer-rate: 3.2s;
}

/* Quieter the further down you go: a substep is detail under a step, not a
   peer of it. */
.progress-children {
  --shimmer-base: #b6bcc6;
  --shimmer-lift: #eceef1;
  --shimmer-rate: 2s;
}

.progress-children .progress-branch .label {
  color: #949aa5;
}

@keyframes shimmer {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -200% 0;
  }
}

.progress-summary {
  background: none;
  border: none;
  padding: 2px 8px;
  cursor: pointer;
  font: inherit;
  color: #6b7280;
  text-align: left;
}

.progress-summary:hover {
  color: #374151;
}

.progress-detail {
  padding-left: 16px;
}

.progress-error {
  color: #b91c1c;
  padding: 4px 0;
}

@keyframes trunk-draw {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}

@keyframes stub-draw {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* Down rather than in from the left: the stage clips its overflow, so a row
   arriving sideways is clipped on the way. */
@keyframes branch-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .progress-branch {
    animation: none;
  }
  .progress-node.leaving {
    animation: none;
    transition: none;
  }
  /* Including the reversed ones, which would otherwise stick at scale 0. */
  .progress-children > .progress-node::before,
  .progress-children > .progress-node.leaving::before,
  .progress-children > .progress-node > .progress-branch::before,
  .progress-children > .progress-node > .progress-branch::after,
  .progress-children > .progress-node.leaving > .progress-branch::before,
  .progress-children > .progress-node.leaving > .progress-branch::after {
    animation: none;
  }
  .progress-stage {
    transition: none;
  }
  .message.arriving {
    animation: none;
  }
  .progress-dots span {
    animation: none;
  }
  .question-dock.question-dock-closing {
    transition: none;
  }
  .progress-branch.pending .label {
    animation: none;
    background: none;
    -webkit-text-fill-color: #6b7280;
  }
}

/* Input area */
.input-area {
  padding: 16px 24px; border-top: 1px solid #e5e7eb; display: flex; gap: 12px;
}
.input-area input {
  flex: 1; padding: 10px 16px; border: 1px solid #d1d5db; border-radius: 8px;
  font-size: 14px; outline: none;
}
.input-area input:focus { border-color: #4f46e5; }
.input-area button {
  padding: 10px 20px; background: #4f46e5; color: #fff; border: none;
  border-radius: 8px; cursor: pointer; font-size: 14px;
}
.input-area button:hover { background: #4338ca; }
.input-area button:disabled { background: #9ca3af; cursor: not-allowed; }

/* Settings (cog) menu in the sidebar header */
.settings-menu { position: relative; flex-shrink: 0; }
.settings-btn {
  background: none; border: none; color: #a6adc8; font-size: 18px;
  cursor: pointer; padding: 4px 6px; border-radius: 6px; line-height: 1;
}
.settings-btn:hover { background: #313244; color: #cdd6f4; }
.settings-dropdown {
  position: absolute; right: 0; top: 34px; background: #313244;
  border: 1px solid #45475a; border-radius: 6px; min-width: 170px; padding: 4px;
  z-index: 20; box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.settings-dropdown a {
  display: block; padding: 8px 10px; font-size: 13px; color: #cdd6f4;
  cursor: pointer; border-radius: 4px; text-decoration: none;
}
.settings-dropdown a:hover { background: #45475a; }

/* Report screen ---------------------------------------------------------- */
/* The rating is presented as proposed rather than decided: the goal this
   serves ends "at an initial risk rating that a person owns", so the screen
   must not read as a verdict already reached. */

.report-rating {
  border: 1px solid #d8dce3;
  border-left: 6px solid #7a8699;
  border-radius: 6px;
  padding: 16px 20px;
  margin-bottom: 24px;
  background: #fbfbfc;
}

.report-band-label {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6b7280;
}

.report-band {
  font-size: 26px;
  font-weight: 600;
  margin: 4px 0 6px;
}

.report-rating.band-1 { border-left-color: #2f7a46; }
.report-rating.band-2 { border-left-color: #5a9e3f; }
.report-rating.band-3 { border-left-color: #b39100; }
.report-rating.band-4 { border-left-color: #d1802b; }
.report-rating.band-5 { border-left-color: #c4552a; }
.report-rating.band-6 { border-left-color: #a02020; }
.report-rating.unscored { border-left-color: #9aa1ac; }

.report-note {
  color: #6b7280;
  font-size: 13px;
  margin: 0;
}

.report-summary { margin: 0 0 24px; line-height: 1.55; }

.report-signal,
.report-finding {
  border-top: 1px solid #eceef1;
  padding: 12px 0;
}

.report-signal-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}

.report-signal-name,
.report-finding-name { font-weight: 600; }

.report-signal-band {
  font-size: 13px;
  white-space: nowrap;
  color: #444;
}

.report-signal-band.band-5,
.report-signal-band.band-6 { color: #a02020; }

.report-signal-why,
.report-finding-account {
  margin: 6px 0 0;
  color: #333;
  line-height: 1.5;
}

/* A step that established nothing stays in place and stays legible — it is
   greyed, not hidden, because the difference between checked-and-empty and
   never-ran is most of what the report is worth. */
.report-finding.unestablished .report-finding-account { color: #6b7280; }

/* Citations sit at the end of the sentence they support, as numbers. The
   URLs they stand for are gathered once under References: the same source
   backs several findings, and printed in full each time it buried the prose
   it was meant to support. */
.report-cites { margin-left: 3px; }

.report-cite {
  font-size: 10.5px;
  vertical-align: super;
  line-height: 0;
  margin-left: 1px;
  padding: 0 1px;
  color: #2f6fe4;
  font-weight: 600;
  text-decoration: none;
  border-radius: 2px;
  white-space: nowrap;
}

.report-cite:hover { background: #e4ecfb; }

.report-references {
  margin: 0;
  padding-left: 22px;
  color: #4b5563;
  font-size: 12.5px;
  line-height: 1.6;
}

.report-references li { margin: 3px 0; }
.report-references a { color: #3b6fb0; text-decoration: none; }
.report-references a:hover { text-decoration: underline; }

/* The full URL stays available to copy, but it is not what the eye lands on:
   the host is. It runs on from the host as ordinary prose and wraps like it,
   breaking mid-URL only where it has to — a URL is one long unbroken word, so
   without this a single reference pushes the list sideways. */
.report-ref-url {
  color: #9aa1ac;
  overflow-wrap: anywhere;
}

/* A cited reference, having just been jumped to. */
.report-references li:target { background: #f4f7fc; }

.report-gaps { margin: 0; padding-left: 20px; color: #4b5563; line-height: 1.7; }

.report-loading, .report-error { color: #6b7280; }

/* The foot of an answer, opening the report -------------------------------
   Bled out to the bubble's own edges so the answer and its rating read as one
   message in two parts, rather than as a second message nobody sent. The rule
   and the change of ground carry the separation that a gap used to. */

.report-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 12px -16px -10px;
  padding: 12px 16px;
  border-top: 1px solid #dcdfe6;
  /* Matches the bubble's own bottom corners, including the clipped one. */
  border-radius: 0 0 16px 4px;
  background: #e6e8ed;
}

.report-card-text { display: flex; flex-direction: column; gap: 2px; }
.report-card-band { font-weight: 600; }
.report-card-band.unscored { color: #6b7280; font-weight: 500; }
.report-card-subject { font-size: 13px; color: #6b7280; }

.report-card-btn {
  padding: 6px 14px;
  border: 1px solid #c6ccd6;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  white-space: nowrap;
}

.report-card-btn:hover { background: #f1f3f6; }

/* The report reads denser than the chat around it: it is a document someone
   works through, not a message they glance at. */
#report-screen .admin-content { font-size: 14px; line-height: 1.55; }
#report-screen h3 { font-size: 15px; margin: 28px 0 4px; }
#report-screen .report-note { font-size: 12.5px; }
#report-screen .report-band { font-size: 24px; }
#report-screen .report-summary { font-size: 14.5px; }
#report-screen .report-sources a { font-size: 11.5px; }
/* The collapsed panel pulls itself up under a chat answer. Here it follows a
   note, and has its own room. */
#report-screen .progress.collapsed { margin-top: 6px; }

/* Quiet until wanted: one of these sits on the rating, every signal and every
   finding, and at full strength they would read as the point of the page. */
.report-explain {
  display: inline-block;
  margin-top: 8px;
  padding: 3px 9px;
  font: inherit;
  font-size: 11.5px;
  color: #6b7280;
  background: transparent;
  border: 1px solid #d8dce2;
  border-radius: 999px;
  cursor: pointer;
}

.report-explain:hover {
  color: #1f2937;
  border-color: #b6bcc6;
  background: #f7f8fa;
}

.report-rating .report-explain { margin-top: 12px; }

.report-signal-weight {
  display: block;
  font-size: 11.5px;
  color: #8a93a0;
  margin-top: 2px;
}

/* What the client told us. A column per batch of questions, which happen to be
   even, so the grid fills rather than leaving an orphan cell. Laid out apart
   from the researched signals because there is no reasoning to read: the answer
   is the whole of the explanation, and a block sized for prose spends a screen
   on three words. */
.declared-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 28px;
}

.declared-group {
  display: grid;
  grid-template-rows: auto;
  grid-auto-rows: 1fr;
  min-width: 0;
}

.declared-group-name {
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6b7280;
  padding-bottom: 6px;
  border-bottom: 1px solid #d8dce3;
}

/* The band as a rule down the side, which is how the overall rating already
   carries one. Colour is the only thing distinguishing the twelve at a glance,
   and the alternative — a coloured chip per item — competes with the rating
   block at the top of the same screen. */
.declared-item {
  display: flex;
  flex-direction: column;
  border-top: 1px solid #eceef1;
  border-left: 3px solid #cfd4dc;
  padding: 10px 0 10px 10px;
}

.declared-group-name + .declared-item { border-top: none; }

.declared-item.band-1 { border-left-color: #2f7a46; }
.declared-item.band-2 { border-left-color: #5a9e3f; }
.declared-item.band-3 { border-left-color: #b39100; }
.declared-item.band-4 { border-left-color: #d1802b; }
.declared-item.band-5 { border-left-color: #c4552a; }
.declared-item.band-6 { border-left-color: #a02020; }

.declared-label { font-size: 12.5px; color: #6b7280; }
.declared-answer { font-weight: 600; margin-top: 1px; }

/* Greyed rather than hidden, for the same reason an unestablished finding is:
   a question nobody answered and an answer that scored low must not look alike. */
.declared-item.unanswered { border-left-style: dashed; }
.declared-item.unanswered .declared-answer { font-weight: 400; color: #8a93a0; }
.declared-item.unscored .declared-band { color: #8a93a0; }

.report-record {
  display: grid;
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  gap: 0;
  margin: 0;
}
.report-record dt,
.report-record dd {
  border-top: 1px solid #eceef1;
  margin: 0;
  padding: 8px 0;
}
.report-record dt { color: #6b7280; font-size: 13px; }
.report-record dd { font-weight: 600; }

@media (max-width: 560px) {
  .report-record { grid-template-columns: minmax(0, 1fr); }
  .report-record dd { border-top: none; padding-top: 0; }
}

.declared-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  margin-top: auto;
  padding-top: 4px;
}

.declared-band { font-size: 13px; color: #444; white-space: nowrap; }
.declared-band.band-5,
.declared-band.band-6 { color: #a02020; }
.declared-weight { font-size: 11.5px; color: #8a93a0; }

/* Two columns before the answers start wrapping to three lines, then one. */
@media (max-width: 1000px) {
  .declared-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; }
  .declared-group { margin-bottom: 18px; }
}

@media (max-width: 560px) {
  .declared-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Where a run puts a question it needs answered, directly above the box you
   answer it in. It keeps the sides the conversation already uses — the question
   on the assistant's, the answer forming on the user's — because an answer
   typed into the composer would read as a new turn. */
.question-dock:empty {
  display: none;
}

.question-dock {
  border-top: 1px solid #e5e7eb;
  padding: 14px 24px 12px;
  background: #fff;
  /* The height is driven from JS and the contents keep their natural size, so
     what changes is how much of them shows. Laying the boxes out again on every
     frame is what put the jitter on their borders. */
  overflow: hidden;
}

/* The height is animated from JS, in whole pixels. Only the fade is left to
   CSS, which does not touch layout and so cannot shear against the scroll. */
.question-dock.question-dock-closing {
  opacity: 0;
  -webkit-mask-image: linear-gradient(
    to bottom, #000 0, #000 calc(100% - 30px), transparent 100%
  );
  mask-image: linear-gradient(
    to bottom, #000 0, #000 calc(100% - 30px), transparent 100%
  );
  transition: opacity 260ms ease-in;
}

/* The dock owns the height; the block only ever sits at its natural size. Two
   motions on the same pixels would fight each other. */
.relationship-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
}


.relationship-ask {
  border-left: 3px solid #4f46e5;
}

.relationship-form {
  align-self: flex-end;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  max-width: 720px;
  padding: 12px 14px;
  /* Dashed, and the user's colour only as an outline: nothing has been said
     yet, and a solid bubble would put words in their mouth. */
  border: 1px dashed #a5b4fc;
  border-radius: 16px 16px 4px 16px;
  background: #f8f8ff;
}

.relationship-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.relationship-label {
  font-size: 12.5px;
  color: #4b5563;
  white-space: nowrap;
}

.relationship-select {
  font: inherit;
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background: #fff;
  color: #1f2937;
  max-width: 340px;
}

.relationship-send {
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 6px 16px;
  border: none;
  border-radius: 8px;
  background: #4f46e5;
  color: #fff;
  cursor: pointer;
}

.relationship-send:disabled {
  background: #c7d2fe;
  cursor: default;
}

.relationship-send:not(:disabled):hover { background: #4338ca; }

.relationship-status {
  align-self: flex-end;
  font-size: 12px;
  color: #b91c1c;
}

.relationship-status:empty { display: none; }

/* The answered state of the same bubble. It replaces the controls in place
   rather than appearing elsewhere, so the answer stays where it was given and
   the page does not jump as the form goes. */
.relationship-form.relationship-form-done {
  border-style: solid;
  border-color: #c7d2fe;
  background: #eef2ff;
  transition: background 220ms ease, border-color 220ms ease;
}

.relationship-ack {
  font-size: 12.5px;
  line-height: 1.5;
  color: #3730a3;
  animation: relationship-ack-in 220ms ease-out both;
}

@keyframes relationship-ack-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Industry classification form (demo surface, same tool as chat) */
.classify-panel {
  flex: 1; overflow-y: auto; padding: 24px; min-height: 0;
}
.classify-body { max-width: 640px; }
.classify-intro {
  color: #4b5563; font-size: 14px; line-height: 1.5; margin-bottom: 20px;
}
.classify-intro code {
  font-size: 12px; background: #eef2ff; color: #3730a3;
  padding: 1px 5px; border-radius: 4px;
}
.classify-body label {
  display: block; font-size: 13px; font-weight: 600; color: #374151; margin-bottom: 6px;
}
.classify-optional { font-weight: 400; color: #6b7280; }
.classify-body input[type="text"] {
  width: 100%; padding: 10px 12px; border: 1px solid #d1d5db; border-radius: 8px;
  font-size: 14px; outline: none; margin-bottom: 6px;
}
.classify-body input[type="text"]:focus { border-color: #4f46e5; }
.classify-hint { color: #6b7280; font-size: 12px; margin-bottom: 14px; line-height: 1.4; }
.classify-fieldset {
  border: none; padding: 0; margin: 0 0 16px;
}
.classify-fieldset legend {
  font-size: 13px; font-weight: 600; color: #374151; margin-bottom: 8px;
}
.classify-taxonomies { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.classify-taxonomies label {
  display: flex; align-items: flex-start; gap: 10px; margin: 0;
  padding: 10px 12px; border: 1px solid #e5e7eb; border-radius: 8px;
  cursor: pointer; font-weight: 500;
}
.classify-taxonomies label:has(input:checked) {
  border-color: #4f46e5; background: #eef2ff;
}
.classify-taxonomies input { margin-top: 3px; }
.classify-tax-label { display: block; }
.classify-tax-vintage { display: block; font-size: 12px; font-weight: 400; color: #6b7280; }
.classify-body button[type="submit"] {
  padding: 10px 20px; background: #4f46e5; color: #fff; border: none;
  border-radius: 8px; cursor: pointer; font-size: 14px;
}
.classify-body button[type="submit"]:hover { background: #4338ca; }
.classify-body button[type="submit"]:disabled { background: #9ca3af; cursor: not-allowed; }
.classify-status {
  margin-top: 16px; color: #4338ca; font-size: 13px; background: #eef2ff;
  border-radius: 8px; padding: 10px 12px;
}
.classify-error { margin-top: 16px; color: #dc2626; font-size: 13px; }
.classify-result { margin-top: 20px; }
.classify-card {
  border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px 20px;
  background: #f9fafb;
}
.classify-card + .classify-card { margin-top: 16px; }
.classify-badge {
  display: inline-block; font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
  text-transform: uppercase; padding: 3px 8px; border-radius: 999px; margin-bottom: 10px;
}
.classify-badge-classified { background: #dcfce7; color: #166534; }
.classify-badge-unclassified { background: #fef3c7; color: #92400e; }
.classify-badge-error { background: #fee2e2; color: #991b1b; }
.classify-badge-unscored { background: #e5e7eb; color: #374151; }
.classify-badge-low { background: #dcfce7; color: #166534; }
.classify-badge-medium { background: #fef3c7; color: #92400e; }
.classify-badge-high { background: #ffedd5; color: #9a3412; }
.classify-badge-critical { background: #fee2e2; color: #991b1b; }
.classify-code { font-size: 28px; font-weight: 700; color: #111827; letter-spacing: -0.02em; }
.classify-label { font-size: 15px; color: #1f2937; margin-top: 4px; line-height: 1.4; }
.classify-meta { font-size: 12px; color: #6b7280; margin-top: 8px; }
.classify-reasoning {
  margin-top: 14px; font-size: 13px; color: #374151; line-height: 1.55;
  border-top: 1px solid #e5e7eb; padding-top: 12px;
}
.classify-breakdown {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid #e5e7eb;
  display: grid; gap: 6px;
}
.classify-breakdown > div {
  display: grid; grid-template-columns: minmax(8em, 40%) 1fr; gap: 8px;
  font-size: 12px;
}
.classify-breakdown dt { color: #6b7280; font-weight: 500; }
.classify-breakdown dd { margin: 0; color: #111827; }
