/* OnlyCRM — self-contained stylesheet.
   No CDN and no build step on purpose: this has to render correctly on a
   developer's WAMP machine with no network. Replace with a compiled
   Tailwind build when the front end is productionised. */

:root {
  --paper: #eef0f4;
  --surface: #ffffff;
  --surface-2: #f6f7fa;
  --ink: #151a26;
  --ink-2: #414b5e;
  --muted: #6b7588;
  --line: #d6dbe4;
  --line-soft: #e6e9f0;
  --accent: #0d6a63;
  --accent-ink: #0b544e;
  --accent-wash: #dcebe8;
  --warn: #a86e15;
  --warn-wash: #f6ead3;
  --crit: #9e2f26;
  --crit-wash: #f7e0dd;
  --ok: #3a6f36;
  --ok-wash: #e0eede;
  --radius: 6px;
  --shadow: 0 1px 2px rgba(20, 25, 36, .05), 0 8px 24px -18px rgba(20, 25, 36, .3);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0d1118; --surface: #151a24; --surface-2: #1b212c;
    --ink: #e7eaf0; --ink-2: #b6bfcd; --muted: #8894a7;
    --line: #2a3240; --line-soft: #222936;
    --accent: #57c1b2; --accent-ink: #7fd5c8; --accent-wash: #123430;
    --warn: #dda851; --warn-wash: #3a2e14;
    --crit: #e5837a; --crit-wash: #3d1f1c;
    --ok: #76bb6c; --ok-wash: #1c2f1a;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 10px 30px -20px rgba(0,0,0,.9);
  }
}
:root[data-theme="dark"] {
  --paper: #0d1118; --surface: #151a24; --surface-2: #1b212c;
  --ink: #e7eaf0; --ink-2: #b6bfcd; --muted: #8894a7;
  --line: #2a3240; --line-soft: #222936;
  --accent: #57c1b2; --accent-ink: #7fd5c8; --accent-wash: #123430;
  --warn: #dda851; --warn-wash: #3a2e14;
  --crit: #e5837a; --crit-wash: #3d1f1c;
  --ok: #76bb6c; --ok-wash: #1c2f1a;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans", "Noto Sans Devanagari", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px;
}

h1, h2, h3, h4 { margin: 0; line-height: 1.2; font-weight: 650; letter-spacing: -.012em; }
h1 { font-size: 24px; }
h2 { font-size: 19px; }
h3 { font-size: 16px; }
h4 { font-size: 13px; }
p { margin: 0 0 10px; }

.mono, code, .tabular { font-family: ui-monospace, SFMono-Regular, "JetBrains Mono", Menlo, monospace; }
.tabular { font-variant-numeric: tabular-nums; }
code {
  font-size: .85em; background: var(--surface-2); border: 1px solid var(--line-soft);
  border-radius: 3px; padding: .1em .35em; color: var(--ink-2); word-break: break-all;
}

/* ---------- shell ---------- */

.shell { display: flex; min-height: 100vh; }

/* The mobile drawer.

   Hidden entirely at desk width — the sidebar is simply there. Everything
   below only comes alive inside the 820px media query near the bottom of this
   file; keeping the pieces defined here means the narrow rules are about
   layout rather than about inventing components. */
.nav-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
.mobile-bar, .nav-scrim { display: none; }

.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;
}

/* Three lines, drawn rather than typed: a hamburger character renders as an
   emoji on some Android builds and as a missing glyph on others. */
.nav-button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
.nav-button .bars, .nav-button .bars::before, .nav-button .bars::after {
  display: block; width: 18px; height: 2px; background: var(--ink); border-radius: 2px;
}
.nav-button .bars { position: relative; }
.nav-button .bars::before, .nav-button .bars::after { content: ""; position: absolute; left: 0; }
.nav-button .bars::before { top: -6px; }
.nav-button .bars::after { top: 6px; }

.nav-toggle:focus-visible + .mobile-bar .nav-button,
.mobile-bar .nav-button:hover { border-color: var(--accent); }

.sidebar {
  width: 232px; flex: none; background: var(--surface);
  border-right: 1px solid var(--line); display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.brand { padding: 18px 18px 14px; border-bottom: 1px solid var(--line-soft); }
.brand .name { font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.brand .org { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* The wordmark comes in two inks because the sidebar sits on --surface, which
   is near-white in one theme and near-black in the other; a single dark-green
   file would disappear in dark mode. Two files swapped by CSS rather than a
   <picture> element, because the theme here is also settable by hand with
   [data-theme] and a media query alone cannot follow that. */
.brand .wordmark { display: block; height: 26px; width: auto; }
.brand .wordmark.on-dark { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand .wordmark.on-light { display: none; }
  :root:not([data-theme="light"]) .brand .wordmark.on-dark { display: block; }
}
:root[data-theme="light"] .brand .wordmark.on-light { display: block; }
:root[data-theme="light"] .brand .wordmark.on-dark { display: none; }
:root[data-theme="dark"] .brand .wordmark.on-light { display: none; }
:root[data-theme="dark"] .brand .wordmark.on-dark { display: block; }

.nav { padding: 10px 10px 20px; display: flex; flex-direction: column; gap: 1px; }
.nav .group {
  font-size: 10px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted); padding: 14px 8px 5px; font-weight: 600;
}

/* Collapsible sections.

   Built on <details>, so open and close work with no JavaScript, the summary
   takes keyboard focus, and the expanded state is announced without any ARIA
   of ours to get wrong. app.js only remembers the choice between visits. */
.nav-group > summary {
  font-size: 10px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted); padding: 14px 8px 5px; font-weight: 600;
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: 6px;
  border-radius: var(--radius);
}
/* The default triangle is replaced by one we can place and rotate. Both
   prefixes are needed: -webkit-details-marker for older WebKit, ::marker for
   everything current. */
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary::marker { content: ""; }

.nav-group > summary::after {
  content: ""; margin-left: auto;
  width: 5px; height: 5px; border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor; transform: rotate(45deg) translate(-1px, -1px);
  transition: transform .12s ease;
}
.nav-group[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }

.nav-group > summary:hover { color: var(--ink-2); }
.nav-group > summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

/* A collapsed group holding the page you are on cannot happen — the server
   sends it open — but the dot marks a group whose contents are the current
   section, which is what makes a half-collapsed sidebar readable at a glance. */
.nav-group > summary.holds-active { color: var(--accent-ink); }
.nav-group > summary.holds-active::before {
  content: ""; width: 4px; height: 4px; border-radius: 50%;
  background: currentColor; flex: none;
}

.nav-items { display: flex; flex-direction: column; gap: 1px; }
.nav a {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px; border-radius: var(--radius); color: var(--ink-2); font-size: 14px;
}
.nav a:hover { background: var(--surface-2); text-decoration: none; color: var(--ink); }
.nav a.active { background: var(--accent-wash); color: var(--accent-ink); font-weight: 600; }
.nav .count {
  font-size: 11px; background: var(--surface-2); border: 1px solid var(--line-soft);
  border-radius: 10px; padding: 1px 7px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.nav a.active .count { background: var(--surface); border-color: var(--accent); color: var(--accent-ink); }
.nav .count.alert { background: var(--crit-wash); color: var(--crit); border-color: transparent; }

.sidebar-foot { margin-top: auto; padding: 14px 18px; border-top: 1px solid var(--line-soft); font-size: 13px; }
.sidebar-foot .who { color: var(--ink); font-weight: 600; }
.sidebar-foot .role { color: var(--muted); font-size: 12px; text-transform: capitalize; }
.sidebar-foot .foot-actions { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }

/* Named, rather than hidden behind the person's own name. Changing a password
   is not something anybody goes looking for under their own name, and this is
   the only route to that screen anywhere in the application. */
.sidebar-foot .foot-link { color: var(--ink-2); }
.sidebar-foot .foot-link:hover { color: var(--ink); }
.sidebar-foot .foot-link.active { color: var(--accent-ink); font-weight: 600; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  background: var(--surface); border-bottom: 1px solid var(--line);
  padding: 14px 24px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.topbar .title { flex: 1; min-width: 200px; }
.topbar .sub { font-size: 13px; color: var(--muted); margin-top: 2px; }

/* The help icon. `order: 2` so it sits at the far right of the bar whatever a
   page put in @yield('actions'), and `flex: none` so a wrapping bar never
   squashes it into an oval. */
.help-icon {
  order: 2; flex: none; width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; text-decoration: none;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); font-size: 15px; font-weight: 700; line-height: 1;
}
.help-icon:hover { color: var(--accent-ink); border-color: var(--accent); text-decoration: none; }
.help-icon.active { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-wash); }
.content { padding: 22px 24px 64px; }

/* ---------- panels ---------- */

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.panel + .panel { margin-top: 16px; }
.panel-head {
  padding: 13px 16px; border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.panel-head h2, .panel-head h3 { flex: 1; min-width: 120px; }
.panel-body { padding: 16px; }
.panel-body.tight { padding: 0; }

.grid { display: grid; gap: 16px; }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid.three { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.grid.four { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.split { display: grid; grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); gap: 16px; align-items: start; }
@media (max-width: 980px) { .split { grid-template-columns: 1fr; } }

/* ---------- stat tiles ---------- */

.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.stat .n { font-size: 26px; font-weight: 650; font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat .l { font-size: 12px; color: var(--muted); margin-top: 4px; }
.stat.alert .n { color: var(--crit); }
.stat.good .n { color: var(--ok); }

/* ---------- tables ---------- */

.table-wrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: 14px; }
th {
  text-align: left; font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; padding: 10px 14px; white-space: nowrap;
  border-bottom: 1px solid var(--line); background: var(--surface-2);
}
td { padding: 10px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; color: var(--ink-2); }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-2); }
td .primary { color: var(--ink); font-weight: 600; }
td .sub { font-size: 12px; color: var(--muted); }
.empty { padding: 40px 16px; text-align: center; color: var(--muted); font-size: 14px; }

/* ---------- pills ---------- */

.pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600;
  padding: 3px 8px; border-radius: 20px; white-space: nowrap;
  background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line-soft);
}
.pill.slate { background: var(--surface-2); color: var(--muted); }
.pill.sky, .pill.indigo, .pill.violet { background: var(--accent-wash); color: var(--accent-ink); border-color: transparent; }
.pill.teal, .pill.emerald, .pill.ok { background: var(--ok-wash); color: var(--ok); border-color: transparent; }
.pill.amber, .pill.warn { background: var(--warn-wash); color: var(--warn); border-color: transparent; }
.pill.rose, .pill.crit, .pill.stone { background: var(--crit-wash); color: var(--crit); border-color: transparent; }
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* ---------- forms ---------- */

label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-2); margin-bottom: 4px; }
label .req { color: var(--crit); }
input[type=text], input[type=email], input[type=password], input[type=tel], input[type=number],
input[type=date], input[type=datetime-local], input[type=search], input[type=file], select, textarea {
  width: 100%; padding: 7px 10px; font: inherit; font-size: 14px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
textarea { min-height: 74px; resize: vertical; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 15px) 15px, calc(100% - 10px) 15px; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 28px; }
.field { margin-bottom: 12px; }
.field .help { font-size: 12px; color: var(--muted); margin-top: 4px; }
.field .error { font-size: 12px; color: var(--crit); margin-top: 4px; }
.form-row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.checkline { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.checkline label { margin: 0; font-weight: 400; }
input[type=checkbox], input[type=radio] { width: 15px; height: 15px; accent-color: var(--accent); }
fieldset { border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 12px 14px; margin: 0 0 14px; }
legend { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 600; padding: 0 5px; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 14px; font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); white-space: nowrap;
}
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
:root[data-theme="dark"] .btn.primary, :root:not([data-theme="light"]) .btn.primary { color: #08211f; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .btn.primary { color: #fff; } }
.btn.primary:hover { filter: brightness(1.08); }
.btn.danger { color: var(--crit); border-color: var(--crit); background: transparent; }
.btn.small { padding: 4px 9px; font-size: 12.5px; }
.btn.link { border-color: transparent; background: transparent; color: var(--accent-ink); padding: 4px 6px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

/* ---------- filters ---------- */

.filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; }
.filters .field { margin: 0; min-width: 140px; }
.filters .field.grow { flex: 1; min-width: 200px; }

/* ---------- timeline ---------- */

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { display: grid; grid-template-columns: 22px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
.timeline li:last-child { border-bottom: none; }
.timeline .marker {
  width: 22px; height: 22px; border-radius: 50%; background: var(--surface-2);
  border: 1px solid var(--line); display: grid; place-items: center;
  font-size: 10px; font-weight: 700; color: var(--muted); margin-top: 2px;
}
.timeline .marker.system { background: var(--accent-wash); border-color: transparent; color: var(--accent-ink); }
.timeline .head { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.timeline .head .who { font-weight: 600; color: var(--ink); font-size: 14px; }
.timeline .head .when { font-size: 12px; color: var(--muted); margin-left: auto; }
.timeline .body { font-size: 14px; color: var(--ink-2); margin-top: 4px; white-space: pre-wrap; }

/* ---------- key/value ---------- */

.kv { display: grid; grid-template-columns: minmax(120px, 38%) 1fr; gap: 8px 14px; font-size: 14px; }
.kv dt { color: var(--muted); font-size: 12.5px; }
.kv dd { margin: 0; color: var(--ink); word-break: break-word; }

/* ---------- flash ---------- */

.flash {
  padding: 10px 14px; border-radius: var(--radius); margin-bottom: 16px; font-size: 14px;
  background: var(--ok-wash); color: var(--ok); border: 1px solid transparent;
}
.flash.error { background: var(--crit-wash); color: var(--crit); }
.errors { background: var(--crit-wash); color: var(--crit); padding: 10px 14px; border-radius: var(--radius); margin-bottom: 14px; font-size: 13.5px; }
.errors ul { margin: 4px 0 0; padding-left: 18px; }

/* ---------- banners ----------
   Distinct from .flash on purpose. A flash is a receipt for something the
   user just did and goes away on the next page; a banner is a standing
   condition — a lapsing subscription, a platform administrator in the room —
   and stays on every screen until it is no longer true. */

.banner {
  display: flex; gap: 14px; align-items: center; justify-content: space-between;
  flex-wrap: wrap; padding: 11px 15px; border-radius: var(--radius);
  margin-bottom: 16px; font-size: 13.5px; line-height: 1.5;
  border: 1px solid transparent;
}
.banner strong { font-weight: 650; }
.banner.warn { background: var(--warn-wash); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
.banner.crit { background: var(--crit-wash); color: var(--crit); border-color: color-mix(in srgb, var(--crit) 30%, transparent); }
/* Support reads as "someone is watching", not as an error. */
.banner.support {
  background: var(--accent-wash); color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.banner form { margin: 0; }

/* ---------- workspace switcher ----------
   Only rendered for people who work in more than one workspace, so it has to
   read as part of the brand block rather than as a control bolted beside it. */

.brand .switcher { margin-top: 4px; }
.brand .switcher select {
  width: 100%; font-size: 13px; padding: 3px 6px;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-soft); border-radius: 4px;
}
.brand .switcher select:hover { border-color: var(--line); }

/* ---------- pagination ---------- */

.pagination { display: flex; gap: 4px; flex-wrap: wrap; padding: 12px 16px; font-size: 13.5px; align-items: center; }
.pagination a, .pagination span { padding: 4px 9px; border-radius: 4px; border: 1px solid var(--line-soft); color: var(--ink-2); }
.pagination .active span { background: var(--accent-wash); color: var(--accent-ink); border-color: transparent; font-weight: 600; }
.pagination .disabled span { opacity: .45; }
.pagination svg { width: 13px; height: 13px; }

/* ---------- bar chart ---------- */

.bars { display: flex; align-items: flex-end; gap: 4px; height: 64px; }
.bars .bar { flex: 1; background: var(--accent); border-radius: 2px 2px 0 0; min-height: 2px; opacity: .85; }
.bars .bar:hover { opacity: 1; }
.barlist { display: flex; flex-direction: column; gap: 8px; }
.barlist .row { display: grid; grid-template-columns: minmax(90px, 34%) 1fr auto; gap: 10px; align-items: center; font-size: 13.5px; }
.barlist .val { font-variant-numeric: tabular-nums; color: var(--muted); font-size: 13px; }

/* Unnested, so a bar can also sit in a table cell — the reports use both. */
.track { background: var(--surface-2); border-radius: 3px; height: 8px; overflow: hidden; }
.fill { background: var(--accent); height: 100%; border-radius: 3px; }

/* ---------- login ---------- */

.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.login-card { width: 100%; max-width: 380px; }
.login-card .brand { border: none; padding: 0 0 18px; }

/* ---------- misc ---------- */

.muted { color: var(--muted); }
.small { font-size: 12.5px; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.inline { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.divider { height: 1px; background: var(--line-soft); margin: 14px 0; }
details.disclose > summary { cursor: pointer; font-weight: 600; font-size: 14px; padding: 6px 0; }
/* Two classes the markup has been using for months with no rule behind them.

   `.help` had only `.field .help`, so every explanatory line outside a form
   field — most of the Lead capture screen — rendered at body size in body
   colour, indistinguishable from the thing it was explaining. `.note` had no
   rule at all, which meant the strongest warnings in the app ("sign the string
   you send", "WhatsApp allows a free-form reply only within 24 hours") were
   plain paragraphs. A caution nobody can see is not a caution. */
.help { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-top: 4px; }
.help a { color: var(--accent-ink); }
.note {
  margin: 10px 0; padding: 10px 13px; font-size: 13px; line-height: 1.55;
  border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  border-left-width: 3px; border-radius: var(--radius);
  background: var(--warn-wash); color: var(--ink-2);
}
.note strong { color: var(--warn); font-weight: 650; }

.copy-field { display: flex; gap: 6px; align-items: center; }
.copy-field code { flex: 1; overflow-x: auto; white-space: nowrap; padding: 6px 8px; }

/* A block of code somebody is meant to read and then copy.

   `.copy-field` is a flex row whose code is `white-space: nowrap`, which is
   right for a URL and quietly wrong for anything longer: a <code> element
   folds newlines like any other inline text, so the eight-line form snippet
   and the ten-line Apps Script on the capture screen were both rendering as
   one enormous line, scrolled off the right edge, with nothing to copy them
   with. Somebody following those instructions was reading a paragraph of
   JavaScript.

   `pre` rather than `code` for the whitespace, and the button is absolutely
   positioned so it does not shorten the first line. */
.code-block { position: relative; margin: 8px 0; }
.code-block pre {
  margin: 0; padding: 12px 74px 12px 12px; overflow-x: auto;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  border-radius: var(--radius); color: var(--ink-2);
  font-family: ui-monospace, SFMono-Regular, "JetBrains Mono", Menlo, monospace;
  font-size: 12.5px; line-height: 1.55; tab-size: 2;
}
.code-block pre code {
  background: none; border: 0; padding: 0; font-size: inherit; color: inherit;
  white-space: pre; word-break: normal;
}
.code-block .copy-block { position: absolute; top: 8px; right: 8px; }

/* The help page: a question, its answer, and a spine of steps down the left. */
.help-toc { display: flex; flex-wrap: wrap; gap: 8px 16px; font-size: 13.5px; }

/* The table of replies.

   `code` is `word-break: break-all` globally, which is right for a long URL in
   a narrow cell and wrong for every value in this table: it rendered the
   statuses as "processe/d", "duplicat/e" and "Empty pa/yload", and split
   Content-Type across a line in the prose beside them. These are short tokens
   somebody is matching against what their own log said, so they must read as
   one word or they are worse than useless.

   The min-width makes the wrapper scroll on a phone rather than squeezing
   three columns into 390px. */
.answers { min-width: 620px; }
.answers code { word-break: normal; white-space: nowrap; }
.answers td:first-child { white-space: nowrap; }

/* On a phone it stops being a table.

   Scrolling it sideways was technically possible and useless: the reply
   column took half the width and the sentence explaining it arrived as a
   ten-character ribbon down the right-hand edge. Three columns do not fit in
   390px and no amount of min-width makes them, so each row becomes a small
   block with its column headings inlined. */
@media (max-width: 700px) {
  .answers { min-width: 0; }
  .answers thead { display: none; }
  .answers, .answers tbody, .answers tr, .answers td { display: block; width: auto; }
  .answers tr { padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
  .answers tr:last-child { border-bottom: 0; }
  .answers td { border: 0; padding: 3px 0; }
  .answers td:first-child { margin-bottom: 6px; }
  .answers td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 2px;
    font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
    color: var(--muted); font-weight: 600;
  }
}
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.steps > li {
  position: relative; padding: 0 0 20px 40px; counter-increment: step;
  border-left: 2px solid var(--line-soft); margin-left: 13px;
}
.steps > li:last-child { border-left-color: transparent; padding-bottom: 0; }
.steps > li::before {
  content: counter(step); position: absolute; left: -14px; top: -2px;
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line);
  font-size: 12px; font-weight: 600; color: var(--ink-2);
}
.steps > li > h3 { margin: 2px 0 6px; font-size: 15px; }
.steps > li > p { margin: 0 0 8px; color: var(--ink-2); font-size: 14px; line-height: 1.55; }

@media (max-width: 820px) {
  .shell { flex-direction: column; }

  /* A bar, and a drawer that slides over the page.

     The sidebar used to stack above the content, which put roughly 1200px of
     navigation between opening the leads list and seeing a lead. Taking it out
     of flow costs nothing at this width — there is no room for a permanent
     sidebar anyway — and gives the page the whole screen. */
  .mobile-bar {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 14px; background: var(--surface);
    border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 30;
  }
  .mobile-bar .wordmark { display: block; height: 22px; width: auto; }
  .mobile-bar .wordmark.on-dark { display: none; }

  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 50;
    width: min(300px, 86vw); height: 100%;
    transform: translateX(-102%);
    transition: transform .18s ease;
    border-right: 1px solid var(--line);
    box-shadow: 0 0 24px rgba(0, 0, 0, .18);
  }
  .nav-toggle:checked ~ .sidebar { transform: translateX(0); }

  .nav-scrim {
    position: fixed; inset: 0; z-index: 40;
    background: rgba(0, 0, 0, .45);
    opacity: 0; pointer-events: none; transition: opacity .18s ease;
  }
  .nav-toggle:checked ~ .nav-scrim { display: block; opacity: 1; pointer-events: auto; }

  /* Inside the drawer it is a column again, the way it is at desk width: the
     drawer is a sidebar, not a strip, so the row layout the old flattened
     header needed no longer applies. */
  .nav-items { flex-direction: column; }
  .sidebar-foot { display: block; }
  .sidebar-foot .foot-actions { margin-top: 10px; flex-direction: column; align-items: flex-start; }

  .content { padding: 16px; }
  .topbar { padding: 14px 16px; }
}

/* Prefers-reduced-motion is handled globally below; the drawer still opens,
   it simply appears rather than slides. */
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ---------------------------------------------------------------------------
   The leads list
--------------------------------------------------------------------------- */

/* Filters, folded away unless something is applied. Same <details> mechanics as
   the sidebar groups: works with no script, keyboard-operable, announces its
   own state. */
.filter-panel > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; cursor: pointer; list-style: none;
}
.filter-panel > summary::-webkit-details-marker { display: none; }
.filter-panel > summary::marker { content: ""; }
.filter-panel > summary::after {
  content: ""; margin-left: auto; flex: none;
  width: 6px; height: 6px; border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted); transform: rotate(45deg) translate(-2px, -2px);
}
.filter-panel[open] > summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.filter-panel > summary:hover { background: var(--surface-2); }
.filter-panel > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.filter-panel .filter-summary-label { font-weight: 600; }
.filter-panel[open] > summary { border-bottom: 1px solid var(--line-soft); }
.filter-panel > summary .count {
  font-size: 11px; background: var(--accent-wash); color: var(--accent-ink);
  border-radius: 10px; padding: 1px 8px; font-variant-numeric: tabular-nums;
}

/* Rows that do not wrap into three lines.

   Ten columns at 1440px left almost every cell wrapping, which made rows about
   110px tall and fitted six leads on a screen. `.table-wrap` already scrolled
   sideways; what it lacked was any reason for the table to want more width than
   the panel, so the browser squeezed columns instead. A min-width gives the
   table permission to be as wide as it needs and lets the scroll do its job —
   a horizontal scrollbar on a wide table is a familiar thing, and much better
   than a grid of two-word stacks.

   Applied only where a table opts in, because `.table-wrap` is used by narrow
   tables elsewhere that have no such problem. */
.table-wrap.wide > table { min-width: 980px; }
.table-wrap.wide td, .table-wrap.wide th { white-space: nowrap; }

/* Except the name, which people read rather than scan. Wrapping a person's
   name is better than truncating it or scrolling to reach it. */
.table-wrap.wide td.wrap, .table-wrap.wide th.wrap { white-space: normal; min-width: 170px; }

/* Call and WhatsApp sat under the number as two stacked links, which is two
   more lines on every single row. Side by side, and quieter. */
.contact-actions { display: inline-flex; gap: 8px; margin-left: 8px; }
.contact-actions a { font-size: 12px; }

/* ---------------------------------------------------------------------------
   Dashboard
--------------------------------------------------------------------------- */

/* This row holds five to eight tiles depending on which modules a tenant has
   on and what the person's role can see, so some counts will always wrap.

   Grid rather than flex, because grid columns are shared down the whole row
   set: a tile that wraps is the same width as the tile above it. Flex sizes
   each line independently, so a lone tile on a second line grew to its cap
   while the six above it sat at their basis — 260px under a row of 180s, which
   reads as a broken layout rather than a list that ran out.

   140px is the widest minimum that still fits seven tiles across the content
   column of a 1440 screen, which is the common full house. */
.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 14px;
}

/* Closed stages under the pipeline chart: counted, not charted. */
.closed-line {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.closed-line .tabular { color: var(--ink); font-weight: 600; margin-left: 3px; }
