/* Adealia Brokerage Services — stylesheet.
   Layout and component structure are the original assistant's, unchanged.
   Colour and type come from the Adealia design system (adealia-tokens.css):
   warm paper canvas, navy authority, ONE attention colour (copper amber) for
   the primary CTA, action-blue for links.

   The legacy token names (--peach, --cream, --line, …) are kept as aliases so
   every rule below is untouched by the palette move — same trick the design
   system itself uses. Only the VALUES changed. */

/* The faces. Instrument Sans carries the UI and JetBrains Mono carries data;
   the display face is Space Grotesk, imported by `adealia-tokens.css`.
   INSTRUMENT SERIF IS GONE and is not requested here any more — it was the
   concept's display face, it read as a newspaper at 46px across every page
   title, and leaving the import behind would have downloaded a face nothing
   uses. `components.css` §Type has the reasoning. */
@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  /* ── Brand ─────────────────────────────────────────────────────── */
  --ink-navy:     #1A2547;
  --warm-paper:   #F6F4EF;
  --steel-slate:  #33475B;
  --copper-amber: #D97A34;   /* THE CTA colour — one per view */
  --signal-green: #1F9D74;   /* data/status only */
  --action-blue:  #2F6DF6;   /* informational links only, never a button */

  /* The brand hues are FILL colours and fail as text; each has a -deep
     partner that passes WCAG AA on paper. Do not "fix" these by eye. */
  --copper-cta:   #A85A22;   /* CTA fill, white text — 5.06:1 */
  --copper-press: #94501E;   /* CTA hover — darker, white stays 6.13:1 */
  --copper-deep:  #A85A22;
  --green-deep:   #0F6B4F;
  --blue-deep:    #1B54D0;

  --navy-soft:    #2A335A;
  --navy-deep:    #11173A;

  /* ── Legacy aliases — the values moved, the names did not ──────── */
  --navy:        var(--ink-navy);
  --peach:       var(--action-blue);
  --peach-soft:  #C3D5FB;
  --peach-deep:  var(--blue-deep);

  /* ── Neutrals — warm-tinted slate, tuned to sit on warm paper ──── */
  --ink-1:  var(--ink-navy);
  --ink-2:  var(--steel-slate);
  --ink-3:  #4F6178;

  /* --ink-4 WAS #8B9AAC, and that value could not be read.
     It measured 2.87:1 on white, 2.61:1 on paper and 2.39:1 on the sidebar,
     against the 4.5:1 that body text needs — and it is the colour of EVERY
     field label in this app (`.person-label`, `.prof-grid label`,
     `.prof-readonly dt`, `.ev-desc-label`), every timestamp, and the chat
     placeholder. 25 rules in this file. The failure was app-wide and nobody
     had measured it, because no planning document in this project has ever
     used the word contrast — see `planning/reports/01-ui-ux-review.md` D1.

     The value below is the SAME HUE darkened until it passes on the darkest
     ground it lands on (the sidebar): 5.41:1 on white, 4.92:1 on paper,
     4.50:1 on sunken. The tier survives — it is still visibly quieter than
     --ink-3 at 6.34 / 5.77 / 5.28 — so no call site had to move.

     The token was changed rather than its 25 call sites, deliberately. A
     26th use is inevitable, and it should be safe by default. */
  --ink-4:  #616B78;

  --line:   #DFD9CE;
  --line-2: #EBE7DE;
  --line-3: #CBC3B4;

  /* The boundary of a CONTROL, and nothing else.
     --line is a decorative rule and is allowed to be quiet: it measures
     1.40:1 on white, which is fine for separating two cards and is not fine
     for telling somebody where a text box begins. WCAG 1.4.11 wants 3:1 for
     the edge of an input, which is exactly the case it exists for.
     This measures 3.30:1 on white and 3.00:1 on paper. Report 01, D5.
     Use --line for dividers. Use this for anything you can type into. */
  --line-input: #918D86;

  --cream:  var(--warm-paper);
  --sunken: #EDEAE3;
  --white:  #FFFFFF;

  /* ── Semantic — status pills, badges. Validated pairs; don't remix. ─ */
  --ok-bg:    #E3F2EA;  --ok-fg:    var(--green-deep);  --ok-dot:    var(--signal-green);
  --warn-bg:  #FAEBDA;  --warn-fg:  #7A3D10;            --warn-dot:  var(--copper-amber);
  --alert-bg: #F9E9E3;  --alert-fg: #7A2E14;            --alert-dot: #A33F1D;
  --info-bg:  #E7F0FB;  --info-fg:  #1B4E86;            --info-dot:  var(--action-blue);
  --muted-bg: #ECE7DF;  --muted-fg: #6B6257;            --muted-dot: #8A7F70;
  --okA-fg:   var(--green-deep);

  /* ── Type ──────────────────────────────────────────────────────── */
  --font-display: 'Space Grotesk', 'Geist', 'Public Sans', Arial, sans-serif;
  --font-sans:    'IBM Plex Sans', 'Geist', 'Public Sans', Arial, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Menlo, Consolas, monospace;

  --radius: 22px;
  --radius-sm: 14px;
  --shadow-sm: 0 1px 2px rgba(26, 37, 71, 0.04), 0 2px 6px rgba(26, 37, 71, 0.05);
  --shadow-md: 0 4px 12px rgba(26, 37, 71, 0.06), 0 18px 48px rgba(26, 37, 71, 0.09);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font-sans);
  color: var(--ink-1);
  background: var(--cream);
  display: flex;
  flex-direction: row;
  -webkit-font-smoothing: antialiased;
}
.main-col {
  flex: 1;
  min-width: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ---- sidebar ---- */
.sidebar {
  width: 262px;
  flex: none;
  height: 100vh;
  background: var(--sunken);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  padding: 12px 10px;
  gap: 9px;
  overflow: hidden;
}
.new-chat {
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 11px 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: var(--shadow-sm);
  transition: border-color 0.18s, transform 0.18s;
}
.new-chat:hover { border-color: var(--peach-deep); transform: translateY(-1px); }
.new-chat .plus { font-size: 17px; font-weight: 700; color: var(--peach-deep); }
.conv-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.conv-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 10px;
  border-radius: 9px;
  cursor: pointer;
  color: var(--ink-2);
  font-size: 13.5px;
  transition: background 0.15s;
}
.conv-item:hover { background: rgba(26, 37, 71, 0.05); }
.conv-item.active { background: var(--white); color: var(--ink-1); font-weight: 600; box-shadow: var(--shadow-sm); }
.conv-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-del {
  border: 0;
  background: none;
  color: var(--ink-4);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  border-radius: 6px;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s;
}
/* :focus-within, not only :hover. Revealing a control on hover alone means a
   keyboard user tabs onto a button with opacity 0 — it holds focus, it is
   fully transparent, and there is no pointer-free way to delete a
   conversation. Report 01, D4. */
.conv-item:hover .conv-del,
.conv-item:focus-within .conv-del { opacity: 1; }
.conv-del:hover { color: #c0392b; }
/* workspace header (R1) */
.workspace {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 12px 10px;
  box-shadow: var(--shadow-sm);
  text-align: center;
}
.ws-logo { max-width: 100%; max-height: 40px; height: auto; display: block; margin: 0 auto 5px; object-fit: contain; }
.ws-sub { font-size: 10.5px; color: var(--ink-3); font-family: var(--font-mono); letter-spacing: 0.02em; }

/* logged-in agent + powered-by */
.sidebar-foot {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.user-chip { display: flex; align-items: center; gap: 9px; }
.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(150deg, var(--navy-soft), var(--navy-deep));
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.user-name { font-size: 13px; font-weight: 700; color: var(--ink-1); line-height: 1.25; }
.user-role { font-size: 11.5px; color: var(--ink-3); }
.powered { display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--ink-3); font-weight: 600; }
.powered img { height: 14px; width: auto; }
/* user chip relocated to the header top-right */
.header-user { gap: 10px; }
.header-user .user-text { text-align: right; line-height: 1.2; }

/* login screen (demo opener) */
#login {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: radial-gradient(120% 90% at 50% 0%, #ffffff 0%, var(--cream) 60%);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.3s ease;
}
#login.hide { opacity: 0; }
.login-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: var(--shadow-md);
  padding: 38px 34px 30px;
  width: min(90vw, 380px);
  text-align: center;
}
.login-logo { max-width: 200px; height: auto; display: block; margin: 0 auto 24px; }
.login-title { font-size: 20px; font-weight: 800; color: var(--navy); margin: 0 0 6px; letter-spacing: -0.01em; }
.login-sub { font-size: 13.5px; color: var(--ink-2); margin: 0 0 24px; }
.login-btn {
  width: 100%;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 12px;
  border-radius: 12px;
  border: 1px solid var(--line-3);
  background: var(--white);
  color: var(--ink-1);
  cursor: pointer;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  transition: border-color 0.18s, transform 0.18s;
}
.login-btn:hover { border-color: var(--navy); transform: translateY(-1px); }
.login-btn.ghost { color: var(--ink-2); }
.login-btn .g { font-weight: 800; color: #4285f4; }
.login-foot {
  margin-top: 18px;
  font-size: 11.5px;
  color: var(--ink-3);
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.login-foot img { height: 15px; width: auto; }
.brand-mark.small { width: 20px; height: 20px; border-radius: 6px; box-shadow: none; }
.brand-mark.small::after { width: 7px; height: 7px; }
/* The original build simply hid the rail below 760px, because it had no
   mobile navigation — losing the rail meant losing Resources, quick links and
   chat history entirely. It is now off-canvas behind a toggle instead; see
   the mobile block at the end of this file. */

/* chat/resources nav — flat list items */
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  width: 100%;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 9px 9px;
  border: 0;
  background: none;
  border-radius: 8px;
  color: var(--ink-2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  transition: background 0.15s;
}
.nav-item:hover { background: var(--white); }
.nav-item.active { background: var(--white); color: var(--navy); box-shadow: var(--shadow-sm); }

/* uniform monochrome line icons across the sidebar */
.ico {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--ink-3);
}
.nav-item.active .ico { color: var(--navy); }
.side-link:hover .ico, .product-link:hover .ico { color: var(--ink-2); }
.ico.ext { width: 13px; height: 13px; color: var(--ink-4); }
.product-link.current .ico { color: var(--navy); }

/* split middle: links (top half) + chat history (bottom half) */
.sidebar-mid { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.links-section {
  /* Shrinkable and scrollable: with quick links, the product rail and the
     knowledge-base picker all present, a fixed-height region pushes Recent
     chats off the bottom of the viewport. */
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 6px 0 16px;
  border-bottom: 1px solid var(--line);
}
.history-section {
  flex: 1 1 auto;
  min-height: 132px;   /* always show a few chats, even on a short viewport */
  display: flex;
  flex-direction: column;
  padding-top: 8px;
  gap: 6px;
  overflow: hidden;
}
.history-section .conv-list { flex: 1; }
.hist-head { display: flex; align-items: center; justify-content: space-between; padding: 0 4px 0 8px; }
.new-chat-mini {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--peach-deep);
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex: none;
  box-shadow: var(--shadow-sm);
  transition: border-color 0.15s, transform 0.15s;
}
.new-chat-mini:hover { border-color: var(--peach-deep); transform: translateY(-1px); }

.side-group { margin-bottom: 20px; }
.side-group-label {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  padding: 0 8px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.hist-label { margin-bottom: 0; }
.lbl-logo { height: 13px; width: auto; }

.side-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.side-link:hover { background: var(--white); color: var(--ink-1); }
.side-ico { font-size: 13px; width: 18px; text-align: center; flex: none; }

.product-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 9px;
  text-decoration: none;
  color: inherit;
  transition: background 0.15s;
}
.product-link:hover { background: var(--white); }
.prod-badge {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  background: linear-gradient(150deg, #fff, var(--sunken));
  border: 1px solid var(--line);
}
.prod-name {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-1);
}
.prod-sub { font-size: 10px; font-weight: 500; color: var(--ink-3); margin-top: 1px; }
.prod-arr { color: var(--ink-4); font-size: 13px; flex: none; }
.product-link.current { background: var(--white); box-shadow: var(--shadow-sm); cursor: default; }
.product-link.current .prod-sub { color: var(--peach-deep); }

/* ---- resources library ---- */
#library { flex: 1; overflow-y: auto; display: none; flex-direction: column; }
.lib-head {
  max-width: 1040px;
  width: 100%;
  margin: 0 auto;
  padding: 22px clamp(16px, 5vw, 40px) 10px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#libSearch {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid var(--line-3);
  border-radius: 12px;
  font: inherit;
  font-size: 15px;
  background: var(--white);
  box-shadow: var(--shadow-sm);
  color: var(--ink-1);
}
#libSearch:focus { outline: none; border-color: var(--peach-deep); box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.15); }
.lib-filters { display: flex; gap: 8px; flex-wrap: wrap; }
.filter {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 7px 15px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink-2);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.filter.active { background: var(--navy); color: #fff; border-color: var(--navy); }
.lib-list { max-width: 1040px; width: 100%; margin: 0 auto; padding: 10px clamp(16px, 5vw, 40px) 48px; }
.lib-folder { margin-bottom: 24px; }
.lib-folder-name {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  margin: 0 2px 9px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--line-2);
}
.lib-count { color: var(--ink-4); }
.lib-cards { display: flex; flex-direction: column; gap: 8px; }
.lib-empty { text-align: center; color: var(--ink-3); padding: 48px 20px; }

/* library accordion item */
.lib-item {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.lib-item-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 15px;
  background: none;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--ink-1);
}
.lib-item-head:hover { background: rgba(26, 37, 71, 0.02); }
.lib-item-name { flex: 1; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chev { color: var(--ink-4); font-size: 19px; line-height: 1; transition: transform 0.2s; flex: none; }
.lib-item.open .chev { transform: rotate(90deg); }
.lib-item-body { display: none; padding: 0 15px 15px; }
.lib-item.open .lib-item-body { display: block; }

/* On a phone the row was ALL badge and no name.
   `.lib-item-name` is `flex: 1` with `overflow: hidden`, which makes its
   min-width resolve to 0, while the four badges beside it (form number, doc
   type, jurisdiction, year) will not shrink. At 390px that gave rows reading
   "A", "F…", "I." — and six of eleven with no title at all. The page a broker
   opens to find a form was the one page they could not read on the device
   they use. Report 01, D9.

   Two changes, in this order of importance: the name may now WRAP to two
   lines rather than being clipped to nothing, and every badge after the first
   is dropped. The first is the form number, which is the one a broker
   searches by; the rest are a browsing aid and are still on the open row.
   `.pill--warn` is exempt — "not searchable" is a warning, not a tag.

   The walkthrough asserts the outcome (`_check_row_titles_visible`), because
   the previous test proved only that the page did not scroll sideways, which
   it never did. */
@media (max-width: 640px) {
  .lib-item-name {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    overflow: hidden;
    min-width: 6ch;
  }
  .lib-item-head .pill ~ .pill:not(.pill--warn) { display: none; }
}
.lib-note { font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }
.lib-note.muted { color: var(--ink-4); font-style: italic; }
.lib-note p { margin: 0 0 8px; }
.lib-note p:last-child { margin-bottom: 0; }
.lib-note ul, .lib-note ol { margin: 6px 0; padding-left: 20px; }
.lib-note li { margin: 2px 0; }
.lib-note a { color: var(--peach-deep); text-decoration: underline; }
.lib-contact {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-2);
}
.lib-actions { margin-top: 13px; flex-wrap: wrap; }

/* ---- header ---- */
/* Scoped to the DIRECT child of .main-col, not to every <header> element.
   A bare `header {}` selector also matched the page headings inside each
   view (`<header class="people-head">`), which made every page title a
   second sticky bar at the same z-index — and, being later in the DOM, it
   painted over the user menu dropdown. The symptom looked exactly like a
   stale stylesheet, which cost a while to find. */
.main-col > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px clamp(16px, 5vw, 40px);
  background: rgba(245, 245, 247, 0.85);
  backdrop-filter: saturate(1.2) blur(8px);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  /* The header is CHROME and must paint above everything in the content
     column. `backdrop-filter` above already makes this a stacking context, so
     the user menu's own z-index is scoped INSIDE the header — which means this
     value, not the dropdown's, decides whether the dropdown is covered.
     Anything in the page body that needs to sit above the header (nothing
     does today) has to be a deliberate decision, not an accident of ordering. */
  z-index: 40;
}
.brand { display: flex; align-items: center; gap: 9px; }
.brand-r1 {
  height: 30px;
  width: auto;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 11px;
  box-shadow: var(--shadow-sm);
  box-sizing: content-box;
}
.brand-sep { color: var(--ink-4); font-size: 17px; font-weight: 300; }
.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: linear-gradient(150deg, var(--navy), var(--navy-deep));
  position: relative;
  box-shadow: var(--shadow-sm);
  flex: none;
}
.brand-mark::after {
  content: "";
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--peach);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.brand-name { font-weight: 800; font-size: 17px; letter-spacing: -0.01em; color: var(--navy); }
.brand-thin { font-weight: 500; color: var(--ink-2); }
.brand-logo { height: 30px; width: auto; display: block; }

.header-right { display: flex; align-items: center; gap: 10px; }
.conn-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 12px;
  white-space: nowrap;
}
.conn-badge .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #1d9e75;
  box-shadow: 0 0 0 3px rgba(29, 158, 117, 0.16);
}

.welcome-logo { height: 60px; width: auto; display: block; margin: 0 auto 18px; }
.foot-logo { height: 22px; width: auto; }

.status {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-2);
  background: var(--sunken);
  border: 1px solid var(--line-2);
  padding: 6px 11px;
  border-radius: 999px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* ---- chat ---- */
#chat {
  flex: 1;
  overflow-y: auto;
  padding: 32px 0 16px;
}
.msg {
  max-width: 1040px;
  margin: 0 auto 18px;
  padding: 0 clamp(16px, 5vw, 40px);
  display: flex;
  flex-direction: column;
}
.msg.user { align-items: flex-end; }
.msg.assistant { align-items: flex-start; }

.bubble {
  padding: 15px 20px;
  border-radius: 18px;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-width: 92%;
  font-size: 15px;
  line-height: 1.62;
}
.msg.assistant .bubble {
  background: var(--white);
  border: 1px solid var(--line);
  border-bottom-left-radius: 6px;
  box-shadow: var(--shadow-sm);
  color: var(--ink-1);
  max-width: 780px;
}
.msg.user .bubble {
  background: linear-gradient(150deg, var(--navy-soft), var(--navy));
  border-bottom-right-radius: 6px;
  color: #fff;
  box-shadow: 0 1px 1px rgba(17, 23, 58, 0.2), 0 8px 22px rgba(26, 37, 71, 0.18);
  max-width: 620px;
}
.bubble a { color: var(--peach-deep); font-weight: 600; }
.msg.user .bubble a { color: var(--peach-soft); }

.greeting-kicker {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--peach-deep);
  margin-bottom: 8px;
}

.bubble.err { background: #faece7; border: 1px solid rgba(113, 43, 19, 0.18); color: #712b13; }

/* streaming cursor */
.blink::after {
  content: "▋";
  color: var(--peach-deep);
  animation: b 1s steps(2) infinite;
  margin-left: 1px;
}
@keyframes b { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

/* ---- composer ---- */
#composer {
  background: rgba(245, 245, 247, 0.9);
  backdrop-filter: saturate(1.2) blur(8px);
  border-top: 1px solid var(--line);
  padding: 14px clamp(16px, 5vw, 40px) 18px;
}
.composer-inner {
  max-width: 1040px;
  margin: 0 auto;
  display: flex;
  gap: 10px;
  align-items: flex-end;
}
#input {
  flex: 1;
  resize: none;
  max-height: 168px;
  padding: 13px 16px;
  border: 1px solid var(--line-input);
  border-radius: var(--radius-sm);
  background: var(--white);
  font: inherit;
  font-size: 15px;
  color: var(--ink-1);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.2s, box-shadow 0.2s;
}
#input:focus {
  outline: none;
  border-color: var(--peach-deep);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.15);
}
#input::placeholder { color: var(--ink-4); }

#send {
  padding: 13px 26px;
  border: none;
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  font-family: inherit;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  box-shadow: 0 1px 1px rgba(17, 23, 58, 0.2), 0 8px 22px rgba(26, 37, 71, 0.22);
  transition: transform 0.22s cubic-bezier(0.2, 0.7, 0.2, 1), background 0.22s, box-shadow 0.22s;
}
#send:hover:not(:disabled) {
  background: var(--navy-soft);
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(17, 23, 58, 0.2), 0 14px 30px rgba(26, 37, 71, 0.28);
}
#send:active:not(:disabled) { transform: scale(0.97); }
#send:disabled { background: var(--ink-4); cursor: default; box-shadow: none; }

/* ---- welcome / empty state ---- */
#welcome {
  max-width: 720px;
  margin: 7vh auto 0;
  padding: 0 24px;
  text-align: center;
  animation: msgIn 0.35s ease;
}
.welcome-mark {
  width: 54px;
  height: 54px;
  border-radius: 16px;
  margin: 0 auto 20px;
  background: linear-gradient(150deg, var(--navy), var(--navy-deep));
  position: relative;
  box-shadow: var(--shadow-md);
}
.welcome-mark::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--peach);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
#welcome .greeting-kicker { display: inline-block; }
.welcome-title {
  font-size: clamp(26px, 4vw, 34px);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--navy);
  margin: 6px 0 10px;
}
.welcome-sub { color: var(--ink-2); font-size: 15px; margin: 0 auto 28px; max-width: 520px; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.chip {
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-1);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 10px 16px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.18s, border-color 0.18s;
}
.chip:hover { transform: translateY(-1px); border-color: var(--peach-deep); }

/* ---- message animation + markdown ---- */
.msg { animation: msgIn 0.25s ease; }
@keyframes msgIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.bubble p { margin: 0 0 10px; }
.bubble p:last-child { margin-bottom: 0; }
.bubble ul, .bubble ol { margin: 6px 0 10px; padding-left: 22px; }
.bubble li { margin: 3px 0; }
.bubble h4 { font-size: 15px; font-weight: 700; margin: 10px 0 6px; }
.bubble a { text-decoration: underline; text-underline-offset: 2px; }
.bubble code {
  font-family: var(--font-mono);
  font-size: 12.5px;
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: 5px;
  padding: 1px 5px;
}
.msg.user .bubble code { background: rgba(255, 255, 255, 0.15); border-color: rgba(255, 255, 255, 0.25); }

/* typing indicator */
.typing { display: inline-flex; gap: 4px; padding: 3px 0; }
.typing i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-4);
  display: inline-block;
  animation: typing 1.2s infinite ease-in-out;
}
.typing i:nth-child(2) { animation-delay: 0.15s; }
.typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes typing { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } }

/* per-message footer (the Copy button; a token count lived here until ADE-169) */
.msg-foot { display: flex; align-items: center; gap: 12px; margin-top: 6px; padding: 0 2px; opacity: 0; transition: opacity 0.2s; }
/* Same reason as .conv-del above — copy was pointer-only. Report 01, D4. */
.msg:hover .msg-foot,
.msg:focus-within .msg-foot { opacity: 1; }
.foot-btn {
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-3);
  background: none;
  border: 0;
  padding: 2px 6px;
  cursor: pointer;
  border-radius: 6px;
}
.foot-btn:hover { color: var(--navy); background: var(--sunken); }

/* ---- action cards ---- */
.cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  max-width: 780px;
  align-self: flex-start;
}
.card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px 12px 10px 14px;
  box-shadow: var(--shadow-sm);
}
.card-info { display: flex; align-items: center; gap: 9px; min-width: 0; }
.card-icon { font-size: 15px; flex: none; }
.card-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-actions { display: flex; gap: 6px; flex: none; }
.card-btn {
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 15px;
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.2s, transform 0.2s;
}
.card-btn:hover { background: var(--navy-soft); transform: translateY(-1px); }
.card-btn.ghost {
  background: transparent;
  color: var(--navy);
  border: 1.5px solid var(--line-3);
}
.card-btn.ghost:hover { background: rgba(26, 37, 71, 0.04); border-color: var(--navy); transform: translateY(-1px); }
.card-btn.disabled {
  background: var(--sunken);
  color: var(--ink-3);
  border: 1px solid var(--line-2);
  cursor: default;
}

/* scrollbar */
#chat::-webkit-scrollbar { width: 10px; }
#chat::-webkit-scrollbar-thumb { background: var(--line-3); border-radius: 999px; border: 3px solid var(--cream); }

/* ══════════════════════════════════════════════════════════════════
   Adealia Brokerage Services — additions on top of the original
   proof-of-concept stylesheet. Everything above this line is carried
   over unchanged; everything below covers surfaces that build never
   had: real auth, uploads, admin, and the collection picker.
   ══════════════════════════════════════════════════════════════════ */

/* ── Flash messages ─────────────────────────────────────────────── */
.flashes {
  /* Deliberately NOT sticky. It used to stick to top: 0, which put it in the
     same place as the sticky header and above it in the stacking order — so a
     flash message covered the user menu dropdown. It now flows directly under
     the header as its own row in the column. */
  padding: 12px clamp(16px, 5vw, 40px) 0;
  display: flex; flex-direction: column; gap: 8px;
}
.flash {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; border-radius: var(--radius-sm);
  font-size: 13.5px; font-weight: 500;
  background: var(--white); border: 1px solid var(--line-2);
  box-shadow: var(--shadow-sm);
}
.flash--error { border-color: #f0c2bc; background: #fdf3f2; color: #8c2f22; }
.flash--info  { border-color: var(--peach-soft); }
.flash-x {
  background: none; border: 0; cursor: pointer;
  font-size: 19px; line-height: 1; color: var(--ink-4); padding: 0 2px;
}
.flash-x:hover { color: var(--ink-2); }

/* ── Auth pages ─────────────────────────────────────────────────── */
body.auth-body { display: block; background: radial-gradient(120% 90% at 50% 0%, #fff 0%, var(--cream) 60%); }
.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 32px 16px; }
.auth-card {
  background: var(--white); border: 1px solid var(--line-2);
  border-radius: var(--radius); box-shadow: var(--shadow-md);
  padding: 38px 34px 26px; width: min(94vw, 420px); text-align: center;
}
.auth-logo { max-width: 150px; height: auto; margin: 0 auto 22px; display: block; }
.auth-title { font-size: 21px; font-weight: 800; margin: 0 0 6px; letter-spacing: -0.01em; color: var(--navy); }
.auth-sub { font-size: 13.5px; color: var(--ink-2); margin: 0 0 22px; }
.auth-form { text-align: left; display: flex; flex-direction: column; }
.auth-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-3); margin: 12px 0 5px;
}
.auth-form input, .auth-form select, .auth-form textarea,
.panel input, .panel select, .panel textarea {
  width: 100%; padding: 10px 13px; font-size: 14.5px; font-family: inherit;
  border: 1px solid var(--line-input); border-radius: 11px; background: var(--white);
  color: var(--ink-1);
}
.auth-form input:focus, .auth-form select:focus, .auth-form textarea:focus,
.panel input:focus, .panel select:focus, .panel textarea:focus {
  outline: none; border-color: var(--peach);
  box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.15);
}
.auth-form input[readonly] { background: var(--sunken); color: var(--ink-2); }
.auth-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.auth-btn {
  margin-top: 20px; width: 100%; padding: 12px;
  font-size: 14.5px; font-weight: 650; font-family: inherit;
  border: 0; border-radius: 12px; background: var(--navy); color: #fff;
  cursor: pointer;
}
.auth-btn:hover { background: var(--navy-soft); }
.auth-err {
  margin-bottom: 16px; padding: 10px 13px; border-radius: 11px;
  background: #fdf3f2; border: 1px solid #f0c2bc; color: #8c2f22;
  font-size: 13px; text-align: left;
}
.auth-hint { margin-top: 18px; font-size: 12.5px; color: var(--ink-3); }
.auth-hint a { color: var(--peach-deep); }
.auth-foot {
  margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line-2);
  font-size: 11px; color: var(--ink-3); font-weight: 600;
  display: flex; align-items: center; justify-content: center; gap: 5px;
}
.auth-foot img { height: 14px; width: auto; }

/* ── Generic page + panel (admin, invites) ──────────────────────── */
.page {
  flex: 1; overflow-y: auto; width: 100%;
  max-width: 1040px; margin: 0 auto;
  padding: 20px clamp(16px, 5vw, 40px) 56px;
}
.panel {
  background: var(--white); border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-sm);
  padding: 20px 22px; margin-bottom: 18px;
}
.panel--ok { border-color: var(--peach-soft); }
.panel h3 { margin: 0 0 4px; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.panel h4 {
  margin: 20px 0 8px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3);
}
.field-hint { font-size: 12px; color: var(--ink-3); margin: 5px 0 0; }
.muted { color: var(--ink-3); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
.copy-field {
  width: 100%; margin-top: 10px; padding: 10px 13px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; border: 1px solid var(--line-input); border-radius: 11px;
  background: var(--sunken); color: var(--ink-1);
}
.plain-list { list-style: none; margin: 0; padding: 0; font-size: 13.5px; }
.plain-list li { padding: 5px 0; border-bottom: 1px solid var(--line-2); }
.plain-list li:last-child { border-bottom: 0; }
.inline-form { display: inline; margin: 0; }
.inline-row {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px;
}
.inline-row input[type="text"], .inline-row input[type="email"] { width: auto; flex: 1; min-width: 150px; }
.inline-check {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--ink-2); white-space: nowrap;
}
.inline-check input { width: auto; }

.grid { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-top: 6px; }
.grid th {
  text-align: left; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3);
  padding: 6px 10px 6px 0; border-bottom: 1px solid var(--line-2);
}
.grid td { padding: 9px 10px 9px 0; border-bottom: 1px solid var(--line-2); vertical-align: top; }
.grid tr:last-child td { border-bottom: 0; }
.row--disabled { opacity: 0.55; }

.pill {
  display: inline-block; margin-left: 6px; padding: 2px 7px;
  border-radius: 999px; font-size: 10.5px; font-weight: 650;
  background: var(--sunken); color: var(--ink-2);
}
.pill--warn { background: #fdf0ee; color: #8c2f22; }

/* ── Sidebar additions ──────────────────────────────────────────── */
.side-logout { display: flex; align-items: center; color: var(--ink-4); margin-left: auto; }
.side-logout:hover { color: var(--ink-2); }
.sidebar-foot .user-chip { width: 100%; margin-bottom: 10px; }
.sidebar-foot .user-text { flex: 1; min-width: 0; }
.sidebar-foot .user-name, .sidebar-foot .user-role {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kb-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: 9px; cursor: pointer;
  font-size: 12.5px; color: var(--ink-2);
}
.kb-item:hover { background: var(--white); color: var(--ink-1); }
.kb-item input { accent-color: var(--peach); flex: none; }
.kb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Chat additions ─────────────────────────────────────────────── */
.tool-status {
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--ink-3); font-size: 13.5px;
}
.card-btn.disabled { opacity: 0.55; cursor: default; pointer-events: none; }

/* ── Resources page ─────────────────────────────────────────────── */
/* The original build toggled #library between chat and library views in one
   page; here Resources is its own route, so it is always shown. */
#library.library--page { display: flex; }
.lib-note-inline { font-size: 12.5px; color: var(--ink-3); margin: 0 0 10px; }
.lib-empty-sm { font-size: 13px; color: var(--ink-4); padding: 10px 2px; }
.lib-meta { font-size: 12px; color: var(--ink-3); margin-bottom: 8px; }
.lib-upload {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  padding: 12px 14px; margin-bottom: 10px;
  background: var(--white); border: 1px dashed var(--line);
  border-radius: var(--radius-sm);
}
.lib-upload input[type="file"] { font-size: 12.5px; flex: 1; min-width: 200px; }
.lib-upload-hint { font-size: 11.5px; color: var(--ink-4); }
.lib-item-head .pill { margin-left: 8px; }

/* The original build's nav items were <button>s; here they are real links, so
   the anchor underline has to be cleared. Same for the sidebar user chip. */
.nav-item, .side-link, .product-link, .side-logout { text-decoration: none; }

/* The status pill is populated by JS only when there is something to say.
   Empty, it rendered as a stray bordered box in the header. */
.status:empty { display: none; }

/* ── Design-system type roles ───────────────────────────────────────
   Display face on the things that are headings, body face everywhere else.
   The original used Plus Jakarta Sans for both; the design system splits
   them, and numerals get the mono face because this product is read as
   data. */
.welcome-title, .brand-name, .auth-title, .panel h3,
.lib-folder-name, h1, h2, h3 { font-family: var(--font-display); }
.greeting-kicker, .side-group-label, .status, .conn-badge,
.mono, .lib-count { font-family: var(--font-mono); }

/* Status badge — the "knowledge base is loaded" signal the original had.
   Uses the validated ok/muted triplets rather than a hand-mixed green. */
.conn-badge.is-warn { background: var(--muted-bg); color: var(--muted-fg); }
.conn-badge.is-warn .dot { background: var(--muted-dot); }

/* Primary action = the one copper CTA per view. Everything else is
   secondary; a second amber button teaches people amber means "a button"
   rather than "the button". */
#send, .auth-btn { background: var(--copper-cta); }
#send:hover, .auth-btn:hover { background: var(--copper-press); }

/* Sign-out sits in the footer beside the Adealia mark — the header user chip
   is identity, not a menu, and the original kept it that way. */
.powered { justify-content: space-between; width: 100%; }
.powered .side-logout { margin-left: auto; }

/* ── Header user menu ───────────────────────────────────────────────
   Identity plus an account menu, pinned right. Sign-out lives here because
   that is where people look for it; it was previously a footer icon beside
   the "Powered by" mark, which reads as decoration. */
.user-menu { position: relative; }
.user-menu-btn {
  font-family: inherit;
  background: none;
  border: 1px solid transparent;
  border-radius: 12px;
  padding: 4px 6px 4px 10px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
}
.user-menu-btn:hover { background: var(--white); border-color: var(--line-2); }
.user-menu.is-open .user-menu-btn { background: var(--white); border-color: var(--line); }
.user-menu-caret { color: var(--ink-4); font-size: 11px; line-height: 1; }

.user-menu-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 208px;
  z-index: 60;
  display: none;
  flex-direction: column;
  padding: 6px;
  background: var(--white);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
}
.user-menu.is-open .user-menu-dropdown { display: flex; }
.user-menu-head { padding: 6px 10px 8px; border-bottom: 1px solid var(--line-2); margin-bottom: 4px; }
.user-menu-email {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.user-menu-item {
  display: block;
  padding: 8px 10px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  text-decoration: none;
}
.user-menu-item:hover { background: var(--sunken); color: var(--ink-1); }
.user-menu-item--muted { color: var(--ink-3); }
.user-menu-divider { height: 1px; background: var(--line-2); margin: 4px 0; }

.conv-empty { font-size: 12.5px; color: var(--ink-4); padding: 6px 8px; margin: 0; }

/* ── Mobile: off-canvas rail ────────────────────────────────────────
   The rail is 244px of a 1440px desktop and reasonable there, but it is most
   of a phone. Below 900px it slides away behind a toggle, with a scrim so a
   tap anywhere on the content closes it. */
.rail-toggle { display: none; }
.rail-scrim { display: none; }

@media (max-width: 900px) {
  .rail-toggle {
    position: fixed;
    top: 14px; left: 12px;
    z-index: 120;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 38px; height: 38px;
    padding: 0 9px;
    background: var(--white);
    border: 1px solid var(--line-2);
    border-radius: 11px;
    box-shadow: var(--shadow-sm);
    cursor: pointer;
  }
  .rail-toggle span {
    display: block; height: 2px; width: 100%;
    background: var(--ink-2); border-radius: 2px;
  }

  .sidebar {
    display: flex;
    position: fixed;
    top: 0; bottom: 0; left: 0;
    z-index: 130;
    transform: translateX(-100%);
    /* `visibility` is the load-bearing half, not the transform.
       A transform moves the rail off screen and leaves every one of its ~20
       links, checkboxes and buttons in the tab order. The rail comes BEFORE
       .main-col in the markup, so on a phone the second Tab press fell into
       controls nobody could see, and focus vanished for ten presses. It fires
       at 200% zoom on a laptop too, because 200% of 1280 is 640 CSS px and
       lands under this breakpoint.
       `visibility: hidden` removes them; it is transitioned with a delay so
       the slide-out animation still plays before they disappear.
       Report 01, D2. */
    visibility: hidden;
    transition: transform 0.22s ease, visibility 0s linear 0.22s;
    box-shadow: var(--shadow-md);
  }
  body.rail-open .sidebar {
    transform: translateX(0);
    visibility: visible;
    transition: transform 0.22s ease, visibility 0s;
  }

  body.rail-open .rail-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 125;
    background: rgba(26, 37, 71, 0.28);
  }

  /* Clear the fixed toggle so it never sits on top of the brand lockup. */
  .main-col > header { padding-left: 62px; }
  .page, .lib-list { padding-left: 16px; padding-right: 16px; }
  /* An off-canvas rail must not leave a gutter behind it. */
  .main-col { width: 100%; }
}

/* Topic tags on a library row. Quiet by design — they are a browsing aid, not
   the row's headline, and a wall of coloured chips would out-shout the title. */
.lib-topics { display: flex; flex-wrap: wrap; gap: 5px; margin: 9px 0 4px; }
.topic {
  font-size: 11px;
  color: var(--ink-3);
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: 2px 8px;
}
.lib-item-head .pill { font-weight: 600; }

/* ---- dashboard ---- */
/* Page wrappers below carry `flex: 1; overflow-y: auto` because .main-col
   is a 100vh flex column: without it a long page is clipped rather than
   scrolled. #chat and #library already work this way. */
/* The role-aware home screen. Cards are supplied by the verticals and this
   knows nothing about their contents, so the grid has to look right at any
   card count — including zero, which is the state it ships in. */
.dash { flex: 1; overflow-y: auto; max-width: 1040px; width: 100%; margin: 0 auto; padding: clamp(20px, 5vw, 40px) clamp(16px, 5vw, 40px) 48px; }
.dash-head { margin-bottom: 24px; }
.dash-head h1 { font-size: 24px; line-height: 1.25; margin: 0; }
.dash-sub { color: var(--ink-3); font-size: 14px; margin: 4px 0 0; }

/* auto-fit rather than a fixed column count: one card shouldn't stretch to
   full width, and six shouldn't need a breakpoint written for them. */
.dash-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  align-items: start;
}
.dash-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px 18px;
}

/* The empty state is the whole page today, so it gets to be deliberate
   rather than a shrug. */
.dash-empty {
  text-align: center;
  padding: clamp(36px, 9vw, 72px) 20px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: var(--white);
}
.dash-empty h2 { font-size: 18px; margin: 0 0 8px; }
.dash-empty p { color: var(--ink-3); font-size: 14px; max-width: 46ch; margin: 0 auto; }
.dash-cta {
  display: inline-block;
  margin-top: 20px;
  padding: 9px 18px;
  border-radius: 8px;
  background: var(--ink-navy);
  color: var(--white);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.dash-cta:hover { background: var(--navy-deep); }

@media (max-width: 900px) {
  /* Match the rail's off-canvas gutter handling above. */
  .dash { padding-left: 16px; padding-right: 16px; }
  /* Single column on a phone: two 280px cards side by side is where a
     "responsive" grid stops being readable. */
  .dash-grid { grid-template-columns: 1fr; }
}

/* Card internals. Kept generic — every vertical's card uses these rather than
   inventing its own, so the dashboard reads as one surface. */
.card-title { font-size: 13px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 12px; }
.card-events { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.card-event { display: flex; flex-direction: column; gap: 2px; }
.card-event-title { font-size: 14px; font-weight: 600; color: var(--ink-navy); text-decoration: none; }
a.card-event-title:hover { text-decoration: underline; }
/* The pre-formatted local-time string. Quiet, because the event name is what
   a broker scans for. */
.card-event-when { font-size: 12.5px; color: var(--ink-3); }

/* ---- people ---- */
/* One card per person. A roster row carries four editable fields, and a table
   of <select> controls is unusable on a phone — which is where brokers are. */
.people { flex: 1; overflow-y: auto; max-width: 1040px; width: 100%; margin: 0 auto; padding: clamp(20px, 5vw, 40px) clamp(16px, 5vw, 40px) 48px; }
.people-head { margin-bottom: 20px; }
.people-head h1 { font-size: 24px; margin: 0; }
.people-sub { color: var(--ink-3); font-size: 14px; margin: 4px 0 0; }

.people-list { display: flex; flex-direction: column; gap: 10px; }
.person {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px 16px;
  display: grid;
  gap: 12px;
  /* Identity on the left, the editable fields on the right, collapsing to one
     column on a phone. */
  grid-template-columns: minmax(180px, 260px) 1fr;
  align-items: start;
}
.person-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.person-name { font-size: 14px; font-weight: 600; }
.person-email { font-size: 12.5px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; }
.person-status {
  align-self: flex-start;
  margin-top: 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--ink-3);
  background: var(--sunken);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: 1px 8px;
}

/* Label above value, repeating down the row. auto-fit keeps four fields on one
   line on a desktop and stacks them cleanly when there is no room. */
.person-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 4px 12px;
  align-items: center;
}
.person-label { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-4); grid-row: 1; }
.person-field, .person-value { grid-row: 2; }
.person-value { font-size: 13.5px; }
.person-field { margin: 0; }
.person-field select {
  width: 100%;
  font-size: 13.5px;
  padding: 5px 8px;
  border: 1px solid var(--line-input);
  border-radius: 6px;
  background: var(--white);
}
.person-field select:disabled { background: var(--sunken); color: var(--ink-3); }

@media (max-width: 900px) {
  .people { padding-left: 16px; padding-right: 16px; }
  .person { grid-template-columns: 1fr; }
  /* Stacked: each label sits directly above its own control rather than
     relying on the two-row grid, which only reads correctly side by side. */
  .person-fields { grid-template-columns: 1fr 1fr; }
  .person-label, .person-field, .person-value { grid-row: auto; }
}

/* ---- profile and licences ---- */
.prof { flex: 1; overflow-y: auto; max-width: 780px; width: 100%; margin: 0 auto; padding: clamp(20px, 5vw, 40px) clamp(16px, 5vw, 40px) 48px; }
.prof-head { margin-bottom: 20px; }
.prof-head h1 { font-size: 24px; margin: 0; }
.prof-sub { color: var(--ink-3); font-size: 14px; margin: 4px 0 0; }
.back-link { font-size: 13px; color: var(--ink-3); text-decoration: none; display: inline-block; margin-bottom: 10px; }
.back-link:hover { color: var(--ink-navy); }

.prof-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 18px 20px;
  margin-bottom: 14px;
}

/* Label above input, one column on a phone and two where there is room. */
.prof-grid, .lic-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.prof-grid label, .lic-grid label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--ink-4);
}
.prof-grid input, .prof-grid select,
.lic-grid input, .lic-grid select {
  font-size: 14px;
  padding: 7px 9px;
  border: 1px solid var(--line-input);
  border-radius: 6px;
  background: var(--white);
  /* 16px on iOS or the browser zooms the page on focus. Handled at the
     breakpoint below rather than here, so desktop keeps the tighter size. */
}
.btn-primary {
  font-size: 14px;
  font-weight: 600;
  padding: 8px 18px;
  border: 0;
  border-radius: 8px;
  background: var(--ink-navy);
  color: var(--white);
  cursor: pointer;
}
.btn-primary:hover { background: var(--navy-deep); }
.btn-quiet {
  font-size: 13px;
  padding: 6px 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  cursor: pointer;
  text-decoration: underline;
}
.btn-quiet:hover { color: var(--copper-cta); }

/* Read-only facts the brokerage owns. */
.prof-readonly { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin: 18px 0 0; }
.prof-readonly div { display: flex; flex-direction: column; gap: 2px; }
.prof-readonly dt { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-4); }
.prof-readonly dd { margin: 0; font-size: 14px; }
.prof-note { font-size: 12.5px; color: var(--ink-3); margin: 14px 0 0; }

.lic-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.lic-item { border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; }
.lic-head { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; justify-content: space-between; }
.lic-name { font-size: 14px; font-weight: 600; }
.lic-type { font-weight: 400; color: var(--ink-3); margin-left: 6px; }
.lic-expiry { font-size: 12.5px; }
.lic-item details, .lic-add { margin-top: 10px; }
.lic-item summary, .lic-add summary { font-size: 13px; color: var(--ink-3); cursor: pointer; }
.lic-form { margin-top: 12px; }
.lic-actions { display: flex; gap: 10px; align-items: center; }
.lic-delete { margin-top: 10px; }

/* One vocabulary of colour for licence state, used on the profile, the detail
   page, and the dashboard card, so the same condition always reads the same. */
.lic-expired  { color: var(--copper-press); font-weight: 600; }
.lic-expiring { color: var(--copper-cta); font-weight: 600; }
.lic-unknown  { color: var(--ink-3); }
.lic-ok       { color: var(--green-deep); }
.lic-missing  { color: var(--ink-3); }

.card-heading { font-size: 15px; font-weight: 600; margin: 0 0 6px; }
.card-detail { font-size: 13px; color: var(--ink-3); margin: 0 0 10px; }
.card-licenses { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.card-licenses li { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; }
.card-action { font-size: 13px; font-weight: 600; color: var(--ink-navy); text-decoration: none; }
.card-action:hover { text-decoration: underline; }

@media (max-width: 900px) {
  .prof { padding-left: 16px; padding-right: 16px; }
  /* iOS zooms the page when a focused field is under 16px. */
  .prof-grid input, .prof-grid select,
  .lic-grid input, .lic-grid select { font-size: 16px; }
}

/* ---- narrow-screen chrome fixes ---- */
/* Measured, not guessed: at 390px the header overflowed the viewport by 38px
   on a brokerage that HAS a logo (R1) and not on one that does not (Sandia).
   .brand was 223px wide and would not shrink, so .header-right was pushed off
   the right edge and every page scrolled sideways. */
.brand { min-width: 0; }
.brand-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.header-right { flex: none; }

@media (max-width: 900px) {
  /* The People page selects were 13.5px. iOS zooms the whole page when a
     focused field is under 16px, which on a roster means the page jumps on
     every single edit. The profile forms already had this; the roster did not. */
  .person-field select { font-size: 16px; }
}

@media (max-width: 600px) {
  /* The chip carries your own name and your own brokerage — both already on
     screen, and together about 90px that the brand needs more. The avatar
     still opens the menu. */
  .user-text { display: none; }
}

/* Change history on a broker's record. */
.history { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.history li { display: flex; flex-wrap: wrap; gap: 4px 12px; justify-content: space-between; align-items: baseline; font-size: 13.5px; }
.history-when { font-size: 12px; color: var(--ink-4); white-space: nowrap; }

/* ---- events ---- */
.ev-head { display: flex; gap: 12px; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; }
.ev-row { grid-template-columns: 1fr auto; align-items: center; }
.ev-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.ev-actions form { display: flex; align-items: center; gap: 10px; }
.ev-count { font-size: 12px; color: var(--ink-4); }
.ev-going { font-size: 13px; color: var(--green-deep); font-weight: 600; }
.ev-description { font-size: 14px; margin: 0 0 14px; white-space: pre-wrap; }
.ev-detail-actions { flex-wrap: wrap; }
/* ADE-175. Which clock the calendar entry lands on, under the button that
   takes it. `field-note` is the page's existing quiet line — the same one the
   History card's zone sentence uses — so this adds no component and no
   colour; the margin is the only thing it needs, because it follows a flex
   row rather than sitting inside one. */
.ev-calendar-clock { margin: 8px 0 0; }
.ev-desc-label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-4); }
.ev-desc-label textarea {
  font-family: inherit; font-size: 14px; padding: 8px 9px;
  border: 1px solid var(--line-input); border-radius: 6px; background: var(--white);
  resize: vertical;
}
.ev-audience-note { margin: 0 0 12px; }
/* ADE-193. Who an event will reach, named on the form before it is saved.
   A block inside the "Who it is for" card rather than a card of its own: it
   is the answer to the fields directly above it, and a second card would put
   a border between a question and its answer. No new component — the sentence
   is `prof-note` and the line under it is `field-note`, both of which this
   page and `/events/<id>` already use. */
.ev-audience-preview {
  margin: 14px 0 0; padding: 12px 14px;
  background: var(--surface-2); border-radius: 8px;
}
.ev-audience-preview__title {
  margin: 0 0 6px; font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .03em; color: var(--ink-4);
}
.ev-audience-preview .prof-note { margin: 0; }
/* ADE-203. The same block, once a limit has moved and the names underneath
   are about the limit that was there before.

   IT IS A TINT AND A RULE DOWN THE EDGE, AND THE NAMES ARE NOT DIMMED. The
   obvious spelling of "stale" is to fade the list, and fading is what
   state-of-play §2's instrument entries are about: text nobody can read is
   not a milder version of text, and `--ink-3` on this ground measures 5.42:1
   where the ordinary card measures 5.28, so this is the more legible of the
   two states rather than the less. What says the list is stale is the
   SENTENCE that replaces the one below it; the colour is only what makes a
   person look at it. */
.ev-audience-preview[data-audience-stale] {
  background: var(--warn-bg);
  box-shadow: inset 3px 0 0 var(--warn-dot);
}
/* NO COLOUR HERE, AND THAT IS THE DECISION. This rule used to say
   `color: var(--warn-fg)` and never applied: `.field-note` is later in this
   file at equal specificity and wins, so the sentence renders at `--ink-4` —
   4.63:1 on `--warn-bg`, which passes AA. Review found it dead and the
   choice is to leave the sentence grey rather than make it amber: the amber
   tint and the 3px rule already say "look at this", and a coloured sentence
   on top of them is what would make a note read as an error. The class is
   kept because the script and the template pass it to each other. */
.attendees { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.attendees li { display: flex; align-items: center; gap: 10px; }
.attendee { display: flex; align-items: center; gap: 9px; font-size: 14px; cursor: pointer; }
.attendee input { width: 17px; height: 17px; }
/* ADE-148. Adding somebody to the register: a picker and one button, on one
   line where there is room and stacked where there is not. `select` is 16px
   on a phone through the shared rule below, so it is not zoomed into. */
.ev-add-person { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.ev-add-person label {
  display: flex; flex-direction: column; gap: 4px; font-size: 11px;
  text-transform: uppercase; letter-spacing: .03em; color: var(--ink-4);
}
.ev-add-person select { font-size: 14px; padding: 7px 9px; }
/* ADE-170. Upcoming / Past, under the page head. Two ghost buttons and no new
   component: the one you are on is marked with `aria-current="page"`, which
   the nav rail in `base.html` already uses for the same job, and the styling
   hangs off that attribute rather than off a class the template has to
   compute a second time. It wraps on a phone like every other button row. */
.ev-switch { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px; }
.ev-switch [aria-current="page"] {
  background: var(--surface-2); border-color: var(--line-3); color: var(--ink-1);
  font-weight: 600;
}

@media (max-width: 900px) {
  .ev-row { grid-template-columns: 1fr; }
  .ev-actions { align-items: flex-start; }
  .ev-desc-label textarea { font-size: 16px; }
}

/* ---- tasks ---- */
/* Reuses the roster row (.person) rather than inventing a second list shape:
   a task row and a broker row carry the same weight of information, and two
   near-identical layouts drift apart. */
.task-section { margin-bottom: 26px; }
.task-section .card-title { margin-bottom: 10px; }
.task-row { grid-template-columns: 1fr auto; align-items: center; }
.task-actions { display: flex; align-items: center; gap: 12px; justify-content: flex-end; }
.task-done .person-name { color: var(--ink-3); text-decoration: line-through; }
.task-empty { padding: 24px 16px; }
.task-queue { font-size: 12px; color: var(--ink-4); text-transform: uppercase; letter-spacing: .03em; }

/* One vocabulary of colour for a deadline, matching the licence states above,
   so "late" always reads the same wherever it appears. */
.task-due { font-size: 12.5px; white-space: nowrap; }
.task-overdue { color: var(--copper-press); font-weight: 600; }
.task-today   { color: var(--copper-cta); font-weight: 600; }
.task-soon    { color: var(--ink-2); }
.task-later   { color: var(--ink-3); }
.task-none    { color: var(--ink-4); }

/* Task lists inside a dashboard card. */
.card-tasks { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.card-task { display: flex; flex-direction: column; gap: 2px; }
.card-task-title { font-size: 14px; font-weight: 600; color: var(--ink-navy); text-decoration: none; }
.card-task-when { font-size: 12.5px; }

/* ---- notifications ---- */
.bell {
  position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 34px; height: 34px; border-radius: 8px;
  color: var(--ink-2); text-decoration: none;
}
.bell:hover { background: var(--sunken); }
.bell-unread { color: var(--copper-cta); }
.bell-count {
  position: absolute; top: 2px; right: 0; min-width: 15px; height: 15px;
  padding: 0 3px; border-radius: 8px; background: var(--copper-cta);
  color: #fff; font-size: 10px; line-height: 15px; text-align: center;
  font-weight: 700;
}
.note-row { grid-template-columns: 1fr auto; align-items: center; }
/* Unread is a bar, not a background wash: the row still has to be readable
   next to a read one on a phone in daylight. */
.note-unread { border-left: 3px solid var(--copper-cta); }
.note-when { font-size: 12px; color: var(--ink-4); white-space: nowrap; }

.push-box {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; padding: 14px 16px; margin-bottom: 18px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--white);
}
.push-title { font-size: 14px; font-weight: 600; margin: 0; }
.push-detail { font-size: 13px; color: var(--ink-3); margin: 4px 0 0; max-width: 52ch; }

@media (max-width: 900px) {
  .task-row, .note-row { grid-template-columns: 1fr; }
  .task-actions { justify-content: flex-start; }
  /* Measured at 390px: the shared .btn-quiet is 27px tall, which is a small
     target for the main action on this page. Padded here rather than in the
     shared rule, so the events pages keep the size they were measured at. */
  .task-actions .btn-quiet,
  .people-head .btn-quiet { padding: 11px 0; }
}

@media (max-width: 900px) {
  /* The three fields the earlier 16px rules missed, each on a page the mobile
     check did not measure: the assistant composer, the login form, and the
     Resources search. iOS zooms the page when a focused field is under 16px.
     The login form is the first thing a broker touches on a phone, and the
     composer is the memo's headline mobile feature. */
  #input,
  .auth-form input,
  #libSearch { font-size: 16px; }
}

@media (max-width: 600px) {
  /* The chat header carries a knowledge-base badge and a document count on top
     of the bell and the avatar. At 390px that pushed .header-right to 417px and
     the whole page scrolled sideways by 101px — on the assistant, which is the
     product's centrepiece. The badge is reassurance, not a control; the bell
     and the avatar are controls. Reassurance goes first. */
  .conn-badge, header .status { display: none; }
}

/* ---- continuing education ---- */
.ce-stub {
  font-size: 13px; color: var(--ink-3);
  background: var(--info-bg); border: 1px solid var(--line-2);
  border-radius: 8px; padding: 10px 13px; margin: 0 0 16px;
}
.ce-reason { font-size: 13px; color: var(--ink-3); margin: 8px 0 0; }
.ce-decide { margin-top: 12px; }
/* The memo's own three words, plus the two a person can decide. One vocabulary
   of colour, matching the licence states above. */
.ce-matched      { color: var(--green-deep); font-weight: 600; }
.ce-approved     { color: var(--green-deep); font-weight: 600; }
.ce-questionable { color: var(--copper-cta); font-weight: 600; }
.ce-unmatched    { color: var(--copper-cta); font-weight: 600; }
.ce-rejected     { color: var(--copper-press); font-weight: 600; }

/* A CE row on the home card carries a name, a state and a reason — three
   parts, so it stacks rather than sitting on one line like a licence. */
.ce-card-row { display: flex; flex-direction: column; gap: 2px; }
.ce-card-row .ce-reason { margin: 0; }

/* ---- the approved-course spreadsheet ---- */
/* The first tables in the app. A preview of somebody else's spreadsheet can be
   any width, so it scrolls inside its own box rather than pushing the page
   sideways — a horizontally scrolling page hides the Import button. */
.tbl-scroll { overflow-x: auto; margin: 12px 0 0; }
.tbl {
  border-collapse: collapse; width: 100%; font-size: 13px;
  color: var(--ink-2);
}
.tbl th, .tbl td {
  border: 1px solid var(--line-2); padding: 6px 10px;
  text-align: left; white-space: nowrap;
}
.tbl th { background: var(--info-bg); color: var(--ink-3); font-weight: 600; }

/* Version history and skipped rows: present, and folded away. Both matter
   only when somebody is asking a question about them. */
.ce-history, .ce-skipped { margin-top: 14px; font-size: 13px; }
.ce-history summary, .ce-skipped summary {
  cursor: pointer; color: var(--ink-3);
}
.ce-skipped ul { margin: 8px 0 0; padding-left: 20px; color: var(--ink-3); }

/* Used in several forms already, never styled. */
.field-note { font-size: 12px; color: var(--ink-4); margin: 6px 0 0; }
.form-actions { margin: 16px 0; }

/* The upload sits under the record of what is already in force, separated by
   a rule: replacing a state's course list is not a routine edit of the card
   above it. Wraps on a phone rather than pushing the button off the side. */
.course-upload {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line-2);
}
.course-upload label {
  display: flex; flex-direction: column; gap: 6px;
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3);
}
.course-upload .field-note { flex-basis: 100%; margin: 0; }

/* Course search. Sits above the per-state cards because the question it
   answers — "is my course approved?" — is why most people open the page. */
.course-search {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  margin: 0 0 18px;
}
.course-search label {
  display: flex; flex-direction: column; gap: 6px; flex: 1 1 260px;
  font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3);
}
/* 16px, not smaller. iOS zooms the whole page on focusing a field below that,
   and the walkthrough asserts it — this rule exists because it failed. */
.course-search input { font-size: 16px; }

/* The site-admin strip. Deliberately plain and always present rather than
   dismissible: an override you have stopped noticing is an override you will
   misread as your own role. */
.admin-bar {
  margin: 0; padding: 8px clamp(16px, 5vw, 40px);
  background: var(--warn-bg); color: var(--warn-fg);
  border-bottom: 1px solid var(--line);
  font-size: 12px; line-height: 1.5;
}

/* The line under the CE course fields: what the state's list says about what
   has been typed. Four states, and the colours are the licence/CE vocabulary
   already in use — green for found, copper for "look again", neutral for
   "there is nothing to check against". */
.ce-hint {
  margin: 10px 0 0; padding: 8px 12px; font-size: 13px; line-height: 1.5;
  border-radius: 8px; border: 1px solid var(--line-2);
  background: var(--info-bg); color: var(--ink-2);
}
.ce-hint--found    { border-color: var(--green-deep); color: var(--green-deep); background: transparent; }
.ce-hint--mismatch { border-color: var(--copper-cta); color: var(--copper-cta); background: transparent; }
.ce-hint--missing  { border-color: var(--copper-cta); color: var(--ink-2); background: transparent; }
.ce-hint--no_list  { color: var(--ink-3); }
/* Near matches under the CE hint. Plain text, never controls — a clickable
   option would fill the field from the state's list, which is exactly what
   this feature refuses to do. */
.ce-hint-options { margin: 6px 0 0; padding-left: 18px; }
.ce-hint-options li { margin: 2px 0; }
.ce-hint--partial { border-color: var(--line-3); color: var(--ink-2); background: transparent; }

/* Brokerage switcher inside the account menu. Each option is a form button
   rather than a link because switching is a state change, and a GET that
   changes what a session acts in would be followed by a crawler or a prefetch. */
.user-menu-switch {
  display: flex; justify-content: space-between; align-items: center;
  width: 100%; background: none; border: 0; text-align: left;
  font: inherit; cursor: pointer;
}
.user-menu-switch.is-acting { font-weight: 700; color: var(--ink-1); }

/* The groups a broker is in, on their record. A list of checkboxes rather
   than a multi-select, because a person is in several groups at once and a
   `<select multiple>` hides that behind a scroll box nobody can use on a
   phone. One column below 560px, two above it, so eight groups do not become
   eight full-width rows on a desktop.

   16px, not smaller, and the walkthrough asserts it: iOS zooms the whole page
   on focusing a control below that. `.course-search input` above carries the
   same rule for the same reason. */
.cohort-choices {
  list-style: none; margin: 0 0 12px; padding: 0;
  display: grid; gap: 8px; grid-template-columns: 1fr;
}
@media (min-width: 560px) {
  .cohort-choices { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.cohort-choice {
  display: flex; align-items: center; gap: 10px;
  font-size: 16px; line-height: 1.4; color: var(--ink-1);
}
/* A 20px target rather than the browser's 13px one. The row is tappable
   because the text is inside the label. */
.cohort-choice input[type="checkbox"] {
  width: 20px; height: 20px; flex: 0 0 auto; margin: 0;
}
