/* ==========================================================================
   BE Rise — front-end prototype stylesheet
   Visual direction per brief §1: modern blue, white, and gray.
   Component language (cards, pills, stat blocks, meta rows) carried over
   from the approved UI concept.
   ========================================================================== */

:root {
  /* Tells the browser which palette to paint the controls IT draws — the open
     <select> list, scrollbars, focus rings, date pickers. Without it a dark
     theme gets a white native dropdown with near-white text in it, which is
     the one part of dark mode CSS alone cannot reach. */
  color-scheme: light;

  /* brand */
  --blue: #2563eb;
  --blue-dark: #1d4ed8;
  --blue-deep: #1e3a8a;
  --blue-soft: #eff4ff;
  --blue-btn: #2563eb;      /* button fill — stays saturated in both themes */
  --danger-btn: #b91c1c;    /* same idea for red: fill, not text */

  /* Incoming chat bubble. Its own token because it is neither a card surface
     nor the page background — it has to read as "not mine" against both. */
  --chat-in-bg: #e9edf3;
  --chat-in-fg: #0f172a;
  /* Ink for text sitting on the warn/danger tints. */
  --warn-ink: #78350f;
  /* Ink for text sitting on the blue tint. Needed for the same reason as the
     warn and danger inks: --blue-soft flips from a near-white fill to a
     translucent tint over a dark page, and text coloured with a fixed brand
     navy goes from readable to invisible. */
  --blue-ink: #17357e;
  --danger-ink: #7f1d1d;
  --blue-line: #c7d9fe;

  /* neutrals */
  --slate-900: #0f172a;
  --slate-800: #1e293b;
  --slate-700: #334155;
  --slate-600: #475569;
  --slate-500: #64748b;
  --slate-400: #94a3b8;
  --slate-300: #cbd5e1;
  --slate-200: #e2e8f0;
  --slate-100: #f1f5f9;
  --slate-50: #f8fafc;

  --heading: var(--slate-900);
  --body: var(--slate-600);
  /* Not --slate-500 (#64748b): that is 4.76:1 on pure white, which leaves no
     headroom — on the tinted selected row (--blue-soft) it drops to 4.32 and
     fails. This value clears 4.5 on every light surface in the app. */
  --muted: #5d6b7f;
  --line: var(--slate-200);
  --bg: #ffffff;
  --bg-alt: var(--slate-50);
  --surface: #ffffff;              /* cards, panels, inputs */
  --surface-veil: rgba(255, 255, 255, 0.94);
  --surface-ai: #faf8ff;           /* assistant bubbles and agent cards */
  --surface-ai-line: #ddd0fb;
  --code-bg: var(--slate-50);

  /* status — payment, maintenance, lease, delivery */
  --ok: #15803d;
  --ok-bg: #dcfce7;
  --warn: #b45309;
  --warn-bg: #fef3c7;
  --danger: #b91c1c;
  --danger-bg: #fee2e2;
  --info: #1d4ed8;
  --info-bg: #dbeafe;
  --neutral: var(--slate-600);
  --neutral-bg: var(--slate-100);
  --purple: #6d28d9;
  --purple-bg: #ede9fe;

  --r-xs: 8px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.06);
  --shadow: 0 8px 24px rgba(15, 23, 42, 0.08);
  --shadow-lg: 0 24px 60px rgba(15, 23, 42, 0.14);

  --sidebar-w: 256px;
  /* Motion tokens.

     The browser's built-in curves are too weak to feel intentional, and the old
     token here was the standard Material curve, which eases both ends. UI
     should START fast: whatever the person just did, the response has to be
     visible immediately, so the default is a strong ease-out. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);          /* entering, hover, press: the default */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);      /* something already on screen moving */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);       /* panels sliding in from an edge */
  --t: 0.18s var(--ease-out);
  /* The properties an interactive control may animate, and nothing else.
     `transition: all` also animates width, padding and position, which is
     layout work on every frame and makes unrelated changes drift. */
  --t-ui: background var(--t), color var(--t), border-color var(--t),
          box-shadow var(--t), transform var(--t), opacity var(--t);
}

*, *::before, *::after { box-sizing: border-box; }

/* An author `display` rule outranks the UA stylesheet's [hidden] rule, so
   components like .notice (display:flex) would stay visible when hidden.
   Keep this ahead of component styles. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: Manrope, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.65;
  color: var(--body);
  background: var(--bg-alt);
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
ul { margin: 0; padding: 0; list-style: none; }
table { border-collapse: collapse; width: 100%; }

h1, h2, h3, h4 {
  margin: 0;
  color: var(--heading);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
}
h1 { font-size: 1.75rem; }
h2 { font-size: 1.3rem; }
h3 { font-size: 1.0625rem; }
h4 { font-size: 0.9375rem; }
p { margin: 0 0 0.9rem; }

/* ---------- prototype banner (brief §2: do not mistake demo for production) ---------- */
.proto-banner {
  background: var(--warn-bg);
  color: #78350f;
  font-size: 0.8125rem;
  font-weight: 600;
  text-align: center;
  padding: 7px 16px;
  border-bottom: 1px solid #fcd34d;
  position: relative;
  z-index: 200;
}
.proto-banner strong { font-weight: 800; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: var(--r-pill);
  font-weight: 700;
  font-size: 0.875rem;
  line-height: 1;
  white-space: nowrap;
  border: 1.5px solid transparent;
  transition: background var(--t), color var(--t), border-color var(--t), box-shadow var(--t);
}
.btn--primary { background: var(--blue-btn); color: #fff; }
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { background: var(--blue-dark);}
}
.btn--ghost { border-color: var(--line); color: var(--heading); background: var(--surface); }
@media (hover: hover) and (pointer: fine) {
  .btn--ghost:hover { border-color: var(--blue); color: var(--blue);}
}
.btn--quiet { color: var(--slate-600); }
@media (hover: hover) and (pointer: fine) {
  .btn--quiet:hover { color: var(--blue); background: var(--blue-soft);}
}
.btn--danger { background: var(--danger-btn); color: #fff; }
@media (hover: hover) and (pointer: fine) {
  .btn--danger:hover { background: #991b1b;}
}
.btn--light { background: var(--surface); color: var(--blue); }
@media (hover: hover) and (pointer: fine) {
  .btn--light:hover { background: var(--blue-soft);}
}
.btn--sm { padding: 8px 15px; font-size: 0.8125rem; }
.btn--lg { padding: 14px 28px; font-size: 0.9375rem; }
.btn--block { width: 100%; }
/* Any svg in a button is sized here, not only .ico. An svg with a viewBox and
   no width/height fills its flex container, which is how the sign-out icon
   ended up 138px square. Belt and braces with the attributes in the markup. */
.btn svg, .btn .ico { width: 15px; height: 15px; flex: none; }
/* controls that are not .btn but still hold an icon */
.signout svg, .chip svg, .tab svg, .qa svg, button.col svg, .col__menu svg,
.suggestions svg, .arrow-link svg, .link-arrow svg { flex: none; }
button.col svg { width: 16px; height: 16px; }
.btn[disabled] { opacity: 0.5; pointer-events: none; }

/* ---------- badges / pills ---------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  background: var(--neutral-bg);
  color: var(--neutral);
}
.pill svg { width: 11px; height: 11px; }
.pill--ok { background: var(--ok-bg); color: var(--ok); }
.pill--warn { background: var(--warn-bg); color: var(--warn); }
.pill--danger { background: var(--danger-bg); color: var(--danger); }
.pill--info { background: var(--info-bg); color: var(--info); }
.pill--purple { background: var(--purple-bg); color: var(--purple); }
.pill--dot::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
}


/* ---------- sign out ----------
   Quiet until you reach for it, and never wider than the space it is in. */
.signout {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  height: 34px;
  padding: 0 11px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  transition: background var(--t), color var(--t), border-color var(--t);
}
.signout:focus-visible {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.42);
  color: #fecaca;
}
@media (hover: hover) and (pointer: fine) {
  .signout:hover {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.42);
  color: #fecaca;
}
}
.signout:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.signout svg { width: 15px; height: 15px; flex: none; }

/* on the dark sidebar the label is dropped — the row is only 232px wide */
.sidebar .signout__label { display: none; }
.sidebar .signout { padding: 0 9px; }

/* light surfaces: the tenant top bar */
.signout--light {
  border-color: var(--line);
  background: var(--surface);
  color: var(--slate-600);
}
.signout--light:focus-visible {
  background: var(--danger-bg);
  border-color: #fca5a5;
  color: var(--danger);
}
@media (hover: hover) and (pointer: fine) {
  .signout--light:hover {
  background: var(--danger-bg);
  border-color: #fca5a5;
  color: var(--danger);
}
}

@media (max-width: 560px) {
  .signout__label { display: none; }
  .signout { padding: 0 9px; }
}

/* ---------- app shell ---------- */
.shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; min-height: 100dvh; }

.sidebar {
  background: var(--slate-900);
  color: var(--slate-400);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
}
.sidebar__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 20px 18px;
  color: #fff;
  font-size: 1.1875rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}
.brand-mark {
  width: 32px; height: 32px;
  border-radius: 9px;
  background: var(--blue-btn);
  display: grid;
  place-items: center;
  flex: none;
  color: #fff;
  font-weight: 800;
  font-size: 0.9375rem;
  letter-spacing: 0;
}
.sidebar__org {
  margin: 0 14px 16px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.06);
  font-size: 0.8125rem;
}
.sidebar__org small { display: block; color: var(--slate-500); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; }
.sidebar__org strong { color: #fff; font-weight: 700; }

.sidebar__label {
  padding: 14px 20px 6px;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate-600);
}
.sidebar__nav { padding: 0 12px; display: grid; gap: 2px; }
.sidebar__nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--r-xs);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--slate-400);
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .sidebar__nav a:hover { background: rgba(255, 255, 255, 0.06); color: #fff;}
}
.sidebar__nav a.is-active { background: var(--blue-btn); color: #fff; }
.sidebar__nav svg { width: 17px; height: 17px; flex: none; }
.sidebar__nav .count {
  margin-left: auto;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  border-radius: var(--r-pill);
  font-size: 0.6875rem;
  font-weight: 800;
  padding: 1px 7px;
}
.sidebar__nav a.is-active .count { background: rgba(255, 255, 255, 0.25); }
.sidebar__foot { margin-top: auto; padding: 16px 14px; border-top: 1px solid rgba(255, 255, 255, 0.08); }

.user-chip { display: flex; align-items: center; gap: 10px; min-width: 0; }
.user-chip__who { min-width: 0; flex: 1; }
.user-chip__who strong,
.user-chip__who small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-chip__av {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--blue-deep);
  color: #fff;
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 800;
  flex: none;
}
.user-chip strong { color: #fff; font-size: 0.8125rem; display: block; line-height: 1.3; }
.user-chip small { font-size: 0.75rem; color: var(--slate-500); }

/* main column */
.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 0 28px;
  min-height: 66px;
  display: flex;
  align-items: center;
  gap: 18px;
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar h1 { font-size: 1.25rem; }
.topbar > div:not(.topbar__actions) { min-width: 0; }
.topbar h1, .topbar__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar__actions { flex: none; }
.topbar__sub { font-size: 0.8125rem; color: var(--muted); margin: 0; }
.topbar__actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }

.icon-btn {
  width: 38px; height: 38px;
  flex: none;            /* a flex child with only width shrinks; the mobile
                            menu toggle was being squashed to ~20px */
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  color: var(--slate-600);
  background: var(--surface);
  position: relative;
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .icon-btn:hover { border-color: var(--blue); color: var(--blue);}
}
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn__dot {
  position: absolute; top: -4px; right: -4px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: var(--r-pill);
  background: var(--danger-btn); color: #fff;
  font-size: 0.625rem; font-weight: 800;
  display: grid; place-items: center;
}

.content { padding: 26px 28px 60px; flex: 1; }
.content--narrow { max-width: 980px; }

.menu-toggle { display: none; }

/* ---------- filter bar ---------- */
.filterbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.filterbar select, .filterbar input {
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--heading);
  outline: none;
  transition: border-color var(--t), box-shadow var(--t);
}
.filterbar select:focus, .filterbar input:focus {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-soft);
}
.filterbar .spacer { margin-left: auto; }
.search-input { position: relative; }
.search-input svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--slate-400); pointer-events: none;
}
.search-input input { padding-left: 34px; min-width: 240px; }

/* ---------- cards ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  min-width: 0;
}
.card__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;       /* title + status pill stack on a phone instead of overflowing */
}
.card__head h2, .card__head h3 { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.card__head .pill { flex: none; }
.card__head .spacer { margin-left: auto; }
.card__body { padding: 20px; }
.card__body--flush { padding: 0; }
.card__foot {
  padding: 13px 20px;
  border-top: 1px solid var(--line);
  background: var(--slate-50);
  border-radius: 0 0 var(--r-md) var(--r-md);
  font-size: 0.8125rem;
}

.grid { display: grid; gap: 18px; }
/* grid items default to min-width:auto, which lets wide tables push the
   column past the viewport — opt every child back to a shrinkable floor */
.grid > * { min-width: 0; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--5 { grid-template-columns: repeat(5, 1fr); }
.grid--main { grid-template-columns: 1.65fr 1fr; align-items: start; }
.grid--side { grid-template-columns: 1fr 320px; align-items: start; }

/* ---------- stat tiles ---------- */
.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 18px;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
/* A tile that stands for a set of records is a link to them. It keeps the
   plain tile's shape so a row of tiles stays even, and earns a lift and an
   arrow on hover to say it goes somewhere. */
.stat--link { transition: border-color var(--t), box-shadow var(--t), transform var(--t); }
@media (hover: hover) and (pointer: fine) {
  .stat--link:hover {
  border-color: var(--blue);
  box-shadow: var(--shadow);
  transform: translateY(-1px);}
}
.stat--link:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.stat__go {
  flex: none;
  color: var(--slate-400);
  display: grid; place-items: center;
  opacity: 0;
  transform: translateX(-3px);
  transition: opacity var(--t), transform var(--t), color var(--t);
}
.stat--link:focus-visible .stat__go { opacity: 1; transform: none; color: var(--blue); }
@media (hover: hover) and (pointer: fine) {
  .stat--link:hover .stat__go { opacity: 1; transform: none; color: var(--blue); }
}
.stat__go svg { width: 16px; height: 16px; }

.stat__top { display: flex; align-items: center; gap: 9px; }
.stat__ico {
  width: 32px; height: 32px;
  border-radius: var(--r-xs);
  background: var(--blue-soft);
  color: var(--blue);
  display: grid; place-items: center;
  flex: none;
}
.stat__ico svg { width: 16px; height: 16px; }
.stat__ico--ok { background: var(--ok-bg); color: var(--ok); }
.stat__ico--warn { background: var(--warn-bg); color: var(--warn); }
.stat__ico--danger { background: var(--danger-bg); color: var(--danger); }
.stat__ico--purple { background: var(--purple-bg); color: var(--purple); }
.stat__label { font-size: 0.8125rem; font-weight: 700; color: var(--slate-500); }
.stat__num {
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--heading);
  letter-spacing: -0.03em;
  line-height: 1.15;
}
.stat__num small { font-size: 0.875rem; font-weight: 700; color: var(--muted); letter-spacing: 0; }
.stat__note { font-size: 0.75rem; color: var(--muted); }
.stat__note b { color: var(--heading); }

/* definition tooltip — brief §5: totals must have clear definitions */
.defn {
  border-bottom: 1px dotted var(--slate-400);
  cursor: help;
}

/* ---------- progress / meters ---------- */
.meter {
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--slate-200);
  overflow: hidden;
  display: flex;
}
.meter span { display: block; height: 100%; }
.meter .is-ok { background: var(--ok); }
.meter .is-info { background: var(--blue); }
.meter .is-warn { background: #f59e0b; }
.meter .is-danger { background: var(--danger); }
.meter-key { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; font-size: 0.75rem; }
.meter-key span { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.meter-key i { width: 9px; height: 9px; border-radius: 3px; display: block; }

/* ---------- tables ---------- */
.table { font-size: 0.875rem; }
.table th {
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate-500);
  padding: 11px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--slate-50);
  white-space: nowrap;
}
.table td { padding: 13px 20px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr { transition: background var(--t); }
@media (hover: hover) and (pointer: fine) {
  .table tbody tr:hover { background: var(--slate-50);}
}
.table .num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--heading); }
.table .nowrap { white-space: nowrap; }
.table a.link { color: var(--blue); font-weight: 700; }
@media (hover: hover) and (pointer: fine) {
  .table a.link:hover { text-decoration: underline;}
}
.table-wrap { overflow-x: auto; }

/* Phones: a row becomes a small card, each cell labelled by its column heading
   (app.js copies the heading into data-label), so nothing scrolls sideways. */
@media (max-width: 640px) {
  .table-wrap { overflow-x: visible; }
  .table, .table tbody, .table tr, .table td { display: block; width: 100%; }
  .table thead { display: none; }
  .table tbody tr { padding: 10px 0; border-bottom: 1px solid var(--line); }
  .table tbody tr:last-child { border-bottom: 0; }
  .table td { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 6px 16px; border: 0; text-align: right; overflow-wrap: anywhere; }
  .table td[data-label]::before { content: attr(data-label); flex: none; max-width: 45%; text-align: left; font-size: 0.6875rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--slate-500); }
  .table td:empty { display: none; }
  .table td[colspan] { display: block; text-align: left; }
}

.person { display: flex; align-items: center; gap: 10px; min-width: 0; }
.person__av {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--blue-soft);
  color: var(--blue-deep);
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 800;
  flex: none;
}
.person strong { display: block; color: var(--heading); font-size: 0.875rem; line-height: 1.3; }
.person small { color: var(--muted); font-size: 0.75rem; }

/* ---------- list rows ---------- */
.rows { display: grid; }
.row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line);
  transition: background var(--t);
}
.row:last-child { border-bottom: 0; }
@media (hover: hover) and (pointer: fine) {
  .row:hover { background: var(--slate-50);}
}
/* A row's text takes the space it can and its actions wrap UNDER it when there
   is not room, rather than the row growing past the screen. Found with a real
   worst case — a long filename beside three buttons overflowed a phone by 325px. */
.row { flex-wrap: wrap; }
.row__main { min-width: 0; flex: 1 1 150px; }
.row__main strong { display: block; color: var(--heading); font-size: 0.875rem; overflow-wrap: anywhere; }
.row__main small { color: var(--muted); font-size: 0.8125rem; overflow-wrap: anywhere; }
.row__side { text-align: right; flex: none; max-width: 100%; margin-inline-start: auto; }

.ico-tile {
  width: 36px; height: 36px;
  border-radius: var(--r-xs);
  display: grid; place-items: center;
  flex: none;
  background: var(--slate-100);
  color: var(--slate-600);
}
.ico-tile svg { width: 17px; height: 17px; }
.ico-tile--ok { background: var(--ok-bg); color: var(--ok); }
.ico-tile--warn { background: var(--warn-bg); color: var(--warn); }
.ico-tile--danger { background: var(--danger-bg); color: var(--danger); }
.ico-tile--info { background: var(--info-bg); color: var(--info); }
.ico-tile--purple { background: var(--purple-bg); color: var(--purple); }

/* ---------- tabs ---------- */
.tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.tab {
  padding: 7px 15px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  font-weight: 700;
  font-size: 0.8125rem;
  color: var(--slate-600);
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .tab:hover { border-color: var(--blue); color: var(--blue);}
}
.tab.is-active { background: var(--blue-btn); border-color: var(--blue-btn); color: #fff; }

.subtabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: 20px; flex-wrap: wrap; }
.subtab {
  padding: 11px 16px;
  font-weight: 700;
  font-size: 0.875rem;
  color: var(--slate-500);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .subtab:hover { color: var(--blue);}
}
.subtab.is-active { color: var(--blue); border-bottom-color: var(--blue); }

/* ---------- forms ---------- */
.field { display: grid; gap: 6px; margin-bottom: 15px; }
.field > label { font-size: 0.8125rem; font-weight: 700; color: var(--heading); }
.field .hint { font-size: 0.75rem; color: var(--muted); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  /* Without this a control inherits its container's colour, so the same
     select reads full-strength in one card and washed-out grey in another. */
  color: var(--heading);
  font-size: 0.875rem;
  outline: none;
  transition: border-color var(--t), box-shadow var(--t);
}
.field input::placeholder, .field textarea::placeholder { color: var(--muted); }

/* Belt and braces for the open dropdown on the browsers that honour it;
   color-scheme above is what actually does the work on the rest. */
select option {
  background: var(--surface);
  color: var(--heading);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-soft);
}
.field textarea { resize: vertical; min-height: 110px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }

/* A checkbox or radio sitting on one line with its own label. `.field input`
   above stretches every control to full width, which turns a checkbox into a
   long grey bar, so these reset the box back to its natural size and only
   then lay the row out. */
.check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--heading);
  cursor: pointer;
}
.field .check input[type="checkbox"],
.field .check input[type="radio"],
.check input[type="checkbox"],
.check input[type="radio"] {
  width: 16px;
  height: 16px;
  flex: none;
  padding: 0;
  margin: 0;
  accent-color: var(--blue-btn, var(--blue));
  cursor: pointer;
}
.check input:disabled { cursor: not-allowed; }

/* ---- engine choice ----
   Two options side by side so the decision reads as a choice between two
   arrangements, not as a setting with a default someone should leave alone. */
.engine-choice {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}
.engine-opt {
  position: relative;
  display: grid;
  gap: 6px;
  text-align: left;
  padding: 16px 16px 16px 44px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--t), box-shadow var(--t), background var(--t);
}
@media (hover: hover) and (pointer: fine) {
  .engine-opt:hover:not([disabled]) { border-color: var(--blue);}
}
.engine-opt.is-on {
  border-color: var(--blue-btn);
  box-shadow: 0 0 0 3px var(--blue-soft);
}
.engine-opt[disabled] { cursor: not-allowed; opacity: 0.7; }
.engine-opt strong { font-size: 0.9375rem; color: var(--heading); }
.engine-opt span:not(.engine-opt__tick) {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--body);
}
.engine-opt__tick {
  position: absolute;
  left: 15px; top: 17px;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  display: grid; place-items: center;
  font-size: 0.6875rem; font-weight: 800;
  color: #fff;
}
.engine-opt.is-on .engine-opt__tick {
  background: var(--blue-btn);
  border-color: var(--blue-btn);
}

/* ---- numbered setup steps ---- */
.step-dot {
  flex: none;
  width: 24px; height: 24px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 800;
  background: var(--bg-alt);
  color: var(--body);
  border: 1px solid var(--line);
  margin-top: 1px;
}
.step-dot--done {
  background: var(--ok-bg, var(--blue-soft));
  color: var(--ok, var(--blue));
  border-color: transparent;
}

/* ==========================================================================
   Chat thread — iMessage shape

   The conventions people already read without being taught: outgoing on the
   right in a filled bubble, incoming on the left in a grey one, consecutive
   messages from the same side grouped tight with only the last one tailed,
   a date divider when the day changes, and the timestamp held back until it
   is wanted. Everything here is layout and colour; who may see a message is
   decided on the server.
   ========================================================================== */
.thread {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px;
  overflow-y: auto;
  scroll-behavior: smooth;
  background: var(--bg-alt);
}
.thread__day {
  align-self: center;
  margin: 14px 0 8px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted);
  text-transform: uppercase;
}

.bub {
  position: relative;
  max-width: min(78%, 520px);
  padding: 8px 14px;
  font-size: 0.9375rem;
  line-height: 1.4;
  border-radius: 18px;
  align-self: flex-start;
  background: var(--chat-in-bg);
  color: var(--chat-in-fg);
  /* Long words and pasted links must wrap rather than widen the bubble. */
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.bub--out {
  align-self: flex-end;
  background: var(--blue-btn);
  color: #fff;
}

/* Grouping: a run from the same side is one visual block. Only the last
   bubble in the run gets the tail, which is what makes it read as a tail
   rather than as a decoration on every line. */
.bub--mid { border-radius: 18px; margin-top: 2px; }
.bub--first { margin-top: 10px; }
.bub--last.bub--out { border-bottom-right-radius: 5px; }
.bub--last:not(.bub--out) { border-bottom-left-radius: 5px; }

/* An internal note is staff-only and must never be mistaken for something the
   resident can see, so it is not bubble-shaped at all. */
.bub--note {
  align-self: stretch;
  max-width: none;
  background: var(--warn-bg);
  color: var(--warn-ink);
  border-radius: var(--r-sm);
  border-left: 3px solid var(--warn);
  font-size: 0.8125rem;
}
.bub--ai {
  background: var(--surface-ai);
  color: var(--heading);
  border: 1px solid var(--surface-ai-line);
}

/* Author and timestamp are held back by fading them — but only where there is
   contrast to spare. White on the blue outgoing bubble is 5.17:1 at FULL
   strength, so any fade at all drops it under AA; the same on the warn-tinted
   note. Those two keep full opacity and are de-emphasised by size alone. */
.bub__who {
  display: block;
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  opacity: 0.75;
  margin-bottom: 2px;
}
.bub__time {
  display: block;
  font-size: 0.625rem;
  margin-top: 3px;
  opacity: 0.72;
  text-align: right;
}
.bub--out .bub__time,
.bub--out .bub__who { opacity: 1; color: #fff; }
.bub--note .bub__time,
.bub--note .bub__who { opacity: 1; color: inherit; }
.bub--ai .bub__time,
.bub--ai .bub__who { opacity: 1; color: var(--body); }

/* Sent-but-not-yet-acknowledged. Reverted on failure rather than left
   looking delivered. */
.bub--pending { opacity: 0.62; }
.bub--failed {
  background: var(--danger-bg);
  color: var(--danger-ink);
  border: 1px solid var(--danger);
}

/* Sent in the app but not to the phone. The bubble is not recoloured — the
   message did send, to one of its two destinations — so the difference is
   carried by a line under it rather than by making it look failed. */
.bub--undelivered { border: 1px dashed var(--warn); }
.bub__warn {
  display: block;
  margin-top: 4px;
  font-size: 0.625rem;
  font-weight: 700;
  color: inherit;
  opacity: 0.95;
}

/* The three dots, shown only while the other side is actually composing. */
.bub--typing { display: flex; gap: 4px; align-items: center; padding: 12px 15px; }
.bub--typing i {
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; opacity: 0.45;
  animation: bub-dot 1.2s infinite ease-in-out;
}
.bub--typing i:nth-child(2) { animation-delay: 0.16s; }
.bub--typing i:nth-child(3) { animation-delay: 0.32s; }
@keyframes bub-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.35; }
  30% { transform: translateY(-3px); opacity: 0.9; }
}
@media (prefers-reduced-motion: reduce) {
  .bub--typing i { animation: none; }
}

/* The composer, pinned under the thread. */
.composer {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.composer textarea {
  flex: 1;
  resize: none;
  min-height: 40px;
  max-height: 140px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--bg-alt);
  color: var(--heading);
  font: inherit;
  font-size: 0.9375rem;
  outline: none;
}
.composer textarea:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
.composer__send {
  flex: none;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--blue-btn);
  color: #fff;
  display: grid; place-items: center;
  border: 0;
  cursor: pointer;
}
.composer__send[disabled] { opacity: 0.4; cursor: not-allowed; }
.composer__send svg { width: 17px; height: 17px; }

/* The thread and its composer are one block that owns its height, so the
   messages scroll and the composer stays put instead of the whole page
   scrolling away from the box you are typing in. */
.chat-shell {
  display: flex;
  flex-direction: column;
  height: clamp(380px, 62vh, 680px);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface);
}
.chat-shell .thread { flex: 1; min-height: 0; }

.check--disabled { opacity: 0.55; cursor: not-allowed; }

/* Variable chips: click to insert a placeholder into the template you are
   editing. */
.var-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.var-chip {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.7rem;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-alt);
  color: var(--heading);
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .var-chip:hover { border-color: var(--blue); color: var(--blue);}
}

/* A destructive area, visually fenced off from the settings above it. */
.danger-zone { border-color: var(--danger); }
.danger-zone .card__head h2 { color: var(--danger); }

.choice { display: flex; gap: 10px; flex-wrap: wrap; }
.choice label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  background: var(--surface);
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .choice label:hover { border-color: var(--blue);}
}
.choice input { accent-color: var(--blue); }
.choice input:checked + span { color: var(--blue); font-weight: 700; }

.switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; font-weight: 600; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch__track {
  width: 42px; height: 24px;
  border-radius: var(--r-pill);
  background: var(--slate-300);
  position: relative;
  transition: background var(--t);
  flex: none;
}
.switch__track::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--t);
}
.switch input:checked + .switch__track { background: var(--blue); }
.switch input:checked + .switch__track::after { transform: translateX(18px); }
.switch input:focus-visible + .switch__track { box-shadow: 0 0 0 3px var(--blue-soft); }

/* ---------- notices ---------- */
.notice {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--r-sm);
  font-size: 0.875rem;
  border: 1px solid;
  margin-bottom: 18px;
}
.notice svg { width: 17px; height: 17px; flex: none; margin-top: 2px; }
.notice p { margin: 0; }
.notice strong { display: block; color: inherit; }
.notice--info { background: var(--info-bg); border-color: #bfdbfe; color: #1e40af; }
.notice--warn { background: var(--warn-bg); border-color: #fcd34d; color: #78350f; }
.notice--ok { background: var(--ok-bg); border-color: #86efac; color: #14532d; }
.notice--danger { background: var(--danger-bg); border-color: #fca5a5; color: #7f1d1d; }

/* A notice paints its own background, so the page's muted grey — which is
   tuned against the page background — can fall below contrast on top of it.
   Inside a notice, de-emphasis is carried by opacity on the notice's own
   colour instead, which stays legible whatever the notice's tint is. */
.notice .muted,
.notice .fs-xs.muted,
.notice .fs-sm.muted {
  color: inherit;
  opacity: 0.78;
}

/* ---------- timeline / audit ---------- */
.timeline { display: grid; gap: 0; }
.tl {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 12px;
  padding-bottom: 18px;
  position: relative;
}
.tl:last-child { padding-bottom: 0; }
.tl::before {
  content: "";
  position: absolute;
  left: 14px; top: 28px; bottom: 0;
  width: 2px;
  background: var(--line);
}
.tl:last-child::before { display: none; }
.tl__dot {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--slate-100);
  color: var(--slate-600);
  display: grid; place-items: center;
  z-index: 1;
}
.tl__dot svg { width: 14px; height: 14px; }
.tl__dot--ok { background: var(--ok-bg); color: var(--ok); }
.tl__dot--info { background: var(--info-bg); color: var(--info); }
.tl__dot--warn { background: var(--warn-bg); color: var(--warn); }
.tl__dot--danger { background: var(--danger-bg); color: var(--danger); }
.tl__dot--purple { background: var(--purple-bg); color: var(--purple); }
.tl__body strong { display: block; color: var(--heading); font-size: 0.875rem; }
.tl__body p { margin: 2px 0 0; font-size: 0.8125rem; }
.tl__meta { font-size: 0.75rem; color: var(--muted); margin-top: 3px; }

/* ---------- conversation ---------- */
.convo { display: flex; flex-direction: column; gap: 16px; padding: 20px; max-height: 540px; overflow-y: auto; }
.msg { display: flex; gap: 11px; max-width: 78%; }
.msg__av {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 0.6875rem; font-weight: 800;
  flex: none;
  background: var(--slate-200);
  color: var(--slate-700);
}
.msg__bubble {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px 14px 14px 14px;
  padding: 11px 14px;
  font-size: 0.875rem;
  color: var(--slate-700);
}
.msg__meta {
  font-size: 0.6875rem;
  color: var(--muted);
  margin-top: 5px;
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
}
.msg--out { margin-left: auto; flex-direction: row-reverse; }
.msg--out .msg__bubble {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
  border-radius: 14px 4px 14px 14px;
}
.msg--out .msg__meta { justify-content: flex-end; }
.msg--out .msg__av { background: var(--blue-deep); color: #fff; }
.msg--ai .msg__av { background: var(--purple-bg); color: var(--purple); }
.msg--ai .msg__bubble { background: #faf8ff; border-color: #ddd0fb; color: var(--slate-700); }
.msg--note .msg__bubble {
  background: var(--warn-bg);
  border-color: #fcd34d;
  color: #78350f;
  border-style: dashed;
}

.composer { border-top: 1px solid var(--line); padding: 14px 20px; background: var(--surface); border-radius: 0 0 var(--r-md) var(--r-md); }
.composer textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 11px 14px;
  font-size: 0.875rem;
  resize: vertical;
  min-height: 72px;
  outline: none;
}
.composer textarea:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
.composer__bar { display: flex; align-items: center; gap: 10px; margin-top: 11px; flex-wrap: wrap; }
.composer__bar .spacer { margin-left: auto; }

/* ---------- AI panel ---------- */
.ai-card {
  border: 1px solid #ddd0fb;
  border-radius: var(--r-md);
  background: linear-gradient(180deg, #faf8ff, #fff 60%);
  padding: 16px;
}
.ai-card__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.ai-card__head h3 { font-size: 0.9375rem; }
.ai-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--purple-bg);
  color: var(--purple);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ai-chip svg { width: 11px; height: 11px; }
.ai-card__why {
  font-size: 0.75rem;
  color: var(--muted);
  background: var(--slate-50);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  padding: 9px 11px;
  margin: 10px 0;
}
.ai-card__why b { color: var(--slate-700); }
.ai-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.authority { display: grid; gap: 10px; }
.authority li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
}
.authority strong { display: block; color: var(--heading); font-size: 0.875rem; }
.authority small { font-size: 0.8125rem; color: var(--muted); }

/* ---------- empty state ---------- */
.empty { text-align: center; padding: 44px 20px; }
.empty__ico {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--slate-100);
  color: var(--slate-400);
  display: grid; place-items: center;
  margin: 0 auto 14px;
}
.empty__ico svg { width: 24px; height: 24px; }
.empty h3 { margin-bottom: 5px; }
.empty p { font-size: 0.875rem; max-width: 380px; margin: 0 auto; }

/* ---------- welcome / auth pages ---------- */
.welcome {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(900px 500px at 82% 12%, rgba(37, 99, 235, 0.16), transparent 62%),
    radial-gradient(700px 420px at 6% 90%, rgba(37, 99, 235, 0.08), transparent 60%),
    var(--slate-900);
  color: #fff;
}
.welcome__nav {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px 32px;
}
.welcome__nav .brand-mark { width: 34px; height: 34px; }
.welcome__brand { display: flex; align-items: center; gap: 10px; color: #fff; font-size: 1.25rem; font-weight: 800; letter-spacing: -0.03em; }
.welcome__nav .spacer { margin-left: auto; }
.welcome__body {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 36px 24px 60px;
}
.welcome__inner { width: 100%; max-width: 980px; text-align: center; }
.welcome h1 {
  color: #fff;
  font-size: clamp(2.1rem, 4.4vw, 3.1rem);
  line-height: 1.14;
  margin-bottom: 14px;
}
.welcome__lead {
  color: rgba(255, 255, 255, 0.68);
  font-size: 1.0625rem;
  max-width: 560px;
  margin: 0 auto 40px;
}
.portal-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; text-align: left; }
.portal-card {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--r-lg);
  padding: 28px;
  transition: var(--t-ui);
  display: flex;
  flex-direction: column;
}
@media (hover: hover) and (pointer: fine) {
  .portal-card:hover { background: rgba(255, 255, 255, 0.09); border-color: var(--blue); transform: translateY(-3px);}
}
.portal-card__ico {
  width: 46px; height: 46px;
  border-radius: 12px;
  background: var(--blue);
  color: #fff;
  display: grid; place-items: center;
  margin-bottom: 16px;
}
.portal-card__ico svg { width: 22px; height: 22px; }
.portal-card h2 { color: #fff; margin-bottom: 7px; }
.portal-card p { color: rgba(255, 255, 255, 0.64); font-size: 0.9375rem; }
.portal-card ul { display: grid; gap: 7px; margin: 4px 0 22px; }
.portal-card li { display: flex; gap: 9px; align-items: flex-start; color: rgba(255, 255, 255, 0.72); font-size: 0.875rem; }
.portal-card li svg { width: 14px; height: 14px; color: var(--blue); flex: none; margin-top: 4px; }
.portal-card .btn { margin-top: auto; }

.auth-wrap { min-height: 100vh; min-height: 100dvh; display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; padding: 40px 20px; background: var(--slate-50); }
.auth-card { width: 100%; max-width: 420px; justify-self: center; }
.auth-card .card { padding: 30px; }
.auth-head { text-align: center; margin-bottom: 24px; }
.auth-head .brand-mark { width: 44px; height: 44px; margin: 0 auto 14px; font-size: 1.125rem; }
.auth-head h1 { font-size: 1.4rem; margin-bottom: 5px; }
.auth-head p { font-size: 0.875rem; margin: 0; }
.auth-alt { text-align: center; font-size: 0.8125rem; margin-top: 18px; }
.auth-alt a { color: var(--blue); font-weight: 700; }

.demo-creds {
  background: var(--slate-50);
  border: 1px dashed var(--slate-300);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  font-size: 0.75rem;
  margin-bottom: 18px;
}
.demo-creds strong { display: block; color: var(--heading); margin-bottom: 3px; }
.demo-creds code {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: 0.75rem;
}

/* ---------- tenant shell (mobile-first per brief §6) ---------- */
.tshell { max-width: 940px; margin: 0 auto; padding: 0 18px 90px; }
.ttop {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 14px 0;
  margin-bottom: 22px;
}
.ttop__inner { max-width: 940px; margin: 0 auto; padding: 0 18px; display: flex; align-items: center; gap: 14px; }
.ttop .spacer { margin-left: auto; }

.tnav {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--surface);
  border-top: 1px solid var(--line);
  display: flex;
  z-index: 60;
  padding-bottom: env(safe-area-inset-bottom);
}
.tnav a {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 4px;
  font-size: 0.6875rem;
  font-weight: 700;
  /* --body rather than --slate-500: this is secondary text, and --body is the
     token for it. Both clear AA in either theme (dark: 8.11 vs 6.74). */
  color: var(--body);
  transition: color var(--t);
  min-height: 56px;
  justify-content: center;
}
.tnav a svg { width: 19px; height: 19px; }
.tnav a.is-active { color: var(--blue); }
.tnav a > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tnav__short { display: none; }
/* six items at phone width leave ~63px each, which "Documents" alone fills */
@media (max-width: 430px) {
  .tnav a { font-size: 0.625rem; padding-inline: 2px; gap: 2px; }
  .tnav__full { display: none; }
  .tnav__short { display: inline; }
}
@media (hover: hover) and (pointer: fine) {
  .tnav a:hover { color: var(--blue);}
}

.balance-card {
  background: linear-gradient(135deg, var(--blue-deep), var(--blue));
  color: #fff;
  border-radius: var(--r-lg);
  padding: 26px;
  box-shadow: var(--shadow);
}
/* 0.92 and 0.96, not 0.76 and 0.84: measured against the lighter stop of the
   card's gradient (--blue), the dimmer values came out at 3.67:1 and 4.13:1.
   The hierarchy here is carried by size and weight instead. */
.balance-card small { font-size: 0.8125rem; color: rgba(255, 255, 255, 0.92); font-weight: 600; }
.balance-card .amount {
  font-size: 2.6rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.1;
  margin: 3px 0 6px;
}
.balance-card .due { font-size: 0.875rem; color: rgba(255, 255, 255, 0.96); }
.balance-card .btn { margin-top: 18px; }

.quick-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.qa {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 12px;
  text-align: center;
  transition: var(--t-ui);
  box-shadow: var(--shadow-sm);
}
@media (hover: hover) and (pointer: fine) {
  .qa:hover { border-color: var(--blue); transform: translateY(-2px); box-shadow: var(--shadow);}
}
.qa__ico {
  width: 38px; height: 38px;
  border-radius: var(--r-sm);
  background: var(--blue-soft);
  color: var(--blue);
  display: grid; place-items: center;
  margin: 0 auto 9px;
}
.qa__ico svg { width: 18px; height: 18px; }
.qa span { font-size: 0.8125rem; font-weight: 700; color: var(--heading); }

/* ---------- property gallery (tenant "My home") ---------- */
.shot {
  border-radius: var(--r-md);
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--slate-100);
  margin-bottom: 12px;
}
.shot img { width: 100%; height: 100%; object-fit: cover; }

.shot-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
.shot-row button {
  border-radius: var(--r-sm);
  overflow: hidden;
  aspect-ratio: 16 / 11;
  background: var(--slate-100);
  border: 2px solid transparent;
  padding: 0;
  transition: border-color var(--t), opacity var(--t);
}
@media (hover: hover) and (pointer: fine) {
  .shot-row button:hover { opacity: 0.85;}
}
.shot-row button.is-active { border-color: var(--blue); }
.shot-row img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shot-caption { font-size: 0.8125rem; color: var(--muted); margin-top: 10px; }

.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; }
.fact { display: flex; gap: 11px; align-items: center; }
.fact__i {
  width: 40px; height: 40px;
  border-radius: var(--r-sm);
  background: var(--blue-soft);
  color: var(--blue);
  display: grid; place-items: center;
  flex: none;
}
.fact__i svg { width: 17px; height: 17px; }
.fact small { display: block; font-size: 0.75rem; color: var(--muted); }
.fact strong { color: var(--heading); font-size: 0.9375rem; }

.amenities { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 11px; }
.amenities li { display: flex; align-items: center; gap: 9px; font-size: 0.9375rem; }
.amenities svg { width: 15px; height: 15px; color: var(--blue); flex: none; }

/* the property card that opens "My home" */
.home-card {
  display: flex;
  gap: 16px;
  align-items: center;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--t), transform var(--t), border-color var(--t);
}
@media (hover: hover) and (pointer: fine) {
  .home-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); border-color: var(--blue);}
}
.home-card__img {
  width: 120px;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-sm);
  overflow: hidden;
  flex: none;
  background: var(--slate-100);
}
.home-card__img img { width: 100%; height: 100%; object-fit: cover; }
.home-card__img--none { display: grid; place-items: center; color: var(--muted); }
.home-card__img--none svg { width: 28px; height: 28px; }
.home-card__body { min-width: 0; flex: 1; }
.home-card__body strong { display: block; color: var(--heading); font-size: 1rem; }
.home-card__body small { color: var(--muted); font-size: 0.8125rem; }
.home-card__go { color: var(--blue); flex: none; }
.home-card__go svg { width: 18px; height: 18px; }

@media (max-width: 640px) {
  .shot-row { grid-template-columns: repeat(3, 1fr); }
  .home-card__img { width: 92px; }
}

/* ---------- modal ---------- */
.modal {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.55);
  display: grid; place-items: center;
  padding: 20px;
  z-index: 300;
}
.modal[hidden] { display: none; }
.modal__box {
  background: var(--surface);
  border-radius: var(--r-lg);
  width: 100%;
  max-width: 520px;
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
}
.modal__head {
  display: flex; align-items: center; gap: 12px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--line);
}
.modal__head h2 { margin: 0; font-size: 1.125rem; }
.modal__head .spacer { margin-left: auto; }
.modal__body { padding: 22px; }
.modal__foot {
  padding: 15px 22px;
  border-top: 1px solid var(--line);
  display: flex; gap: 10px; justify-content: flex-end;
  background: var(--slate-50);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* ---------- utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.muted { color: var(--muted); }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.mb-18 { margin-bottom: 18px; }
.mb-24 { margin-bottom: 24px; }
.flex { display: flex; align-items: center; gap: 10px; }
.flex-wrap { flex-wrap: wrap; }
.spacer { margin-left: auto; }
.text-right { text-align: right; }
.fs-sm { font-size: 0.8125rem; }
.fs-xs { font-size: 0.75rem; }
.fw-700 { font-weight: 700; }
.tnum { font-variant-numeric: tabular-nums; }
.section-gap { margin-bottom: 22px; }

/* ---------- responsive ---------- */
@media (max-width: 1180px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--5 { grid-template-columns: repeat(3, 1fr); }
  .grid--main, .grid--side { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: 260px;
    z-index: 150;
    transform: translateX(-100%);
    transition: transform var(--t); }
  .sidebar.is-open { transform: translateX(0); box-shadow: var(--shadow-lg); }
  .menu-toggle { display: grid; }
  .content { padding: 20px 18px 60px; }
  .topbar { padding: 0 18px; }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .portal-grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .grid--2, .grid--3, .grid--4, .grid--5 { grid-template-columns: 1fr; }
  .field-row { grid-template-columns: 1fr; }
  .quick-actions { grid-template-columns: repeat(2, 1fr); }
  .msg { max-width: 92%; }
  .topbar { min-height: 58px; }
  .topbar h1 { font-size: 1.0625rem; }
  /* The page title is what a phone header is for. With the labelled button beside
     it, "Dashboard" was squeezed to 50px and cut off; the icon alone says enough. */
  .topbar__actions .btn__label { display: none; }
  .topbar__actions { gap: 6px; }
  .balance-card .amount { font-size: 2.1rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ==========================================================================
   Work-order pipeline (kanban) + Maintenance Agent
   ========================================================================== */

.board {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  overflow-x: auto;
  padding-bottom: 14px;
  scroll-snap-type: x proximity;
}

.col {
  flex: 0 0 286px;
  background: var(--slate-100);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 230px);
  scroll-snap-align: start;
  transition: background var(--t), border-color var(--t);
}
.col.is-over { background: var(--blue-soft); border-color: var(--blue); }

.col__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 13px;
  border-bottom: 1px solid var(--line);
}
.col__dot { width: 9px; height: 9px; border-radius: 3px; background: var(--slate-400); flex: none; }
.col__dot--info { background: var(--blue); }
.col__dot--ok { background: var(--ok); }
.col__dot--warn { background: #f59e0b; }
.col__dot--purple { background: var(--purple); }
.col__name {
  font-weight: 800;
  font-size: 0.8125rem;
  color: var(--heading);
  letter-spacing: -0.01em;
  min-width: 0;
  flex: 1;
}
.col__name[contenteditable="true"] { outline: none; }
.col__name[contenteditable="true"]:focus {
  background: var(--surface);
  box-shadow: 0 0 0 2px var(--blue);
  border-radius: 4px;
  padding: 0 3px;
}
.col__count {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: 0.6875rem;
  font-weight: 800;
  padding: 1px 7px;
  color: var(--slate-600);
}
.col__menu { position: relative; flex: none; }
.col__menu > button {
  width: 24px; height: 24px;
  border-radius: 5px;
  display: grid; place-items: center;
  color: var(--slate-500);
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .col__menu > button:hover { background: var(--surface); color: var(--heading);}
}
.col__menu svg { width: 14px; height: 14px; }
.col__menu__panel {
  position: absolute; top: 100%; right: 0;
  min-width: 170px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lg);
  padding: 5px;
  z-index: 40;
  display: none;
}
.col__menu.is-open .col__menu__panel { display: block; }
.col__menu__panel button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 7px 10px;
  border-radius: 5px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--slate-700);
  transition: background var(--t);
}
@media (hover: hover) and (pointer: fine) {
  .col__menu__panel button:hover { background: var(--slate-100);}
}
.col__menu__panel button.is-danger { color: var(--danger); }

.col__body {
  padding: 10px;
  display: grid;
  gap: 9px;
  overflow-y: auto;
  min-height: 70px;
  align-content: start;
}
.col__empty {
  border: 1.5px dashed var(--slate-300);
  border-radius: var(--r-sm);
  padding: 16px 10px;
  text-align: center;
  font-size: 0.75rem;
  /* slate-400 is 2.56:1 on white — decorative-grey territory, not text. */
  color: var(--slate-500);
  font-weight: 600;
}

/* cards */
.wo {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 11px;
  cursor: grab;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--t), transform var(--t), opacity var(--t);
}
@media (hover: hover) and (pointer: fine) {
  .wo:hover { box-shadow: var(--shadow); transform: translateY(-1px);}
}
.wo:active { cursor: grabbing; }
.wo.is-dragging { opacity: 0.45; }
.wo__top { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; flex-wrap: wrap; }
.wo__id { font-size: 0.6875rem; font-weight: 800; color: var(--slate-500); letter-spacing: 0.03em; }
.wo__title { font-size: 0.875rem; font-weight: 700; color: var(--heading); line-height: 1.35; margin-bottom: 6px; }
.wo__meta { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 0.75rem; color: var(--muted); }
.wo__foot { display: flex; align-items: center; gap: 7px; margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line); }
.wo__av {
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--blue-soft);
  color: var(--blue-deep);
  display: grid; place-items: center;
  font-size: 0.625rem; font-weight: 800;
  flex: none;
}
.wo__av--empty { background: var(--slate-200); color: var(--slate-600); }
.wo__bill { margin-left: auto; font-size: 0.75rem; font-weight: 700; color: var(--heading); }

.flag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 7px; border-radius: var(--r-pill);
  font-size: 0.625rem; font-weight: 800;
  letter-spacing: 0.03em; text-transform: uppercase;
}
.flag--high { background: var(--danger-bg); color: var(--danger); }
.flag--blocked { background: #fff7ed; color: #9a3412; border: 1px solid #fed7aa; }
.flag--overdue { background: var(--warn-bg); color: var(--warn); }
.flag svg { width: 9px; height: 9px; }

/* A card the AI agent opened, and the worst case of one.

   Both read as an edge and a chip rather than a new text/background pair:
   the colour carries no words of its own, so there is no new contrast
   pairing to re-prove in either theme. The chip reuses .ai-chip, which is
   the purple the app already uses for everything the agent did, and the
   emergency flag reuses the --danger-bg / --danger pair that .flag--high
   already proved on this card. */
.wo--agent { border-left: 3px solid var(--purple); }
.wo--emergency {
  border-left: 3px solid var(--danger);
  box-shadow: inset 2px 0 0 var(--danger-bg), var(--shadow-sm);
}
.wo__top .ai-chip { padding: 1px 7px; font-size: 0.625rem; }
.wo__top .ai-chip svg { width: 9px; height: 9px; }
.flag--emergency { background: var(--danger-bg); color: var(--danger); }

/* agent summary */
.agent {
  border: 1px solid #ddd0fb;
  border-radius: var(--r-md);
  background: linear-gradient(180deg, #faf8ff, #fff 55%);
  padding: 18px;
}
.agent__head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
.agent__head h2 { font-size: 1rem; }
.agent__stamp { font-size: 0.75rem; color: var(--muted); }
.agent__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin: 14px 0; }
.agent__stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 11px 13px;
}
.agent__stat b { display: block; font-size: 1.375rem; font-weight: 800; color: var(--heading); letter-spacing: -0.03em; line-height: 1.2; }
.agent__stat span { font-size: 0.75rem; font-weight: 700; color: var(--muted); }
.agent__list { display: grid; gap: 7px; }
.agent__list li { display: flex; gap: 9px; align-items: flex-start; font-size: 0.8125rem; }
.agent__list svg { width: 13px; height: 13px; flex: none; margin-top: 3px; }
.agent__list a { color: var(--blue); font-weight: 700; }
@media (hover: hover) and (pointer: fine) {
  .agent__list a:hover { text-decoration: underline;}
}

/* drawer */
.drawer {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.5);
  z-index: 300;
  display: flex;
  justify-content: flex-end;
}
.drawer[hidden] { display: none; }
.drawer__panel {
  width: min(560px, 100%);
  background: var(--surface);
  height: 100%;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
}
.drawer__head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--surface); z-index: 2;
}
.drawer__head h2 { font-size: 1.0625rem; }
.drawer__body { padding: 22px; flex: 1; }
.drawer__sec { margin-bottom: 24px; }
.drawer__sec h3 { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--slate-500); margin-bottom: 11px; }

.kv-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: 9px; }
.kv-list div { display: flex; gap: 12px; font-size: 0.875rem; }
.kv-list dt { color: var(--muted); min-width: 118px; flex: none; }
.kv-list dd { margin: 0; color: var(--heading); font-weight: 600; min-width: 0; overflow-wrap: anywhere; }

.bill-row {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.875rem;
}
.bill-row:last-child { border-bottom: 0; }
.bill-row__main { flex: 1; min-width: 0; }
.bill-row__main strong { display: block; color: var(--heading); font-size: 0.875rem; }
.bill-row__main small { color: var(--muted); font-size: 0.75rem; }

/* conversational assistant */
.chat { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.chat__log {
  flex: 1;
  overflow-y: auto;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
}
.typing { display: inline-flex; gap: 4px; align-items: center; padding: 3px 0; }
.typing i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--purple);
  animation: blink 1.3s infinite;
}
.typing i:nth-child(2) { animation-delay: 0.18s; }
.typing i:nth-child(3) { animation-delay: 0.36s; }
@keyframes blink { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 1; } }

.suggestions { display: flex; gap: 7px; flex-wrap: wrap; padding: 0 18px 12px; }
.suggestions button {
  padding: 6px 13px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--slate-600);
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .suggestions button:hover { border-color: var(--blue); color: var(--blue);}
}

.provider-note {
  display: flex; gap: 9px;
  font-size: 0.75rem;
  color: var(--muted);
  padding: 9px 18px;
  border-top: 1px solid var(--line);
  background: var(--slate-50);
}
.provider-note svg { width: 13px; height: 13px; flex: none; margin-top: 2px; }
.provider-note code { font-size: 0.6875rem; background: var(--surface); border: 1px solid var(--line); border-radius: 3px; padding: 0 4px; }

@media (max-width: 900px) {
  .col { flex-basis: 258px; max-height: none; }
  .board { padding-bottom: 18px; }
}

/* ==========================================================================
   Dark theme

   Semantic tokens are swapped, not the whole palette: --slate-700/800/900 stay
   dark because the sidebar, hero and footer are built from them and must remain
   dark in both themes. Everything that was a light surface becomes a raised
   dark one, and every text token is lifted to clear the new background.

   Follows the system by default; an explicit choice on <html data-theme> wins.
   ========================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --bg: #0b1220;
    --bg-alt: #0b1220;
    --surface: #121c2e;
    --surface-veil: rgba(18, 28, 46, 0.94);
    --surface-ai: #1a1630;
    --surface-ai-line: #3a2f63;
    --code-bg: #0e1626;

    --heading: #e9eff7;
    --body: #a7b4c6;
    --muted: #8a99ad;
    --line: #223049;

    --slate-50:  #141f33;
    --slate-100: #19253c;
    --slate-200: #223049;
    --slate-300: #2e3e5c;
    --slate-400: #7d8ca2;
    --slate-500: #95a4ba;
    --slate-600: #aebbcc;
    --slate-700: #c9d4e1;

    --blue-soft: rgba(37, 99, 235, 0.18);
    --blue-line: rgba(37, 99, 235, 0.38);

    --ok-bg: rgba(21, 128, 61, 0.22);
    --warn-bg: rgba(180, 83, 9, 0.24);
    --danger-bg: rgba(185, 28, 28, 0.24);
    --info-bg: rgba(37, 99, 235, 0.22);
    --purple-bg: rgba(109, 40, 217, 0.26);
    --neutral-bg: #1b2740;
    --ok: #6ee7a0;
    --warn: #fbbf62;
    --danger: #fca5a5;
    --info: #93b4fd;
    --purple: #c4b0fb;
    --neutral: #aebbcc;

    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
    --shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.6); }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0b1220;
  --bg-alt: #0b1220;
  --surface: #121c2e;
  --surface-veil: rgba(18, 28, 46, 0.94);
  --surface-ai: #1a1630;
  --surface-ai-line: #3a2f63;
  --code-bg: #0e1626;

  --heading: #e9eff7;
  --body: #a7b4c6;
  --muted: #8a99ad;
  --line: #223049;

  --slate-50:  #141f33;
  --slate-100: #19253c;
  --slate-200: #223049;
  --slate-300: #2e3e5c;
  --slate-400: #7d8ca2;
  --slate-500: #95a4ba;
  --slate-600: #aebbcc;
  --slate-700: #c9d4e1;

  --blue-soft: rgba(37, 99, 235, 0.18);
  --blue-line: rgba(37, 99, 235, 0.38);

  --ok-bg: rgba(21, 128, 61, 0.22);
  --warn-bg: rgba(180, 83, 9, 0.24);
  --danger-bg: rgba(185, 28, 28, 0.24);
  --info-bg: rgba(37, 99, 235, 0.22);
  --purple-bg: rgba(109, 40, 217, 0.26);
  --neutral-bg: #1b2740;
  --ok: #6ee7a0;
  --warn: #fbbf62;
  --danger: #fca5a5;
  --info: #93b4fd;
  --purple: #c4b0fb;
  --neutral: #aebbcc;

  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.6);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    
      --bg: #0b1220;
      --bg-alt: #0b1220;
      --surface: #121c2e;
      --surface-veil: rgba(18, 28, 46, 0.94);
      --surface-ai: #1a1630;
      --surface-ai-line: #3a2f63;
      --code-bg: #0e1626;
    
      --heading: #e9eff7;
      --body: #a7b4c6;
      --muted: #8a99ad;
      --line: #223049;
    
      --slate-50:  #141f33;
      --slate-100: #19253c;
      --slate-200: #223049;
      --slate-300: #2e3e5c;
      --slate-400: #7d8ca2;
      --slate-500: #95a4ba;
      --slate-600: #aebbcc;
      --slate-700: #c9d4e1;
    
      --blue-soft: rgba(37, 99, 235, 0.18);
      --blue-line: rgba(37, 99, 235, 0.38);
    
      --ok-bg: rgba(21, 128, 61, 0.22);
      --warn-bg: rgba(180, 83, 9, 0.24);
      --danger-bg: rgba(185, 28, 28, 0.24);
      --info-bg: rgba(37, 99, 235, 0.22);
      --purple-bg: rgba(109, 40, 217, 0.26);
      --neutral-bg: #1b2740;
      --ok: #6ee7a0;
      --warn: #fbbf62;
      --danger: #fca5a5;
      --info: #93b4fd;
      --purple: #c4b0fb;
      --neutral: #aebbcc;
    
      --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
      --shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
      --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.6);
  }
}

/* the few places a light value was baked in rather than tokenised */
:root[data-theme="dark"] .msg--ai .msg__bubble {
  background: var(--surface-ai);
    border-color: var(--surface-ai-line);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .msg--ai .msg__bubble {
    background: var(--surface-ai);
        border-color: var(--surface-ai-line);
  }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .msg--ai .msg__bubble {
    background: var(--surface-ai);
      border-color: var(--surface-ai-line); }
}

:root[data-theme="dark"] .ai-card,
:root[data-theme="dark"] .agent {
  background: linear-gradient(180deg, var(--surface-ai), var(--surface) 60%);
  border-color: var(--surface-ai-line);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ai-card,
  :root:not([data-theme="light"]) .agent {
    background: linear-gradient(180deg, var(--surface-ai), var(--surface) 60%);
      border-color: var(--surface-ai-line);
  }
}
:root[data-theme="dark"] .proto-banner {
  background: rgba(180, 83, 9, 0.28);
  color: #fcd9a4;
  border-bottom-color: rgba(251, 191, 98, 0.4);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .proto-banner {
    background: rgba(180, 83, 9, 0.28);
      color: #fcd9a4;
      border-bottom-color: rgba(251, 191, 98, 0.4);
  }
}
/* The banner had no counterpart for "follow the system", and it is the one
   rule here that hardcodes its text colour instead of using a token: with no
   data-theme set on a dark OS the tokens went dark, --warn-bg with them, and
   #78350f on that measured 1.67:1. Found by sweeping the third theme state. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .proto-banner {
    background: rgba(180, 83, 9, 0.28);
    color: #fcd9a4;
    border-bottom-color: rgba(251, 191, 98, 0.4); }
}
:root[data-theme="dark"] .demo-creds { background: var(--slate-50); border-color: var(--slate-300); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .demo-creds { background: var(--slate-50); border-color: var(--slate-300); }
}
:root[data-theme="dark"] .demo-creds code,
:root[data-theme="dark"] code { background: var(--code-bg); border-color: var(--line); color: var(--heading); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .demo-creds code,
  :root:not([data-theme="light"]) code { background: var(--code-bg); border-color: var(--line); color: var(--heading); }
}
:root[data-theme="dark"] .balance-card { box-shadow: var(--shadow); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .balance-card { box-shadow: var(--shadow); }
}
:root[data-theme="dark"] img:not([src$=".svg"]) { filter: brightness(0.92); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) img:not([src$=".svg"]) { filter: brightness(0.92); }
}

/* theme toggle */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 38px; height: 38px;
  flex: none;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--slate-600);
  transition: var(--t-ui);
}
@media (hover: hover) and (pointer: fine) {
  .theme-toggle:hover { border-color: var(--blue); color: var(--blue);}
}
.theme-toggle svg { width: 17px; height: 17px; }
.theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .moon { display: block; }
}
:root[data-theme="dark"] .theme-toggle .sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: none; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .moon { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .sun { display: none; }
}

/* ---- dark-mode contrast corrections -------------------------------------
   Found by measuring rendered text against its actual background, not by eye.
   Three causes: brand blue is too dark to read on a dark surface; tokens that
   were lightened for text are also used as badge fills under white text; and
   a few deep-navy foregrounds were left on backgrounds that had gone dark. */
:root[data-theme="dark"] {
  --blue: #7fa9ff;          /* links and accents — 4.5:1+ on the dark surface */
  --blue-btn: #2f6fe4;      /* fill stays strong enough for white text */
  --chat-in-bg: #1e2a40;
  --chat-in-fg: #e9eff7;
  --warn-ink: #fcd9a4;
  --blue-ink: #bcd2ff;
  --danger-ink: #fecdd3;
  --danger-btn: #dc2626;    /* brighter than the light-mode fill so it reads as
                               a button against a dark card, still 4.8:1 with
                               white text — --danger itself is lightened for
                               text and is far too pale to sit white on */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --blue: #7fa9ff;          /* links and accents — 4.5:1+ on the dark surface */
      --blue-btn: #2f6fe4;      /* fill stays strong enough for white text */
      --danger-btn: #dc2626;    /* brighter than the light-mode fill so it reads as
                                   a button against a dark card, still 4.8:1 with
                                   white text — --danger itself is lightened for
                                   text and is far too pale to sit white on */
  }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --blue: #7fa9ff;
    --blue-btn: #2f6fe4;
    --chat-in-bg: #1e2a40;
    --chat-in-fg: #e9eff7;
    --warn-ink: #fcd9a4;
    --blue-ink: #bcd2ff;
    --danger-ink: #fecdd3;
    --danger-btn: #dc2626; }
}

/* A badge whose fill is a status colour carries white text, and those tokens
   were lightened for use AS text — so the fill needs pinning back. */
:root[data-theme="dark"] .icon-btn__dot {
  background: #b91c1c;
    color: #fff;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .icon-btn__dot {
    background: #b91c1c;
        color: #fff;
  }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .icon-btn__dot {
    background: #b91c1c;
      color: #fff; }
}


/* The balance card is the same case: its gradient is built from --blue, which
   dark mode lightens so it can be read AS text. White on that pale blue
   measured 2.2:1. Pinned back to the saturated pair the light theme uses — a
   deep blue card still reads as the primary surface on a dark page. */
:root[data-theme="dark"] .balance-card { background: linear-gradient(135deg, #1e3a8a, #2563eb); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .balance-card { background: linear-gradient(135deg, #1e3a8a, #2563eb); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .balance-card { background: linear-gradient(135deg, #1e3a8a, #2563eb); }
}


/* Avatar initials sit on a translucent blue tint that went dark. The sidebar's
   own chip is NOT included: that chrome is dark in both themes and was already
   correct — changing it is how it ended up unreadable. */
:root[data-theme="dark"] .person__av,
:root[data-theme="dark"] .wo__av {
  color: #cfe0ff;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .person__av,
  :root:not([data-theme="light"]) .wo__av { color: #cfe0ff; }
}

/* ==========================================================================
   Dark theme — fills that carry white text

   One recurring cause behind nearly every dark-mode contrast failure: a token
   lightened so it reads AS text (--ok, --warn, --danger, --blue) is elsewhere
   used as a background with white text on it. Lightening the token inverts
   that pairing. Each fill below is pinned to a saturated value so white stays
   legible, while the token itself remains readable as text.
   ========================================================================== */
:root[data-theme="dark"] .unit__state { background: #15803d; color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__state { background: #15803d; color: #fff; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__state { background: #15803d; color: #fff; }
}

:root[data-theme="dark"] .unit__state--soon { background: #a3620a; color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__state--soon { background: #a3620a; color: #fff; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__state--soon { background: #a3620a; color: #fff; }
}

:root[data-theme="dark"] .unit__state--let { background: #3b4a63; color: #e9eff7; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__state--let { background: #3b4a63; color: #e9eff7; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__state--let { background: #3b4a63; color: #e9eff7; }
}


:root[data-theme="dark"] .fav-count,
:root[data-theme="dark"] .sidebar__nav .count,
:root[data-theme="dark"] .step__n,
:root[data-theme="dark"] .portal-card__ico,
:root[data-theme="dark"] .finder__go { background: var(--blue-btn); color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .fav-count,
  :root:not([data-theme="light"]) .sidebar__nav .count,
  :root:not([data-theme="light"]) .step__n,
  :root:not([data-theme="light"]) .portal-card__ico,
  :root:not([data-theme="light"]) .finder__go { background: var(--blue-btn); color: #fff; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .fav-count,
    :root:not([data-theme="light"]) .step__n,
    :root:not([data-theme="light"]) .finder__go { background: var(--blue-btn); color: #fff; }
}


:root[data-theme="dark"] .badge,
:root[data-theme="dark"] .listing__tag { background: var(--blue-btn); color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge,
  :root:not([data-theme="light"]) .listing__tag { background: var(--blue-btn); color: #fff; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .listing__tag { background: var(--blue-btn); color: #fff; }
}

:root[data-theme="dark"] .badge--featured { background: #a3620a; color: #fff; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge--featured { background: #a3620a; color: #fff; }
}

/* the rent pill sits on a translucent surface; its secondary text was marginal */
:root[data-theme="dark"] .unit__rent { background: #1b2740; color: var(--heading); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__rent { background: #1b2740; color: var(--heading); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__rent { background: #1b2740; color: var(--heading); }
}

:root[data-theme="dark"] .unit__rent span { color: #9fb0c6; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__rent span { color: #9fb0c6; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unit__rent span { color: #9fb0c6; }
}


/* lift secondary text a little — several readings sat just under 4.5 */
:root[data-theme="dark"] { --muted: #9aa8bd; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --muted: #9aa8bd; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --muted: #9aa8bd; }
}

/* ==========================================================================
   Remaining contrast corrections (measured, both themes)
   ========================================================================== */

/* The sidebar is dark in BOTH themes, so these were failing in light mode too
   and had been since it was built — grey-on-navy at 2.36:1. */
.sidebar__label { color: #8b9ab2; }
.user-chip small { color: #9aa9c0; }
.sidebar__org small { color: #93a3ba; }
.sidebar__nav a { color: #b3c0d3; }

/* Notice text is a deep ink chosen for a pale tint; in dark the tint inverts. */
:root[data-theme="dark"] .notice--info { color: #bcd2ff; border-color: rgba(37,99,235,.45); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--info { color: #bcd2ff; border-color: rgba(37,99,235,.45); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--info { color: #bcd2ff; border-color: rgba(37,99,235,.45); }
}

:root[data-theme="dark"] .notice--warn { color: #fcd9a4; border-color: rgba(251,191,98,.45); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--warn { color: #fcd9a4; border-color: rgba(251,191,98,.45); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--warn { color: #fcd9a4; border-color: rgba(251,191,98,.45); }
}

:root[data-theme="dark"] .notice--ok { color: #a7f3c4; border-color: rgba(110,231,160,.45); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--ok { color: #a7f3c4; border-color: rgba(110,231,160,.45); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--ok { color: #a7f3c4; border-color: rgba(110,231,160,.45); }
}

:root[data-theme="dark"] .notice--danger { color: #fecdd3; border-color: rgba(252,165,165,.45); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--danger { color: #fecdd3; border-color: rgba(252,165,165,.45); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .notice--danger { color: #fecdd3; border-color: rgba(252,165,165,.45); }
}


/* Internal notes use the same warm ink on a tint that inverts. */
:root[data-theme="dark"] .msg--note .msg__bubble {
  background: rgba(180, 83, 9, 0.22);
    border-color: rgba(251, 191, 98, 0.45);
    color: #fcd9a4;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .msg--note .msg__bubble {
    background: rgba(180, 83, 9, 0.22);
        border-color: rgba(251, 191, 98, 0.45);
        color: #fcd9a4;
  }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .msg--note .msg__bubble {
    background: rgba(180, 83, 9, 0.22);
      border-color: rgba(251, 191, 98, 0.45);
      color: #fcd9a4; }
}


/* empty-column hint sat a hair under the threshold at 4.48:1 */
.col__empty { color: var(--slate-600); }

/* ==========================================================================
   Branding screen — one row per colour
   ========================================================================== */
.brand-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.brand-row:last-child { border-bottom: 0; }
.brand-row__main { flex: 1; min-width: 0; }
.brand-row__main strong { display: block; font-size: .875rem; color: var(--heading); }
.brand-row__main small { display: block; font-size: .75rem; color: var(--muted); }

/* The native colour well, sized to read as a swatch rather than a form
   control. Its own border means a white value is still visible on white. */
.brand-row__dot {
  flex: none;
  width: 44px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: none;
  cursor: pointer;
}
.brand-row__dot::-webkit-color-swatch-wrapper { padding: 3px; }
.brand-row__dot::-webkit-color-swatch { border: 0; border-radius: 6px; }
.brand-row__dot:disabled { cursor: default; opacity: .6; }

.brand-row__hex {
  flex: none;
  width: 9ch;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--heading);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8125rem;
  text-transform: lowercase;
}
.brand-row__hex:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* An uploaded logo stands in for the lettered badge. Capped rather than
   stretched: agencies upload wordmarks and squares alike, and a fixed box
   would distort one of them. */
.brand-logo {
  display: block;
  height: var(--logo-h, 28px);
  max-width: calc(var(--logo-h, 28px) * 6);
  width: auto;
  object-fit: contain;
}
.brand-logo--rounded { border-radius: 22%; }
/* A circle only makes sense for a square mark; cropping is deliberate. */
.brand-logo--circle { border-radius: 50%; aspect-ratio: 1; object-fit: cover; width: var(--logo-h, 28px); }
/* Where the logo is drawn larger than the header's, it scales with the setting
   rather than being fixed, so the slider means the same thing everywhere. */
.lp-brand .brand-logo { height: calc(var(--logo-h, 28px) * 1.3); }
.auth-head .brand-logo { height: calc(var(--logo-h, 28px) * 1.45); margin: 0 auto 4px; }

/* The "powered by" line. Quiet by design — it is an attribution, not a
   banner — and removed from the flow entirely when white label is on. */
.vendor-mark {
  display: block;
  margin-top: 10px;
  font-size: .6875rem;
  letter-spacing: .02em;
  color: var(--muted);
  opacity: .85;
}
.vendor-mark[hidden] { display: none; }

/* ==========================================================================
   Maintenance pipeline, job panel, chat and document viewer
   Everything on theme tokens, so the owner's palette and dark mode apply.
   ========================================================================== */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--surface); }
.seg__btn { padding: 7px 13px; border: 0; background: none; color: var(--body); font: inherit; font-size: .8125rem; font-weight: 600; cursor: pointer; }
.seg__btn + .seg__btn { border-inline-start: 1px solid var(--line); }
@media (hover: hover) and (pointer: fine) {
  .seg__btn:hover { background: var(--bg-alt);}
}
.seg__btn.is-on { background: var(--blue-btn); color: #fff; }
.seg__btn:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

.jboard { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(250px, 1fr); gap: 14px; overflow-x: auto; padding-bottom: 14px; align-items: start; }
.jcol { background: var(--bg-alt); border: 1px solid var(--line); border-radius: 14px; min-height: 140px; }
.jcol__head { display: flex; align-items: center; justify-content: space-between; padding: 11px 14px; font-size: .8125rem; font-weight: 800; color: var(--heading); letter-spacing: .01em; }
.jcol__n { min-width: 22px; padding: 1px 7px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); text-align: center; font-weight: 700; color: var(--muted); }
.jcol__body { display: grid; gap: 10px; padding: 0 10px 12px; min-height: 60px; border-radius: 12px; transition: background .15s; }
.jcol__body.is-over { background: var(--blue-soft); outline: 2px dashed var(--blue); outline-offset: -4px; }
.jcol__empty { margin: 6px 4px; font-size: .75rem; color: var(--muted); text-align: center; }

.jcard { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 11px 12px; cursor: pointer; transition: box-shadow .15s, border-color .15s; }
@media (hover: hover) and (pointer: fine) {
  .jcard:hover { border-color: var(--blue); box-shadow: 0 6px 16px -10px rgba(15, 23, 42, .5);}
}
.jcard:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.jcard.is-dragging { opacity: .45; }
.jcard--emergency { border-inline-start: 4px solid var(--danger-btn); }
.jcard__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: .8125rem; color: var(--heading); }
.jcard__sum { margin: 6px 0 4px; font-size: .8125rem; line-height: 1.4; color: var(--body); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.jcard__meta { font-size: .75rem; color: var(--muted); }
.jcard__foot { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.jcard__who { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--blue-btn); color: #fff; font-size: .6875rem; font-weight: 800; }
.jcard__who--none { background: var(--bg-alt); color: var(--muted); border: 1px dashed var(--muted); }

.drawer {
  position: fixed; inset-block: 0; inset-inline-end: 0; z-index: 80; width: min(540px, 100vw);
  display: flex; flex-direction: column; background: var(--surface);
  border-inline-start: 1px solid var(--line); box-shadow: -24px 0 48px -24px rgba(15, 23, 42, .45);
  /* Closed: off to its own edge, and hidden so it cannot be tabbed into. It
     used to be display:none, which cannot be animated — the panel simply
     appeared, which reads as a glitch rather than a change of place. Leaving is
     quicker than arriving: the person asked for it to go. */
  transform: translateX(100%); visibility: hidden;
  transition: transform 180ms var(--ease-out), visibility 0s linear 180ms;
}
.drawer.is-open {
  transform: none; visibility: visible;
  transition: transform 280ms var(--ease-drawer), visibility 0s;
}
.drawer__head { display: flex; align-items: flex-start; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--line); }
.drawer__ref { font-size: 1.0625rem; color: var(--heading); }
.drawer__body { flex: 1; overflow-y: auto; padding: 18px 20px 40px; }
.drawer__sum { margin: 0 0 6px; font-size: .9375rem; color: var(--heading); font-weight: 600; line-height: 1.45; }
.drawer__h { margin: 22px 0 8px; padding-top: 16px; border-top: 1px solid var(--line); font-size: .8125rem; font-weight: 800; letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
.drawer__form { margin-top: 10px; }
.drawer__form .field { margin-bottom: 10px; }
@media (max-width: 640px) { .drawer { width: 100vw; } }

.jcompose { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.jcompose textarea, .jcompose input[type="text"], .jcompose select { flex: 1; min-width: 140px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); color: var(--heading); font: inherit; font-size: .875rem; }
.jcompose textarea:focus-visible, .jcompose input:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

.jthread { max-height: 260px; overflow-y: auto; display: grid; gap: 8px; padding: 10px; margin-bottom: 8px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg-alt); }
.jmsg { max-width: 88%; padding: 8px 11px; border-radius: 12px; background: var(--chat-in-bg); color: var(--chat-in-fg); font-size: .875rem; line-height: 1.45; }
.jmsg--out { justify-self: end; background: var(--blue-btn); color: #fff; }
.jmsg__who { margin-bottom: 2px; font-size: .6875rem; opacity: .8; font-weight: 700; }
.jatt { display: block; margin-top: 6px; font-size: .8125rem; font-weight: 700; color: inherit; text-decoration: underline; }
.jhist { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; font-size: .8125rem; color: var(--body); }

.docview {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center; padding: 20px;
  background: rgba(2, 6, 23, .66);
  opacity: 1; transition: opacity 160ms var(--ease-out);
  @starting-style { opacity: 0; }
}
/* A modal is not anchored to a trigger, so it settles from the centre, and it
   never starts from nothing: scale(0) looks like it came from nowhere. */
.docview__box { transition: transform 200ms var(--ease-out); @starting-style { transform: scale(0.97); } }
.docview__box { display: flex; flex-direction: column; width: min(960px, 100%); height: min(88vh, 900px); height: min(88dvh, 900px); background: var(--surface); border-radius: 14px; overflow: hidden; box-shadow: 0 30px 80px rgba(0, 0, 0, .5); }
.docview__head { display: flex; align-items: center; gap: 10px; padding: 11px 16px; border-bottom: 1px solid var(--line); color: var(--heading); }
.docview__body { flex: 1; min-height: 0; display: grid; place-items: center; background: var(--bg-alt); overflow: auto; }
.docview__frame { width: 100%; height: 100%; border: 0; background: #fff; }
.docview__img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* The maintenance portal's pages are wider than a resident's: a six-column
   board needs the room, and a contractor on a laptop should not be reading it
   through a 940px slot. */
.tshell--wide { max-width: 1480px; }
.ttop--wide .ttop__inner { max-width: 1480px; }
.page-title h1 { margin: 0; font-size: 1.5rem; letter-spacing: -.02em; color: var(--heading); }
.page-title p { margin: 4px 0 18px; font-size: .9375rem; }
.lp-brand .brand-logo--circle, .auth-head .brand-logo--circle { width: auto; }

/* The logo editor's preview strip: the same logo on a light and on a dark
   surface, because the question it answers is "does this work on both?" */
.logo-preview { display: grid; grid-template-columns: 1fr 1fr; gap: 0; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.logo-preview > div { display: grid; place-items: center; min-height: 92px; padding: 14px; }
.logo-preview__light { background: #ffffff; }
.logo-preview__dark { background: #0b1220; }
.logo-preview img { height: var(--logo-h, 28px); max-width: calc(var(--logo-h, 28px) * 6); width: auto; object-fit: contain; }
.logo-preview img.brand-logo--circle { width: var(--logo-h, 28px); }
.logo-preview small { display: block; margin-top: 8px; font-size: .6875rem; color: #64748b; text-align: center; }
.logo-preview__dark small { color: #94a3b8; }

/* The partner form's bot trap: present in the document, absent for a person.
   Off-screen rather than display:none, because some bots skip hidden fields. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* An icon inside a plain link: svg is display:block everywhere, so without this
   the icon drops onto its own line above the words. */
.auth-alt a { display: inline-flex; align-items: center; gap: 6px; }
.auth-alt a svg { width: 15px; height: 15px; flex: none; }

.perk-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 0 0 22px; padding: 0; list-style: none; }
.perk-list li { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; background: var(--blue-soft); color: var(--blue-ink); font-size: .75rem; font-weight: 600; }
.perk-list svg { width: 13px; height: 13px; color: var(--blue); flex: none; }


/* ==========================================================================
   Touch and press baseline

   Each rule is here for a reason that only shows on a phone, where most of the
   people using this are: residents texting in, contractors on a ladder.
   ========================================================================== */

html {
  /* The grey/blue flash a phone paints over anything tappable. With it gone,
     every control needs its own :active state, which is the block below. */
  -webkit-tap-highlight-color: transparent;
  /* No font inflation when a phone is turned sideways. */
  -webkit-text-size-adjust: 100%;
}

/* A control that never double-tap-zooms can answer a tap immediately instead of
   waiting to see whether a second one is coming. */
a, button, [role="button"], summary, label.switch, label.check, select, .seg__btn, .jcard, .row[data-job] {
  touch-action: manipulation;
}

/* Text that is a CONTROL should not be selectable on long-press; text that is
   content must stay selectable, which is why this is not on body. */
button, [role="button"], .seg__btn, .tab, .tnav a, .engine-opt, .icon-btn {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* iOS zooms the page when focus lands on an input under 16px and does not zoom
   back out. Fixing the size is the right answer; disabling zoom is an
   accessibility failure. Only on touch pointers, so desktop density is kept. */
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
  select, textarea,
  .filterbar select, .filterbar input,
  .field input, .field select, .field textarea,
  .composer textarea,
  .jcompose textarea, .jcompose input[type="text"], .jcompose select,
  .lp-field input, .search-input input {
    font-size: 16px;
  }
}

/* Press feedback. A button has to feel like it heard you, and on touch :active
   is the only feedback there is (hover is gated off for pointers that cannot
   hover). Subtle: 0.97, quick on the way down, which is the point. */
.btn, .icon-btn, .seg__btn, .engine-opt, .tab, .tnav a, .qa, .theme-toggle,
.suggestions button, .signout, .lp-submit, .lp-alt, .lp-trade, .lp-role,
.col__menu > button {
  transition: var(--t-ui);
}
:is(.btn, .icon-btn, .seg__btn, .engine-opt, .tab, .tnav a, .qa, .theme-toggle,
    .suggestions button, .signout, .lp-submit, .lp-alt, .lp-trade, .lp-role):active:not(:disabled):not([disabled]) {
  transform: scale(0.97);
  transition-duration: 90ms;
}
.jcard:active { transform: scale(0.985); transition: transform 90ms var(--ease-out); }

/* The bottom navigation and the open panel respect the notch and the home bar. */
.tnav { padding-bottom: env(safe-area-inset-bottom); }
.drawer__head { padding-top: calc(16px + env(safe-area-inset-top)); }
.drawer__body { padding-bottom: calc(40px + env(safe-area-inset-bottom)); }


/* Text that people and other systems supply — a resident's message, a filename,
   a pasted link, a corporate email address — has no guaranteed break points, so
   anywhere it is shown in a column it has to be allowed to wrap mid-word. */
.drawer__sum, .jmsg, .jatt, .jhist li, .jcard__sum, .jcard__meta, .jcard__top strong { overflow-wrap: anywhere; }
.drawer__head > div:first-child { min-width: 0; }
.drawer__head .fs-sm { overflow-wrap: anywhere; }

.card__body p, .card p { overflow-wrap: anywhere; }


/* ---------- sign-in extras ---------- */
.or-rule { display: flex; align-items: center; gap: 12px; margin: 18px 0 14px; color: var(--muted); font-size: 0.8125rem; }
.or-rule::before, .or-rule::after { content: ""; flex: 1; height: 1px; background: var(--line); }

@media (max-width: 640px) {
  .kv-list div { flex-direction: column; gap: 2px; min-width: 0; }
  .kv-list dt { min-width: 0; }
  .kv-list dd select, .kv-list dd input { max-width: 100%; }
}


/* ---------- collect payment ---------- */
.collect { max-width: 520px; margin-inline: auto; }
.collect__qr { background: #fff; padding: 12px; border-radius: 16px; border: 1px solid var(--line); width: min(100%, 300px); aspect-ratio: 1; margin: 0 auto; display: grid; place-items: center; }
.collect__qr svg { width: 100%; height: 100%; display: block; }
.collect__url { display: block; font-size: 0.75rem; word-break: break-all; user-select: all; padding: 10px 12px; border-radius: 10px; background: var(--slate-50); border: 1px solid var(--line); color: var(--body); }
