/* ══ The office CRM's design language ═══════════════════════════════════════

   One sheet every page draws from. Decided 2026-09-22 (Direction A on the
   canvas at claude.ai/artifact/U9muxigzFgRftHAgNpPG36): the dark ground and
   blue accent the office already knows, DM Sans for everything, tabular
   numbers, 48px rows, and colour reserved for STATE — six roles, used the same
   way on every page. Facts (source, office, timezone) are quiet.

   Two layers, on purpose:

     1. TOKENS — under the names the pages already use (--bg, --s1, --acc,
        --grn, --tx1, --r…) so a page migrates by dropping its own :root and
        linking this file, and under role names (--good, --warn, --bad, --ai,
        --info) which is what the components below read. Same values.

     2. COMPONENTS — .ui-* classes. A page uses them instead of restyling
        the same button for the ninth time. /styleguide renders every one.

   The customer portal and the installer app are light on purpose (they are
   customer-facing); they take the same six roles under [data-theme="light"]
   so a status means the same thing on every screen, and keep their own
   accent (orange). */

@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=DM+Mono:wght@400;500&display=swap');

:root {
  /* ground */
  --bg:   #0B0E14;
  --s1:   #10141B;
  --s2:   #151A23;
  --s3:   #1B2130;
  --b1:   #232A38;   /* line */
  --b2:   #2E3748;   /* line, stronger: inputs, chips */
  /* text */
  --tx1:  #E8ECF4;
  --tx2:  #9AA4B8;
  --tx3:  #6B768E;
  /* accent: actions and selection, nothing else */
  --acc:  #4F8CFF;
  --acc2: #7FAAFF;
  --acc-ink: #FFFFFF;
  --adim: rgba(79,140,255,.14);
  /* the six roles — the only colours that mean something */
  --good: #22C55E; --good-soft: rgba(34,197,94,.14);
  --warn: #F5B301; --warn-soft: rgba(245,179,1,.14);
  --bad:  #F0504F; --bad-soft:  rgba(240,80,79,.14);
  --ai:   #A78BFA; --ai-soft:   rgba(167,139,250,.16);
  --info: #4F8CFF; --info-soft: rgba(79,140,255,.14);
  --muted: #9AA4B8; --muted-soft: #1B2130;
  /* the names the pages already use, pointed at the roles */
  --grn: var(--good); --gdim: var(--good-soft);
  --ylw: var(--warn); --ydim: var(--warn-soft);
  --red: var(--bad);  --rdim: var(--bad-soft);
  --pur: var(--ai);   --pdim: var(--ai-soft);
  --cyn: var(--info); --cdim: var(--info-soft);
  --org: #F2761B;     --odim: rgba(242,118,27,.14);
  /* shape */
  --r:  8px;
  --r2: 10px;
  --row: 48px;
  --sidebar: 236px;
  --topbar: 60px;
  /* type */
  --font: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'DM Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --shadow: 0 20px 50px rgba(0,0,0,.45);
}

/* The customer-facing apps: same roles, on white. Accent stays theirs. */
[data-theme="light"] {
  --bg: #F6F5F2; --s1: #FFFFFF; --s2: #FFFFFF; --s3: #F0EEE9; --b1: #ECEAE5; --b2: #D9D6CF;
  --tx1: #16191F; --tx2: #5F6672; --tx3: #8A909C;
  --acc: #F2761B; --acc2: #C2410C; --acc-ink: #FFFFFF; --adim: rgba(242,118,27,.14);
  --good: #0B6B3A; --good-soft: #E8F6ED;
  --warn: #B45309; --warn-soft: #FFF7ED;
  --bad:  #B91C1C; --bad-soft:  #FEE2E2;
  --ai:   #6D28D9; --ai-soft:   #EDE9FE;
  --info: #1D4ED8; --info-soft: #DBEAFE;
  --muted: #5F6672; --muted-soft: #F0EEE9;
  --shadow: 0 12px 30px rgba(22,25,31,.12);
}

/* The office CRM by day (2026-10-02): the same roles on white, with the
   office's own blue accent — not the portal's orange. Chosen per computer
   with the sun/moon in the top bar (/shared/theme.js). */
[data-theme="day"] {
  color-scheme: light;
  --bg: #F4F5F7; --s1: #FFFFFF; --s2: #F7F8FA; --s3: #ECEEF2; --b1: #E2E5EB; --b2: #CBD0D9;
  --tx1: #121620; --tx2: #4B5363; --tx3: #7B8496;
  --acc: #2563EB; --acc2: #1D4ED8; --acc-ink: #FFFFFF; --adim: rgba(37,99,235,.10);
  --good: #15803D; --good-soft: #E7F6EC;
  --warn: #B45309; --warn-soft: #FEF3E2;
  --bad:  #C62828; --bad-soft:  #FDE8E8;
  --ai:   #6D28D9; --ai-soft:   #EFEAFE;
  --info: #1D4ED8; --info-soft: #E3ECFD;
  --muted: #4B5363; --muted-soft: #ECEEF2;
  --org: #C2410C; --odim: rgba(194,65,12,.10);
  --shadow: 0 12px 30px rgba(18,22,32,.12);
}

/* ── Base ───────────────────────────────────────────────────────────────── */
.ui, .ui * { box-sizing: border-box; }
.ui { font-family: var(--font); color: var(--tx1); background: var(--bg); font-size: 13px; line-height: 1.45; -webkit-font-smoothing: antialiased; }
.ui button, .ui input, .ui select, .ui textarea { font: inherit; color: inherit; }
.ui a { color: var(--acc); text-decoration: none; }
.ui a:hover { color: var(--acc2); }
.ui ::placeholder { color: var(--tx3); }
.ui :focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

/* ── Scrollbars: one look everywhere ────────────────────────────────────
   Every scrolling box in the CRM — lists, drawers, the Schedule board, the
   global search results, modals — gets the same thin bar: a rounded thumb in
   the stronger line colour on no track, a shade lighter under the pointer.
   From the tokens, so the light theme (portal) gets a light one. This is
   the one copy; pages used to carry their own (4px here, 8px there, and none
   at all on the pages that did not load assistant.js — the Schedule showed
   the browser's grey bars). A box that hides its bar on purpose
   (scrollbar-width:none on a tab strip) still wins: it is more specific.
   Firefox and current Chrome read the first two properties; Safari reads the
   ::-webkit ones. */
* { scrollbar-width: thin; scrollbar-color: var(--b2) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--b2); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--tx3); border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }

/* ── Type ───────────────────────────────────────────────────────────────── */
.ui-title { font-size: 20px; font-weight: 700; line-height: 1.2; color: var(--tx1); margin: 0; }
.ui-title .ui-count { font-size: 13px; font-weight: 600; color: var(--tx3); margin-left: 10px; font-variant-numeric: tabular-nums; }
.ui-h2 { font-size: 16px; font-weight: 700; line-height: 1.25; color: var(--tx1); margin: 0; }
.ui-name { font-size: 14px; font-weight: 700; color: var(--tx1); }
.ui-meta { font-size: 12px; font-weight: 500; color: var(--tx2); }
.ui-quiet { color: var(--tx3); }
.ui-label { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--tx3); }
.ui-mono { font-family: var(--mono); font-size: 12px; }
.ui-num { font-variant-numeric: tabular-nums; }

/* ── Icons: inline stroke SVG, sized by the parent's font ───────────────── */
.ui-ic { width: 1.15em; height: 1.15em; flex-shrink: 0; vertical-align: -.2em; display: inline-block; }
.ui-ic.md { width: 18px; height: 18px; }
.ui-ic.lg { width: 22px; height: 22px; }

/* ── Buttons ────────────────────────────────────────────────────────────── */
.ui-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 36px; padding: 0 14px; border-radius: var(--r); font-size: 13px; font-weight: 600; white-space: nowrap; cursor: pointer; border: 1px solid transparent; background: var(--s3); color: var(--tx1); border-color: var(--b2); transition: background .12s, border-color .12s, color .12s; }
.ui-btn:hover { background: var(--b1); }
.ui-btn:active { transform: translateY(1px); }
.ui-btn:disabled { opacity: .5; cursor: default; transform: none; }
.ui-btn.primary { background: var(--acc); color: var(--acc-ink); border-color: var(--acc); }
.ui-btn.primary:hover { background: var(--acc2); border-color: var(--acc2); }
.ui-btn.outline { background: transparent; color: var(--tx1); border-color: var(--b2); }
.ui-btn.outline:hover { background: var(--s2); }
.ui-btn.quiet { background: transparent; color: var(--tx2); border-color: transparent; }
.ui-btn.quiet:hover { background: var(--s2); color: var(--tx1); }
.ui-btn.danger { background: var(--bad-soft); color: var(--bad); border-color: transparent; }
.ui-btn.danger:hover { background: rgba(240,80,79,.24); }
.ui-btn.sm { height: 30px; padding: 0 11px; font-size: 12.5px; }
.ui-btn.block { width: 100%; }
.ui-iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--r); border: 1px solid var(--b1); background: var(--s2); color: var(--tx2); cursor: pointer; position: relative; }
.ui-iconbtn:hover { color: var(--tx1); background: var(--s3); }
.ui-iconbtn.sm { width: 30px; height: 30px; border-color: transparent; background: transparent; }
.ui-iconbtn .ui-dot { position: absolute; top: 7px; right: 7px; width: 8px; height: 8px; border-radius: 999px; background: var(--bad); border: 2px solid var(--s2); }

/* ── Inputs ─────────────────────────────────────────────────────────────── */
.ui-field { display: flex; flex-direction: column; gap: 6px; font-size: 12px; font-weight: 600; color: var(--tx2); }
.ui-input { display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 12px; border-radius: var(--r); background: var(--s2); border: 1px solid var(--b1); color: var(--tx1); font-size: 13px; font-weight: 500; width: 100%; }
.ui-input:focus-within, .ui-input:focus { border-color: var(--acc); box-shadow: 0 0 0 3px var(--adim); outline: none; }
.ui-input input, .ui-input select { flex-grow: 1; min-width: 0; background: transparent; border: 0; outline: none; color: var(--tx1); }
.ui-input select { appearance: none; -webkit-appearance: none; padding-right: 4px; }
.ui-input select option { background: var(--s2); color: var(--tx1); }
.ui-input.error { border-color: var(--bad); }
.ui-field .ui-error { font-size: 11.5px; font-weight: 500; color: var(--bad); }
.ui-input .ui-ic { color: var(--tx3); }
textarea.ui-input { height: auto; min-height: 88px; padding: 10px 12px; resize: vertical; line-height: 1.45; }
.ui-segments { display: inline-flex; background: var(--s2); border: 1px solid var(--b1); border-radius: var(--r); padding: 3px; }
.ui-segments button { height: 28px; padding: 0 12px; border: 0; border-radius: 6px; background: transparent; color: var(--tx2); font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.ui-segments button.on { background: var(--s3); color: var(--tx1); }

/* ── Pills: state gets colour; facts stay quiet ─────────────────────────── */
.ui-pill { display: inline-flex; align-items: center; gap: 7px; height: 24px; padding: 0 9px; border-radius: 999px; background: var(--muted-soft); color: var(--tx1); font-size: 12px; font-weight: 600; white-space: nowrap; }
.ui-pill::before { content: ""; width: 7px; height: 7px; border-radius: 999px; background: var(--muted); flex-shrink: 0; }
.ui-pill[data-tone="good"] { background: var(--good-soft); } .ui-pill[data-tone="good"]::before { background: var(--good); }
.ui-pill[data-tone="warn"] { background: var(--warn-soft); } .ui-pill[data-tone="warn"]::before { background: var(--warn); }
.ui-pill[data-tone="bad"]  { background: var(--bad-soft); }  .ui-pill[data-tone="bad"]::before  { background: var(--bad); }
.ui-pill[data-tone="ai"]   { background: var(--ai-soft); }   .ui-pill[data-tone="ai"]::before   { background: var(--ai); }
.ui-pill[data-tone="info"] { background: var(--info-soft); } .ui-pill[data-tone="info"]::before { background: var(--info); }
.ui-pill[data-tone="muted"] { color: var(--tx2); }
/* The one filled pill: a state that is FINAL — Converted, Done, Paid. */
.ui-pill.filled { color: #08130C; font-weight: 700; }

/* ── Due: a pill that needs a person breathes ─────────────────────────────
   The office asked for the blink back the day this shipped. It is a slow,
   soft breath of opacity — never a flash, never a glow — so a DUE or an
   "Update needed" tugs at the eye from across the room without shouting,
   and it stops for anyone whose system asks for less motion.

   Four breaths, then still (Omri, 2026-10-24). It breathed for ever, and a
   page full of them kept a slow laptop repainting all day — half of what an
   idle tab cost. A pill drawn fresh (a list redrawn because something
   changed) breathes again; the still state is the normal pill. The same
   count is used for every attention cue in the CRM. */
@keyframes ui-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .42; } }
.ui-pill.is-due, .ui-breathe { animation: ui-breathe 2.2s ease-in-out 4; }
@media (prefers-reduced-motion: reduce) { .ui-pill.is-due, .ui-breathe { animation: none; } }
.ui-pill.filled::before { display: none; }
.ui-pill.filled[data-tone="good"] { background: var(--good); }
.ui-pill.filled[data-tone="bad"]  { background: var(--bad); color: #fff; }
.ui-chip { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px; border-radius: 999px; border: 1px solid var(--b2); color: var(--tx2); font-size: 12px; font-weight: 600; white-space: nowrap; background: transparent; }
.ui-count-pill { font-size: 11.5px; font-weight: 700; color: var(--tx2); background: var(--s3); border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums; }

/* ── Avatar ─────────────────────────────────────────────────────────────── */
.ui-avatar { width: 30px; height: 30px; border-radius: 999px; background: var(--s3); border: 1px solid var(--b2); color: var(--tx1); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; flex-shrink: 0; }
.ui-avatar.sm { width: 22px; height: 22px; font-size: 10px; }
.ui-avatar.ai { color: var(--ai); }

/* ── Tables: a header row and 48px rows ────────────────────────────────── */
.ui-table { display: flex; flex-direction: column; min-width: 0; }
.ui-thead { display: flex; align-items: center; gap: 16px; height: 40px; padding: 0 20px; border-bottom: 1px solid var(--b1); background: var(--s1); position: sticky; top: 0; z-index: 1; }
.ui-th { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; color: var(--tx3); white-space: nowrap; }
.ui-row { display: flex; align-items: center; gap: 16px; min-height: var(--row); padding: 0 20px; border-bottom: 1px solid var(--b1); border-left: 3px solid transparent; padding-left: 17px; cursor: pointer; }
.ui-row:hover { background: var(--s1); }
.ui-row.is-selected { background: var(--s2); border-left-color: var(--acc); }
.ui-row.is-unclaimed { border-left-color: var(--warn); }
.ui-row.is-muted { opacity: .6; }
.ui-col { flex-shrink: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-col.grow { flex-grow: 1; }
.ui-cell-name { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ui-cell-name > div { display: flex; flex-direction: column; min-width: 0; }
.ui-cell-name .ui-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-cell-name .ui-meta { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-tfoot { height: 40px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; border-top: 1px solid var(--b1); font-size: 12px; color: var(--tx3); }

/* ── Cards, key/value rows, tabs, sections ──────────────────────────────── */
.ui-card { border: 1px solid var(--b1); border-radius: var(--r2); background: var(--s1); overflow: hidden; }
.ui-card-hd { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--b1); }
.ui-card-hd .ui-h2 { font-size: 13px; }
.ui-card-bd { padding: 12px 14px; }
.ui-kv { display: flex; align-items: center; justify-content: space-between; gap: 14px; min-height: 30px; font-size: 13px; }
.ui-kv + .ui-kv { border-top: 1px solid var(--b1); }
.ui-kv .k { color: var(--tx3); }
.ui-kv .v { color: var(--tx1); font-weight: 500; text-align: right; }
.ui-kv .v.empty { color: var(--tx3); }
.ui-tabs { display: flex; gap: 18px; border-bottom: 1px solid var(--b1); padding: 0 2px; }
.ui-tab { padding: 0 2px 10px; font-size: 13px; font-weight: 600; color: var(--tx2); border: 0; background: none; border-bottom: 2px solid transparent; cursor: pointer; margin-bottom: -1px; display: inline-flex; flex-direction: column; gap: 2px; align-items: flex-start; }
.ui-tab.on { color: var(--tx1); border-bottom-color: var(--acc); }
.ui-tab small { font-size: 11px; font-weight: 500; color: var(--tx3); }
.ui-section { display: flex; align-items: center; gap: 10px; }
.ui-section::after { content: ""; flex-grow: 1; height: 1px; background: var(--b1); }
.ui-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 22px 16px; border: 1px dashed var(--b2); border-radius: var(--r); text-align: center; color: var(--tx3); }
.ui-empty .ui-name { font-size: 13px; }
.ui-empty .ui-meta { color: var(--tx3); }

/* ── Sidebar ────────────────────────────────────────────────────────────── */
.ui-sidebar { width: var(--sidebar); flex-shrink: 0; background: var(--s1); border-right: 1px solid var(--b1); display: flex; flex-direction: column; padding: 14px 12px; gap: 6px; height: 100vh; position: sticky; top: 0; }
.ui-brand { display: flex; align-items: center; gap: 10px; padding: 2px 6px 10px; }
.ui-brand-mark { width: 28px; height: 28px; border-radius: 8px; background: var(--acc); color: var(--acc-ink); display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; flex-shrink: 0; }
.ui-brand b { display: block; font-size: 14px; font-weight: 700; color: var(--tx1); }
.ui-brand small { display: block; font-size: 11.5px; color: var(--tx3); white-space: nowrap; }
.ui-navgroup { display: flex; flex-direction: column; gap: 2px; }
.ui-navgroup > .ui-label { padding: 12px 10px 4px; }
.ui-navitem { display: flex; align-items: center; gap: 10px; height: 36px; padding: 0 10px; border-radius: var(--r); color: var(--tx2); font-size: 13.5px; font-weight: 500; text-decoration: none; }
.ui-navitem .ui-ic { color: var(--tx3); width: 17px; height: 17px; }
.ui-navitem > span { flex-grow: 1; white-space: nowrap; }
.ui-navitem > .ui-count-pill { flex-grow: 0; }
.ui-navitem:hover { background: var(--s2); color: var(--tx1); }
.ui-navitem.on { background: var(--adim); color: var(--tx1); font-weight: 600; }
.ui-navitem.on .ui-ic { color: var(--acc); }
.ui-navitem.on .ui-count-pill { background: transparent; color: var(--acc); }
.ui-sidebar-foot { display: flex; align-items: center; gap: 10px; padding: 10px 6px 0; border-top: 1px solid var(--b1); margin-top: auto; }
.ui-sidebar-foot b { display: block; font-size: 13px; font-weight: 600; }
.ui-sidebar-foot small { display: block; font-size: 11.5px; color: var(--tx3); }

/* ── The inbox rail: a second, narrow menu beside the nav ───────────────
   One icon per channel with a count. Kept as its own column (the owner's
   call, 2026-09-22): it is a fast switcher and would be buried in the nav.
   Icon-only, so each button carries its name for the tooltip and for a
   screen reader. The count is the same pill everywhere; red only when
   something is waiting on a person. */
.ui-rail { width: 56px; flex-shrink: 0; background: var(--s1); border-right: 1px solid var(--b1); display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 14px 0; height: 100vh; position: sticky; top: 0; }
.ui-rail-btn { position: relative; width: 40px; height: 40px; border-radius: var(--r); border: 0; background: transparent; color: var(--tx3); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.ui-rail-btn .ui-ic { width: 20px; height: 20px; }
.ui-rail-btn:hover { background: var(--s2); color: var(--tx1); }
.ui-rail-btn.on { background: var(--adim); color: var(--acc); }
.ui-rail-btn .ui-badge { position: absolute; top: 2px; right: 1px; min-width: 17px; height: 17px; padding: 0 5px; border-radius: 999px; background: var(--s3); border: 1px solid var(--b2); color: var(--tx1); font-size: 10.5px; font-weight: 700; line-height: 15px; text-align: center; font-variant-numeric: tabular-nums; }
.ui-rail-btn .ui-badge.hot { background: var(--bad); border-color: var(--bad); color: #fff; }
.ui-rail-btn .ui-badge.warm { background: var(--warn); border-color: var(--warn); color: #161616; }
.ui-rail-btn .ui-badge.ai { background: var(--ai); border-color: var(--ai); color: #fff; }
/* The name, on hover — to the right, out of the way of the next button. */
.ui-rail-btn::after { content: attr(data-label); position: absolute; left: 48px; top: 50%; transform: translateY(-50%); padding: 5px 9px; border-radius: 6px; background: var(--s3); border: 1px solid var(--b2); color: var(--tx1); font-size: 12px; font-weight: 600; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .1s; z-index: 5; }
.ui-rail-btn:hover::after, .ui-rail-btn:focus-visible::after { opacity: 1; }
.ui-rail-sep { width: 24px; height: 1px; background: var(--b1); margin: 6px 0; }

/* ── Top bar ────────────────────────────────────────────────────────────── */
.ui-topbar { height: var(--topbar); flex-shrink: 0; display: flex; align-items: center; gap: 12px; padding: 0 24px; border-bottom: 1px solid var(--b1); background: var(--bg); position: sticky; top: 0; z-index: 2; }
.ui-topbar .ui-spacer { flex-grow: 1; }
.ui-topbar .ui-search { width: 300px; }
.ui-clock { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--tx2); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── Modal & toast ──────────────────────────────────────────────────────── */
.ui-backdrop { position: fixed; inset: 0; background: rgba(4,6,10,.62); z-index: 100; display: flex; align-items: center; justify-content: center; padding: 24px; }
.ui-modal { width: 100%; max-width: 440px; border: 1px solid var(--b2); border-radius: 12px; background: var(--s2); box-shadow: var(--shadow); overflow: hidden; }
.ui-modal-hd { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--b1); }
.ui-modal-hd .ui-h2 { font-size: 16px; }
.ui-modal-bd { padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; color: var(--tx2); line-height: 1.5; }
.ui-modal-ft { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--b1); }
.ui-toast { display: inline-flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: var(--r); background: var(--s3); border: 1px solid var(--b2); color: var(--tx1); font-size: 13px; font-weight: 600; box-shadow: var(--shadow); }
.ui-toast .ui-ic { color: var(--good); }
.ui-toast.bad { background: var(--bad-soft); border-color: transparent; color: var(--bad); }
.ui-toast.bad .ui-ic { color: var(--bad); }

/* ── Layout shell ───────────────────────────────────────────────────────── */
.ui-shell { display: flex; min-height: 100vh; }
.ui-main { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; }
.ui-page { padding: 20px 24px; display: flex; flex-direction: column; gap: 16px; }
