/* ---- the wordmark faces ---------------------------------------------------
   Hellforge, the industrial slab the PROSPECTOR wordmark is set in, supplied as
   OpenType. OTF is a perfectly good webfont format — .woff2 would be roughly a
   third smaller, but at 6KB the saving is not worth a format conversion that
   the licence may not cover.

   The file is CAPS ONLY: 26 uppercase letters, no lowercase, no digits. That is
   all the wordmark needs, and unicode-range says so out loud — the browser will
   only ever reach for this face for A-Z, so if it is ever applied to text with
   digits or lowercase in it, those characters come from the fallback instead of
   turning into blank boxes. It is also why nothing but the wordmark uses this
   stack: "44i lead generation" underneath it would lose both of its 4s.

   Alfa Slab One stays as the fallback for anywhere Hellforge cannot be served
   — it is a heavy display slab under the SIL Open Font License, self-hosted, so
   nothing is fetched from a third party at runtime. Licence beside it in
   assets/fonts/alfa-slab-one-OFL.txt. */
@font-face {
    font-family: 'Hellforge';
    src: url('../fonts/Hellforge.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0041-005A;
}

@font-face {
    font-family: 'Alfa Slab One';
    src: url('../fonts/alfa-slab-one.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* Prospector — application styles
   Dark by default with a light theme available; both are explicit so the
   toggle wins over the OS preference. */

:root {
    --bg: #0e0f12;
    --surface: #16181c;
    --surface-2: #1c1f24;
    --surface-3: #23262d;
    --border: #2a2e36;
    --border-strong: #383d47;
    --text: #e9ebef;
    --text-dim: #b3b9c4;
    --muted: #8b929e;
    /* Fluorescent lime. Full chroma on dark, where it can actually glow;
       --accent-glow is the colour bled behind accent surfaces to give it that
       lit-from-within look without washing out the text sitting on top. */
    --accent: #c8ff00;
    --accent-hover: #d8ff4d;
    --accent-ink: #10160a;
    --accent-glow: color-mix(in srgb, #c8ff00 38%, transparent);
    /* The mark is a fixed-colour image, so it cannot follow --accent the way
       everything else does. On dark it is already the right lime and only wants
       the same bloom the other accent surfaces get. */
    --mark-filter: drop-shadow(0 0 7px var(--accent-glow));
    --link: #9fd0ff;
    --danger: #ff6b6b;
    --danger-bg: #2c1618;
    --success: #57d9a3;
    --success-bg: #12291f;
    --warning: #ffc857;
    --warning-bg: #2b2110;
    --info: #7cb8ff;
    --info-bg: #14202f;
    --violet: #b79cff;
    --violet-bg: #1f1a2e;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .28);
    --radius: 10px;
    --radius-sm: 7px;
    --sidebar-w: 244px;
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    color-scheme: dark;
}

:root[data-theme="light"] {
    --bg: #f4f6f8;
    --surface: #ffffff;
    --surface-2: #f7f8fa;
    --surface-3: #eef1f5;
    --border: #e3e7ec;
    --border-strong: #cfd5de;
    --text: #14171c;
    --text-dim: #3d444f;
    --muted: #6b7280;
    /* Nudged down on light: #c8ff00 on white is barely visible, and a glow on a
       white ground reads as a smudge rather than as light. Same hue, enough
       depth to sit on paper. */
    --accent: #a8d900;
    --accent-hover: #b8ec1a;
    --accent-ink: #131a00;
    --accent-glow: transparent;
    /* Same nudge as --accent, applied to the artwork instead of to a hex: full
       lime on white is a smudge. Saturate first so pulling the brightness down
       deepens the colour rather than greying it. Lands on roughly #acd202,
       which is --accent to the eye. */
    --mark-filter: saturate(1.18) brightness(.84);
    --link: #1f6feb;
    --danger: #d5362f;
    --danger-bg: #fdeceb;
    --success: #14804a;
    --success-bg: #e9f7ef;
    --warning: #a1620a;
    --warning-bg: #fdf3e3;
    --info: #1f6feb;
    --info-bg: #ecf3fe;
    --violet: #6c4ed9;
    --violet-bg: #f1edfd;
    --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 6px 18px rgba(16, 24, 40, .07);
    color-scheme: light;
}

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) {
        --bg: #f4f6f8;
        --surface: #ffffff;
        --surface-2: #f7f8fa;
        --surface-3: #eef1f5;
        --border: #e3e7ec;
        --border-strong: #cfd5de;
        --text: #14171c;
        --text-dim: #3d444f;
        --muted: #6b7280;
        --accent: #a8d900;
        --accent-hover: #b8ec1a;
        --accent-ink: #131a00;
        --accent-glow: transparent;
        --mark-filter: saturate(1.18) brightness(.84);
        --link: #1f6feb;
        --danger: #d5362f;
        --danger-bg: #fdeceb;
        --success: #14804a;
        --success-bg: #e9f7ef;
        --warning: #a1620a;
        --warning-bg: #fdf3e3;
        --info: #1f6feb;
        --info-bg: #ecf3fe;
        --violet: #6c4ed9;
        --violet-bg: #f1edfd;
        --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 6px 18px rgba(16, 24, 40, .07);
        color-scheme: light;
    }
}

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

html, body { height: 100%; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.5;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }

p { margin: 0 0 10px; }
p:last-child { margin-bottom: 0; }

code {
    font-family: var(--mono);
    font-size: 12.5px;
    background: var(--surface-3);
    padding: 1px 5px;
    border-radius: 4px;
}

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

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

.sidebar {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 18px;
    color: var(--accent);
    border-bottom: 1px solid var(--border);
}

/* The wordmark. Uppercase and letterspaced because that is how an industrial
   slab wants to be set, and because it holds its shape when Hellforge is not
   installed and the fallback slab stands in. */
.brand-name {
    font-family: 'Hellforge', 'Alfa Slab One', 'Rockwell', 'Roboto Slab', Georgia, serif;
    font-size: 19px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .055em;
    text-transform: uppercase;
    color: var(--text);
}

.brand-sub {
    display: block;
    margin-top: 3px;
    font-size: 10.5px;
    font-weight: 500;
    color: var(--muted);
    letter-spacing: .06em;
    text-transform: uppercase;
}

.nav { padding: 12px 10px; flex: 1; }

.nav-group + .nav-group { margin-top: 18px; }

.nav-label {
    font-size: 10.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--muted);
    padding: 0 10px 6px;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-weight: 500;
    margin-bottom: 1px;
}

.nav-item:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }

.nav-item.is-active {
    background: var(--surface-3);
    color: var(--text);
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--accent);
}

.nav-item svg { flex: 0 0 16px; opacity: .85; }

.nav-count {
    margin-left: auto;
    font-size: 11px;
    font-weight: 650;
    color: var(--muted);
    background: var(--surface-3);
    border-radius: 20px;
    padding: 1px 7px;
}

.nav-item.is-active .nav-count { background: var(--bg); color: var(--text-dim); }

.sidebar-foot { border-top: 1px solid var(--border); padding: 12px; }

.user-chip { display: flex; align-items: center; gap: 10px; }

.avatar {
    width: 30px; height: 30px;
    flex: 0 0 30px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--accent-ink);
    display: grid;
    place-items: center;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .02em;
}

.avatar.avatar-lg { width: 42px; height: 42px; flex-basis: 42px; font-size: 15px; }

.user-chip-meta { min-width: 0; flex: 1; }
.user-chip-name { font-weight: 600; font-size: 13px; }
.user-chip-role { font-size: 11.5px; color: var(--muted); }

/* ----------------------------------------------------------------- main */

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

.topbar {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 11px 22px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 20;
}

.search { flex: 1; max-width: 520px; position: relative; }

.search svg {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--muted);
    pointer-events: none;
}

/* Attribute selector included deliberately: it has to outrank the generic
   input[type="search"] rule further down, which would otherwise reset the
   left padding and let the text run under the magnifier. */
.search input[type="search"] {
    width: 100%;
    padding: 8px 12px 8px 34px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text);
    font-size: 13.5px;
    font-family: inherit;
}

.search input[type="search"]:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 9px; }

.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 550;
    color: var(--text-dim);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 4px 11px;
    white-space: nowrap;
}

.icon-btn {
    display: grid;
    place-items: center;
    width: 32px; height: 32px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-dim);
    cursor: pointer;
}
.icon-btn:hover { color: var(--text); border-color: var(--border-strong); }

.content { padding: 22px; max-width: 1500px; width: 100%; }

.page-head {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}

.page-head .sub { color: var(--muted); font-size: 13px; margin-top: 3px; }
.page-head-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* --------------------------------------------------------------- pieces */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.card-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
}

.card-head h2, .card-head h3 { margin-right: auto; }
.card-body { padding: 16px; }
.card-body.tight { padding: 0; }
.card-foot { padding: 11px 16px; border-top: 1px solid var(--border); font-size: 12.5px; color: var(--muted); }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid-tiles { grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }

.tile {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
}

.tile-label {
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
}

.tile-value { font-size: 27px; font-weight: 680; letter-spacing: -.02em; margin-top: 5px; line-height: 1.1; }
.tile-note { font-size: 12px; color: var(--muted); margin-top: 3px; }
.tile.accent { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.tile.accent .tile-value { color: var(--accent); }
:root[data-theme="light"] .tile.accent .tile-value { color: var(--text); }

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

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.data, table.md-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

table.data th, table.md-table th {
    text-align: left;
    font-size: 11.5px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
    padding: 9px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    white-space: nowrap;
}

table.data td, table.md-table td {
    padding: 11px 12px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

table.data tbody tr:hover { background: var(--surface-2); }
table.data tbody tr:last-child td, table.md-table tbody tr:last-child td { border-bottom: 0; }
table.data td.nowrap, table.data th.nowrap { white-space: nowrap; }
table.data td.shrink { width: 1%; }

.cell-primary { font-weight: 600; }
.cell-sub { color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.cell-clip { max-width: 340px; }

/* --------------------------------------------------------------- badges */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11.5px;
    font-weight: 620;
    padding: 2px 8px;
    border-radius: 20px;
    white-space: nowrap;
    border: 1px solid transparent;
}

.badge-new { background: var(--info-bg); color: var(--info); border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.badge-contacted { background: var(--warning-bg); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.badge-no_answer { background: var(--surface-3); color: var(--muted); border-color: var(--border); }
.badge-meeting { background: var(--violet-bg); color: var(--violet); border-color: color-mix(in srgb, var(--violet) 30%, transparent); }
.badge-signed { background: var(--success-bg); color: var(--success); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.badge-not_interested { background: var(--danger-bg); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.badge-disqualified { background: var(--surface-3); color: var(--muted); border-color: var(--border); }
.badge-neutral { background: var(--surface-3); color: var(--text-dim); border-color: var(--border); }
.badge-verified { background: var(--success-bg); color: var(--success); }
.badge-high { background: var(--info-bg); color: var(--info); }
.badge-pattern { background: var(--warning-bg); color: var(--warning); }

.score {
    display: inline-grid;
    place-items: center;
    min-width: 38px;
    padding: 3px 7px;
    border-radius: 7px;
    font-size: 13px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    background: var(--surface-3);
    color: var(--text-dim);
    border: 1px solid var(--border);
}

.score.s-high { background: var(--success-bg); color: var(--success); border-color: color-mix(in srgb, var(--success) 35%, transparent); }
.score.s-mid { background: var(--warning-bg); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 35%, transparent); }
.score.s-low { background: var(--surface-3); color: var(--muted); }

.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); display: inline-block; }
.dot.ok { background: var(--success); }
.dot.warn { background: var(--warning); }
.dot.bad { background: var(--danger); }

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

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    padding: 8px 14px;
    border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: var(--surface-2);
    color: var(--text);
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
}

.btn:hover { background: var(--surface-3); text-decoration: none; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/* The glow is what separates "fluorescent" from "green". It sits outside the
   button rather than on the text, so nothing that has to be read gets softer —
   and it is a no-op on light, where --accent-glow is transparent. */
.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
    box-shadow: 0 0 0 1px var(--accent-glow), 0 2px 14px -4px var(--accent-glow);
}
.btn-primary:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    box-shadow: 0 0 0 1px var(--accent-glow), 0 3px 20px -3px var(--accent-glow);
}

.btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--border)); }
.btn-danger:hover { background: var(--danger-bg); }

.btn-sm { font-size: 12.5px; padding: 5px 10px; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }
.btn-block { width: 100%; }

.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

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

label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-dim); margin-bottom: 5px; }

/* Every text-shaped input, listed by type rather than caught with :not() so a
   checkbox or a file picker is never dragged in by accident. tel is here
   because the new-lead form has two phone boxes and they were the only styled
   fields on the site rendering as browser defaults. */
input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="search"], input[type="url"], input[type="tel"], select, textarea {
    width: 100%;
    padding: 8px 11px;
    font-family: inherit;
    font-size: 13.5px;
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
}

select { appearance: none; background-image: none; padding-right: 30px; cursor: pointer; }

textarea { resize: vertical; min-height: 76px; line-height: 1.5; }

input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: transparent;
}

.field { margin-bottom: 14px; }
.field-row { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.hint { font-size: 12px; color: var(--muted); margin-top: 5px; }

/* A roomier version of .field-row, for a screen that is nothing but form.
   auto-FILL rather than auto-fit on purpose: with auto-fit the empty tracks
   collapse, so a group holding one field stretches it the full width of the
   card, and a lone status dropdown a thousand pixels wide looks like a mistake.
   align-items: start stops a field with a two-line hint from stretching its
   neighbours to match. */
.field-grid {
    display: grid;
    gap: 12px 14px;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    align-items: start;
}

/* A field that wants the whole row rather than a share of it — the prose
   boxes, mostly, which are unreadable in a narrow column. */
.field-wide { grid-column: 1 / -1; }

/* A validation message, in place of the hint it replaces. Coloured and marked
   so it does not depend on colour alone to be noticed. */
.hint-error { color: var(--danger); }
.hint-error::before { content: '! '; font-weight: 700; }
.field:has(.hint-error) input,
.field:has(.hint-error) select,
.field:has(.hint-error) textarea { border-color: var(--danger); }

.form-actions { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; }

.check { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.check input { width: 15px; height: 15px; margin: 2px 0 0; accent-color: var(--accent); flex: 0 0 auto; }

/* Row-selection boxes. A class rather than an inline style so the coarse-
   pointer rule below can grow them — an inline style beats a stylesheet,
   which is how these stayed 15px on a touchscreen. */
.check-box { width: 15px; height: 15px; accent-color: var(--accent); }
.check label { margin: 0; font-weight: 500; color: var(--text); }
.check .hint { margin-top: 2px; }

fieldset { border: 0; margin: 0; padding: 0; }

.filters {
    display: flex;
    gap: 9px;
    flex-wrap: wrap;
    align-items: flex-end;
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    border-radius: var(--radius) var(--radius) 0 0;
}

.filters .field { margin: 0; min-width: 132px; }
.filters .field.grow { flex: 1; min-width: 190px; }
.filters label { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }

/* --------------------------------------------------------------- alerts */

.alert {
    display: flex;
    gap: 10px;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--surface-2);
    margin-bottom: 14px;
    font-size: 13.5px;
}

.alert-success { background: var(--success-bg); border-color: color-mix(in srgb, var(--success) 30%, transparent); color: var(--success); }
.alert-error { background: var(--danger-bg); border-color: color-mix(in srgb, var(--danger) 30%, transparent); color: var(--danger); }
.alert-warning { background: var(--warning-bg); border-color: color-mix(in srgb, var(--warning) 30%, transparent); color: var(--warning); }
.alert-info { background: var(--info-bg); border-color: color-mix(in srgb, var(--info) 30%, transparent); color: var(--info); }
.alert strong { font-weight: 650; }

.empty { text-align: center; padding: 44px 20px; color: var(--muted); }
.empty svg { color: var(--border-strong); margin-bottom: 12px; }
.empty h3 { color: var(--text); margin-bottom: 6px; }
.empty p { max-width: 430px; margin: 0 auto 14px; }

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

.stack { display: flex; flex-direction: column; gap: 14px; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row-between { display: flex; gap: 10px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.mt { margin-top: 14px; }
.mt-sm { margin-top: 8px; }
.mb { margin-bottom: 14px; }
.muted { color: var(--muted); }
.dim { color: var(--text-dim); }
.small { font-size: 12.5px; }
.mono { font-family: var(--mono); font-size: 12.5px; }
.nowrap { white-space: nowrap; }
.center { text-align: center; }
.right { text-align: right; }
.spacer { flex: 1; }
.hidden { display: none !important; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

.divider { height: 1px; background: var(--border); margin: 16px 0; border: 0; }

.kv { display: grid; grid-template-columns: 128px 1fr; gap: 8px 14px; font-size: 13.5px; }
.kv dt { color: var(--muted); font-weight: 550; }
.kv dd { margin: 0; word-break: break-word; }

.sparkline { display: flex; align-items: flex-end; gap: 3px; height: 46px; }
.sparkline span {
    flex: 1;
    min-height: 3px;
    background: color-mix(in srgb, var(--accent) 55%, transparent);
    border-radius: 2px 2px 0 0;
}
.sparkline span.is-today { background: var(--accent); }

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { position: relative; padding: 0 0 15px 20px; border-left: 1px solid var(--border); }
.timeline li:last-child { padding-bottom: 0; border-left-color: transparent; }
.timeline li::before {
    content: "";
    position: absolute;
    left: -4.5px; top: 5px;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--border-strong);
}
.timeline li.is-note::before { background: var(--info); }
.timeline li.is-status::before { background: var(--accent); }
.timeline li.is-ghl::before { background: var(--violet); }
.timeline li.is-ghl_error::before { background: var(--danger); }
.timeline-meta { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

.brief { font-size: 14px; line-height: 1.62; }
.brief h2 { font-size: 16px; margin: 22px 0 9px; padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.brief h3, .brief h4 { font-size: 14px; margin: 18px 0 7px; }
.brief h2:first-child, .brief h3:first-child { margin-top: 0; }
.brief ul, .brief ol { margin: 0 0 12px; padding-left: 20px; }
.brief li { margin-bottom: 4px; }
.brief table.md-table { margin: 0 0 14px; font-size: 13px; }
.brief .table-scroll { border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 14px; }
.brief hr { border: 0; border-top: 1px solid var(--border); margin: 18px 0; }

.bulkbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    background: var(--surface-3);
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}

.bulkbar select { width: auto; min-width: 170px; }
.bulkbar .count { font-weight: 650; }

.pagination { display: flex; gap: 6px; align-items: center; justify-content: center; padding: 14px; flex-wrap: wrap; }
.pagination a, .pagination span {
    padding: 5px 10px;
    border-radius: 7px;
    border: 1px solid var(--border);
    font-size: 13px;
    color: var(--text-dim);
}
.pagination a:hover { background: var(--surface-2); text-decoration: none; }
.pagination .is-current { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 650; }

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

.auth-wrap {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 24px;
    background:
        radial-gradient(900px 460px at 50% -8%, color-mix(in srgb, var(--accent) 13%, transparent), transparent 70%),
        var(--bg);
}

.auth-card { width: 100%; max-width: 396px; }

.auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 11px;
    color: var(--accent);
    margin-bottom: 6px;
}

/* Same wordmark, bigger, on the sign-in screen. */
.auth-brand span {
    font-family: 'Hellforge', 'Alfa Slab One', 'Rockwell', 'Roboto Slab', Georgia, serif;
    font-size: 30px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text);
}
.auth-tag { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 13.5px; }
.auth-card .card-body { padding: 22px; }
.auth-foot { text-align: center; margin-top: 16px; font-size: 12.5px; color: var(--muted); }

/* --------------------------------------------------------- responsive */

.mobile-only { display: none; }

@media (max-width: 900px) {
    .shell { flex-direction: column; }
    .sidebar {
        width: 100%;
        flex-basis: auto;
        height: auto;
        position: static;
        border-right: 0;
        border-bottom: 1px solid var(--border);
    }
    .sidebar[data-collapsed="true"] .nav,
    .sidebar[data-collapsed="true"] .sidebar-foot { display: none; }
    .brand { justify-content: flex-start; }
    .mobile-only { display: grid; }
    .nav { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 2px 10px; }
    .nav-group + .nav-group { margin-top: 8px; }
    .content { padding: 16px; }
    .kv { grid-template-columns: 1fr; gap: 2px; }
    .kv dd { margin-bottom: 8px; }
    .topbar { padding: 10px 14px; }
}

/* --------------------------------------------------------------- notices
   The unopened-batch notice. Accented rather than warning-coloured: a batch
   waiting is an opportunity, not a problem. It turns amber only once something
   has been sitting two days, which is the point at which it has stopped being
   "I was out yesterday". */

.notice {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 14px 16px;
    margin-bottom: 14px;
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--border));
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    box-shadow: 0 0 26px -18px var(--accent-glow);
}

.notice.is-stale {
    border-color: color-mix(in srgb, var(--warning) 45%, var(--border));
    border-left-color: var(--warning);
    box-shadow: none;
}

.notice-mark { color: var(--accent); flex: 0 0 auto; padding-top: 1px; }
.notice.is-stale .notice-mark { color: var(--warning); }

.notice-body { flex: 1 1 auto; min-width: 0; font-size: 13.5px; }
.notice-body strong { display: block; color: var(--text); font-weight: 650; }

.notice-list {
    list-style: none;
    margin: 6px 0 0;
    padding: 0;
    display: grid;
    gap: 3px;
    font-size: 13px;
}
.notice-list li { display: flex; align-items: center; gap: 7px; }

.notice-go { flex: 0 0 auto; }

/* A lead nobody has opened. Small enough to be a mark rather than a shout, and
   it goes the moment the lead is opened. */
.unopened-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent);
    flex: 0 0 auto;
}

/* The topbar chip that carries the count. */
.pill-alert {
    color: var(--accent);
    border-color: color-mix(in srgb, var(--accent) 50%, var(--border));
    font-weight: 650;
}
.pill-alert:hover { text-decoration: none; background: var(--surface-3); }

/* ------------------------------------------------------- action colours
   Three buttons that say what they do by colour as well as by label, picked by
   the owner. They carry their own ink rather than inheriting --accent-ink,
   because each needs a different one to stay readable: near-black on the two
   bright ones, white on the red.

   Given explicitly rather than as a filter of --accent so they are the same in
   both themes — a destructive button that changes colour with the theme is a
   destructive button somebody eventually fails to recognise. */

.btn-delete { background: #ff003c; border-color: #ff003c; color: #ffffff; font-weight: 650; }
.btn-delete:hover:not(:disabled) { background: #e60036; border-color: #e60036; color: #ffffff; }

.btn-ghl { background: #e400ff; border-color: #e400ff; color: #ffffff; font-weight: 650; }
.btn-ghl:hover:not(:disabled) { background: #cc00e6; border-color: #cc00e6; color: #ffffff; }

.btn-send { background: #00ff9c; border-color: #00ff9c; color: #06231a; font-weight: 650; }
.btn-send:hover:not(:disabled) { background: #00e68c; border-color: #00e68c; color: #06231a; }

/* The icon inside each takes the button's own ink rather than the link blue it
   would otherwise inherit. */
.btn-delete svg, .btn-ghl svg, .btn-send svg { color: currentColor; }

/* ------------------------------------------------------------ bulk actions
   A select and its button read as one control, so they sit in one box. */
/* The phone's stand-in for the select-all in the table header. */
.select-all {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-dim);
    border-bottom: 1px solid var(--border);
    cursor: pointer;
}

.bulk-group { display: inline-flex; align-items: stretch; gap: 6px; }
.bulk-group select { width: auto; min-width: 168px; }

/* ---------------------------------------------------------- the composer */

.composer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 5px;
}
.composer-head label { margin: 0; }

.toolbar { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }

.tool {
    min-width: 30px;
    height: 30px;
    padding: 0 7px;
    font-size: 13px;
    font-family: inherit;
    color: var(--text-dim);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
}
.tool:hover { background: var(--surface-3); color: var(--text); }
.tool-sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
.tool-size { width: auto; padding: 4px 8px; font-size: 12.5px; height: 30px; min-height: 0; }

.composer {
    min-height: 168px;
    max-height: 40vh;
    overflow-y: auto;
    padding: 11px 12px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.composer:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
.composer:empty::before {
    content: attr(data-placeholder);
    color: var(--muted);
    pointer-events: none;
}
.composer p { margin: 0 0 8px; }
.composer ul, .composer ol { margin: 0 0 8px; padding-left: 22px; }
.composer a { color: var(--link); }

.merge-picker { width: auto; min-width: 220px; }

.attach-list { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 5px; }
.attach-list:empty { display: none; }
.attach-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 10px;
    font-size: 13px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.attach-row span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-row.is-uploading { color: var(--muted); font-style: italic; }
.attach-row.is-failed { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }

/* ---------------------------------------------------------------- sheets
   The compose dialog. A sheet rather than a centred box: on a phone it comes
   up from the bottom edge and fills the screen, which is where a full-height
   form belongs, and on a desktop it settles into a centred panel. */

dialog.sheet {
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow);
    width: min(560px, calc(100% - 32px));
    max-height: min(85vh, 780px);
    overflow: hidden;
}

dialog.sheet::backdrop { background: rgba(0, 0, 0, .55); }

dialog.sheet form { display: flex; flex-direction: column; max-height: inherit; }

/* A confirmation is a question, not a form, so it wants far less room. */
dialog.sheet.sheet-sm { width: min(420px, calc(100% - 32px)); }

.sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
}
.sheet-head h2 { font-size: 16px; }

.sheet-body { padding: 16px; overflow-y: auto; flex: 1 1 auto; }

.sheet-foot {
    display: flex;
    gap: 9px;
    padding: 13px 16px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
}

/* Something the form states but does not let you change. Reads as a value
   rather than as a disabled input, which would invite clicking at it. */
.fixed-value {
    margin: 0;
    padding: 8px 11px;
    border: 1px dashed var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    font-size: 13.5px;
    color: var(--text-dim);
}

.signature-preview { margin-top: 4px; }
.signature-preview summary {
    cursor: pointer;
    font-size: 12px;
    color: var(--muted);
    padding: 6px 0;
}
/* The signature is rendered with the inline colours it will carry into an
   inbox, so it is shown on the light ground it was written for rather than
   grey-on-grey inside a dark panel. */
.signature-render {
    background: #ffffff;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 12px 14px;
    overflow-x: auto;
}
.signature-render img { max-width: 100%; height: auto; }

/* The phone row on a list screen. Written into the markup as its own cell and
   hidden here, so above 720px the real columns are what you see. */
.cell-compact { display: none; }

/* Visible only to a screen reader. */
.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;
}

/* The stage picker on a pipeline card. Always present — it is the only way to
   move a deal without a mouse — but quiet until you reach for it, so the card
   still reads as a card rather than as a form. */
.board-card-move { margin-top: 8px; }
.board-card-move select {
    font-size: 12px;
    padding: 5px 8px;
    background: var(--surface-2);
    color: var(--text-dim);
}

/* Two hints for one control: which half is shown depends on whether dragging
   is even possible. */
.touch-only { display: none; }
@media (pointer: coarse) {
    .pointer-only { display: none; }
    .touch-only { display: inline; }
}

/* ---- phones ------------------------------------------------------------
   Everything below is about a 390px screen held in one hand. The sellers work
   leads from their phones between calls, so this is not a courtesy breakpoint.

   720px rather than 900px for the structural changes: a tablet in landscape
   has room for a table, a phone does not, and the 900px rules above already
   handle the sidebar for both. */

@media (max-width: 900px) {
    /* iOS Safari zooms the whole page in when you focus a field smaller than
       16px, and does not zoom back out afterwards. Every input in the app was
       13.5px, so tapping any of them left you pinching to read the rest of the
       screen. This is the single most irritating thing about the app on a
       phone and it costs nothing to fix. */
    input[type="text"], input[type="email"], input[type="password"], input[type="number"],
    input[type="search"], input[type="url"], input[type="tel"], select, textarea {
        font-size: 16px;
    }

    .filters label { font-size: 11px; }

    /* The topbar search sets its own font-size, so the generic rule above does
       not reach it and it stays a zoom trigger. */
    .search input[type="search"] { font-size: 16px; }
}

/* Touch targets. A mouse pointer lands where you aimed it; a fingertip covers
   about 9mm, which is why Apple asks for 44px and Google for 48px.

   Width first, pointer second. Pointer:coarse is the more precise question to
   ask, but it is unreliable enough across emulators and desktop touchscreens
   that leaning on it alone means the rule silently does not apply — which is
   what happened here. Width is what the rest of this stylesheet keys off, and a
   narrow window on a laptop gets bigger targets too, which is no loss.

   Height only: a wide button is easy to hit already. */
@media (max-width: 900px), (pointer: coarse) {
    .btn { min-height: 44px; }
    .btn-sm { min-height: 40px; }
    .board-card-move select { font-size: 16px; }
    input, select, textarea { min-height: 44px; }
    textarea { min-height: 88px; }
    .check input, .check-box { width: 22px; height: 22px; }

    /* The two icon buttons in the chrome — open the navigation, switch the
       theme — were 32px square. They are the only way to reach the rest of the
       app on a phone, so they are the last things that should be fiddly. */
    .icon-btn { min-width: 44px; min-height: 44px; }

    /* A button styled as a link is still a button. "Dig for details" was a
       17px-tall target sitting inside a list row. */
    .linkish, .linklike { min-height: 40px; }

    /* The address and phone on a lead are tap-to-mail and tap-to-call, which
       makes them the two most-used targets on the screen and the two smallest:
       a 15px line of type is a 15px target. Padding rather than height, so the
       line box does not grow and push the layout around it. */
    .kv dd a, table.data td a, .listy a, .thread a, .board-card a {
        display: inline-block;
        padding: 10px 0;
    }
}

@media (max-width: 720px) {
    /* Tables become cards.

       A nine-column table at 390px either scrolls sideways — burying Status
       and Delivered off-screen where nobody finds them — or wraps company
       names one word per line. Neither is a list you can work from.

       The row becomes a card and each cell a labelled line. Labels come from
       app.js, which copies them off the <th> at load, so this works for every
       table in the app and cannot drift out of step with a column that only
       admins see. Without JS the tables stay tables and still scroll, which is
       the behaviour this replaces rather than a new failure. */
    .table-scroll { overflow-x: visible; }

    table.data { display: block; }
    table.data thead { display: none; }
    table.data tbody { display: block; }

    table.data:not(.compact) tbody tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 2px 10px;
        padding: 12px 14px;
        border-bottom: 1px solid var(--border);
    }
    table.data tbody tr:last-child { border-bottom: 0; }
    table.data tbody tr:hover { background: none; }

    table.data:not(.compact) tbody td {
        display: block;
        width: 100%;
        padding: 3px 0;
        border: 0;
    }

    /* The checkbox and the fit score are controls, not facts. They sit
       together on the first line, where a table would have put them, and the
       company name lands underneath as the card's headline. */
    table.data:not(.compact) tbody td.shrink { width: auto; padding: 0; }

    table.data:not(.compact) tbody td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 10.5px;
        font-weight: 650;
        text-transform: uppercase;
        letter-spacing: .05em;
        color: var(--muted);
        margin-bottom: 1px;
    }

    /* A card should not carry an empty labelled line, nor one whose whole
       content is the em dash a table cell prints to hold its column open.
       app.js marks those; see the note there. */
    table.data:not(.compact) tbody td:empty,
    table.data:not(.compact) tbody td[data-blank],
    table.data:not(.compact) tbody .cell-sub[data-blank] { display: none; }

    /* The checkbox, the score and the company name caption themselves. A line
       reading "COMPANY" above the company name is noise. */
    table.data:not(.compact) tbody td.shrink::before,
    table.data:not(.compact) tbody td:has(.cell-primary)::before { display: none; }

    /* The company name is the card's tap target, so give it a real one. */
    table.data:not(.compact) .cell-primary a { display: inline-flex; align-items: center; min-height: 44px; }

    /* The schedule pill is the least load-bearing thing in the topbar, and
       with the unopened count beside it the row no longer fits. */
    .hide-narrow { display: none; }

    .notice { flex-wrap: wrap; }
    .notice-go { width: 100%; justify-content: center; }

    /* ---- lists marked .compact get one line per row ------------------
       The card layout was right for a table that had to be readable at all,
       but a lead list is something you scan: nine cards of captions is a lot
       of thumb for "which of these do I call". A row is a checkbox, a score
       and a name, and everything else is one tap away. */
    table.data.compact tbody tr {
        /* The card rules no longer reach this table, so it declares its own
           box rather than inheriting one. */
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
        gap: 10px;
        padding: 6px 14px;
        min-height: 52px;
    }

    /* Everything the desktop shows comes off; the purpose-built cell replaces
       the lot. */
    table.data.compact tbody td { display: none; }
    /* min-width keeps the column of checkboxes straight when a row has none —
       on the outreach list a lead that cannot be sent to has an empty cell,
       and a zero-width one pulls that row out of line with the rest. */
    table.data.compact tbody td.shrink {
        display: block;
        width: auto;
        min-width: 22px;
        padding: 0;
    }
    table.data.compact tbody td::before { content: none; }

    table.data.compact .cell-compact {
        display: flex;
        align-items: center;
        gap: 7px;
        /* min-width:0 is what actually lets the text truncate: a flex item
           refuses to shrink below its content without it. */
        min-width: 0;
        flex: 1 1 auto;
        padding: 0;
    }

    /* Written long enough to out-specify the touch rule above, which makes
       every link in a table inline-block — that turned the two spans into
       inline boxes and wrapped the row onto a second line, which is the one
       thing a one-line row must not do. */
    table.data.compact .cell-compact > a {
        display: flex;
        align-items: baseline;
        gap: 7px;
        min-width: 0;
        flex: 1 1 auto;
        padding: 9px 0;
    }
    table.data.compact .cell-compact > a:hover { text-decoration: none; }

    /* The company takes the room it needs and gives the rest to the name; both
       clip rather than wrap, because a wrapped row is not a one-line row. */
    .compact-name {
        font-weight: 600;
        color: var(--text);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        /* min-width:0 as well as flex-shrink: without it the company name
           refuses to go below its natural width and pushes the person off the
           end instead of both clipping. */
        flex: 0 1 auto;
        min-width: 0;
    }
    .compact-sub {
        font-size: 12.5px;
        color: var(--muted);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        flex: 1 1 auto;
        min-width: 0;
    }
    .cell-compact .badge { flex: 0 0 auto; }

    /* Nine cards of 150-character prose is a very long page. Clamped to two
       lines rather than hidden — it is the column that decides whether a lead
       is worth opening, so losing it would defeat the list. */
    table.data:not(.compact) tbody td.cell-clip:not(:empty):not([data-blank]) {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    table.data:not(.compact) td.nowrap { white-space: normal; }
    table.data:not(.compact) td.right { text-align: left; }
    .cell-clip { max-width: none; }

    /* Filters fold away. Eight of them stacked two-up fill the screen before a
       single lead is visible; the toggle button carries a count so a filter
       left on is still obvious while the panel is shut. */
    .filters.collapsible { display: none; }
    .filters.collapsible.is-open { display: flex; }
    .filters-toggle { margin: 12px 14px; }
    .filters .field, .filters .field.grow { min-width: 0; flex: 1 1 45%; }

    /* The bulk bar sticks to the bottom once something is selected. It lives
       above the list, so on a phone you would otherwise tick six leads, scroll
       back up past all of them, and only then choose an action. */
    .bulkbar:not(.hidden) {
        position: sticky;
        bottom: 0;
        z-index: 5;
        border-top: 1px solid var(--border-strong);
        border-bottom: 0;
        box-shadow: 0 -6px 18px rgba(0, 0, 0, .18);
    }
    .bulkbar select, .bulkbar .btn { width: 100%; }
    .bulkbar .count { width: 100%; }

    /* Page actions: full width and stacked beats three buttons reflowing into
       a ragged two-and-one. */
    .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
    .page-head-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
    .page-head-actions .btn { justify-content: center; }

    /* Two side-by-side cards at 390px are two half-width cards. */
    .grid-2, .grid-3 { grid-template-columns: 1fr; }

    .content { padding: 12px; }
    .card-head { flex-wrap: wrap; gap: 4px; }
    h1 { font-size: 22px; }

    /* Full-height sheet off the bottom edge, which is where a thumb is. */
    dialog.sheet {
        width: 100%;
        max-width: 100%;
        max-height: 92vh;
        margin: auto 0 0;
        border-radius: var(--radius) var(--radius) 0 0;
        border-bottom: 0;
    }
    .sheet-foot .btn { flex: 1 1 auto; justify-content: center; }
}

@media print {
    .sidebar, .topbar, .page-head-actions, .btn, .filters, .bulkbar, .pagination { display: none !important; }
    body { background: #fff; color: #000; }
    .card { border-color: #ccc; box-shadow: none; }
}

/* ------------------------------------------- GoHighLevel workspace */

.tabs {
    display: flex;
    gap: 2px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.tab {
    padding: 9px 14px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--muted);
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}

.tab:hover { color: var(--text); text-decoration: none; }
.tab.is-active { color: var(--text); border-bottom-color: var(--accent); }

.inline-form { display: inline-flex; align-items: center; gap: 7px; margin: 0; }
.inline-label { margin: 0; font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.inline-form select { width: auto; min-width: 150px; }

.pill-warn { background: var(--warning-bg); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }

.board-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }

/* The board scrolls sideways as one unit; each column scrolls vertically on
   its own so a long stage never stretches the page. */
.board {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 8px;
    align-items: flex-start;
}

.board-col {
    flex: 0 0 268px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    max-height: 70vh;
}

.board-col-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
}

.board-col-name { font-size: 12.5px; font-weight: 700; color: var(--text); letter-spacing: .01em; }

.board-count {
    margin-left: auto;
    font-size: 11.5px;
    color: var(--muted);
    background: var(--surface-3);
    border-radius: 999px;
    padding: 1px 8px;
}

.board-drop { padding: 10px; display: grid; gap: 8px; overflow-y: auto; min-height: 60px; }
.board-drop.is-over { background: color-mix(in srgb, var(--accent) 10%, transparent); }

.board-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 10px;
    cursor: grab;
    box-shadow: var(--shadow);
}

.board-card:active { cursor: grabbing; }
.board-card.is-dragging { opacity: .45; }
.board-card.is-saving { border-color: var(--accent); }
.board-card-title { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.35; }
.board-card-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.board-card-foot { display: flex; align-items: center; gap: 7px; margin-top: 8px; flex-wrap: wrap; }
.board-value { font-size: 12px; font-weight: 600; color: var(--success); }
.board-card-link { font-size: 12px; margin-left: auto; }

.badge-won { background: var(--success-bg); color: var(--success); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.badge-lost, .badge-abandoned { background: var(--danger-bg); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }

/* Conversation thread */
.thread { display: grid; gap: 10px; max-height: 380px; overflow-y: auto; margin-bottom: 16px; }

.msg { max-width: 82%; border-radius: var(--radius); padding: 9px 11px; border: 1px solid var(--border); }
.msg-in { background: var(--surface-2); justify-self: start; }
.msg-out { background: color-mix(in srgb, var(--accent) 12%, var(--surface)); justify-self: end; }
.msg-meta { display: flex; gap: 10px; font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.msg-body { font-size: 13px; line-height: 1.45; color: var(--text); overflow-wrap: anywhere; }

.send-form { border-top: 1px solid var(--border); padding-top: 14px; }

.contact-grid { align-items: start; }

.listy { display: grid; gap: 1px; margin: 0; padding: 0; list-style: none; background: var(--border); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.listy li { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--surface); }
.listy-title { font-size: 13px; font-weight: 600; color: var(--text); }

.tasklist { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.tasklist li { display: flex; align-items: flex-start; gap: 9px; font-size: 13px; }
.tasklist li.is-done { color: var(--muted); text-decoration: line-through; }

.linklike {
    background: none;
    border: 1px solid var(--border-strong);
    border-radius: 999px;
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    color: var(--muted);
    cursor: pointer;
    flex: 0 0 auto;
    padding: 0;
}

.linklike:hover:not(:disabled) { color: var(--success); border-color: var(--success); }
.linklike:disabled { cursor: default; color: var(--success); border-color: var(--success); }

.steps { padding-left: 18px; display: grid; gap: 6px; margin-bottom: 16px; font-size: 13.5px; color: var(--text-dim); }
.steps li { list-style: decimal; }

@media (max-width: 720px) {
    .board-col { flex-basis: 84vw; max-height: none; }
    .msg { max-width: 94%; }
}

/* ------------------------------------------------- lead upload */

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
    font-size: 11.5px;
    padding: 2px 7px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-dim);
}

.notes { margin: 0; padding-left: 17px; display: grid; gap: 6px; font-size: 13px; color: var(--text-dim); }
.notes li { list-style: disc; }

input[type="file"] {
    width: 100%;
    font-size: 13px;
    color: var(--text-dim);
    padding: 7px 0;
}

.card-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* ------------------------------------------- dig for contact details */

.finding {
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

.finding:last-of-type { border-bottom: 0; }
.finding .check { margin-bottom: 3px; }
.finding label { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.finding-label { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); min-width: 96px; }
.finding-value { font-size: 13.5px; font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.finding-source { font-size: 11.5px; color: var(--muted); padding-left: 23px; overflow-wrap: anywhere; }
.warn-text { color: var(--warning); }

/* A dig takes 20-40 seconds, so the button has to say something is happening. */
.btn.is-digging { opacity: .65; pointer-events: none; }

.linkish {
    background: none;
    border: 0;
    padding: 0;
    margin-top: 3px;
    font: inherit;
    font-size: 11.5px;
    color: var(--link);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.linkish:hover { text-decoration: underline; }

.spinner {
    display: inline-block;
    width: 13px;
    height: 13px;
    border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
    border-top-color: currentColor;
    border-radius: 50%;
    animation: spin .7s linear infinite;
    flex: 0 0 auto;
}

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .spinner { animation-duration: 2.4s; }
}

/* A sent email, shown as it went out — preserve the line breaks the sender
   typed without rendering it in a monospace face they never chose. */
.sent-body {
    white-space: pre-wrap;
    word-break: break-word;
    font: inherit;
    margin: 0;
    padding: 11px 13px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
}

/* A GoHighLevel thread on the lead screen. Inbound and outbound are told apart
   by weight and a border rather than by chat bubbles — this is a record to
   read, not a messaging app to live in. */
.thread { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.thread-msg { padding: 9px 12px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface-2); }
.thread-msg.is-in { border-left: 3px solid var(--accent); }
.thread-msg.is-out { opacity: .88; }
.thread-meta { display: flex; align-items: center; gap: 7px; font-size: 12px; margin-bottom: 4px; }
.thread-subject { font-weight: 600; font-size: 13px; margin-bottom: 3px; }
.thread-body { font-size: 13px; white-space: pre-wrap; word-break: break-word; color: var(--text); }

/* ---- fluorescent accents -------------------------------------------------
   A handful of places where the accent is the point, given a little bloom so
   #c8ff00 reads as lit rather than merely bright. Every one of these is inert
   on the light theme, where --accent-glow is transparent. */

.nav-item.is-active { box-shadow: inset 2px 0 0 var(--accent), inset 12px 0 22px -18px var(--accent-glow); }

.tile.accent { box-shadow: 0 0 26px -14px var(--accent-glow); }

.badge-new { box-shadow: 0 0 12px -6px var(--accent-glow); }

/* The pickaxe mark and the wordmark next to it. See --mark-filter: on dark it
   is a bloom, on light it is the same depth adjustment --accent gets. */
.brand-mark { filter: var(--mark-filter); }
