/* ═══════════════════════════════════════════════════════════════════════════
   ATLAS — the Hub assistant
   ═══════════════════════════════════════════════════════════════════════════

   Everything the chat widget and its admin screen look like, in one file.

   Split out of style.css so Atlas can be deployed on its own. Sharing the Hub's
   stylesheet meant every release had to carry a 1.6MB file that everything else
   also writes to, so a deploy either clobbered an unrelated change or had to be
   merged by hand. This file is Atlas's alone.

   Loaded from inc/global/header.php, so it is on every page in the Hub — which
   is exactly why the rule below matters.

   Nothing here may style anything outside Atlas. Two rules once did — the
   jquery-confirm dialog and form.is-busy — and both reached the whole Hub,
   because a class alone is not a scope. Prefix with .ha-, .assistant-admin or
   body.ha-confirming.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
   HUB ASSISTANT — chat widget  (inc/global/assistant-widget.php)
   ═══════════════════════════════════════════════════════════════════════════ */

.ha-root {
  position: fixed;
  right: 22px; bottom: 22px;
  z-index: 1080;              /* above Bootstrap modals (1055) so it stays reachable */
  font-family: 'Poppins', -apple-system, system-ui, sans-serif;
}

/* ── Launcher ────────────────────────────────────────────────────────────── */
/* Orange, alone on the page. Everything else in the Hub is navy or green, so the
   one control that has to be findable from any screen is the one colour nothing
   else uses. */
.ha-launcher-arc {
  position: absolute;
  /* Centred on the button, not on the container's edge: .ha-root is only as wide
     as the launcher, so 50% is the button's midpoint. */
  /* Sized and offset so the SVG's arc centre lands exactly on the button's
     centre: the button's midpoint is 29px up from the root's base, and the arc
     centre sits 8px above the SVG's own base. */
  left: 50%; bottom: 21px;
  width: 160px; height: 90px;
  transform: translateX(-50%);
  transform-origin: 50% 100%;
  overflow: visible;
  pointer-events: none;
  transition: opacity .18s, transform .18s;
}
.ha-launcher-arc text {
  font-family: 'Poppins', -apple-system, system-ui, sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .02em;
  fill: var(--primary-color, #1F3665);
  /* A soft halo so it stays readable over whatever the page puts behind it,
     without needing a solid plate that would look like a second button. */
  paint-order: stroke fill;
  stroke: rgba(255,255,255,.94);
  /* 3px, not 4: a heavier halo starts to close the gaps between letters and the
     word turns into a white smear at small sizes. */
  stroke-width: 3px;
  stroke-linejoin: round;
}

/* Once, shortly after arrival, and never again. A launcher that pulses forever
   is a launcher people learn to ignore — and on a clinical platform a permanent
   moving object in the corner is an irritation, not an invitation. */
@keyframes ha-launcher-notice {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-3px) scale(1.05); }
}
.ha-launcher { animation: ha-launcher-notice .9s ease 1.2s 1; }
.ha-root.is-open .ha-launcher { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .ha-launcher { animation: none; }
  .ha-launcher, .ha-launcher::after, .ha-launcher-arc { transition: none; }
}
.ha-root.is-open .ha-launcher-arc { opacity: 0; transform: translateX(-50%) translateY(5px) scale(.96); }


.ha-launcher {
  position: relative;
  width: 58px; height: 58px;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: linear-gradient(140deg, #FBA23D 0%, #F07B22 55%, #E2650F 100%);
  color: #fff; font-size: 23px; cursor: pointer;
  /* Three layers doing three jobs: a tight contact shadow so it sits on the
     page rather than floating above it, a wider tinted one for lift, and an
     inset highlight so the sphere reads as lit from above instead of flat. */
  box-shadow:
    0 1px 2px rgba(20,38,66,.20),
    0 8px 22px rgba(226,101,15,.34),
    inset 0 1px 0 rgba(255,255,255,.34);
  transition: transform .18s cubic-bezier(.2,.8,.3,1), box-shadow .18s;
}

/* A quiet ring that grows on hover. Drawn on a pseudo-element so it can sit
   outside the button without nudging anything in the layout. */
.ha-launcher::after {
  content: '';
  position: absolute; inset: -4px;
  border-radius: 50%;
  border: 2px solid rgba(240,123,34,.28);
  opacity: 0;
  transform: scale(.9);
  transition: opacity .18s, transform .18s;
  pointer-events: none;
}
.ha-launcher:hover::after { opacity: 1; transform: scale(1); }
.ha-launcher:hover {
  transform: translateY(-2px) scale(1.03);
  box-shadow:
    0 2px 4px rgba(20,38,66,.20),
    0 14px 30px rgba(226,101,15,.42),
    inset 0 1px 0 rgba(255,255,255,.4);
}
/* A press should feel like a press. */
.ha-launcher:active { transform: translateY(0) scale(.97); transition-duration: .08s; }
.ha-launcher:focus-visible { outline: 3px solid var(--primary-color, #1F3665); outline-offset: 3px; }
.ha-launcher-close { display: none; }
.ha-root.is-open .ha-launcher-open  { display: none; }
.ha-root.is-open .ha-launcher-close { display: inline; font-size: 18px; }
/* Closing is a different act from opening, and the colour should stop shouting
   once the panel it points at is already open. */
.ha-root.is-open .ha-launcher {
  background: linear-gradient(135deg, #2C4E86 0%, #17294B 100%);
  box-shadow: 0 6px 22px rgba(23,41,75,.34);
}

/* ── Panel ───────────────────────────────────────────────────────────────── */
.ha-panel {
  position: absolute;
  right: 0; bottom: 70px;
  width: min(400px, calc(100vw - 32px));
  height: min(640px, calc(100vh - 130px));
  display: flex; flex-direction: column;
  background: #fff;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 18px 54px rgba(20,38,66,.22), 0 2px 8px rgba(20,38,66,.08);
}

.ha-head {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 15px;
  background: linear-gradient(135deg, #14324F 0%, #0E2740 55%, #0F3D2E 100%);
  color: #fff;
}
.ha-head-text { min-width: 0; flex: 1 1 auto; line-height: 1.3; }
.ha-head-text b { display: block; font-size: 14.5px; font-weight: 600; }
.ha-head-text span { font-size: 11.5px; color: rgba(255,255,255,.62); }
.ha-avatar {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: rgba(255,255,255,.14);
  color: #6FE0AC; font-size: 15px;
}
.ha-avatar.lg { width: 38px; height: 38px; font-size: 17px; background: rgba(60,194,135,.13); }
.ha-newchat {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
  height: 30px; padding: 0 11px;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 8px;
  background: rgba(255,255,255,.10);
  color: rgba(255,255,255,.88);
  font: inherit; font-size: 11.5px; font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background .14s, border-color .14s, color .14s;
}
.ha-newchat i { font-size: 11px; }
.ha-newchat:hover { background: rgba(255,255,255,.2); border-color: rgba(255,255,255,.3); color: #fff; }
.ha-newchat:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 2px; }

/* Below ~360px the label would push the title out; the icon alone still works
   because the confirmation that follows says what it does. */
@media (max-width: 359px) {
  .ha-newchat span { display: none; }
  .ha-newchat { padding: 0 9px; }
}

/* ── Message log ─────────────────────────────────────────────────────────── */
.ha-log {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;   /* scrolling the thread must not scroll the page */
  padding: 16px 14px;
  background: #F6F8FC;
  /* Smaller than body copy on purpose: a 400px column shows very few words per
     line, and at 13.5px a normal answer needed scrolling before it could be
     read. The page override below takes it back up, where there is room. */
  font-size: 12.5px;
  line-height: 1.55;
}
/* A thin scrollbar, so the thread does not lose 15px of width to system chrome. */
.ha-log::-webkit-scrollbar { width: 8px; }
.ha-log::-webkit-scrollbar-thumb { background: #D7DFE9; border-radius: 8px; border: 2px solid #F6F8FC; }
.ha-log::-webkit-scrollbar-thumb:hover { background: #C2CDDB; }

/* Centred vertically, the way ChatGPT does it — an empty panel with a line of
   text stranded at the top reads as something failing to load.
   Centring is done on the log itself rather than by giving the greeting
   min-height:100%: a percentage height inside a scrolling flex child resolves
   inconsistently, whereas justify-content on the container always holds. Once a
   message arrives the greeting is removed and the log returns to normal flow. */
.ha-log:has(.ha-greeting), .ha-log:has(.ha-loading) { display: flex; flex-direction: column; justify-content: center; }
.ha-greeting {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 10px 6px 18px;
}
.ha-greeting-title { margin: 12px 0 0; font-size: 15.5px; font-weight: 600; color: var(--primary-color, #1F3665); }
.ha-greeting-sub { margin: 6px 0 0; max-width: 32ch; font-size: 12.5px; line-height: 1.5; color: #7C899A; }

/* Starters double as a scope hint — they are drawn from what is actually
   indexed, so a suggestion can never be something it cannot answer. */
/* One row that scrolls, rather than a grid that grows downward.
   In a 400px panel a third card would push the composer off the bottom, and
   stacking them turns a few examples into a menu of commands. Sideways, the
   panel stays the same height however many are configured. */
.ha-starters {
  display: flex;
  gap: 8px;
  width: 100%;
  margin-top: 18px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Bleeds to the panel edges so a half-visible card says "there is more",
     rather than ending flush and looking like the last one. */
  margin-left: -14px; margin-right: -14px;
  padding: 2px 14px 8px;
  scrollbar-width: thin;
  scrollbar-color: #D7DFE9 transparent;
}
.ha-starters::-webkit-scrollbar { height: 5px; }
.ha-starters::-webkit-scrollbar-thumb { background: #D7DFE9; border-radius: 5px; }
.ha-starters::-webkit-scrollbar-track { background: transparent; }

/* The same width a half-of-two grid column used to be — 400px panel, less 14px
   of padding each side and an 8px gap. Keeping it means adding a third card
   changes what is reachable, not how the first two look. */
.ha-starters > .ha-starter {
  flex: 0 0 auto;
  width: 178px;
  scroll-snap-align: start;
}
/* One or two fit without scrolling, so they share the row properly instead of
   sitting at two-thirds width with a gap beside them. */
/* One or two fit without scrolling, so they share the row exactly as the grid
   did rather than sitting at a fixed width with a gap beside them. */
.ha-starters.is-single > .ha-starter { width: 100%; max-width: 280px; margin: 0 auto; }
.ha-starters.is-pair > .ha-starter { flex: 1 1 0; width: auto; }

.ha-starter {
  display: flex; flex-direction: column; gap: 3px;
  border: 1px solid #E2E9F2; background: #fff; border-radius: 11px;
  padding: 11px 13px; font: inherit; line-height: 1.4;
  color: var(--primary-color, #1F3665); text-align: left; cursor: pointer;
  transition: border-color .14s, background .14s, transform .12s;
}
.ha-starter b { font-size: 12.5px; font-weight: 600; }
.ha-starter span {
  font-size: 11.5px; color: #8A97A8;
  /* Two lines at most: the card is a prompt to click, not something to read in
     full — the whole question goes into the box either way. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ha-starter:hover { border-color: var(--green-color, #4ac186); background: #F6FBF8; transform: translateY(-1px); }
.ha-starter:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 1px; }

/* ── Messages ────────────────────────────────────────────────────────────── */
.ha-msg { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 14px; }
.ha-msg--user { flex-direction: row-reverse; }
/* Runs from the same speaker tighten up and drop the repeated avatar. */
.ha-msg.is-run { margin-top: -8px; }
.ha-msg.is-run .ha-msg-avatar { visibility: hidden; }

.ha-msg-avatar {
  flex: 0 0 auto;
  width: 26px; height: 26px; margin-top: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: rgba(60,194,135,.14);
  color: #2E9E6B; font-size: 12px;
}
.ha-msg-body { min-width: 0; max-width: 84%; display: flex; flex-direction: column; }
.ha-msg--user .ha-msg-body { align-items: flex-end; }

.ha-bubble {
  padding: 9px 12px;
  border-radius: 11px;
  background: #fff;
  border: 1px solid #E7ECF3;
  color: #37475F;
  overflow-wrap: anywhere;        /* a pasted URL must not widen the panel */
  box-shadow: 0 1px 2px rgba(20,38,66,.04);
}
/* ── Formatting inside a reply ────────────────────────────────────────────────
   The model writes Markdown whether asked to or not, so a small subset is
   rendered rather than shown as syntax. Spacing is tighter than browser defaults
   throughout: this is a 400px column, not an article. */
.ha-bubble p { margin: 0; }
.ha-bubble p + p { margin-top: .62em; }

.ha-bubble strong { font-weight: 600; color: var(--primary-color, #1F3665); }
.ha-bubble em     { font-style: italic; }
.ha-bubble del    { opacity: .65; }
.ha-bubble code {
  padding: 1px 5px;
  border-radius: 4px;
  background: #EEF2F7;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .88em;
  color: #37475F;
  overflow-wrap: anywhere;
}

/* A heading in a chat bubble does not want to be bigger, only firmer. */
.ha-bubble .ha-lead { font-weight: 600; color: var(--primary-color, #1F3665); }
.ha-bubble .ha-lead + * { margin-top: .35em; }

/* ── When a message was sent ──────────────────────────────────────────────
   Quiet by default and only fully legible on hover: in a thread you are reading,
   the time is reference, not content. The absolute stamp sits in the title. */
.ha-time {
  display: flex; align-items: center; gap: 3px;
  /*
   * Only as wide as its own text, pushed right by the auto margin.
   *
   * justify-content did the same job visually but left the element spanning the
   * full width of the bubble — so the tooltip, which centres on what it is
   * describing, appeared in the middle of the message instead of above the
   * time. Shrinking the box is what makes the tooltip land in the right place.
   */
  width: fit-content;
  margin: 6px 0 0 auto;
  font-size: 10px; line-height: 1.4; color: #A9B4C1;
  font-variant-numeric: tabular-nums; cursor: default;
  transition: color .15s ease;
}
.ha-time .bi { font-size: 9.5px; opacity: .85; }
.ha-msg:hover .ha-time { color: #7C8899; }
/* Inside the rate row it shares the line with the thumbs, pushed to the far end
   by the auto margin rather than by a width. */
.ha-rate .ha-time { margin: 0 0 0 auto; }

/* ── Message the team, from the welcome screen ───────────────────────────
   Under the suggestions rather than among them: a card would put "I need a
   human" in competition with the questions Atlas can actually answer. */
/* The same box .ha-starters resolves to, so the button and the cards share an
   edge: 100% wide, bled 14px each side, then padded back. */
.ha-tosupport-wrap {
  width: 100%; box-sizing: border-box;
  /* Close to the cards above: it is the last option in the same set, not a
     separate section. .ha-starters already pads 8px below itself for its
     scrollbar, so this only needs a little on top of that. */
  margin: 2px -14px 0; padding: 0 14px;
}
/* No cards above it, so nothing is providing the gap.
   .ha-starters carried margin-top:18px, and with it gone the button sat 2px
   under the greeting — reading as part of the sentence rather than a control
   below it. This restores that 18px, and only in that case. */
.ha-tosupport-wrap.is-alone { margin-top: 18px; }
.ha-tosupport {
  display: flex; align-items: center; justify-content: center; gap: 11px;
  /* Same padding, radius and line-height as .ha-starter, so it reads as part of
     the same set rather than a different component that happens to sit below. */
  width: 100%; padding: 11px 13px; line-height: 1.4;
  border: 1px dashed #CDD8E6; border-radius: 11px;
  /* A tint rather than white: white would make it a third card competing with
     the two suggestions above, and transparent left it the faintest thing on an
     already pale panel. This sits a step darker than the log behind it, so it
     reads as a different kind of control. */
  background: #EBF0F7; color: #8A97A8;
  font-family: inherit; font-size: 12.5px; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.ha-tosupport:hover {
  background: #E1E9F4; border-color: #A8BAD0; color: var(--primary-color, #1F3665);
}
/* The icon in a badge rather than loose beside the text. A bare glyph next to a
   two-line block reads as something that fell off; the badge gives it the same
   footprint as the block it sits with, and matches the avatar language the panel
   already uses. */
.ha-tosupport-ico {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  /* A step lighter than the button, not white: pure white made the badge the
     brightest thing in the panel and pulled the eye off the label it belongs to. */
  background: #DCE5F0; color: #5F6B7A; font-size: 16px;
  transition: background .15s ease, color .15s ease;
}
.ha-tosupport:hover .ha-tosupport-ico {
  background: #CFDCEC; color: var(--primary-color, #1F3665);
}

/* Two lines: the question, then what to do about it. */
/* The card's own two sizes: 12.5px title, 11.5px body. */
.ha-tosupport-txt { display: flex; flex-direction: column; gap: 3px; text-align: left; }
.ha-tosupport b {
  font-weight: 600; font-size: 12.5px; color: var(--primary-color, #1F3665);
}
.ha-tosupport-txt { font-size: 11.5px; color: #8A97A8; }

/* The support dialog, sharing the new-chat dialog's position and backdrop so
   the panel only ever has one way of asking something. */
.ha-support {
  position: absolute; left: 14px; right: 14px; bottom: 96px; z-index: 30;
  display: flex; flex-direction: column;
  padding: 16px; border-radius: 14px;
  background: #fff; border: 1px solid #E4EAF3;
  box-shadow: 0 18px 44px rgba(16,34,66,.20);
}
.ha-support[hidden] { display: none; }
.ha-support-title {
  font-size: 14px; font-weight: 600; color: var(--primary-color, #1F3665);
}
.ha-support-sub {
  margin-top: 3px; font-size: 11.5px; line-height: 1.5; color: #7C8899;
}
.ha-support-label {
  margin: 12px 0 6px; font-size: 12px; font-weight: 600;
  color: var(--primary-color, #1F3665);
}
.ha-support .ha-esc-note { border-color: #D8E0EA; }
.ha-support .ha-esc-note:focus {
  border-color: var(--green-color, #4ac186); box-shadow: 0 0 0 3px rgba(74,193,134,.13);
}
.ha-support-actions {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 12px;
}
/* Sent. The dialog answers its own question rather than leaving a turn in a
   conversation the request never went through. */
.ha-support.is-done { align-items: center; text-align: center; }
.ha-support.is-done .ha-support-actions { justify-content: center; }
.ha-support-tick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; margin-bottom: 10px;
  border-radius: 50%; background: rgba(60,194,135,.16);
  color: var(--green-color, #3aa76d); font-size: 16px;
}

/* Sent empty. Required for both kinds now — a refusal sent with only the
   question left the team unable to tell what was actually wanted. */
.ha-esc-note.is-empty {
  border-color: #C0392B !important; box-shadow: 0 0 0 3px rgba(192,57,43,.12) !important;
}

/* ── Ask the team ─────────────────────────────────────────────────────────
   Only ever under a refusal, so it is allowed to be a little louder than the
   rating row — it is the way out of a dead end, not a footnote. */
.ha-escalate {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin-top: 9px; padding: 9px 11px;
  background: #FFF9EC; border: 1px solid #F0DCB0; border-radius: 10px;
  font-size: 12px; color: #6B5518;
}
/* Step one and step two of the same row, one visible at a time. */
.ha-esc-top { display: flex; align-items: center; gap: 9px; width: 100%; }
.ha-esc-form { width: 100%; }
.ha-esc-form label {
  display: block; margin: 0 0 6px;
  font-size: 11.5px; line-height: 1.45; color: #6B5518;
}
.ha-esc-note {
  width: 100%; padding: 8px 10px; border: 1px solid #E0C489; border-radius: 8px;
  background: #fff; color: var(--primary-color, #1F3665);
  font-family: inherit; font-size: 12.5px; line-height: 1.5;
  resize: vertical; box-sizing: border-box;
}
.ha-esc-note:focus { outline: none; border-color: #C9A85C;
  box-shadow: 0 0 0 3px rgba(201,168,92,.18); }
.ha-esc-actions { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.ha-esc-cancel {
  padding: 6px 10px; border: 0; background: none;
  color: #8A7448; font-family: inherit; font-size: 12px; cursor: pointer;
}
.ha-esc-cancel:hover { color: #6B5518; text-decoration: underline; }
.ha-esc-send {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: auto; padding: 7px 14px;
  border: 0; border-radius: 999px;
  background: var(--primary-color, #1F3665); color: #fff;
  font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  transition: opacity .15s ease;
}
.ha-esc-send:hover:not(:disabled) { opacity: .9; }
.ha-esc-send:disabled { opacity: .6; cursor: default; }

.ha-esc-btn {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: auto; padding: 6px 12px;
  border: 1px solid #E0C489; border-radius: 999px;
  background: #fff; color: #7A5B12;
  font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.ha-esc-btn:hover:not(:disabled) { background: #FDF3DC; border-color: #C9A85C; }
.ha-esc-btn:disabled { opacity: .7; cursor: default; }
/* Sent. Quieter than the prompt it replaced — the work is done, so it is a
   confirmation rather than something asking to be pressed. The icon sits ON the
   line with the text: wrap was letting the long sentence drop below it, which
   left a lone tick floating above a paragraph. */
.ha-escalate.is-sent {
  flex-wrap: nowrap; align-items: flex-start; gap: 8px;
  padding: 8px 11px;
  background: #F1F8F4; border-color: #CFE6D9; color: #2C6A4A;
  font-weight: 500;
}
/* The confirmation is a turn, not a panel: it uses the ordinary message avatar
   in the ordinary gutter, so it lines up with every other message. */
.ha-msg--confirm .ha-escalate { margin-top: 0; }
.ha-escalate.is-sent .ha-esc-msg { flex: 1 1 auto; min-width: 0; }
/* Two weights: what happened, then what happens next. One weight for both made
   the whole thing read as a heading. */
.ha-escalate.is-sent .ha-esc-msg strong {
  display: block; font-weight: 600; line-height: 1.45;
}
/* Direct child only. The detail rule was also catching the span inside the
   timestamp, which turned "6 mins ago" into a block and broke it onto its own
   line under the word "Sent". */
.ha-escalate.is-sent .ha-esc-msg > span {
  display: block; margin-top: 1px;
  font-weight: 400; font-size: 11.5px; line-height: 1.45;
  color: #5C8A72;
}

/* Inside the headline, so it reads as part of the sentence — lighter than the
   words around it, because when it happened is the smaller half of the fact. */
.ha-escalate.is-sent .ha-esc-when {
  font-weight: 400; color: #5C8A72;
  font-variant-numeric: tabular-nums; cursor: help;
}

/* ── Table in an answer ───────────────────────────────────────────────────
   Its own scroller, so a table too wide for a 400px panel scrolls sideways
   inside itself rather than stretching the bubble and the whole thread. */
.ha-tablewrap {
  /* Bottom margin clears the scrollbar, which is drawn inside this box and
     otherwise sits on top of the paragraph underneath. */
  margin: .7em 0 .5em; overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid #E4EAF3; border-radius: 9px; background: #fff;
}
.ha-table { border-collapse: collapse; width: 100%; font-size: 12px; }
.ha-table th, .ha-table td {
  padding: 8px 10px; text-align: left; vertical-align: top;
  border-bottom: 1px solid #F1F4F8;
  /* Cells wrap. nowrap suits a grid of short values, but a description column
     in a 400px panel just hides itself behind a scrollbar — two words visible
     and the rest gone is worse than three lines that can be read. */
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.45;
}
/* The label column is short by nature and reads better held on one line. */
.ha-table td:first-child, .ha-table th:first-child {
  white-space: nowrap; font-weight: 500; color: var(--primary-color, #1F3665);
}
.ha-table th {
  background: #F6F8FC; color: var(--primary-color, #1F3665);
  font-weight: 600; font-size: 11px; letter-spacing: .02em;
  border-bottom: 1px solid #E4EAF3;
}
.ha-table tbody tr:last-child td { border-bottom: 0; }
/* Figures line up; words do not need to. */
.ha-table td { font-variant-numeric: tabular-nums; }
/* Only a genuinely wide table scrolls now — four or more columns. Below that
   wrapping always fits, so the scrollbar never appears. */
.ha-table th + th + th + th { min-width: 92px; }

.ha-bubble ul, .ha-bubble ol { margin: .6em 0 0; padding-left: 1.55em; }
.ha-bubble ul { list-style: disc; }
.ha-bubble ol { list-style: decimal; }
/* Steps need to read as separate lines, not as a paragraph that happens to have
   numbers in it — so a little more air between them than a bullet list needs. */
.ha-bubble li { margin: 0 0 .5em; padding-left: .2em; }
.ha-bubble ol li { margin-bottom: .62em; }
.ha-bubble li:last-child { margin-bottom: 0; }
/* Paragraphs inside a reply need a real gap, not a line break. Without it two
   separate points read as one run-on block however well the answer is written. */
.ha-bubble p { margin: 0; }
.ha-bubble p + p { margin-top: .78em; }
.ha-bubble p + ul, .ha-bubble p + ol { margin-top: .5em; }
/* The lead-in line above a list, from a heading in the model's markdown. */
.ha-bubble .ha-lead { font-weight: 600; margin-top: .85em; }
.ha-bubble > .ha-lead:first-child { margin-top: 0; }
.ha-bubble li::marker { color: var(--primary-color, #1F3665); font-weight: 600; }
.ha-bubble ol li::marker { font-variant-numeric: tabular-nums; }
/* The line that introduces a list should not sit flush against it. */
.ha-bubble p + ul, .ha-bubble p + ol { margin-top: .5em; }
.ha-bubble ul + p, .ha-bubble ol + p { margin-top: .62em; }

.ha-msg--assistant .ha-bubble { border-bottom-left-radius: 4px; }
.ha-msg--user .ha-bubble {
  background: linear-gradient(135deg, #2C4E86 0%, #17294B 100%);
  border-color: transparent; color: #fff;
  border-bottom-right-radius: 4px;
  box-shadow: 0 2px 8px rgba(23,41,75,.18);
}
/* ── System notices ───────────────────────────────────────────────────────────
   Still Atlas speaking — it keeps the avatar and sits where a reply sits — but
   about the account rather than the question. The amber card and warning mark
   are what stop it being read as an answer to what was just asked. */
.ha-msg--notice .ha-msg-body { max-width: 92%; }
/* Notices are paragraphed now, so they need the same rhythm as a bubble. */
.ha-notice p { margin: 0; }
.ha-notice p + p { margin-top: .55em; }

.ha-notice {
  display: flex; align-items: flex-start; gap: 9px;
  margin: 0;
  padding: 11px 13px;
  border: 1px solid #F0DCB0;
  border-left-width: 3px;
  border-radius: 9px;
  background: #FFFBF2;
  color: #6B5518;
  font-size: 12.5px;
  line-height: 1.55;
}
.ha-notice i { flex: 0 0 auto; margin-top: 1px; font-size: 13px; color: #D69A2B; }
.ha-notice span { min-width: 0; overflow-wrap: anywhere; }
.ha-root.is-page .ha-notice { font-size: 13.5px; padding: 13px 15px; }

/* A "not in my knowledge" answer is a different kind of reply, and looking
   different stops it reading as a failure. */
.ha-msg.is-unknown .ha-bubble { background: #FFF9EC; border-color: #F0DCB0; color: #6B5518; }
.ha-msg.is-error   .ha-bubble { background: #FDF3F2; border-color: #E8C4C0; color: #A93226; }

/* Sources as chips rather than a run-on sentence — they are objects you could
   go and open, not prose. */
/* Links inside an answer. Only ever the ones that were in the source material —
   see linkify() — so this style never appears on something invented. */
/* Sits in the sentence, but obviously pressable — a coloured word alone is easy
   to read straight past, and the arrow says it leaves the page. */
.ha-link {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 1px 7px;
  border-radius: 6px;
  background: rgba(60,194,135,.12);
  color: #23724D;
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: background .14s, color .14s;
}
.ha-link:hover { background: rgba(60,194,135,.22); color: #175236; }
.ha-link:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 1px; }
.ha-link i { font-size: .78em; opacity: .75; }

/* The support address, when it appears in a reply or a notice. Underlined
   rather than pill-styled: it is a line of prose, not a card.
   Compound selector on purpose — as a single class it tied with .ha-link on
   specificity and lost on source order, which is how it ended up wearing the
   pill it was written to remove. */
.ha-link.ha-link--mail {
  background: none;
  padding: 0;
  border-radius: 0;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/* A link that plays rather than navigates. The icon is the difference: without
   it a video and a page look identical and one of them surprises you. */
.ha-link--play { gap:5px; }
.ha-link--play i { font-size:11px; opacity:.9; }

.ha-link.ha-link--mail:hover { background: none; text-decoration-thickness: 2px; }
.ha-msg--user .ha-link { background: rgba(255,255,255,.16); color: #DFF4E8; }

.ha-cites { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.ha-cite {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  background: #EEF3F9; color: #6B7785; font-size: 10.5px; font-weight: 500;
}
.ha-cite i { font-size: 10px; color: #97A6B8; }
/* The overflow pill. Hover names what is hidden rather than expanding — the
   sources are a footnote and should not become a list of their own. */
.ha-cite--more { cursor: default; font-weight: 600; color: #8A97A8; }

/* ── Resource cards ───────────────────────────────────────────────────────────
   Media attached to the documents an answer used. Built from server data, never
   from the model's text — these are the only elements in a reply that carry
   markup, which is what lets the reply itself stay fully escaped. */
.ha-res { display: flex; flex-direction: column; gap: 6px; margin-top: 9px; }

.ha-res-card {
  display: flex; align-items: center; gap: 12px;
  padding: 7px 10px 7px 7px;
  border: 1px solid #E7ECF3;
  border-radius: 11px;
  background: #fff;
  color: var(--primary-color, #1F3665);
  text-decoration: none;
  transition: border-color .14s, box-shadow .14s;
}
.ha-res-card:hover {
  border-color: #CBD9E8;
  box-shadow: 0 3px 14px rgba(20,38,66,.09);
  color: var(--primary-color, #1F3665);
}
.ha-res-card:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 2px; }

/* The thumbnail is a fixed tile so a stack of cards lines up whether the still
   loaded or not — a missing image must not resize the card. */
.ha-res-thumb {
  position: relative;
  flex: 0 0 auto;
  width: 52px; height: 39px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: #EEF3F9;
  color: #7A8698;
  font-size: 15px;
  overflow: hidden;
}
.ha-res-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* A belt-and-braces cap. The tile clips its own image, but nothing else in a
   message should ever be able to widen the thread — an image that escapes its
   container takes the whole panel's layout with it. */
.ha-msg img { max-width: 100%; }
.ha-log { overflow-x: hidden; }

/* An image card's thumbnail IS the preview, so an icon on top of it is noise. */
.ha-res-card--image .ha-res-thumb i { display: none; }

/* A video needs a play mark, and a white glyph alone disappears against a bright
   frame — which is what a video still usually is. So it gets a solid badge over
   a slight scrim: legible on any thumbnail, unmistakably a button. */
.ha-res-card--video .ha-res-thumb { background: #17294B; }
.ha-res-card--video .ha-res-thumb::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(12,22,40,.26);
}
.ha-res-card--video .ha-res-thumb i {
  position: relative; z-index: 1;
  width: 21px; height: 21px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: rgba(255,255,255,.95);
  color: #17294B;
  font-size: 9.5px;
  padding-left: 1px;          /* the glyph's triangle is off-centre in its box */
  box-shadow: 0 1px 4px rgba(0,0,0,.28);
}

/* Deleted, but still part of the conversation. Muted and unclickable, with the
   label kept so the thread says what it was rather than losing a card. */
.ha-res-card--gone { background: #FAFBFD; border-style: dashed; cursor: default; }
.ha-res-card--gone:hover { border-color: #E7ECF3; box-shadow: none; }
.ha-res-card--gone .ha-res-thumb { background: #F1F4F9; color: #B4BECB; }
.ha-res-card--gone .ha-res-body b { color: #9AA5B4; font-weight: 500; }
.ha-res-card--gone .ha-res-body span { color: #B4BECB; }

/* A file tile shows its extension rather than a generic document glyph: the one
   thing you want to know before downloading is what it is. */
.ha-res-ext {
  font-size: 10px; font-weight: 700; letter-spacing: .04em;
  color: #6B7785;
}
.ha-res-card--download:hover .ha-res-ext { color: var(--primary-color, #1F3665); }

/* Files keep a plain tinted tile — there is nothing to preview. */
.ha-res-card--download .ha-res-thumb { background: #F1F4F9; color: #7A8698; font-size: 15px; }

.ha-res-body { flex: 1 1 auto; min-width: 0; line-height: 1.35; }
.ha-res-body b {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  /* Sized just under the message text around it. A card is a footnote to the
     answer, and set at the same size it competed with it. */
  font-size: 12px; font-weight: 600; line-height: 1.35;
  /* Two lines rather than one: a truncated label tells you less than it was
     written to tell you, and the card has the height to spare. */
}
/* The kind, small and quiet — it answers "what happens if I click this" without
   competing with the label. */
.ha-res-body span {
  display: block;
  margin-top: 1px;
  font-size: 9.5px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
  color: #9AA5B4;
}

/* A round icon rather than a word. Three cards stacked, each ending in a
   different-width verb, made the right edge look accidental; a fixed circle
   lines them up and the meta line already says what kind it is. */
.ha-res-go {
  flex: 0 0 auto;
  width: 25px; height: 25px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: #F1F4F9;
  color: #6B7785;
  font-size: 10.5px;
  transition: background .14s, color .14s;
}
.ha-res-card:hover .ha-res-go { background: var(--green-color, #4ac186); color: #fff; }

/* Cards past the fourth stay hidden until asked for. */
.ha-res-card.is-extra { display: none; }
.ha-res.is-open .ha-res-card.is-extra { display: flex; }
.ha-res-more {
  align-self: flex-start;
  border: 1px dashed #D8E0EA; background: none; border-radius: 9px;
  padding: 6px 12px; font: inherit; font-size: 11.5px; font-weight: 600;
  color: #8A97A8; cursor: pointer;
}
.ha-res-more:hover { border-color: #CBD5E1; color: var(--primary-color, #1F3665); }

/* On the page there is room to lay them out properly, so they stop scrolling. */
.ha-root.is-page .ha-starters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  overflow: visible;
  margin-left: 0; margin-right: 0;
  padding: 2px 0 0;
}
.ha-root.is-page .ha-starters > .ha-starter { width: auto; max-width: none; }

/* On the page there is room for two across. */
.ha-root.is-page .ha-res { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 8px; }
@media (max-width: 600px) {
  .ha-root.is-page .ha-res { grid-template-columns: minmax(0,1fr); }
}

/* A typing indicator, so a slow answer does not look like a dead widget. Three
   dots rising in sequence reads as "composing" in a way a pulsing ellipsis does
   not. */
.ha-msg.is-thinking .ha-bubble { padding: 13px 15px; }
.ha-dots { display: inline-flex; align-items: flex-end; gap: 4px; height: 8px; }
.ha-dots i { width: 6px; height: 6px; border-radius: 50%; background: #B4C0CE;
  animation: ha-typing 1.25s ease-in-out infinite; }
.ha-dots i:nth-child(2) { animation-delay: .16s; }
.ha-dots i:nth-child(3) { animation-delay: .32s; }
@keyframes ha-typing {
  0%, 60%, 100% { transform: translateY(0);    opacity: .45; }
  30%           { transform: translateY(-5px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .ha-dots i { animation: ha-typing-still 1.25s ease-in-out infinite; }
  @keyframes ha-typing-still { 0%,100% { opacity:.35; } 50% { opacity:1; } }
}

/* ── Composer ────────────────────────────────────────────────────────────── */
/* The input and the send button share one rounded field, so the composer reads
   as a single control rather than a box next to a button. */
.ha-compose {
  display: flex;
  /* Centred, not bottom-aligned. At rest the field is a single row and a button
     pinned to the bottom of it floats away from the text it belongs to. It only
     needs to drop once the field has actually grown, which the modifier below
     handles. */
  align-items: center;
  gap: 6px;
  margin: 12px 12px 2px;
  padding: 5px 5px 5px 6px;
  background: #fff;
  border: 1px solid #DDE4EE;
  border-radius: 12px;
  transition: border-color .15s, box-shadow .15s;
}
/* Added by the auto-grow once the text runs past one line. */
.ha-compose.is-tall { align-items: flex-end; }
.ha-compose:focus-within { border-color: #A8D5C0; box-shadow: 0 0 0 3px rgba(60,194,135,.13); }
.ha-compose textarea {
  flex: 1 1 auto; min-width: 0;
  border: 0; background: none;
  padding: 10px 8px 10px 10px;
  font: inherit; font-size: 13.5px; line-height: 1.45;
  resize: none;
  box-sizing: border-box;
  /* One comfortable row at rest, growing to five. A tall empty box reads as
     unfinished; it earns the height once there is text in it. */
  height: 40px;
  min-height: 40px;
  max-height: 132px;
  overflow-y: auto;
  color: #37475F;
}
.ha-compose textarea:focus { outline: none; }
.ha-compose textarea::placeholder { color: #A3AEBD; }
/* Always shown, so the limit is known before it is met. Faint enough to ignore
   until one of the two states that matter. */
.ha-count {
  flex: 0 0 auto;
  align-self: flex-end;
  margin: 0 2px 12px 0;
  font-size: 10px;
  font-variant-numeric: tabular-nums;   /* so it does not jitter while typing */
  color: #C3CCD8;
  transition: color .15s;
}
.ha-count.is-near  { color: #C08A2B; }
.ha-count.is-tight { color: #C0392B; font-weight: 600; }

.ha-send {
  flex: 0 0 auto; width: 34px; height: 34px;
  border: 0; border-radius: 9px; cursor: pointer;
  background: linear-gradient(135deg, #52c98e 0%, #43bb7f 100%);
  color: #fff; font-size: 15px;
  transition: opacity .15s, transform .12s;
}
.ha-send:hover:not(:disabled) { transform: translateY(-1px); }
.ha-send:disabled { opacity: .45; cursor: default; }
.ha-foot { background: #fff; padding: 8px 14px 12px; }
.ha-note {
  margin: 0;
  padding: 8px 0 0;
  font-size: 10.5px;
  line-height: 1.5;
  color: #A3AEBD;
  text-align: center;
}
/* Second sentence on its own line — two short lines read faster than one long
   wrapped one at this size. */
.ha-note span { display: block; }

/* ── Usage meter ─────────────────────────────────────────────────────────── */
.ha-usage {
  display: flex; align-items: center; gap: 8px; width: 100%;
  border: 0; background: none; padding: 6px 2px; cursor: pointer;
  font: inherit; font-size: 10.5px; color: #A3AEBD;
}
.ha-usage:hover { color: #6B7785; }
.ha-usage-bar {
  flex: 1 1 auto; height: 4px; border-radius: 4px;
  background: #E9EEF4; overflow: hidden;
}
.ha-usage-bar.lg { display: block; height: 6px; margin: 8px 0 0; }
.ha-usage-bar i { display: block; height: 100%; width: 0;
  background: #B9C6D6; border-radius: 4px; transition: width .3s, background .3s; }
.ha-usage-label { flex: 0 0 auto; white-space: nowrap; }
/* Scoped to the root so the meter and the popover's bar move together — they
   are siblings, not nested, and colouring only the meter left the popover
   claiming 100% next to a grey bar. */
.ha-root.is-warn .ha-usage-bar i { background: #E2A32C; }
.ha-root.is-warn .ha-usage-label { color: #8A6111; }
.ha-root.is-warn .ha-pop-row b   { color: #8A6111; }
.ha-root.is-out  .ha-usage-bar i { background: #C0392B; }
.ha-root.is-out  .ha-usage-label { color: #A93226; font-weight: 600; }
.ha-root.is-out  .ha-pop-row b   { color: #A93226; }

/* ── Usage popover ───────────────────────────────────────────────────────── */
.ha-pop {
  position: absolute; left: 12px; right: 12px; bottom: 92px; z-index: 3;
  background: #fff; border: 1px solid #E4E9F0; border-radius: 12px;
  padding: 13px 15px;
  box-shadow: 0 12px 34px rgba(20,38,66,.18);
}
.ha-pop-row { display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12.5px; color: #54627A; }
.ha-pop-row b { font-size: 14px; color: var(--primary-color, #1F3665); }
.ha-pop-note { margin: 9px 0 0; font-size: 11.5px; line-height: 1.45; color: #8A97A8; }

@media (max-width: 575px) {
  .ha-root { right: 14px; bottom: 14px; }
  .ha-panel { bottom: 66px; height: min(70vh, calc(100vh - 110px)); }

  /* ── The welcome screen on a small panel ───────────────────────────────
     There is much less height to spend, and the greeting is what someone
     opened this to read — so everything above the suggestions gets tighter
     and the suggestions themselves stop at one line each. */
  .ha-greeting { padding: 4px 6px 12px; }
  .ha-greeting-title { margin-top: 8px; font-size: 14.5px; }
  .ha-greeting-sub { margin-top: 4px; font-size: 11.5px; max-width: 30ch; }
  .ha-greeting .ha-avatar.lg { width: 32px; height: 32px; font-size: 15px; }

  .ha-starters { margin-top: 12px; }
  .ha-starter { padding: 9px 11px; }
  .ha-starter b { font-size: 12px; }
  /* One line and an ellipsis: the card is a prompt to click, and two lines of
     preview is the difference between the support block being on screen and
     being below the fold. */
  .ha-starter span { font-size: 11px; -webkit-line-clamp: 1; }

  .ha-tosupport { padding: 9px 11px; gap: 9px; }
  .ha-tosupport-wrap { margin-top: 0; }
  .ha-tosupport-ico { width: 30px; height: 30px; font-size: 14px; }
  .ha-tosupport b { font-size: 12px; }
  /* No line-clamp here: this block is a flex column holding two lines, and
     -webkit-box would replace that layout to clamp text that is a fixed label
     and cannot overflow anyway. */
  .ha-tosupport-txt { font-size: 11px; }

  /* The dialog has to fit the panel it is pinned inside, whatever its height. */
  .ha-support { bottom: 88px; max-height: calc(100% - 150px); overflow-y: auto; }
}

/* Short viewports — a phone in landscape, or a small window. The panel is only
   a few hundred pixels tall, so the greeting gives up its ornament first. */
@media (max-height: 620px) {
  .ha-greeting { padding: 2px 6px 10px; }
  .ha-greeting .ha-avatar.lg { display: none; }
  .ha-greeting-title { margin-top: 0; }
  .ha-starter span { -webkit-line-clamp: 1; }
  .ha-support { bottom: 84px; max-height: calc(100% - 130px); overflow-y: auto; }
}

/* ── Full-page mode  (/assistant.php) ─────────────────────────────────────────
   The same partial, unpinned: the floating shell becomes an ordinary card in the
   page flow. Only the shell changes — the header, log, composer and usage meter
   below are shared with the bubble, which is why they are not restated here. */
/* The page fills the window rather than sitting in a fixed-height box. Every
   height below is a percentage of what the layout actually gives it, so there
   are no magic numbers to drift out of date when the chrome around it changes. */
.assistant-page .main-content.with-header {
  height: 100vh;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding-bottom: 0;
}
.ha-page {
  flex: 1 1 auto;
  min-height: 0;              /* without this a flex child refuses to shrink */
  display: flex;
  padding: 18px 20px 20px;
}

.ha-root.is-page {
  position: static;
  right: auto; bottom: auto;
  z-index: auto;
  flex: 1 1 auto;
  min-width: 0; min-height: 0;
  display: flex;
}

/* ── History, as a slide-out inside the chat ──────────────────────────────────
   Covers everything below the header — thread, composer and all — rather than
   sitting beside the conversation. One implementation for both shells: a rail
   alongside was never going to work in a 400px bubble, and on the page a
   permanent third column spent width the conversation wanted. The header stays
   visible so the button that opened it is also the way back. */
.ha-body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex; flex-direction: column;
}

.ha-scrim {
  position: absolute; inset: 0; z-index: 4;
  background: rgba(17,32,56,.28);
  animation: ha-fade .18s ease;
}
@keyframes ha-fade { from { opacity: 0; } to { opacity: 1; } }

.ha-rail {
  position: absolute; inset: 0; z-index: 5;
  display: flex; flex-direction: column;
  padding: 12px;
  background: #fff;
  transform: translateX(-100%);
  visibility: hidden;
  transition: transform .22s ease, visibility .22s;
}
.ha-root.is-rail-open .ha-rail { transform: none; visibility: visible; }

.ha-rail-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase;
  color: #8A97A8;
  padding: 2px 2px 10px;
}
.ha-rail-close {
  border: 0; background: none; color: #8A97A8;
  font-size: 13px; padding: 4px 6px; cursor: pointer; border-radius: 6px;
}
.ha-rail-close:hover { background: #F1F4F8; color: #54627A; }

/* Left-aligned and solid, so it reads as the first item in the list rather than
   as a dashed drop zone. */
.ha-rail-new {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  padding: 9px 10px;
  border: 1px solid #E4E9F0;
  border-radius: 9px;
  background: #fff;
  color: var(--primary-color, #1F3665);
  font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.ha-rail-new:hover { border-color: var(--green-color, #4ac186); background: rgba(74,193,134,.07); }
.ha-rail-new:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 2px; }

/* ── Search ─────────────────────────────────────────────────────────────────── */
.ha-rail-search { position: relative; margin-top: 8px; }
.ha-rail-search > i {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  font-size: 12px; color: #A7B2C1; pointer-events: none;
}
.ha-rail-search input {
  width: 100%;
  padding: 8px 10px 8px 31px;
  border: 1px solid #E4E9F0;
  border-radius: 9px;
  background: #F8FAFC;
  font: inherit; font-size: 13px;
  color: #37475F;
}
.ha-rail-search input::placeholder { color: #A3AEBD; }
.ha-rail-search input:focus {
  outline: none;
  border-color: var(--green-color, #4ac186);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(74,193,134,.13);
}
/* Safari draws its own clear button on type=search; it fights the styling. */
.ha-rail-search input::-webkit-search-decoration,
.ha-rail-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.ha-rail-list { flex: 1 1 auto; overflow-y: auto; margin: 10px -4px 0; padding: 0 4px; }
.ha-rail-empty { padding: 14px 4px; font-size: 12.5px; color: #98A3B3; line-height: 1.5; }

/* The next page loads on scroll; the button is the fallback for anyone who does
   not reach the bottom by scrolling, and the place the spinner goes. */
.ha-rail-more { display: flex; justify-content: center; padding: 10px 0 4px; }
.ha-rail-more button {
  border: 1px solid #E4E9F0; background: #fff; border-radius: 8px;
  padding: 6px 14px; font: inherit; font-size: 12px; font-weight: 600;
  color: #6B7785; cursor: pointer;
}
.ha-rail-more button:hover { border-color: #CBD5E1; color: var(--primary-color, #1F3665); }

.ha-thread {
  position: relative;
  display: flex; align-items: stretch;
  border-radius: 9px;
  margin-bottom: 2px;
  transition: background .14s;
}
.ha-thread:hover { background: #F4F7FB; }
.ha-thread.is-active { background: rgba(74,193,134,.12); }
.ha-thread.is-going  { opacity: .45; pointer-events: none; }

.ha-thread-open {
  flex: 1 1 auto; min-width: 0;
  display: block; text-align: left;
  border: 0; background: none; cursor: pointer;
  font: inherit;
  padding: 9px 6px 9px 10px;
}
.ha-thread-open b {
  display: block;
  font-size: 13px; font-weight: 500; line-height: 1.35;
  color: var(--primary-color, #1F3665);
  /* One line, clipped: a thread title is a landmark, not something to read. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ha-thread.is-active .ha-thread-open b { font-weight: 600; }
.ha-thread-open span { display: block; font-size: 11px; color: #8A97A8; margin-top: 1px; }

/* Revealed on hover on a pointer device, but always present for keyboard and
   touch — a control you can only reach with a mouse is not reachable. */
.ha-thread-tools {
  flex: 0 0 auto;
  display: inline-flex; align-items: center;
  padding-right: 4px;
  opacity: 0;
  transition: opacity .14s;
}
.ha-thread:hover .ha-thread-tools,
.ha-thread:focus-within .ha-thread-tools { opacity: 1; }
@media (hover: none) { .ha-thread-tools { opacity: 1; } }

.ha-thread-edit,
.ha-thread-del {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: none; cursor: pointer;
  border-radius: 6px;
  color: #A7B2C1; font-size: 12px;
  transition: color .14s, background .14s;
}
.ha-thread-edit:hover { color: var(--primary-color, #1F3665); background: #E9EEF5; }
.ha-thread-del:hover  { color: #C0392B; background: #FBECEA; }
.ha-thread-edit:focus-visible,
.ha-thread-del:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: -1px; }

/* Sits over the row while renaming, for the same reason the delete confirm does:
   swapping the title for a field in place makes the whole list jump. */
.ha-thread-rename {
  display: none;
  position: absolute; inset: 0;
  align-items: center;
  padding: 0 6px;
}
.ha-thread.is-renaming .ha-thread-rename { display: flex; }
.ha-thread.is-renaming .ha-thread-tools  { display: none; }
.ha-thread-input {
  width: 100%;
  padding: 6px 9px;
  border: 1px solid var(--green-color, #4ac186);
  border-radius: 7px;
  background: #fff;
  font: inherit; font-size: 13px;
  color: var(--primary-color, #1F3665);
}
.ha-thread-input:focus { outline: none; box-shadow: 0 0 0 3px rgba(74,193,134,.16); }

/* Sits over the row rather than resizing it, so the list does not jump. */
.ha-thread-confirm {
  display: none;
  position: absolute; inset: 0;
  align-items: center; gap: 6px;
  padding: 0 8px;
  border-radius: 9px;
  background: #FDF3F2;
  font-size: 12px; color: #8C3B32;
}
.ha-thread.is-confirming .ha-thread-confirm { display: flex; }
.ha-thread-confirm button {
  border: 0; border-radius: 6px; cursor: pointer;
  font: inherit; padding: 3px 9px; font-size: 12px; font-weight: 600;
}
.ha-thread-no  { margin-left: auto; background: #fff; color: #54627A; border: 1px solid #E2E8F0 !important; }
.ha-thread-yes { background: #C0392B; color: #fff; }
.ha-thread-yes:hover { background: #A93226; }

.ha-rail-note {
  margin: 10px 2px 0;
  padding-top: 10px;
  border-top: 1px solid #F1F4F8;
  font-size: 10.5px; line-height: 1.45; color: #9AA5B4;
}
.ha-root.is-page .ha-panel {
  position: static;
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  height: 100%;
  border-radius: 14px;
  border: 1px solid #E4E9F0;
  box-shadow: 0 2px 10px rgba(20,38,66,.06);
}

/* A wide chat is a hard read — long lines lose the eye on the way back. The log
   keeps its own measure and centres, rather than stretching to the card. */
/* On the page there is room for the starter cards to breathe. */
.ha-root.is-page .ha-starters { gap: 10px; }
.ha-root.is-page .ha-starter { padding: 13px 15px; }

/* The bubble's look is the look — dark header, grey ground, replies in cards. It
   is the same product on a bigger surface, so nothing about the styling changes
   here. What changes is the space: the measure below keeps a wide window from
   turning replies into 1,400px lines, and the composer gets the size it could
   never have in a 400px box.

   Centred with align-self, NOT with auto margins: an auto margin on the cross
   axis of a flex column silently cancels `stretch`, and the element collapses to
   the width of its own content. That is what turned the composer into a 227px
   stub. width:100% plus max-width keeps it honest. */
.ha-root.is-page .ha-log { padding: 24px 20px 10px; font-size: 14px; }
.ha-root.is-page .ha-log > *,
.ha-root.is-page .ha-compose,
.ha-root.is-page .ha-foot {
  align-self: center;
  width: 100%;
  max-width: 780px;
}

/* ── Composer ─────────────────────────────────────────────────────────────────
   The one control everyone touches, and the part that felt cramped: at page size
   it gets a real target — a taller field, room to grow to a proper paragraph
   before it starts scrolling, and a send button big enough to hit without
   aiming. */
.ha-root.is-page .ha-compose {
  margin: 14px 12px 2px;
  padding: 7px 7px 7px 10px;
  border-radius: 14px;
  box-shadow: 0 2px 10px rgba(20,38,66,.06);
}
.ha-root.is-page .ha-compose textarea {
  font-size: 15px;
  line-height: 1.55;
  padding: 13px 10px;
  height: 54px; min-height: 54px;
  max-height: 220px;
}
.ha-root.is-page .ha-send { width: 40px; height: 40px; border-radius: 11px; font-size: 16px; }

/* Foot on one line rather than three: at this width the meter and the small
   print sit side by side instead of stacking 60px of chrome under the box. */
.ha-root.is-page .ha-foot {
  display: flex; align-items: center; gap: 18px;
  padding: 8px 14px 14px;
}
.ha-root.is-page .ha-usage { width: auto; flex: 0 0 auto; padding: 0; }
.ha-root.is-page .ha-usage .ha-usage-bar { flex: 0 0 78px; width: 78px; }
.ha-root.is-page .ha-note { flex: 1 1 auto; text-align: right; padding: 0; }
.ha-root.is-page .ha-note span { display: inline; }
.ha-root.is-page .ha-pop { bottom: 74px; }

@media (max-width: 767px) {
  /* Back to stacked: side by side, both halves end up unreadable. */
  .ha-root.is-page .ha-foot { display: block; }
  .ha-root.is-page .ha-usage { width: 100%; }
  .ha-root.is-page .ha-usage .ha-usage-bar { flex: 1 1 auto; width: auto; }
  .ha-root.is-page .ha-note { text-align: center; padding-top: 8px; }
  .ha-root.is-page .ha-note span { display: block; }
}

/* ── Header icon buttons ──────────────────────────────────────────────────────
   One shape for all of them — history, full page, back — because three buttons
   in three different shapes is what made the header look accidental. Labels do
   not fit a 400px header, so each names itself on hover instead. */
.ha-head-btn {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 8px;
  background: rgba(255,255,255,.10);
  color: rgba(255,255,255,.88);
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
  transition: background .14s, border-color .14s, color .14s;
}
.ha-head-btn:hover { background: rgba(255,255,255,.2); border-color: rgba(255,255,255,.3); color: #fff; }
.ha-head-btn:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 2px; }
.ha-rail-toggle[aria-expanded="true"] { background: rgba(255,255,255,.24); color: #fff; }

/* ── Tooltip ──────────────────────────────────────────────────────────────
   One element, moved to whatever is hovered, positioned fixed so it lives
   outside .ha-log's scroll box — a pseudo-element tooltip was clipped by that
   overflow every time.

   Named .ha-tipbox, NOT .ha-tip: .ha-tip is already on the header buttons as
   the marker for this system, and styling it as the floating box itself made
   those buttons position:fixed and invisible. The class on a control and the
   class on the tooltip have to be different things. */
.ha-tip { position: relative; }

.ha-tipbox {
  position: fixed; z-index: 2147483000;
  max-width: 230px; padding: 6px 9px; border-radius: 7px;
  background: #1F3665; color: #fff;
  font-family: inherit; font-size: 11.5px; font-weight: 500; line-height: 1.4;
  text-align: center; white-space: normal;
  box-shadow: 0 6px 18px rgba(16, 34, 66, .24);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(3px);
  transition: opacity .12s ease, transform .12s ease, visibility .12s;
}
.ha-tipbox.is-on { opacity: 1; visibility: visible; transform: translateY(0); }
.ha-tipbox::after {
  content: ""; position: absolute; top: 100%; left: var(--tip-arrow, 50%);
  transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: #1F3665;
}
/* Below the control instead of above, when there is no room above it. */
.ha-tipbox.is-under::after {
  top: auto; bottom: 100%;
  border-top-color: transparent; border-bottom-color: #1F3665;
}
/* Tone follows the control, using the same two colours the thumbs turn when
   they are chosen — so the tooltip and the button agree. */
.ha-tipbox.is-good { background: var(--green-color, #3aa76d); }
.ha-tipbox.is-good::after { border-top-color: var(--green-color, #3aa76d); }
.ha-tipbox.is-good.is-under::after { border-top-color: transparent; border-bottom-color: var(--green-color, #3aa76d); }
.ha-tipbox.is-bad { background: #C0392B; }
.ha-tipbox.is-bad::after { border-top-color: #C0392B; }
.ha-tipbox.is-bad.is-under::after { border-top-color: transparent; border-bottom-color: #C0392B; }

@media (prefers-reduced-motion: reduce) { .ha-tipbox { transition: none; } }

/* The slide-out gets its own measure on the page, so a 1,400px window does not
   produce 1,400px-wide chat titles. */
.ha-root.is-page .ha-rail { padding: 18px 20px; }
.ha-root.is-page .ha-rail-head,
.ha-root.is-page .ha-rail-new,
.ha-root.is-page .ha-rail-list,
.ha-root.is-page .ha-rail-note { width: 100%; max-width: 780px; align-self: center; }


@media (max-width: 575px) {
  .ha-page { padding: 10px 10px 12px; }
  .ha-root.is-page .ha-log { padding: 16px 12px 6px; }
}

/* ── jquery-confirm, wearing the Hub's colours ────────────────────────────────
   The library ships its own blue-and-grey look, which reads as a third-party
   dialog dropped on the page. These are the few pieces that matter: the button
   shapes and the two states we actually use.

   Scoped to body.ha-confirming, which haConfirm() adds while one of ITS dialogs
   is open and removes when it closes.

   Unscoped, these restyled every confirm dialog in the Hub — jquery-confirm
   appends .jconfirm to <body>, so there is no page container to hang them off,
   and dozens of tools use the same library. A body class is the only ancestor
   the two have in common, and it exists for exactly as long as our own dialog
   does. */
body.ha-confirming .jconfirm .jconfirm-box { border-radius:14px; padding:22px; font-family:'Poppins',sans-serif; }
body.ha-confirming .jconfirm .jconfirm-title { font-size:16px !important; font-weight:600 !important;
  color:var(--primary-color,#1F3665) !important; }
body.ha-confirming .jconfirm .jconfirm-content { font-size:13.5px; line-height:1.6; color:#54627A; }
body.ha-confirming .jconfirm .jconfirm-buttons { padding-top:18px !important; }
body.ha-confirming .jconfirm .jconfirm-buttons button {
  border-radius:9px !important; padding:9px 18px !important;
  font-family:'Poppins',sans-serif !important; font-size:13px !important;
  font-weight:600 !important; text-transform:none !important; }
body.ha-confirming .jconfirm .jconfirm-buttons button.btn-green {
  background:linear-gradient(135deg,#52c98e 0%,#43bb7f 100%) !important; color:#fff !important; }
body.ha-confirming .jconfirm .jconfirm-buttons button.btn-red {
  background:#C0392B !important; color:#fff !important; }
body.ha-confirming .jconfirm .jconfirm-buttons button.btn-default {
  background:#fff !important; border:1px solid #E2E8F0 !important; color:#54627A !important; }

/* ── Page hero ────────────────────────────────────────────────────────────────
   The dashboard's own .rdx-hero, reused rather than reproduced — same component,
   same tokens, so it cannot drift from the page people see most. Only the things
   specific to a page with no video need saying here. */
/* One source of top spacing, not three. The strip is gone, so the page had my
   26px plus Bootstrap's pt-4 plus p-2 stacked on top of each other — about 58px
   of nothing above the hero. */
.assistant-admin .main-content.with-header { padding-top:0; }
.ha-adm-hero .rdx-hero-copy { padding:24px 28px; }
.ha-adm-hero h1 { font-size:24px; }
/* Without a video alongside it, the copy would otherwise run the full width of a
   wide screen and the eye would lose the line ends. */
.ha-adm-hero p.tag { max-width:560px; }
/* No buttons above it any more, so the rule that separated the two would be a
   line under the description for no reason. */
.ha-adm-hero .rdx-hero-meta { margin-top:16px; padding-top:0; border-top:0; }

/* ── Section tabs ─────────────────────────────────────────────────────────────
   Real links, so each section can be sent to someone or landed on after a save.
   Sits on the page's own background rather than in a card — it frames the cards
   below, and a box around a box is one box too many. */
/* ── Section tabs ──────────────────────────────────────────────────────────
   A segmented control on the page's own background, not folder tabs hanging off
   a rule. The underline version needed a border to sit against and a negative
   margin to cover it, which broke the moment the row wrapped on a narrow screen
   — the second line of tabs sat over nothing.

   Colours come from the Hub's tokens so this row matches the dashboard rather
   than approximating it. */
.ha-adm-tabs {
  display: flex; gap: 2px; flex-wrap: wrap;
  margin-bottom: 22px; padding: 4px;
  background: #EFF1F6;
  border-radius: 12px;
}
.ha-adm-tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px; border-radius: 9px;
  font-size: 13px; font-weight: 500;
  color: var(--rdx-muted, #8992a3); text-decoration: none;
  border: 0; white-space: nowrap;
  transition: color .14s, background .14s, box-shadow .14s;
}
.ha-adm-tab i { font-size: 14px; opacity: .8; }
.ha-adm-tab:hover { color: var(--rdx-ink, #161b26); background: rgba(255,255,255,.6); }
/* The current tab in the Hub's green, lifted off the track rather than
   underlined: on a wrapped row an underline marks the current tab on one line
   and nothing on the other.

   WHITE TEXT, ON A DEEPER GREEN. White on the brand #4ac186 is 2.3:1, which is
   not readable at 13px; #2C7A5B is the same green taken down far enough to
   carry it at 5.2:1. The brand colour is untouched everywhere else — this is
   the one place it has to sit behind small white type.

   No ring. A shadow alone lifts it; an outline as well turned the pill into a
   bordered card sitting in a bordered track. */
.ha-adm-tab.is-on {
  background: #2C7A5B;
  color: #fff;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(20,30,60,.14);
}
.ha-adm-tab.is-on i { opacity: 1; color: #fff; }
.ha-adm-tab.is-on:hover { background: #25674D; }

@media (max-width: 760px) {
  /* Icons only for the tabs you are not on, so the row still fits and the one
     you are on still says what it is. */
  .ha-adm-tab { padding: 9px 11px; }
  .ha-adm-tab span { display: none; }
  .ha-adm-tab.is-on span { display: inline; }
}
}

.ha-adm-sub { font-size:12.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
  color:#98A3B3; margin:22px 0 8px; }

/* ── Documents table ──────────────────────────────────────────────────────────
   The widest table here, and the one carrying controls rather than figures. Its
   columns get explicit room so the action buttons stop wrapping mid-word and the
   title stops eating the space the rest of the row needs. */
/* The widths live on the cells further down, where they can also carry a
   minimum. These are left as the colgroup's own fallback. */
.ha-adm-docs col.c-title  { width:auto; }

/* Not display:flex.
   A <td> given display:flex stops being a table cell, so vertical-align no
   longer applies to it — which is why this one button sat level with the title
   while the folder and access controls centred themselves on the row. It stays a
   cell, and the button inside is centred as inline content. */
.ha-adm-docs td.ha-adm-actions { display:table-cell; text-align:center; }
.ha-adm-docs td.ha-adm-actions .ha-adm-rowmenu { display:inline-block; }
/* The folder select and the access button sit side by side, so they are built
   from the same numbers: one border, one radius, one height. They were a
   half-pixel apart in every one of them, which is the sort of difference you
   cannot name but can see. The native arrow goes for a drawn one, because the
   platform's is a different size on every platform. */
.ha-adm-docs select {
  -webkit-appearance:none; -moz-appearance:none; appearance:none;
  display:inline-flex; align-items:center;
  width:100%; height:32px; padding:0 28px 0 10px;
  border:1px solid #E2E8F0; border-radius:8px; background:#fff;
  font:inherit; font-size:12px; color:#54627A; cursor:pointer;
  text-overflow:ellipsis;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238A96A8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 10px center;
}
.ha-adm-docs select:hover { border-color:#CBD5E1; color:var(--primary-color,#1F3665); }
.ha-adm-docs select:focus-visible { outline:2px solid var(--green-color,#4ac186);
  outline-offset:2px; }

/* Matched to the select above, so a row reads as one band of controls. */
.ha-adm-docs .ha-adm-access-btn { height:32px; padding:0 10px; }
/* The title is the only free-text field in the row; it should look editable
   without stretching the dashed rule across half the table. */
.ha-adm-docs .ha-adm-doctitle { max-width:100%; }

/* Column widths, so the title gets the room it needs.
   Without these the browser sized every column from its content, and the
   actions — five buttons that cannot wrap — took whatever they wanted while the
   title was squeezed to a few characters and its metadata wrapped into a tall
   thin stack. */
/* Scrolls sideways rather than letting the row draw over itself.
   table-layout:fixed divides whatever width it is given, so on a narrow window
   the percentages resolved to less than the buttons needed and the controls
   overlapped the columns beside them. The floor below is the width at which
   every column still holds its content; under that, this scrolls. */
.ha-adm-tscroll { overflow-x: auto; margin: 0 -2px; padding: 0 2px; }
.ha-adm-docs { table-layout: fixed; width: 100%; min-width: 720px; }
/* Pixels, not percentages: five of these six columns hold controls of a known
   size, and only the title benefits from the leftovers. */
.ha-adm-docs th:nth-child(1), .ha-adm-docs td:nth-child(1) { width: auto; min-width: 260px; }
.ha-adm-docs th:nth-child(2), .ha-adm-docs td:nth-child(2) { width: 168px; }
.ha-adm-docs th:nth-child(3), .ha-adm-docs td:nth-child(3) { width: 196px; }
/* One menu button, where this used to hold five controls in a row. Centred
   rather than right-aligned: a lone icon under a right-aligned heading sat off
   its own column, because the cell has no right padding to align into. */
.ha-adm-docs th:nth-child(4), .ha-adm-docs td:nth-child(4) { width: 92px; text-align: center; }

/* ── Title, with the state beside it ─────────────────────────────────────────
   The dot carries what the Status column used to. Fixed size and never shrinking,
   so a column of them lines up down the page and can be scanned without reading. */
.ha-adm-docs .ha-adm-titlerow { display:flex; align-items:center; gap:9px; min-width:0; }
.ha-adm-dot { flex:0 0 auto; width:9px; height:9px; border-radius:50%;
  background:#CBD5E1; cursor:help; }
.ha-adm-dot.is-indexed { background:var(--green-color,#4ac186);
  box-shadow:0 0 0 3px rgba(74,193,134,.18); }
.ha-adm-dot.is-pending { background:#E2A32C; box-shadow:0 0 0 3px rgba(226,163,44,.18); }
.ha-adm-dot.is-failed  { background:#C0392B; box-shadow:0 0 0 3px rgba(192,57,43,.16); }
.ha-adm-docs .ha-adm-titlerow .ha-adm-doctitle { flex:1 1 auto; min-width:0; }

/* ── The quiet line under a title ────────────────────────────────────────────
   Owner, review date and aliases. Three stacked greys made every row four lines
   tall and none of them readable, so they share one line: the facts first, then
   the aliases taking whatever room is left and truncating rather than wrapping.
   The full list is on the hover title, which is where a long one belongs. */
.ha-adm-docs .ha-adm-docmeta-row { display:flex; align-items:center; gap:16px;
  margin-top:7px; padding-left:18px; min-width:0; }
/* Aliases get their own line under the facts. Sharing one line meant the last
   chip was always half-cut by the column edge, and a sliced alias is worse than
   no alias — it reads as a different word. */
.ha-adm-docs .ha-adm-aliasrow { display:flex; align-items:center; gap:5px;
  margin-top:5px; padding-left:18px; min-width:0; overflow:hidden; cursor:help; }
.ha-adm-docs .ha-adm-aliasrow > i { flex:0 0 auto; margin-right:2px;
  font-size:10.5px; color:#BCC6D4; }

/* Each fact its own group, with an icon that says which one it is before the
   words are read. Run together with middots they were a single grey string in
   which nothing could be found without reading all of it. */
.ha-adm-fact { flex:0 0 auto; display:inline-flex; align-items:center; gap:5px;
  font-size:11.5px; line-height:1.5; color:#7A879A; white-space:nowrap; cursor:help; }
.ha-adm-fact i { flex:0 0 auto; font-size:11px; color:#A7B2C1; }
.ha-adm-fact.is-overdue { color:#A93226; font-weight:600; }
.ha-adm-fact.is-overdue i { color:#C0392B; }



/* One chip per alias. A chip that will not fit is dropped whole rather than
   sliced, which is what the "+2" is for — a half-word tells you nothing. */
.ha-adm-aliases { display:flex; align-items:center; gap:5px; min-width:0;
  flex:1 1 auto; overflow:hidden; cursor:help; }
.ha-adm-chip { flex:0 0 auto; max-width:130px; padding:2px 7px; border-radius:5px;
  background:#F1F4F8; color:#7A879A; font-size:10.5px; line-height:1.5;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ha-adm-chip.is-more { background:none; padding:2px 2px; color:#A7B2C1;
  font-weight:600; cursor:help; }

/* Every cell starts at the top of the row.
   The base table centres its cells, which was fine when a row was one line
   tall. The owner, review date and aliases under the title make this row two
   lines, so centring left the folder, status and actions floating at different
   heights with nothing lining up. */
/* The title cell is two lines and the others are one control, so top-aligning
   everything left the folder, access and menu hanging above the row's middle
   with nothing to line up against. Centred, each control sits on the row's own
   centre line and the three columns read straight across. */
.ha-adm-docs td { vertical-align: middle; }
/* ── Help ────────────────────────────────────────────────────────────────────
   A ? beside the heading, and one modal explaining the table. Quieter than the
   heading it sits next to: it is there when wanted, not competing for attention
   with the thing it explains. */
.ha-adm-h3row { display:flex; align-items:center; gap:9px; }
.ha-adm-h3row h3 { margin:0; }
.ha-adm-help { display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; padding:0; border:1px solid #E2E8F0; border-radius:50%;
  background:#fff; color:#A7B2C1; font-size:11px; cursor:pointer; }
.ha-adm-help:hover { border-color:var(--green-color,#4ac186);
  color:var(--green-color,#2f9e6a); background:rgba(74,193,134,.08); }
.ha-adm-help:focus-visible { outline:2px solid var(--green-color,#4ac186); outline-offset:2px; }

.ha-adm-help-list { margin:0 0 4px; }
.ha-adm-help-list > div { display:grid; grid-template-columns:170px 1fr; gap:10px;
  padding:10px 0; border-top:1px solid #F1F4F8; }
.ha-adm-help-list > div:first-child { border-top:0; padding-top:0; }
.ha-adm-help-list dt { display:flex; align-items:center; gap:8px;
  font-size:12.5px; font-weight:600; color:var(--primary-color,#1F3665); }
.ha-adm-help-list dt i { flex:0 0 auto; width:14px; font-size:12px; color:#A7B2C1; }
/* The dots keep the colours they have in the table, or the key explains nothing. */
.ha-adm-help-list dt i.is-indexed { color:var(--green-color,#4ac186); font-size:9px; }
.ha-adm-help-list dt i.is-pending { color:#E2A32C; font-size:9px; }
.ha-adm-help-list dt i.is-failed  { color:#C0392B; font-size:9px; }
.ha-adm-help-list dd { margin:0; font-size:12.5px; line-height:1.6; color:#6B7785; }
.ha-adm-help-list dd b { color:#54627A; }

@media (max-width: 560px) {
  .ha-adm-help-list > div { grid-template-columns:1fr; gap:3px; }
}

/* The styled tooltip that used to live here is gone. Its explanations became
   the ? modal above, and what is left on each control is a two-word label the
   browser's own tooltip handles perfectly well — and which doubles as the
   accessible name for the icon-only ones. */

/* ── Row menu ────────────────────────────────────────────────────────────────
   Indexing stays a button because it is why you came to the row. Downloading,
   replacing and removing are occasional, and five controls in a row could not
   fit beside the columns carrying the information — they overlapped them.

   The pop-out is position:fixed and placed by JavaScript: .ha-adm-tscroll has
   overflow-x:auto, which would clip anything positioned inside it. */
.ha-adm-rowmenu { position:relative; flex:0 0 auto; }
.ha-adm-menubtn { position:relative; display:inline-flex; align-items:center;
  justify-content:center; width:32px; height:32px; padding:0;
  border:1px solid #E2E8F0; border-radius:8px; background:#fff;
  color:#6B7785; font-size:15px; cursor:pointer; }
.ha-adm-menubtn:hover { border-color:#CBD5E1; color:var(--primary-color,#1F3665); }
.ha-adm-menubtn[aria-expanded="true"] { border-color:var(--green-color,#4ac186);
  color:var(--primary-color,#1F3665); background:rgba(74,193,134,.08); }
.ha-adm-menubtn:focus-visible { outline:2px solid var(--green-color,#4ac186); outline-offset:2px; }
/* How many resources are attached, without opening anything. */
.ha-adm-menudot { position:absolute; top:-5px; right:-5px; min-width:16px; height:16px;
  padding:0 4px; border-radius:999px; background:var(--green-color,#4ac186);
  color:#fff; font-size:10px; font-weight:700; line-height:16px; }

.ha-adm-menupop { position:fixed; z-index:1080; min-width:216px; padding:5px;
  background:#fff; border:1px solid #E4E9F0; border-radius:10px;
  box-shadow:0 12px 30px rgba(17,32,56,.14); }
.ha-adm-menupop[hidden] { display:none; }
.ha-adm-menupop form { margin:0; }

.ha-adm-menuitem { display:flex; width:100%; align-items:center; gap:9px;
  padding:8px 10px; border:0; border-radius:7px; background:none;
  font:inherit; font-size:13px; color:var(--primary-color,#1F3665);
  text-align:left; text-decoration:none; cursor:pointer; }
.ha-adm-menuitem:hover { background:#F4F7FB; }
.ha-adm-menuitem:focus-visible { outline:2px solid var(--green-color,#4ac186); outline-offset:-2px; }
.ha-adm-menuitem i { flex:0 0 auto; width:15px; font-size:13px; color:#8A96A8; }
.ha-adm-menuitem span { flex:1 1 auto; }
/* The resource count, right-aligned and quiet. */
.ha-adm-menuitem em { flex:0 0 auto; font-style:normal; font-size:11px; color:#A7B2C1; }
.ha-adm-menuitem:hover i { color:var(--primary-color,#1F3665); }
/* Indexing leads the menu, so it is weighted like the button it replaced. */
.ha-adm-menuitem.is-primary { font-weight:600; }
.ha-adm-menuitem.is-primary i { color:var(--green-color,#4ac186); }
.ha-adm-menuitem:disabled { opacity:.45; cursor:default; }
.ha-adm-menuitem:disabled:hover { background:none; }
.ha-adm-menusep { height:1px; margin:4px 6px; background:#EEF2F7; }

.ha-adm-menuitem.is-danger { color:#A93226; }
.ha-adm-menuitem.is-danger i { color:#C0574A; }
.ha-adm-menuitem.is-danger:hover { background:rgba(169,50,38,.07); }
.ha-adm-menuitem.is-danger:hover i { color:#A93226; }

/* ── Numbered pages ───────────────────────────────────────────────────────── */
.ha-adm-pager { display:flex; align-items:center; gap:4px; flex-wrap:wrap;
  padding:14px 0 2px; border-top:1px solid #F1F4F8; margin-top:10px; }
.ha-adm-page { min-width:30px; height:30px; padding:0 8px;
  border:1px solid #E2E8F0; border-radius:8px; background:#fff;
  font:inherit; font-size:12.5px; font-weight:600; color:#54627A; cursor:pointer;
  transition:background .14s, border-color .14s, color .14s; }
.ha-adm-page:hover:not(:disabled):not(.is-on) { background:#F6F8FC; border-color:#CBD5E1;
  color:var(--primary-color,#1F3665); }
.ha-adm-page.is-on { background:var(--green-color,#4ac186); border-color:var(--green-color,#4ac186);
  color:#fff; cursor:default; }
.ha-adm-page:disabled { opacity:.4; cursor:default; }
.ha-adm-page.is-step { font-size:15px; line-height:1; }
.ha-adm-page-gap { color:#A7B2C1; padding:0 2px; }
/* Pushed to the far end: it is context, not a control. */
.ha-adm-page-count { margin-left:auto; font-size:11.5px; color:#98A3B3; }

/* ── Admin: usage, credit and chat review ─────────────────────────────────── */
.ha-adm-muted { color:#8A97A8; }
.ha-adm-bad   { color:#C0392B; font-weight:600; }
.ha-adm-up    { color:#2E9E6B; }

/* A bar narrow enough to sit in a table cell without becoming the cell. */
.ha-adm-mini { display:inline-block; width:86px; height:6px; border-radius:4px;
  background:#EEF2F7; overflow:hidden; vertical-align:middle; margin-right:8px; }
.ha-adm-mini i { display:block; height:100%; background:var(--green-color,#4ac186); }

/* The allowance cell: bar and figure on one line, the figure not wandering with
   the bar's width. */
/* Icon headers sit slightly high against uppercase text next to them. */
.ha-adm-table th i { font-size:12px; vertical-align:-1px; }

.ha-adm-allow { white-space:nowrap; }
.ha-adm-allow span:last-child { font-variant-numeric:tabular-nums; font-size:12.5px; color:#54627A; }
/* The clinic's own allowance, under its name — it is what the percentage is of,
   and having to look it up elsewhere makes the percentage meaningless. */
.ha-adm-table td small { display:block; color:#A7B2C1; font-size:11px; margin-top:2px; }
/* The parts of the token figure, under it. A total covering three counts across
   two models matches nothing on the OpenAI dashboard, so the number that does is
   shown rather than explained. */
.ha-adm-tokbits { white-space:nowrap; font-size:10.5px; color:#B6C0CD; }

/* A form row where every control is the same height and lines up on its bottom
   edge. Mixed heights were making the button look dropped rather than aligned. */
.ha-adm-limits { display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap;
  padding:16px 0; border-top:1px solid #F1F4F8; }
.ha-adm-limits .ha-adm-field { flex:1 1 200px; min-width:0; margin-bottom:0; }
.ha-adm-limits .ha-adm-field.narrow { flex:0 0 140px; }
.ha-adm-limits .ha-adm-field input[type=text] { height:40px; }
.ha-adm-limits .ha-adm-btn { height:40px; flex:0 0 auto; }

/* ── select2, wearing the same clothes as the plain inputs ─────────────────── */
.ha-adm-card .select2-container { width:100% !important; }
.ha-adm-card .select2-container--default .select2-selection--single {
  height:40px; border:1px solid #D8E0EA; border-radius:8px; background:#fff; }
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__rendered { line-height:38px; padding-left:11px; padding-right:30px;
  font-size:13px; color:#37475F; }
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__placeholder { color:#A3AEBD; }
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__arrow { height:38px; right:6px; }
.ha-adm-card .select2-container--default.select2-container--open
  .select2-selection--single { border-color:var(--green-color,#4ac186);
  box-shadow:0 0 0 3px rgba(74,193,134,.13); }
/* ── The closed control ───────────────────────────────────────────────────────
   select2 ships a bare "×" glyph jammed against a tiny caret, both unstyled and
   both easy to hit by accident. These give each a real target and a state. */
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__rendered { padding-right:56px; }

.ha-adm-card .select2-selection__clear {
  position:absolute; right:30px; top:50%; transform:translateY(-50%);
  width:22px; height:22px; margin:0;
  display:flex !important; align-items:center; justify-content:center;
  border-radius:50%; background:#F1F4F8; color:#8A97A8;
  font-size:0; line-height:0; cursor:pointer;
  transition:background .14s, color .14s;
}
/* The library's own "×" is a text node inside; replaced so the mark is centred
   and the same weight as the rest of the interface. */
.ha-adm-card .select2-selection__clear > span { display:none; }
.ha-adm-card .select2-selection__clear::after {
  content:'\00d7'; font-size:14px; line-height:1; font-weight:600;
}
.ha-adm-card .select2-selection__clear:hover { background:#FDECEA; color:#C0392B; }

/* A chevron rather than the default up-pointing triangle, matching the selects
   elsewhere on the page. */
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__arrow b { display:none; }
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__arrow::after {
  content:'\f282'; font-family:'bootstrap-icons';
  position:absolute; right:12px; top:50%; transform:translateY(-50%);
  font-size:11px; color:#A7B2C1; transition:transform .16s, color .14s;
}
.ha-adm-card .select2-container--default.select2-container--open
  .select2-selection__arrow::after { transform:translateY(-50%) rotate(180deg); color:#54627A; }

/* A chosen clinic should look chosen, not like placeholder text that happens to
   have changed. */
.ha-adm-card .select2-selection__rendered .ha-co-id { margin-left:4px; }

/* ── A clinic row in the picker ────────────────────────────────────────────── */
.ha-co { line-height:1.4; }
.ha-co-top { display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.ha-co-name { font-weight:600; color:var(--primary-color,#1F3665); }
/* The id earns its place: it is what appears in URLs and support threads, and it
   is the only thing that is definitely unique. */
.ha-co-id { font-size:11px; font-weight:600; color:#A7B2C1; font-variant-numeric:tabular-nums; }
.ha-co-set { font-size:10.5px; font-weight:600; background:rgba(60,194,135,.14); color:#237a52;
  padding:1px 7px; border-radius:999px; }
.ha-co-who { font-size:11.5px; color:#8A97A8; margin-top:2px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }

/* The dropdown itself, so it does not arrive as unstyled browser chrome. */
/* ── The dropdown ─────────────────────────────────────────────────────────────
   Scoped to .ha-co-drop, which select2 puts on the dropdown itself. The dropdown
   is appended to <body>, so anything scoped to the card around the control never
   reaches it — which is how the site's global select2 rules (a wash-blue that
   resolves to nothing outside .playbook-page, and font-weight:700) went on
   applying unopposed. */
.ha-co-drop { border-color:#D8E0EA; border-radius:12px; overflow:hidden;
  box-shadow:0 16px 40px rgba(20,38,66,.16); }

.ha-co-drop .select2-search--dropdown { padding:10px; border-bottom:1px solid #F1F4F8; }
.ha-co-drop .select2-search__field {
  border:1px solid #E2E8F0 !important; border-radius:9px !important;
  padding:9px 12px !important; font-size:13px !important; background:#F8FAFC;
}
.ha-co-drop .select2-search__field:focus { outline:none; background:#fff;
  border-color:var(--green-color,#4ac186) !important;
  box-shadow:0 0 0 3px rgba(74,193,134,.13); }

.ha-co-drop .select2-results > .select2-results__options { max-height:330px; padding:6px; }
.ha-co-drop .select2-results__option { padding:9px 11px !important; border-radius:9px;
  margin-bottom:2px; }
.ha-co-drop .select2-results__message { color:#8A97A8; font-size:12.5px; }

/* Hover and keyboard selection: a light grey ground, nothing else. Bold text on
   hover made the row jump as the weight changed, and inverting to white text
   fought a background that was not reliably there. */
.ha-co-drop .select2-results__option--highlighted,
.ha-co-drop .select2-results__option--highlighted[aria-selected] {
  background:#F1F5F9 !important;
  color:var(--primary-color,#1F3665) !important;
  font-weight:400 !important;
}
/* The one already chosen keeps a tint, so it is findable in a long list. */
.ha-co-drop .select2-results__option[aria-selected="true"] { background:#EDF6F1; }

/* ── The closed control ───────────────────────────────────────────────────────
   select2 ships a bare "×" glyph jammed against a tiny caret, both unstyled and
   both easy to hit by accident. These give each a real target and a state. */
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__rendered { padding-right:56px; }

.ha-adm-card .select2-selection__clear {
  position:absolute; right:30px; top:50%; transform:translateY(-50%);
  width:22px; height:22px; margin:0;
  display:flex !important; align-items:center; justify-content:center;
  border-radius:50%; background:#F1F4F8; color:#8A97A8;
  font-size:0; line-height:0; cursor:pointer;
  transition:background .14s, color .14s;
}
/* The library's own "×" is a text node inside; replaced so the mark is centred
   and the same weight as the rest of the interface. */
.ha-adm-card .select2-selection__clear > span { display:none; }
.ha-adm-card .select2-selection__clear::after {
  content:'\00d7'; font-size:14px; line-height:1; font-weight:600;
}
.ha-adm-card .select2-selection__clear:hover { background:#FDECEA; color:#C0392B; }

/* A chevron rather than the default up-pointing triangle, matching the selects
   elsewhere on the page. */
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__arrow b { display:none; }
.ha-adm-card .select2-container--default .select2-selection--single
  .select2-selection__arrow::after {
  content:'\f282'; font-family:'bootstrap-icons';
  position:absolute; right:12px; top:50%; transform:translateY(-50%);
  font-size:11px; color:#A7B2C1; transition:transform .16s, color .14s;
}
.ha-adm-card .select2-container--default.select2-container--open
  .select2-selection__arrow::after { transform:translateY(-50%) rotate(180deg); color:#54627A; }

/* A chosen clinic should look chosen, not like placeholder text that happens to
   have changed. */


/* ── A clinic row in the picker ────────────────────────────────────────────── */
.ha-co { line-height:1.35; }
.ha-co-top { display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.ha-co-name { font-weight:600; color:var(--primary-color,#1F3665); }
/* The id earns its place: it is what appears in URLs and support threads, and it
   is the only thing that is definitely unique. */
.ha-co-id { font-size:11px; font-weight:600; color:#A7B2C1; font-variant-numeric:tabular-nums; }
.ha-co-set { font-size:10.5px; font-weight:600; background:rgba(60,194,135,.14); color:#237a52;
  padding:1px 7px; border-radius:999px; }
.ha-co-who { font-size:11.5px; color:#8A97A8; margin-top:1px; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
/* Nothing inverts, so the row's own colours stay as they are and stay legible
   whether it is hovered or not. */

/* The dropdown itself, so it does not arrive as unstyled browser chrome. */
/* A light wash, not a solid fill, and no white text anywhere.
   
   The site already has a global .select2-results__option--highlighted rule using
   --tp-wash-blue and --tp-navy, but those variables are only declared on
   .playbook-page — so off that page both values are invalid, the background
   never paints, and anything relying on it being dark iswhite on white. Owning the
   whole state here, in one colour that works without any variable, avoids the
   problem instead of layering another !important on top of it. */
.ha-adm-card .select2-container--default .select2-results__option--highlighted,
.ha-adm-card .select2-container--default .select2-results__option--highlighted[aria-selected] {
  background:#EDF6F1 !important;
  color:var(--primary-color,#1F3665) !important;
  font-weight:400 !important;
}

/* Company under the person, quieter — on most rows it is the same clinic over and
   over, and repeating it at full strength buries the thing that differs. */
.ha-adm-chats td small { display:block; color:#A7B2C1; font-size:11px; margin-top:1px; }
.ha-adm-chats .ha-adm-q { font-weight:600; color:var(--primary-color,#1F3665); }
/* Wide enough to read a question, capped so it cannot push the counts off. */
.ha-adm-chats td:first-child { max-width:360px; }
.ha-adm-more { padding:12px 0 2px; text-align:center; }

/* ── Transcript ───────────────────────────────────────────────────────────────
   Shaped like the conversation it records: question right, answer left with its
   sources beneath. Laid out as database rows it had to be translated back into a
   conversation in your head before you could judge whether the answer was good. */
/* The transcript body gets the chat's own ground, so white bubbles read as
   bubbles rather than as blank space on a white modal. */
.ha-adm-modal-body.is-tx { background:#F6F8FC; padding:18px; }
/* The transcript IS the chat, so it gets the chat's column and the chat's type.
   The modal is three times the width of the panel, and letting the bubbles fill
   it stretched a 400px design across 1,400px — same classes, nothing alike. */
.ha-tx {
  display:flex; flex-direction:column; gap:14px;
  max-width:460px; margin:0 auto; padding:2px;
  font-size:12.5px; line-height:1.55; color:var(--primary-color,#1F3665);
}
/* The turn someone clicked through to find. The class goes on the .ha-msg, so
   the highlight has to reach into the bubble the chat markup puts inside it —
   the old rule named an element that no longer exists. */
.ha-tx .ha-msg.is-focus .ha-bubble {
  box-shadow: 0 0 0 3px rgba(74,193,134,.30);
  border-color: var(--green-color, #4ac186);
}

/* Admin-only furniture under each turn, at the transcript's own scale. */
.ha-tx .ha-tx-meta { font-size:10.5px; color:#A7B2C1; margin-top:5px; }
.ha-tx .ha-tx-rating { font-size:11px; margin-top:6px; }
.ha-tx .ha-tx-rating.is-up   { color:var(--green-color,#3aa76d); }
.ha-tx .ha-tx-rating.is-down { color:#C0392B; }
/* The green box carries its own time here rather than a relative one. */
.ha-tx .ha-escalate.is-sent .ha-esc-msg > span { font-size:11px; }

/* Refusals and system notices, marked as the chat marks them — those are the
   turns you are scanning a transcript to find. */

/* The turn you came to read. Fades after a moment — it is a signpost on arrival,
   not a permanent state of the message. */
@keyframes ha-tx-focus {
  0%, 55% { box-shadow:0 0 0 3px rgba(226,163,44,.35); }
  100%    { box-shadow:0 0 0 3px rgba(226,163,44,0); }
}







/* Feedback is the reason many of these get opened, so it says so in words. */
.ha-tx-rating { display:inline-flex; align-items:center; gap:5px; margin-top:7px;
  font-size:10.5px; font-weight:600; padding:3px 9px; border-radius:999px; }
.ha-tx-rating.is-up   { background:rgba(60,194,135,.13); color:#237a52; }
.ha-tx-rating.is-down { background:rgba(192,57,43,.10); color:#A93226; }

.ha-tx-meta { margin-top:6px; font-size:10.5px; color:#B0BAC7; }

.ha-adm-modal-box.wide { width:min(760px, 100%); max-height:min(820px, calc(100vh - 40px)); }
/* The access modal carries two searchable lists, so it needs the room the
   default 520px box does not have. */
#ha-access-modal .ha-adm-modal-box { width:min(600px, 100%); }

/* ── A card of the clinic's own numbers ───────────────────────────────────────
   The scoreboard's language, at chat size: metric, value against target, and a
   dot for the state. Deliberately not a table — five rows in a 400px bubble is
   the most that can be read without it becoming a screenshot of a dashboard. */
/* Side by side while both fit; the dates drop to their own line when they do
   not. A clinic name is not something to hyphenate into a corner, which is what
   a plain nowrap date next to it forces. */


/* The target sits with the value but must not compete with it. */


/* A week nobody entered, which is a different thing from a week of zeros. */

/* On the page there is room for the card to breathe a little more. */

/* ── Choices offered by a tool ────────────────────────────────────────────────
   Buttons, because the alternative is asking someone to retype
   "Huddersfield + Denby Dale · 2025" exactly. */

/* ── Thumbs on an answer ──────────────────────────────────────────────────────
   Faint until hovered. Feedback should be there when you want it and invisible
   when you do not — a pair of buttons under every reply competing with the reply
   is the fastest way to make people stop reading either. */
.ha-rate { display: flex; align-items: center; gap: 2px; margin-top: 6px; }
.ha-rate-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  border: 0; border-radius: 6px;
  background: none; color: #C3CCD8;
  font-size: 12px; cursor: pointer;
  opacity: 0;
  transition: opacity .15s, color .15s, background .15s;
}
.ha-msg:hover .ha-rate-btn,
.ha-rate-btn:focus-visible,
.ha-rate-btn.is-on { opacity: 1; }
.ha-rate-btn:hover { background: #EEF3F9; color: #54627A; }
.ha-rate-btn.is-on { color: var(--green-color, #3aa76d); }
.ha-rate-btn.is-on.is-down { color: #C0392B; }
/* Copy sits with the thumbs but is not a rating — a small gap keeps the two
   thumbs reading as a pair and this as its own thing. */
.ha-copy { margin-left: 6px; }
.ha-copy.is-done { color: var(--green-color, #3aa76d); opacity: 1; }
/* Touch has no hover, so they simply stay visible. */
@media (hover: none) { .ha-rate-btn { opacity: 1; } }


/* ── Hub Assistant admin ─────────────────────────────────────────────────── */
.ha-adm-notice { display:flex; align-items:center; gap:9px; padding:12px 16px; border-radius:9px;
  font-size:13.5px; margin-bottom:16px; }
.ha-adm-notice.ok  { background:rgba(60,194,135,.10); border:1px solid rgba(60,194,135,.32); color:#237a52; }
.ha-adm-notice.bad { background:rgba(226,163,44,.10); border:1px solid rgba(226,163,44,.34); color:#8A6111; }
.ha-adm-notice code { background:rgba(0,0,0,.06); padding:1px 5px; border-radius:4px; font-size:12px; }

.ha-adm-stats { display:flex; gap:12px; margin-bottom:20px; flex-wrap:wrap; }
.ha-adm-stat { flex:1 1 130px; background:#fff; border:1px solid #E4E9F0; border-radius:10px; padding:14px 16px; }
.ha-adm-stat b { display:block; font-size:22px; color:var(--primary-color,#1F3665); line-height:1.1; }
.ha-adm-stat span { font-size:12px; color:#6B7785; }

.ha-adm-card { background:#fff; border:1px solid #E4E9F0; border-radius:12px; padding:20px 22px; margin-bottom:16px; }
.ha-adm-card h3 { font-size:15px; color:var(--primary-color,#1F3665); margin:0 0 4px; font-weight:600; }
.ha-adm-hint { font-size:12.5px; color:#6B7785; margin:0 0 16px; line-height:1.55; }
.ha-adm-hint.inline { display:inline; margin-left:10px; }

.ha-adm-folder { display:grid; grid-template-columns:190px 1fr auto auto auto; gap:9px; align-items:center;
  padding:9px 0; border-top:1px solid #F1F4F8; }
.ha-adm-folder.new { border-top:1px dashed #D8E0EA; }
.ha-adm-folder input[type=text] { padding:8px 11px; border:1px solid #D8E0EA; border-radius:8px; font-size:13px; }
.ha-adm-roles { display:flex; gap:11px; flex-wrap:wrap; font-size:12px; color:#54627A; }
.ha-adm-roles label { display:inline-flex; align-items:center; gap:4px; margin:0; font-weight:400; }

/* ── Suggested questions ────────────────────────────────────────────────────
   The fields on one line, the reorder arrows parked on the right. Arrows rather
   than a number field: order only ever matters relative to the row above. */
.ha-adm-starter { display:flex; align-items:flex-start; gap:8px;
  padding:10px 0; border-top:1px solid #F1F4F8; }
.ha-adm-starter.new { border-top:1px dashed #D8E0EA; padding-top:14px; }
.ha-adm-starter-main { flex:1 1 auto; min-width:0;
  display:grid; grid-template-columns:190px minmax(0,1fr) auto auto auto auto;
  gap:8px; align-items:center; }
.ha-adm-starter input[type=text] { padding:8px 11px; border:1px solid #D8E0EA;
  border-radius:8px; font-size:13px; min-width:0; }
.ha-adm-starter input:focus { outline:none; border-color:var(--green-color,#4ac186);
  box-shadow:0 0 0 3px rgba(74,193,134,.13); }
/* An unpublished row stays editable, just visibly not live. */
.ha-adm-starter.is-off input[type=text] { color:#8A97A8; background:#FAFBFD; }

/* The waiting-to-index banner. Same shape as the stale one, but this is work
   not yet done rather than work gone out of date, so it reads as neutral. */
.ha-adm-stale.is-pending { border-color:#CFE0F5; background:#F2F7FE; color:#2C4E77; }
.ha-adm-stale.is-pending i { color:#4A7DB5; }

/* ── Clinic-data tools ────────────────────────────────────────────────────────
   Same row shape as the suggestion editor: identity, the long field that
   matters, access, a live switch, save. The description gets a textarea rather
   than an input because the model reads it whole and it is written in
   sentences. */
/* Off stays editable, just visibly not live — same as an unpublished starter. */
@media (max-width:900px) {
}

/* ── Support settings ─────────────────────────────────────────────────────
   Two fields and a button on one line, wrapping to stacked on a narrow admin. */
/* Two per row, then the note and the button on rows of their own.
   Four inputs and a button in one wrapping flex row left the button stranded
   mid-form with no obvious field it belonged to. */
.ha-adm-support { display:flex; gap:10px 14px; align-items:flex-start; flex-wrap:wrap; }
.ha-adm-support .ha-adm-field { flex:1 1 240px; min-width:0; margin-bottom:0; }
.ha-adm-support .ha-adm-field.is-wide { flex:1 1 100%; }

/* ── One block per email ─────────────────────────────────────────────────────
   Two emails go out of this screen and they are not the same email, so each
   one's subject and template sit together under its own heading. Grouped by
   field type instead, you filled in four boxes and worked out afterwards which
   two belonged to each other. */
.ha-adm-support-pair { flex:1 1 100%; padding-top:12px; border-top:1px solid #EEF2F7; }
.ha-adm-support-pair h5 { margin:0 0 9px; font-size:12.5px; font-weight:600;
  color:var(--primary-color,#1F3665); }
/* The subject is a sentence and takes the room; the id is a fixed-length token
   and does not need any more than it has. */
.ha-adm-support-row { display:flex; gap:12px; flex-wrap:wrap; }
.ha-adm-support-row .ha-adm-field { flex:1 1 300px; min-width:0; margin-bottom:0; }
.ha-adm-support-row .ha-adm-field.narrow { flex:0 1 220px; }
.ha-adm-support .ha-adm-support-note,
.ha-adm-support .ha-adm-support-actions { flex:1 1 100%; }
.ha-adm-support .ha-adm-support-note { margin:0; }
/* Left, under the fields, where the eye lands after the last one. */
.ha-adm-support .ha-adm-support-actions { margin-top:2px; }
.ha-adm-support input {
  width:100%; padding:9px 12px; border:1px solid #D8E0EA; border-radius:8px;
  font-size:13.5px; font-family:inherit;
}
.ha-adm-support input:focus { outline:none; border-color:var(--green-color,#4ac186);
  box-shadow:0 0 0 3px rgba(74,193,134,.13); }
.ha-adm-support-vars { margin-top:12px; }
.ha-adm-support-vars code {
  display:inline-block; margin:2px 3px 2px 0; padding:2px 7px;
  background:#F1F4F8; border:1px solid #E4E9F0; border-radius:5px;
  font-size:11.5px; color:#54627A;
}

/* An answer drawn from several documents. Amber rather than grey: it is not a
   fault, but it is the thing to look at first when the answer is wrong. */
.ha-tx-spans {
  background:#FBF3E2 !important; border-color:#E8D3A2 !important; color:#8A6212 !important;
  font-weight:600;
}
.ha-tx-spans i { color:#C08A2B !important; }

/* Spinner on a button that is doing something slow. */
.ha-adm-spin { display:inline-block; animation:ha-adm-spin 1s linear infinite; }
@keyframes ha-adm-spin { to { transform: rotate(360deg); } }
.ha-adm-btn:disabled { opacity:.72; cursor:default; }

/* Small print inside a hint: the exception, not the headline. */
.ha-adm-hint small { display:inline-block; margin-top:4px; font-size:11.5px; color:#98A4B4; }

/* ── Documents to review ──────────────────────────────────────────────────
   Grouped by what to do about it, not listed flat: overdue is a different job
   from due-soon, and both are different from never having had an owner. */
.ha-adm-revgroup { margin-top:14px; }
.ha-adm-revgroup h4 {
  display:flex; align-items:center; gap:7px; margin:0 0 8px;
  font-size:12px; font-weight:600; letter-spacing:.02em;
}
.ha-adm-revgroup h4 span {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:19px; height:19px; padding:0 5px; border-radius:999px;
  font-size:10.5px; font-variant-numeric:tabular-nums;
}
.ha-adm-revgroup ul { margin:0; padding:0; list-style:none;
  border:1px solid #EDF1F6; border-radius:9px; overflow:hidden; }
.ha-adm-revgroup li {
  display:flex; align-items:baseline; gap:9px; flex-wrap:wrap;
  padding:9px 12px; font-size:12.5px; background:#fff;
}
.ha-adm-revgroup li + li { border-top:1px solid #F1F4F8; }
.ha-adm-revgroup li b { color:var(--primary-color,#1F3665); font-weight:600; }
.ha-adm-revgroup li span {
  padding:1px 7px; border-radius:999px; background:#F1F4F8;
  font-size:11px; color:#5A6B7D;
}
.ha-adm-revgroup li em {
  margin-left:auto; font-style:normal; font-size:11.5px; color:#98A4B4;
  font-variant-numeric:tabular-nums;
}

.ha-adm-revgroup.is-overdue h4        { color:#A93226; }
.ha-adm-revgroup.is-overdue h4 span   { background:#FBEDEB; color:#A93226; }
.ha-adm-revgroup.is-overdue ul        { border-color:#F0D6D2; }
.ha-adm-revgroup.is-overdue li em     { color:#A93226; font-weight:600; }

.ha-adm-revgroup.is-soon h4           { color:#8A6212; }
.ha-adm-revgroup.is-soon h4 span      { background:#FBF3E2; color:#8A6212; }
.ha-adm-revgroup.is-soon ul           { border-color:#EFE0C2; }

.ha-adm-revgroup.is-unowned h4        { color:#5A6B7D; }
.ha-adm-revgroup.is-unowned h4 span   { background:#F1F4F8; color:#5A6B7D; }

/* Document metadata — owner, review date and aliases — is styled with
   .ha-adm-fact and .ha-adm-chip up in the documents table. The three stacked
   blocks that used to live here went when they became one line. */

/* ── Unanswered queue ─────────────────────────────────────────────────────
   State on every row, and the controls to move it. A gap someone chased is
   marked, because that one has a person waiting behind it. */
.ha-adm-gapfilters { display:flex; gap:6px; margin-bottom:12px; flex-wrap:wrap; }
.ha-adm-gapfilter {
  padding:6px 12px; border:1px solid #E2E8F0; border-radius:999px;
  background:#fff; color:#54627A; font-family:inherit; font-size:12px;
  font-weight:500; cursor:pointer; transition:background .12s, border-color .12s;
}
.ha-adm-gapfilter:hover { background:#F4F7FB; }
.ha-adm-gapfilter.is-on {
  background:var(--primary-color,#1F3665); border-color:var(--primary-color,#1F3665); color:#fff;
}

.ha-adm-gapstate {
  display:inline-flex; align-items:center; gap:5px;
  font-size:11.5px; font-weight:600; white-space:nowrap;
}
.ha-adm-gapstate.is-open    { color:#8A97A8; font-weight:500; }
.ha-adm-gapstate.is-covered { color:var(--green-color,#3aa76d); }
.ha-adm-gapstate.is-ignored { color:#A7B2C1; }

.ha-adm-chased {
  display:inline-flex; align-items:center; gap:4px;
  margin-top:4px; color:#9A6F14; font-size:11px; font-weight:600;
}

.ha-adm-gapdo { white-space:nowrap; }
.ha-adm-inline { display:inline-block; margin-left:6px; }
.ha-adm-gapdo select {
  padding:5px 8px; border:1px solid #E2E8F0; border-radius:7px;
  font-size:12px; font-family:inherit; color:#54627A; background:#fff;
}
.ha-adm-gapdo select:focus { outline:none; border-color:var(--green-color,#4ac186); }

/* The replace form is only a button; the file input inside it is hidden. */
.ha-adm-replace { display:inline; }



/* Below the gate: it came back, but on its own it would not have been answered. */

.ha-adm-check { display:inline-flex; align-items:center; gap:5px; margin:0;
  font-size:12px; font-weight:400; color:#54627A; white-space:nowrap; }

/* One control, split in two — not two buttons that happen to be near each other.
   The border lives on the group so the halves cannot drift apart. */
.ha-adm-move { flex:0 0 auto; display:flex; flex-direction:column;
  border:1px solid #E2E8F0; border-radius:8px; overflow:hidden; align-self:center; }
.ha-adm-arrow { width:28px; height:18px; display:flex; align-items:center;
  justify-content:center; padding:0; border:0; background:#fff;
  color:#6B7785; font-size:9px; line-height:1; cursor:pointer; }
.ha-adm-move form + form .ha-adm-arrow { border-top:1px solid #E2E8F0; }
.ha-adm-arrow:hover:not(:disabled) { background:#F4F7FB; color:var(--primary-color,#1F3665); }
/* Disabled, not hidden — a control that disappears at the ends makes the whole
   column jump as rows move. */
.ha-adm-arrow:disabled { opacity:.35; cursor:default; }

/* ── Access: a button that summarises, a modal that edits ────────────────────
   A dozen checkboxes inline made every row four lines tall for a setting most
   rows never change. The button says where it stands; the modal does the work. */
.ha-adm-access-btn { display:inline-flex; align-items:center; gap:6px;
  padding:6px 10px; border:1px solid #E2E8F0; border-radius:8px; background:#fff;
  font:inherit; font-size:12px; color:#6B7785; cursor:pointer; white-space:nowrap; }
.ha-adm-access-btn:hover { border-color:#CBD5E1; color:var(--primary-color,#1F3665); }
.ha-adm-access-btn:focus-visible { outline:2px solid var(--green-color,#4ac186); outline-offset:2px; }
.ha-adm-access-btn.is-set { border-color:rgba(74,193,134,.5); background:rgba(74,193,134,.07); }
.ha-adm-pill { background:#EEF2F7; color:#54627A; border-radius:999px;
  padding:1px 8px; font-size:11px; font-weight:600; }
.ha-adm-access-btn.is-set .ha-adm-pill { background:rgba(60,194,135,.16); color:#237a52; }
/* "Follows Head Physio Dashboard" is longer than the column. It truncates here
   rather than widening every row; the button's title says it in full. */
.ha-adm-access-btn { max-width:100%; }
.ha-adm-access-btn .ha-adm-pill { overflow:hidden; text-overflow:ellipsis; min-width:0; }

/* ── Who can see this: two ways to decide, the same shape ────────────────────
   The choice lives in the modal, not the row; the row only shows where it
   landed. Both halves are a card: a heading that selects it, then a search, then
   a scrolling list. Identical on purpose — the pair is one decision, and a
   different layout on each side would read as two unrelated settings. */
.ha-adm-mode { display:flex; flex-direction:column; gap:10px; }

.ha-adm-mode-card { border:1px solid #E2E8F0; border-radius:10px; background:#fff;
  transition:border-color .12s, background .12s; }
.ha-adm-mode-card[hidden] { display:none; }
.ha-adm-mode-card:hover { border-color:#CBD5E1; }
.ha-adm-mode-card:has(input[data-access-mode]:checked) {
  border-color:rgba(74,193,134,.55); background:rgba(74,193,134,.06); }

.ha-adm-mode-head { display:flex; align-items:flex-start; gap:9px;
  padding:11px 13px; cursor:pointer; margin:0; }
.ha-adm-mode-head input { margin-top:3px; flex:0 0 auto; }
.ha-adm-mode-head b { display:block; font-size:13px; color:var(--primary-color,#1F3665); }
.ha-adm-mode-head small { display:block; margin-top:2px; font-size:11.5px;
  line-height:1.5; color:#6B7785; font-weight:400; }
.ha-adm-mode-head small b { display:inline; font-size:inherit; font-weight:600; }

/* A folder or a starter has no tool to follow, so there is no choice to make.
   The card drops its heading and goes back to being the only thing there. */
.ha-adm-mode-card.is-only { border-color:transparent; background:none; }
.ha-adm-mode-card.is-only .ha-adm-mode-head { display:none; }
.ha-adm-mode-card.is-only .ha-adm-pickbody { padding:0; }
/* The explanation is inside the radio header, which is hidden here — so this
   copy of it takes over, and stays out of the way when the header is showing. */
.ha-adm-mode-card .is-onlynote { display:none; }
.ha-adm-mode-card.is-only .is-onlynote { display:block; margin:0 0 10px; }

/* ── The lists ───────────────────────────────────────────────────────────────
   Forty-three tools and twenty-two roles and memberships. A <select> gave a
   scroll with no way to narrow it and hid the choice the moment it closed —
   which is the thing you most want to see while deciding. These search, group,
   and stay open. Indented to sit under the radio they belong to. */
.ha-adm-pickbody { padding:0 13px 12px 35px; }
.ha-adm-pickbody .ha-adm-search { margin-bottom:7px; }
.ha-adm-pickbody .ha-adm-search input { width:100%; }

/* Tall enough to show a whole group and the start of the next, so the list
   reads as a list rather than as a window onto one. 196px cut the Memberships
   heading in half, which looks like something failed to load. */
.ha-adm-picklist { max-height:260px; overflow-y:auto; border:1px solid #E6EBF2;
  border-radius:9px; background:#fff; padding:4px; }
.ha-adm-pickcat { padding:7px 9px 3px; font-size:10px; font-weight:700;
  text-transform:uppercase; letter-spacing:.06em; color:#A7B2C1;
  position:sticky; top:-4px; background:#fff; }
.ha-adm-pickcat:first-child { padding-top:3px; }
.ha-adm-pickcat[hidden] { display:none; }

.ha-adm-pickopt { display:flex; align-items:center; gap:9px; margin:0;
  padding:6px 9px; border-radius:7px; cursor:pointer; font-size:12.5px;
  color:var(--primary-color,#1F3665); }
.ha-adm-pickopt:hover { background:#F4F7FB; }
.ha-adm-pickopt input { flex:0 0 auto; margin:0; }
.ha-adm-pickopt:has(input:checked) { background:rgba(74,193,134,.14); font-weight:600; }
.ha-adm-pickopt[hidden] { display:none; }

.ha-adm-picknone { margin:8px 0 0; font-size:12px; color:#8A94A6; text-align:center; }
.ha-adm-picknone[hidden] { display:none; }

/* Switched off, not hidden: seeing what the other half would be is useful, and
   disabling it is also what stops a half-made choice being saved. */
.ha-adm-pickbody.is-off { opacity:.4; pointer-events:none; }
.ha-adm-mode-card.is-only .ha-adm-pickbody.is-off { opacity:1; pointer-events:auto; }

.ha-adm-modal { position:fixed; inset:0; z-index:1090; display:flex;
  align-items:center; justify-content:center; padding:20px; }
.ha-adm-modal[hidden] { display:none; }
.ha-adm-modal-scrim { position:absolute; inset:0; background:rgba(17,32,56,.42); }
.ha-adm-modal-box { position:relative; z-index:1; width:min(520px,100%);
  max-height:min(680px, calc(100vh - 40px)); display:flex; flex-direction:column;
  background:#fff; border-radius:14px; box-shadow:0 24px 60px rgba(20,38,66,.3);
  animation:ha-pop-in-c .16s ease; }
@keyframes ha-pop-in-c { from { opacity:0; transform:scale(.97); } to { opacity:1; transform:none; } }
/* The page behind must not scroll while a modal is open. */
body.ha-adm-modal-open { overflow:hidden; }

.ha-adm-modal-box header { display:flex; align-items:center; justify-content:space-between;
  padding:16px 18px; border-bottom:1px solid #EDF1F6; }
.ha-adm-modal-box header h4 { margin:0; font-size:15px; font-weight:600;
  color:var(--primary-color,#1F3665); }
.ha-adm-modal-x { border:0; background:none; color:#8A97A8; font-size:13px;
  padding:4px 6px; border-radius:6px; cursor:pointer; }
.ha-adm-modal-x:hover { background:#F1F4F8; color:#54627A; }

/* Positioned, so a message's offsetTop is measured against this box and not
   against whatever happens to be the nearest positioned ancestor. */
.ha-adm-modal-body { position:relative; flex:1 1 auto; overflow-y:auto; padding:16px 18px; }
.ha-adm-modal-group + .ha-adm-modal-group { margin-top:18px; }
/* Direct children only.
   As a descendant selector this turned every <b> inside the group into a block
   heading — including the emphasis in "one of the roles AND one of the
   memberships", which came out on its own line, uppercase and grey. The heading
   it is for is always a direct child. */
.ha-adm-modal-group > b { display:block; font-size:11px; text-transform:uppercase;
  letter-spacing:.05em; color:#8A97A8; margin-bottom:8px; }
/* One column. Membership names run long enough that two columns wrap most of
   them onto a second line, which makes the list harder to scan than it is tall. */
.ha-adm-checks { display:flex; flex-direction:column; gap:2px; }
.ha-adm-checks label { display:flex; align-items:center; gap:9px; margin:0;
  padding:6px 8px; border-radius:7px; cursor:pointer;
  font-size:13px; font-weight:400; color:#54627A; }
.ha-adm-checks label:hover { background:#F6F8FC; }
.ha-adm-checks input { flex:0 0 auto; }
.ha-adm-access-note { margin:0 0 16px; padding:10px 12px; background:#F6F8FC;
  border-radius:8px; font-size:12px; line-height:1.5; color:#6B7785; }

.ha-adm-modal-box footer { display:flex; align-items:center; gap:8px;
  padding:13px 18px; border-top:1px solid #EDF1F6; }
.ha-adm-modal-spacer { flex:1 1 auto; }


.ha-adm-docaccess { display:flex; align-items:center; gap:6px; }

/* ── Card headers with a control on the right ──────────────────────────────── */
.ha-adm-cardhead { display:flex; align-items:flex-start; justify-content:space-between;
  gap:16px; flex-wrap:wrap; }
.ha-adm-cardhead h3 { margin-bottom:4px; }
.ha-adm-cardhead .ha-adm-hint { margin-bottom:0; }
.ha-adm-count { margin:12px 0 4px; font-size:11px; font-weight:600; letter-spacing:.05em;
  text-transform:uppercase; color:#9AA5B4; }

.ha-adm-search { position:relative; flex:0 0 auto; }
.ha-adm-search > i { position:absolute; left:11px; top:50%; transform:translateY(-50%);
  font-size:12px; color:#A7B2C1; pointer-events:none; }
.ha-adm-search input { width:230px; max-width:100%; padding:8px 11px 8px 31px;
  border:1px solid #E2E8F0; border-radius:9px; background:#F8FAFC;
  font:inherit; font-size:13px; color:#37475F; }
.ha-adm-search input:focus { outline:none; background:#fff;
  border-color:var(--green-color,#4ac186); box-shadow:0 0 0 3px rgba(74,193,134,.13); }
.ha-adm-search input::-webkit-search-decoration,
.ha-adm-search input::-webkit-search-cancel-button { -webkit-appearance:none; }

/* ── "Load more" ───────────────────────────────────────────────────────────── */
.ha-adm-more { display:flex; justify-content:center; padding:14px 0 2px; }
.ha-adm-more button { border:1px solid #E2E8F0; background:#fff; border-radius:9px;
  padding:8px 18px; font:inherit; font-size:12.5px; font-weight:600; color:#6B7785;
  cursor:pointer; }
.ha-adm-more button:hover { border-color:#CBD5E1; color:var(--primary-color,#1F3665); }

/* ── About the assistant ───────────────────────────────────────────────────── */
.ha-adm-about-form textarea { width:100%; padding:12px 14px; border:1px solid #D8E0EA;
  border-radius:10px; font:inherit; font-size:13.5px; line-height:1.6; color:#37475F;
  resize:vertical; }
.ha-adm-about-form textarea:focus { outline:none; border-color:var(--green-color,#4ac186);
  box-shadow:0 0 0 3px rgba(74,193,134,.13); }
.ha-adm-about-foot { display:flex; align-items:center; justify-content:space-between;
  gap:14px; margin-top:10px; flex-wrap:wrap; }
.ha-adm-about-foot .ha-adm-hint { margin:0; }

/* ── Upload row ────────────────────────────────────────────────────────────── */
/* A file input is the one control browsers will not let you style, so the real
   one is hidden inside the label and the visible parts are ours. */
.ha-adm-file { display:inline-flex; align-items:center; gap:11px; margin:0; cursor:pointer; }
.ha-adm-file input[type=file] { position:absolute; width:1px; height:1px;
  opacity:0; pointer-events:none; }
.ha-adm-file-btn { display:inline-flex; align-items:center; gap:7px;
  padding:9px 15px; border:1px solid #D8E0EA; border-radius:9px; background:#fff;
  font-size:13px; font-weight:600; color:var(--primary-color,#1F3665); white-space:nowrap; }
.ha-adm-file:hover .ha-adm-file-btn { border-color:#CBD5E1; background:#F8FAFC; }
.ha-adm-file input:focus-visible + .ha-adm-file-btn { outline:2px solid var(--green-color,#4ac186);
  outline-offset:2px; }
.ha-adm-file-name { font-size:12.5px; color:#9AA5B4; }
.ha-adm-file-name.is-set { color:var(--primary-color,#1F3665); font-weight:600; }

.ha-adm-inline { display:inline-flex; align-items:center; gap:9px; margin:0;
  font-size:12.5px; font-weight:600; color:#8A97A8; }
.ha-adm-inline select { padding:8px 11px; border:1px solid #D8E0EA; border-radius:9px;
  font:inherit; font-size:13px; color:#37475F; background:#fff; }

/* Guide state, sitting with the button it describes. */
.ha-adm-guidestat { font-size:12.5px; color:#8A97A8; }
.ha-adm-guidestat b { color:var(--primary-color,#1F3665); font-weight:600; }
.ha-adm-guidestat b.is-todo { color:#C08A2B; }

/* Only appears when something is actually out of date, so it can afford to be
   noticeable — it is never background furniture. */
.ha-adm-stale {
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  margin-top:12px; padding:11px 14px;
  border:1px solid #F0DCB0; border-radius:10px; background:#FFF9EC;
  font-size:12.5px; line-height:1.5; color:#6B5518;
}
.ha-adm-stale > span { flex:1 1 auto; min-width:0; }
.ha-adm-stale i { color:#C08A2B; margin-right:5px; }
.ha-adm-stale b { font-weight:700; }

.ha-adm-orline { display:flex; align-items:center; gap:12px; margin:16px 0;
  font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:#B4BECB; }
.ha-adm-orline::before, .ha-adm-orline::after { content:''; flex:1 1 auto;
  height:1px; background:#F1F4F8; }

.ha-adm-sync { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.ha-adm-sync .ha-adm-hint { margin:0; }

/* Editable in place. The title looks like text until you touch it — a table of
   input boxes reads as a form to fill in rather than a list to scan. */
/* An editable field that looked exactly like static text, so nobody could tell
   it was editable. A dashed underline is enough to say "you can change this"
   without turning a quiet list into a form. */
.ha-adm-doctitle { width:100%; max-width:300px; padding:5px 8px; font:inherit;
  font-size:13px; font-weight:600; color:var(--primary-color,#1F3665);
  border:1px solid transparent; border-radius:7px; background:transparent;
  border-bottom:1px dashed #CBD5E1; border-bottom-left-radius:0; border-bottom-right-radius:0;
  cursor:text; transition:border-color .14s, background .14s; }
.ha-adm-doctitle:hover { border-color:#E2E8F0; background:#fff;
  border-bottom-style:solid; border-bottom-color:#CBD5E1; }
.ha-adm-doctitle:focus { outline:none; border-color:var(--green-color,#4ac186);
  border-bottom-style:solid; background:#fff; box-shadow:0 0 0 3px rgba(74,193,134,.13);
  border-radius:7px; }
.ha-adm-table select { padding:6px 9px; border:1px solid #E2E8F0; border-radius:7px;
  font:inherit; font-size:12.5px; color:#54627A; background:#fff; max-width:170px; }
.ha-adm-table select:focus { outline:none; border-color:var(--green-color,#4ac186);
  box-shadow:0 0 0 3px rgba(74,193,134,.13); }
.ha-adm-docmeta { display:none; }

/* ── Resources on a document ────────────────────────────────────────────────── */
.ha-adm-resbtn { display:inline-flex; align-items:center; gap:5px;
  padding:6px 9px; border:1px solid #E2E8F0; border-radius:8px; background:#fff;
  font:inherit; font-size:12px; color:#6B7785; cursor:pointer; }
.ha-adm-resbtn:hover { border-color:#CBD5E1; color:var(--primary-color,#1F3665); }
.ha-adm-resbtn:focus-visible { outline:2px solid var(--green-color,#4ac186); outline-offset:2px; }
.ha-adm-resbtn .ha-adm-pill.is-on { background:rgba(60,194,135,.16); color:#237a52; }

/* The list inside the modal. */
.ha-adm-reslist { margin-bottom:16px; }
.ha-adm-resrow { display:flex; align-items:center; gap:10px; padding:9px 10px;
  border:1px solid #EDF1F6; border-radius:9px; margin-bottom:6px; background:#fff; }
.ha-adm-resrow.is-editing { border-color:var(--green-color,#4ac186);
  background:rgba(74,193,134,.06); }
.ha-adm-resrow > i { flex:0 0 auto; color:#8A97A8; font-size:15px; }
.ha-adm-resrow-body { flex:1 1 auto; min-width:0; line-height:1.35; }
.ha-adm-resrow-body b { display:block; font-size:13px; font-weight:600;
  color:var(--primary-color,#1F3665); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ha-adm-resrow-body span { display:block; font-size:11px; color:#9AA5B4; }

/* Labelled fields, because a modal has the room and a row of bare placeholders
   stops telling you anything the moment you start typing. */
/* Two dates side by side. They are one decision — when it was looked at and
   when it is next due — so they sit on one line and wrap together. */
.ha-adm-fieldrow { display:flex; gap:12px; flex-wrap:wrap; }
.ha-adm-fieldrow .ha-adm-field { flex:1 1 180px; min-width:0; }

/* Dates, matched to the text fields beside them. A native date input sizes
   itself from its own text, so two of them came out different widths for the
   same kind of value. */
.ha-adm-field input[type=date] { width:100%; padding:9px 11px;
  border:1px solid #D8E0EA; border-radius:8px; font:inherit; font-size:13px;
  color:var(--primary-color,#1F3665); background:#fff; }
.ha-adm-field input[type=date]:focus { outline:none;
  border-color:var(--green-color,#4ac186); box-shadow:0 0 0 3px rgba(74,193,134,.14); }

/* A note that sits with the form rather than above it. The old block sat between
   the reader and the first field, which is the one place a paragraph is most in
   the way. */
.ha-adm-note { display:flex; align-items:flex-start; gap:8px; margin:0 0 12px;
  padding:9px 11px; border-radius:8px; background:#F7F9FC;
  font-size:12px; line-height:1.55; color:#6B7785; }
.ha-adm-note i { flex:0 0 auto; margin-top:1px; color:#A7B2C1; }
.ha-adm-note.is-quiet { margin:2px 0 0; padding:0; background:none; color:#98A4B4;
  font-size:11.5px; }

/* ── Names, as chips ─────────────────────────────────────────────────────────
   The aliases are a list. Editing them as a line of commas meant dropping the
   middle name involved finding both commas and not leaving a double — so each is
   its own thing to remove, and the box behaves like the input it replaced. */
/* No border of its own: the chips are the content and the box below them is the
   input. Bordering both put a field inside a field, which read as a mistake. */
.ha-adm-tags { display:flex; flex-wrap:wrap; align-items:center; gap:5px; }

.ha-adm-tagchip { display:inline-flex; align-items:center; gap:2px;
  padding:4px 5px 4px 10px; border-radius:6px; background:#EEF2F7;
  font-size:12px; line-height:1.5; color:#54627A; }
.ha-adm-tagx { display:inline-flex; align-items:center; justify-content:center;
  width:17px; height:17px; padding:0; border:0; border-radius:4px;
  background:none; color:#A7B2C1; font-size:12px; cursor:pointer; }
.ha-adm-tagx:hover { background:rgba(169,50,38,.1); color:#A93226; }
.ha-adm-tagx:focus-visible { outline:2px solid var(--green-color,#4ac186); outline-offset:1px; }

/* Its own line, under whatever chips there are.
   Sharing a line meant it started wherever the last chip happened to end, so the
   place you type moved every time a name was added or removed. Below them it is
   in the same place every time, and it is plainly the thing you type into.

   The selector is this specific on purpose: .ha-adm-field input[type=text] also
   matches, at equal weight, and whichever came later in the file would win. */
.ha-adm-field .ha-adm-tags input.ha-adm-taginput {
  flex:1 0 100%; width:100%; margin-top:3px;
  padding:9px 11px; border:1px solid #D8E0EA; border-radius:8px;
  font:inherit; font-size:13px; background:#fff; }
.ha-adm-field .ha-adm-tags input.ha-adm-taginput:focus { outline:none;
  border-color:var(--green-color,#4ac186); box-shadow:0 0 0 3px rgba(74,193,134,.14); }
/* Nothing above it yet, so no gap to close. */
.ha-adm-field .ha-adm-tags input.ha-adm-taginput:first-child { margin-top:0; }


/* ── Preview ─────────────────────────────────────────────────────────────────
   The document as the assistant reads it. The chunk boundaries are the point: a
   document that answers badly usually chunks badly, and there was no way to see
   that without indexing it and asking questions until something went wrong. */
.ha-adm-prev { display:flex; flex-direction:column; gap:10px; }
.ha-adm-prevbar { display:flex; align-items:center; flex-wrap:wrap; gap:6px 14px;
  padding-bottom:10px; border-bottom:1px solid #EEF2F7;
  font-size:12px; color:#7A879A; }
.ha-adm-prevbar b { color:var(--primary-color,#1F3665); font-weight:600; }
.ha-adm-prevkind { padding:1px 7px; border-radius:5px; background:#F1F4F8;
  font-size:11px; font-weight:600; color:#7A879A; }
.ha-adm-prevnote { flex:1 1 100%; font-size:11.5px; color:#98A4B4; }

/* The front matter, shown as what it is: description, lifted off before the
   document is indexed rather than part of what it teaches. */
.ha-adm-prevmeta { display:grid; grid-template-columns:auto 1fr; gap:4px 10px;
  margin:0; padding:10px 12px; border-radius:8px; background:#F7F9FC; }
.ha-adm-prevmeta dt { font-size:11px; font-weight:600; color:#A7B2C1;
  text-transform:uppercase; letter-spacing:.04em; white-space:nowrap; }
.ha-adm-prevmeta dd { margin:0; font-size:12.5px; color:#54627A;
  overflow-wrap:anywhere; }

/* The document itself, read as a document. */
.ha-adm-prevbody { font-size:13px; line-height:1.65; color:#3E4C63; }
.ha-adm-prevbody > *:first-child { margin-top:0; }
.ha-adm-prevbody > *:last-child { margin-bottom:0; }
.ha-adm-prevbody p { margin:0 0 11px; }
.ha-adm-prevbody b, .ha-adm-prevbody strong { color:var(--primary-color,#1F3665); }
.ha-adm-prevbody ul, .ha-adm-prevbody ol { margin:0 0 11px; padding-left:20px; }
.ha-adm-prevbody li { margin-bottom:4px; }
.ha-adm-prevbody a { color:var(--green-color,#2f9e6a); }
.ha-adm-prevbody code { padding:1px 5px; border-radius:4px; background:#F1F4F8;
  font-size:12px; color:#54627A; }
/* The files use markdown headings for every question they answer, so these
   carry most of the structure. */
.ha-adm-prevbody h4 { margin:18px 0 7px; font-size:13.5px; font-weight:600;
  color:var(--primary-color,#1F3665); }
/* The file's own top-level heading repeats the document title in the modal's own
   header, so it is set down rather than up. */
.ha-adm-prevbody h4.ha-md-h1 { margin-top:0; font-size:15px; }
.ha-adm-prevbody h4.ha-md-h3, .ha-adm-prevbody h4.ha-md-h4 { font-size:12.5px; color:#54627A; }
.ha-adm-prevbody table { width:100%; border-collapse:collapse; margin:0 0 12px;
  font-size:12.5px; }
.ha-adm-prevbody th, .ha-adm-prevbody td { padding:6px 9px; text-align:left;
  border:1px solid #EEF2F7; }
.ha-adm-prevbody th { background:#F7F9FC; font-weight:600; color:#54627A; }

.ha-adm-field { display:block; margin-bottom:13px; }
/* :not([class]) matters. select2 replaces a <select> with a <span class="select2
   …">, which is a direct child of the field — so this rule was styling the whole
   dropdown as a label, and the placeholder came out uppercase, grey and 11px. A
   label here never carries a class; select2's container always does. */
.ha-adm-field > span:not([class]) { display:block; margin-bottom:5px;
  font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.05em;
  color:#8A97A8; }
.ha-adm-field > span:not([class]) em { font-style:normal; text-transform:none; letter-spacing:0;
  font-weight:400; color:#A7B2C1; }
.ha-adm-field input[type=text],
.ha-adm-field textarea { width:100%; padding:9px 11px; border:1px solid #D8E0EA;
  border-radius:8px; font:inherit; font-size:13px; }
.ha-adm-field textarea { resize:vertical; line-height:1.5; }
.ha-adm-field input:focus, .ha-adm-field textarea:focus { outline:none;
  border-color:var(--green-color,#4ac186); box-shadow:0 0 0 3px rgba(74,193,134,.13); }
.ha-adm-field input[type=file] { font-size:12.5px; }
.ha-adm-field small { display:block; margin-top:5px; font-size:11px; color:#9AA5B4; }
.ha-adm-field small:empty { display:none; }

/* Segmented control — one of two, never both. */
.ha-adm-seg { display:inline-flex; border:1px solid #E2E8F0; border-radius:9px;
  overflow:hidden; background:#F8FAFC; }
.ha-adm-seg button { display:inline-flex; align-items:center; gap:6px;
  padding:8px 14px; border:0; background:none; cursor:pointer;
  font:inherit; font-size:12.5px; font-weight:600; color:#8A97A8; }
.ha-adm-seg button + button { border-left:1px solid #E2E8F0; }
.ha-adm-seg button.is-on { background:#fff; color:var(--primary-color,#1F3665);
  box-shadow:inset 0 -2px 0 var(--green-color,#4ac186); }
.ha-adm-seg button:hover:not(.is-on) { color:#54627A; }

.ha-adm-modal-actions { display:flex; align-items:center; gap:8px;
  padding-top:12px; border-top:1px solid #EDF1F6; }


/* ── Live editing ─────────────────────────────────────────────────────────────
   Edits swap the list in place, so there is no page reload to confirm anything
   happened. The toast is that confirmation, and the row dims while it is in
   flight so a second click on a slow connection is obviously pointless. */
.ha-adm-toast { position:fixed; z-index:1095; left:50%; bottom:26px;
  transform:translateX(-50%);
  padding:10px 18px; border-radius:10px;
  background:var(--primary-color,#1F3665); color:#fff;
  font-size:13px; font-weight:500;
  box-shadow:0 12px 30px rgba(20,38,66,.28);
  animation:ha-toast-in .18s ease; }
.ha-adm-toast[hidden] { display:none; }
.ha-adm-toast.is-bad { background:#C0392B; }
@keyframes ha-toast-in { from { opacity:0; transform:translate(-50%,8px); }
                         to   { opacity:1; transform:translate(-50%,0); } }

/* Scoped: .is-busy is a name any form anywhere might use, and this page has no
   business dimming one it did not put the class on. */
.assistant-admin form.is-busy { opacity:.55; pointer-events:none; }
/* The documents pane while it fetches another page. Same treatment as a form
   mid-save, because it is the same wait. */
#ha-adm-documents.is-busy { opacity:.55; pointer-events:none; }

/* Column headings once per list, rather than a label on every row. In a grid of
   identical rows one set of headings reads better than the same three labels
   repeated down the page — the inputs still name themselves for screen readers. */
.ha-adm-heads { padding:0 0 6px; border:0; }
.ha-adm-heads span { font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
  color:#9AA5B4; font-weight:600; }
.ha-adm-heads.ha-adm-starter-main,


@media (max-width: 1100px) {
  /* The question needs the full width before it needs to share a row. */
  .ha-adm-starter-main { grid-template-columns:1fr auto auto auto auto; }
  .ha-adm-starter-main input[name=prompt] { grid-column:1 / -1; }
}

.ha-adm-upload { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.ha-adm-upload select { padding:8px 11px; border:1px solid #D8E0EA; border-radius:8px; font-size:13px; }

.ha-adm-btn { display:inline-flex; align-items:center; justify-content:center; gap:6px;
  padding:9px 16px; border-radius:8px; white-space:nowrap;
  border:1px solid transparent; background:linear-gradient(135deg,#52c98e 0%,#43bb7f 100%);
  color:#fff; font-size:13px; font-weight:600; line-height:1.2; cursor:pointer; }
.ha-adm-btn:hover { background:linear-gradient(135deg,#5ed49b 0%,#4ac186 100%); }
.ha-adm-btn:disabled { opacity:.5; cursor:default; }
.ha-adm-btn.sm { padding:6px 12px; font-size:12px; }
.ha-adm-btn.ghost { background:none; border-color:#D6DEE8; color:var(--primary-color,#1F3665); }
.ha-adm-btn.ghost:hover { background:#F7F9FC; }
.ha-adm-btn.danger { background:none; border-color:#E8C4C0; color:#C0392B; }
.ha-adm-btn.danger:hover { background:#FDF6F5; }

/* ── Tables ───────────────────────────────────────────────────────────────────
   Numbers right, words left, and a row you can actually track across. The
   defaults were doing none of that: left-aligned counts cannot be compared down
   a column, and 10px of padding on a row carrying two lines of text makes every
   row look like the same row. */
.ha-adm-table { width:100%; border-collapse:collapse; font-size:13px; }
.ha-adm-table thead th { border-bottom:1px solid #E4E9F0; }
.ha-adm-table tbody tr { transition:background .12s; }
.ha-adm-table tbody tr:hover { background:#F8FAFC; }

/* Right-aligned and tabular, so a column of figures lines up on the digit
   rather than wandering with the width of a 1 versus a 7. */
.ha-adm-table th.num, .ha-adm-table td.num {
  text-align:right; font-variant-numeric:tabular-nums; padding-right:18px;
  white-space:nowrap;
}
/* A dash is not data — it should recede rather than sit at full strength in the
   middle of a column of real numbers. */
.ha-adm-table td.num.is-nil { color:#C3CCD8; }

/* The whole row opens the thing the row is about. A button in the last column
   makes the other 90% of the row look inert. */
.ha-adm-table tr.is-clickable { cursor:pointer; }
.ha-adm-table tr.is-clickable:hover { background:#F4F7FB; }
.ha-adm-table tr.is-clickable:hover .ha-adm-rowgo { color:var(--primary-color,#1F3665); }
.ha-adm-rowgo { color:#C3CCD8; font-size:14px; transition:color .12s; }
.ha-adm-th-note { text-transform:none; letter-spacing:0; font-weight:400; color:#A7B2C1; }
.ha-adm-table th { text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
  color:#98A3B3; font-weight:700; padding:0 14px 10px 0; white-space:nowrap; }
.ha-adm-table td { padding:13px 14px 13px 0; border-top:1px solid #F1F4F8; vertical-align:middle; }
.ha-adm-table tbody tr:first-child td { border-top:0; }
/* Failure notes only — scoped so it stops colouring every secondary line in
   every table red. */
.ha-adm-table td small.is-fail { color:#A93226; font-size:11.5px; }
.ha-adm-actions { display:flex; gap:6px; justify-content:flex-end; }
.ha-adm-tag { display:inline-block; white-space:nowrap; vertical-align:middle;
  font-size:10px; text-transform:uppercase; letter-spacing:.05em; background:#EEF2F7;
  color:#6B7785; padding:2px 6px; border-radius:4px; margin-left:6px; }

/* A pill that wraps stops being a pill — the rounded ends land mid-word and the
   two halves overlap. "Not indexed" holds its line and the column is sized for
   it. */
.ha-adm-state { display:inline-block; white-space:nowrap;
  font-size:11px; font-weight:700; padding:3px 9px; border-radius:999px; }
.ha-adm-state--indexed { background:rgba(60,194,135,.15); color:#237a52; }
.ha-adm-state--pending { background:rgba(226,163,44,.16); color:#8A6111; }
.ha-adm-state--failed  { background:rgba(192,57,43,.10); color:#A93226; }


/* Shown while a thread is being fetched — an empty panel reads as a failure. */
.ha-loading {
  flex: 1 1 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px;
  color: #97A6B8; font-size: 12.5px;
}
.ha-loading .ha-dots i { background: #C3CEDC; }

/* ── In-panel confirmation ───────────────────────────────────────────────── */
/* Sits between the thread and the composer so the question appears next to the
   button that raised it, rather than in a browser dialog at the top of the screen. */
/* ── New chat dialog ──────────────────────────────────────────────────────────
   Floats over the chat rather than sitting in the flow. As a block it pushed the
   composer down the moment it appeared, moving the button you were aiming at;
   and a bar wedged between the thread and the input read as a message rather
   than a question waiting on an answer.

   White, not amber. Amber says something is about to go wrong — and since the
   history landed, nothing does: the chat is kept, which is exactly what the
   dialog now says. */
.ha-confirm {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  /* Above the history panel, so New chat can be answered from either place
     without the list closing underneath the question. */
  z-index: 8;
  width: calc(100% - 36px);
  max-width: 330px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 3px 11px;
  margin: 0;
  padding: 18px;
  background: #fff;
  border: 1px solid #E7ECF3;
  border-radius: 14px;
  box-shadow: 0 20px 48px rgba(20,38,66,.24), 0 2px 6px rgba(20,38,66,.08);
  animation: ha-pop-in .16s ease;
}
@keyframes ha-pop-in {
  from { opacity: 0; transform: translate(-50%, -46%) scale(.97); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.ha-confirm-icon {
  grid-row: 1 / 3;
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 10px;
  background: rgba(60,194,135,.13);
  color: #2E9E6B;
  font-size: 15px;
}
.ha-confirm-title {
  align-self: center;
  font-size: 14.5px; font-weight: 600; line-height: 1.3;
  color: var(--primary-color, #1F3665);
}
.ha-confirm-sub {
  font-size: 12.5px; line-height: 1.5;
  color: #7A8698;
}
/* Under the whole dialog, not just the text column — two buttons indented to
   align with a paragraph look like part of the sentence. */
.ha-confirm-actions {
  grid-column: 1 / -1;
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: 14px;
}

/* Dims what is behind it, so the dialog reads as the only thing to answer. */
.ha-root.is-asking .ha-body::after {
  content: '';
  position: absolute; inset: 0; z-index: 7;
  background: rgba(17,32,56,.24);
  animation: ha-fade .16s ease;
}
.ha-confirm-btn {
  border: 1px solid #E2E8F0;
  background: #fff;
  border-radius: 9px;
  padding: 8px 15px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: #54627A;
  cursor: pointer;
  transition: background .14s, border-color .14s, color .14s;
}
.ha-confirm-btn:hover { background: #F6F8FC; border-color: #CBD5E1; color: var(--primary-color, #1F3665); }
.ha-confirm-btn.is-go {
  background: var(--primary-color, #1F3665);
  border-color: var(--primary-color, #1F3665);
  color: #fff;
}
.ha-confirm-btn.is-go:hover { background: #16294e; }
.ha-confirm-btn:focus-visible { outline: 2px solid var(--green-color, #4ac186); outline-offset: 2px; }

/* Marker for older messages, shown at the top of a paged thread. */
.ha-more { display: flex; justify-content: center; padding: 2px 0 12px; }
.ha-more button {
  border: 1px solid #E2E9F2; background: #fff; border-radius: 999px;
  padding: 5px 14px; font: inherit; font-size: 11.5px; font-weight: 600;
  color: #6B7785; cursor: pointer;
}
.ha-more button:hover { border-color: #C6D2E2; color: var(--primary-color, #1F3665); }
.ha-more .ha-dots { padding: 6px 0; }

/* ── Who can see the chat ──────────────────────────────────────────────────
   Two tick-lists side by side, because memberships and roles are read together:
   the rule is "one of these AND one of those", and putting them in a column
   would hide half of it below the fold on the list that matters most. */
.ha-adm-gate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  margin-bottom: 18px;
}
.ha-adm-gate-set {
  border: 1px solid #E4EAF2;
  border-radius: 10px;
  padding: 14px 16px 12px;
  margin: 0;
  min-width: 0;
}
.ha-adm-gate-set legend {
  font-size: 13px; font-weight: 700; color: #1B2A4A;
  padding: 0 6px; width: auto; margin: 0;
}
.ha-adm-gate-note { font-size: 12px; color: #7C8BA1; margin: 0 0 10px; }
/* Its own scroll: 17 memberships is a long column next to 5 roles, and letting
   it set the card's height makes the roles list look like a mistake. */
.ha-adm-gate-ticks { display: flex; flex-direction: column; gap: 2px; max-height: 232px; overflow-y: auto; }
.ha-adm-tick {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 6px; border-radius: 7px; cursor: pointer;
  font-size: 13px; color: #33415C; line-height: 1.35;
}
.ha-adm-tick:hover { background: #F4F7FB; }
.ha-adm-tick input { margin: 0; flex: 0 0 auto; }
.ha-adm-tick span  { min-width: 0; }
.ha-adm-gate-more { margin: 4px 0 16px; }
.ha-adm-gate-more > summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: #33415C;
  padding: 6px 0; list-style: revert;
}
.ha-adm-gate-more[open] > summary { margin-bottom: 12px; }
.ha-adm-gate-actions { display: flex; justify-content: flex-end; }
/* select2 sets its own width inline; this keeps the closed control lined up
   with the text inputs above it rather than hugging its content. */
.ha-adm-gate .select2-container { width: 100% !important; }
/* Nothing selected is a real state, not an empty form: it closes the chat to
   everybody, and the hint has to carry that weight rather than read as a note. */
.ha-adm-gate-shut { color: #B4232A; }

/* ── Overview ──────────────────────────────────────────────────────────────
   Tiles, not cards: these are read at a glance and compared with each other, so
   they share one grid, one baseline and one inner rhythm. Auto-fit rather than a
   fixed count, because six across on a laptop is unreadable and two on a wide
   screen wastes it. */
/* The Hub's .rdx-stats is a fixed four-column grid, which suits the four cards
   the main dashboard shows and leaves two stranded on a second row here. Flex
   with every card allowed to grow means a short last row widens to fill the
   space instead of trailing off, whatever the count. */
.ha-adm-stats-grid {
  display: flex; flex-wrap: wrap;
  /* .rdx-stats carries margin-bottom:24px for the main dashboard, where the
     cards sit on the page. Inside a card the padding already provides it, and
     leaving it doubled the gap under the row. */
  margin-bottom: 0;
}
.ha-adm-stats-grid > .rdx-stat-card { flex: 1 1 190px; min-width: 0; }
.ha-adm-stats-grid .rdx-stat-foot a { color: #1B6FB8; text-decoration: none; }
.ha-adm-stats-grid .rdx-stat-foot a:hover { text-decoration: underline; }

/* The window picker. Segmented, so the options read as one control with one of
   them chosen, rather than five separate links that happen to sit together. */
.ha-adm-range {
  display: flex; gap: 2px; flex-wrap: wrap;
  background: #EEF2F7; padding: 3px; border-radius: 9px;
  /* Pushed to its own end of the row rather than sitting against the heading,
     which made the two read as one control with a label. */
  margin-left: auto;
}
.ha-adm-rangebtn {
  padding: 5px 11px; border-radius: 7px; font-size: 12.5px;
  color: #55627A; text-decoration: none; white-space: nowrap;
  /* Custom is a <button> among <a>s and arrives with a UA border and font. */
  border: 0; background: transparent; font-family: inherit; cursor: pointer;
}
.ha-adm-rangebtn:hover { color: #1B2A4A; }
.ha-adm-rangebtn.is-on { background: #fff; color: #1B2A4A; font-weight: 600; box-shadow: 0 1px 2px rgba(27,42,74,.10); }

/* Chart.js needs a sized box to be responsive inside; without a height here the
   canvas grows on every resize. */
.ha-adm-chart { position: relative; height: 260px; }

/* ── Conversations: the person's threads beside the transcript ────────────
   The rail only exists when a person was opened; coming from the unanswered
   list there is one conversation and nothing to list, so the class is added by
   the opener rather than assumed here. */
.ha-adm-tx-split { display: flex; min-height: 0; flex: 1 1 auto; }
.ha-adm-tx-rail {
  display: none;
  flex: 0 0 244px;
  border-right: 1px solid #E4EAF2;
  background: #FBFCFE;
  overflow-y: auto;
  padding: 8px;
}
#ha-tx-modal.has-rail .ha-adm-tx-rail { display: block; }
.ha-adm-threads { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.ha-adm-thread {
  display: flex; flex-direction: column; gap: 2px;
  width: 100%; text-align: left;
  padding: 9px 10px; border: 0; border-radius: 8px;
  background: transparent; cursor: pointer; color: #33415C;
}
.ha-adm-thread:hover { background: #EFF4FA; }
.ha-adm-thread.is-on { background: #E6EFFA; }
/* The title is the person's own words and can be any length; two lines then
   ellipsis keeps the rail scannable without hiding which thread is which. */
.ha-adm-thread-t {
  font-size: 13px; font-weight: 600; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ha-adm-thread-m { font-size: 11px; color: #8A97AC; }
.ha-adm-thread-m b { color: #B4232A; font-weight: 600; }
.ha-adm-tx-split > .ha-adm-modal-body { flex: 1 1 auto; min-width: 0; }

@media (max-width: 720px) {
  /* Stacked rather than side by side: 244px of rail on a phone leaves the
     transcript in a column too narrow to read. */
  .ha-adm-tx-split { flex-direction: column; }
  .ha-adm-tx-rail { flex: 0 0 auto; max-height: 168px; border-right: 0; border-bottom: 1px solid #E4EAF2; }
}
\n
/* The section while a tab is being fetched. Dimmed rather than blanked: the old
   screen staying put for a beat reads as fast, where an empty box reads as
   broken — and on a quick connection this is never seen at all. */
#ha-adm-section { transition: opacity .12s ease; }
#ha-adm-section.is-loading { opacity: .45; pointer-events: none; }

/* A table inside a modal scrolls in its own box, not by widening the modal or
   pushing the page sideways. The header row stays put so the columns are still
   labelled once you have scrolled down a long clinic. */
.ha-adm-modal-body > .ha-adm-table { margin: 0; }
.ha-adm-modal-body { overflow-x: auto; }
.ha-adm-modal-body > .ha-adm-table thead th {
  position: sticky; top: -16px;
  background: #fff; z-index: 1;
}
#ha-usage-body .ha-adm-table td,
#ha-usage-body .ha-adm-table th { white-space: nowrap; }
#ha-usage-body .ha-adm-table td:first-child,
#ha-usage-body .ha-adm-table th:first-child { white-space: normal; min-width: 180px; }

/* ── The "always allow these people" chips ─────────────────────────────────
   SPECIFICITY, DELIBERATELY. select2's stylesheet is loaded from a CDN in
   header.php AFTER this file, so at equal weight its defaults win and an
   override here does nothing at all. Its own rules are
   .select2-container--default .select2-selection--multiple .select2-selection__choice
   at three classes; prefixing .assistant-admin makes four and settles it
   without !important on every line.

   select2 4.1 renders each choice as a <button> remove followed by a
   <span class="…__display"> holding whatever templateSelection returned. */
.assistant-admin .select2-container--default .select2-selection--multiple {
  min-height: 44px;
  padding: 5px;
  border: 1px solid #D9E1EC;
  border-radius: 10px;
  background: #fff;
}
.assistant-admin .select2-container--default.select2-container--focus .select2-selection--multiple {
  border-color: #9FBEE3;
}
.assistant-admin .select2-container--default .select2-selection--multiple .select2-selection__rendered {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 0; margin: 0;
}
.assistant-admin .select2-container--default .select2-selection--multiple .select2-selection__choice {
  display: flex; align-items: center; gap: 6px;
  /* select2 sets margins per side; all four are replaced by the gap above. */
  margin: 0;
  padding: 6px 6px 6px 10px;
  background: #F4F8FD;
  border: 1px solid #DCE7F4;
  border-radius: 9px;
  /* Two of these have to fit a row on a laptop without either one wrapping to
     its own line, and an email is the widest thing in them. */
  max-width: min(320px, 100%);
  min-width: 0;
}
.assistant-admin .select2-container--default .select2-selection--multiple .select2-selection__choice__display {
  padding: 0; min-width: 0; order: 1;
}
.assistant-admin .ha-person { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.assistant-admin .ha-person b {
  font-size: 12.5px; font-weight: 600; color: #1B2A4A;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.assistant-admin .ha-person small {
  font-size: 11px; color: #7C8BA1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* The × last and quiet. select2 puts it first with a border down one side,
   which is what made it read as a separate box stuck to the front of the card. */
.assistant-admin .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
  order: 2;
  position: static;
  width: 20px; height: 20px; flex: 0 0 20px;
  display: flex; align-items: center; justify-content: center;
  margin: 0; padding: 0;
  border: 0; border-right: 0;
  border-radius: 6px;
  background: transparent; color: #9AA8BC;
  font-size: 14px; font-weight: 400; line-height: 1;
}
.assistant-admin .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover,
.assistant-admin .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:focus {
  background: #E3EBF5; color: #33415C; outline: none;
}

/* ── Overview: the window picker ──────────────────────────────────────────
   The preset buttons and the custom range are one control in two parts, so they
   share a row and wrap together rather than the dates dropping under the card's
   heading on their own. */
.ha-adm-ranges {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-left: auto;
}
.ha-adm-range { margin-left: 0; }
.ha-adm-daterange {
  display: flex; align-items: center; gap: 6px;
  padding: 3px; border: 1px solid #E4EAF2; border-radius: 9px;
  background: #fff;
}
.ha-adm-daterange.is-on { border-color: #9FBEE3; background: #F7FAFE; }
.ha-adm-daterange input[type="date"] {
  border: 0; background: transparent;
  font-size: 12.5px; color: #33415C; padding: 4px 6px;
  font-family: inherit;
}
.ha-adm-daterange input[type="date"]:focus { outline: none; }
.ha-adm-daterange-to { font-size: 12px; color: #8A97AC; }
.ha-adm-daterange .ha-adm-btn { padding: 4px 10px; }
/* Visible to a screen reader only — the date inputs need names, but "From" and
   "To" printed beside them would double up with the "to" already between. */
.ha-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* Heading and its subtitle on the left, the window picker on the right, both
   aligned to the top so the picker does not float against the middle of a
   two-line block. */
.ha-adm-h3row--stacked { align-items: flex-start; }
.ha-adm-h3text { min-width: 0; }
.ha-adm-h3sub {
  margin: 3px 0 0;
  font-size: 12.5px;
  color: var(--rdx-muted, #8992a3);
}

/* Breathing room, in two places.
   Inside the card: the stat row needs air under the heading, which now holds
   the window picker as well and reads as a control strip.
   Between cards: .ha-adm-card already carries margin-bottom:16px and adjacent
   margins collapse, so this is the larger of the two rather than a sum — 24px
   is enough to read the stats and the chart as separate blocks. */
.ha-adm-card > .ha-adm-stats-grid { margin-top: 16px; }
.ha-adm-card + .ha-adm-card       { margin-top: 24px; }
