/* ============================================================
   NURTRA CRM — design system

   The palette is taken from the logo, not invented alongside it:
   #2B6968 deep teal, #9ABD97 sage and #FF4466 coral are sampled
   straight out of the artwork, and everything else is derived
   from the teal so the whole surface belongs to one family.

   The greys are the brand hue desaturated rather than neutral,
   which is what stops a mostly-grey screen looking unrelated to
   the mark in the corner. Every text token clears WCAG AA on
   white — --faint at 4.65 is the floor, and it carries real
   sentences (field hints, empty states), not decoration.

   What is deliberately NOT derived from the brand: the stage
   colours and the heat/priority language. Those carry meaning,
   they are stored per organisation in the database, and a stage
   that changes colour because the logo changed would be a lie.
   ============================================================ */
:root{
  --ink:#193D3C; --ink-soft:#21504F; --ink-line:#275E5E;
  --brand:#2B6968; --brand-d:#225251; --brand-l:#E6EDED; --brand-ll:#F4F8F7;

  /* The logo's two supporting colours. Sage carries the sidebar's active state; coral is
     reserved for the few places that must catch the eye, as it does in the mark. */
  --sage:#9ABD97; --sage-l:#EFF4EE;
  --accent:#FF4466; --accent-l:#FFECF0;

  --warm:#ef9a55; --warm-d:#d97e36; --warm-l:#fdf0e4;
  --canvas:#F5F8F8; --surface:#ffffff; --surface-2:#FAFBFB;
  --line:#E0E9E9; --line-soft:#EFF4F4;
  --text:#132F2F; --muted:#455F5E; --faint:#5C7A7A;
  --hot:#e2574f; --heat-warm:#ef9a55; --cool:#4f9fc4; --cold:#9aa8ad;
  --ok:#2e9e6b; --ok-l:#e6f5ee; --warn:#dd9a2f; --warn-l:#fbf2dd;
  --danger:#df5151; --danger-l:#fbe7e7; --info:#3e8ede; --info-l:#e8f1fc;
  --purple:#7b6bd1; --purple-l:#eee9fb;
  --radius:14px; --radius-sm:10px; --radius-lg:20px;
  --shadow-sm:0 1px 2px rgba(19,47,47,.05),0 1px 3px rgba(19,47,47,.06);
  --shadow:0 2px 8px rgba(19,47,47,.06),0 8px 24px rgba(19,47,47,.06);
  --shadow-lg:0 12px 36px rgba(19,47,47,.16);
  --sidebar-w:248px;
  --font-d:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-b:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:var(--font-b);
  background:var(--canvas);
  color:var(--text);
  font-size:14px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
h1,h2,h3,h4,h5{font-family:var(--font-d);font-weight:700;color:var(--ink);letter-spacing:-.01em;line-height:1.2}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit}
input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}
a{color:inherit;text-decoration:none}
/* A link to a record inside a table: coloured so it reads as clickable, underlined on hover. */
.row-link{color:var(--brand-d);font-weight:600}
.row-link:hover{color:var(--brand);text-decoration:underline}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:#CCDBDA;border-radius:20px;border:3px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:#B2C6C5;background-clip:content-box}

/* ---------- App shell ---------- */
.app{display:flex;min-height:100vh}
.sidebar{
  width:var(--sidebar-w);flex:0 0 var(--sidebar-w);
  background:linear-gradient(180deg,var(--ink) 0%,#102A29 100%);
  color:#C4D6D5;display:flex;flex-direction:column;
  position:fixed;top:0;left:0;bottom:0;z-index:40;
}
/* The lockup carries the name, so the brand block is the logo stacked over a label saying
   which application this is. The SVG has its own internal padding; the negative left margin
   pulls the artwork's edge to the same 20px gutter the nav items sit on. */
.brand{display:block;padding:20px 20px 14px;text-decoration:none}
/* The artwork sits inside its file with an even 15px border on all four sides (of 403 tall),
   which is about 1.5px once scaled down here. Small enough to pull back with a flat -1px
   rather than the per-edge corrections the previous logo needed. Remeasure if the files are
   ever regenerated — the old ones were padded asymmetrically. */
.brand-lockup{display:block;height:36px;width:auto;margin:-1px 0 -1px -1px}
.brand-sub{font-size:10.5px;color:#8FADAC;font-weight:500;letter-spacing:.04em;text-transform:uppercase;margin-top:8px}

.ctx-pick{margin:4px 14px 10px;padding:9px 11px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.07);border-radius:11px;cursor:pointer;transition:.15s}
.ctx-pick:hover{background:rgba(255,255,255,.08)}
.ctx-pick .lbl{font-size:9.5px;text-transform:uppercase;letter-spacing:.06em;color:#8FADAC;font-weight:600}
.ctx-pick .val{display:flex;align-items:center;justify-content:space-between;gap:6px;color:#F0F6F5;font-weight:600;font-size:13px;margin-top:2px}
.ctx-pick .val svg{width:14px;height:14px;opacity:.6}

.nav{flex:1;overflow-y:auto;padding:6px 12px 12px}
.nav-group-label{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#9CB6B5;font-weight:700;padding:14px 12px 6px}
.nav-item{
  display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:10px;
  color:#A9C2C1;font-weight:500;font-size:13.5px;cursor:pointer;transition:.13s;position:relative;margin-bottom:1px;
}
.nav-item svg{width:18px;height:18px;flex:0 0 18px;opacity:.85}
.nav-item:hover{background:rgba(255,255,255,.07);color:#F0F6F5}
.nav-item.active{background:rgba(154,189,151,.20);color:#fff;font-weight:600}
.nav-item.active svg{opacity:1;color:var(--sage)}
.nav-item.active::before{content:"";position:absolute;left:-12px;top:7px;bottom:7px;width:3px;border-radius:0 3px 3px 0;background:var(--sage)}
.nav-badge{margin-left:auto;background:var(--warm);color:#3a2710;font-size:11px;font-weight:700;min-width:19px;height:19px;border-radius:10px;display:grid;place-items:center;padding:0 5px}
.nav-badge.dot{background:var(--hot);min-width:8px;width:8px;height:8px;padding:0;border-radius:50%}

.sidebar-foot{padding:12px;border-top:1px solid rgba(255,255,255,.07)}
.user-chip{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:11px;cursor:pointer;transition:.13s}
.user-chip:hover{background:rgba(255,255,255,.06)}
.avatar{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;font-weight:700;font-size:13px;color:#fff;flex:0 0 34px}
.user-chip .nm{font-size:13px;font-weight:600;color:#F0F6F5;line-height:1.2}
.user-chip .rl{font-size:11px;color:#8FADAC}

/* ---------- Main ---------- */
.main{flex:1;margin-left:var(--sidebar-w);min-width:0;display:flex;flex-direction:column}
.topbar{
  height:64px;background:var(--surface);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:16px;padding:0 26px;position:sticky;top:0;z-index:30;
}
.page-title{font-size:19px;font-weight:700}
.page-sub{font-size:12.5px;color:var(--muted);font-weight:450;margin-top:1px}
.search{
  margin-left:auto;display:flex;align-items:center;gap:9px;background:var(--canvas);
  border:1px solid transparent;border-radius:11px;padding:9px 13px;width:260px;transition:.15s;color:var(--muted);
  position:relative;
}
.search:focus-within{background:#fff;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-l)}
.search svg{width:16px;height:16px;flex:0 0 16px}
.search input{border:none;background:none;outline:none;width:100%;font-size:13.5px;color:var(--text)}
.icon-btn{width:40px;height:40px;border-radius:11px;display:grid;place-items:center;color:var(--muted);position:relative;transition:.13s}
.icon-btn:hover{background:var(--canvas);color:var(--ink)}
.icon-btn svg{width:19px;height:19px}
.icon-btn .pip{position:absolute;top:8px;right:9px;width:8px;height:8px;border-radius:50%;background:var(--accent);border:2px solid var(--surface)}

.content{padding:24px 26px 60px;flex:1}
.view{animation:fade .25s ease}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:7px;padding:9px 15px;border-radius:11px;font-weight:600;font-size:13px;transition:.14s;white-space:nowrap;border:1px solid transparent}
.btn svg{width:16px;height:16px}
.btn-primary{background:var(--brand);color:#fff;box-shadow:0 1px 2px rgba(34,82,81,.3)}
.btn-primary:hover{background:var(--brand-d)}
.btn-ghost{background:var(--surface);color:var(--ink);border-color:var(--line)}
.btn-ghost:hover{border-color:#C6D8D7;background:var(--surface-2)}
.btn-soft{background:var(--brand-l);color:var(--brand-d)}
.btn-soft:hover{background:#D6E4E3}
.btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
.btn-warm{background:var(--warm);color:#3a2710}
.btn-warm:hover{background:var(--warm-d);color:#fff}
.btn-sm{padding:6px 11px;font-size:12px;border-radius:9px;gap:5px}
.btn-sm svg{width:14px;height:14px}
.btn-icon{padding:8px;border-radius:9px}

/* ---------- Cards ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-sm)}
.card-pad{padding:18px}
.card-head{display:flex;align-items:center;gap:10px;padding:15px 18px;border-bottom:1px solid var(--line-soft)}
.card-head h3{font-size:14.5px}
.card-head .sub{font-size:12px;color:var(--muted);font-weight:450}
.card-head .right{margin-left:auto;display:flex;align-items:center;gap:8px}
.grid{display:grid;gap:16px}

/* ---------- KPI tiles ---------- */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));gap:14px;margin-bottom:18px}
.kpi{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:16px 17px;position:relative;overflow:hidden;box-shadow:var(--shadow-sm)}
.kpi .ic{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;margin-bottom:12px}
.kpi .ic svg{width:18px;height:18px}
.kpi .v{font-family:var(--font-d);font-size:26px;font-weight:800;color:var(--ink);line-height:1;letter-spacing:-.02em}
.kpi .l{font-size:12px;color:var(--muted);font-weight:500;margin-top:5px}
.kpi .d{display:inline-flex;align-items:center;gap:3px;font-size:11.5px;font-weight:700;margin-top:8px;padding:2px 7px;border-radius:20px}
.kpi .d svg{width:12px;height:12px}
.d.up{color:var(--ok);background:var(--ok-l)}
.d.down{color:var(--danger);background:var(--danger-l)}
.d.flat{color:var(--muted);background:var(--canvas)}

/* ---------- Lead heat + priority language (SIGNATURE) ---------- */
.heat{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;padding:2px 8px 2px 6px;border-radius:20px}
.heat .dot{width:8px;height:8px;border-radius:50%}
.heat.hot{background:#fdeceb;color:#c63d35}.heat.hot .dot{background:var(--hot)}
.heat.warm{background:var(--warm-l);color:#b96a1f}.heat.warm .dot{background:var(--heat-warm)}
.heat.cool{background:#e8f3f8;color:#2f7ea3}.heat.cool .dot{background:var(--cool)}
.heat.cold{background:#eef1f2;color:#6c7c81}.heat.cold .dot{background:var(--cold)}
.score-ring{--p:0;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;flex:0 0 38px;
  background:conic-gradient(var(--ring-c) calc(var(--p)*1%),var(--line-soft) 0)}
.score-ring .inner{width:30px;height:30px;border-radius:50%;background:var(--surface);display:grid;place-items:center;font-weight:800;font-size:12px;font-family:var(--font-d);color:var(--ink)}

.urg{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:2px 8px;border-radius:7px}
.urg .sq{width:7px;height:7px;border-radius:2px}
.urg.immediate{background:#fdeceb;color:#c63d35}.urg.immediate .sq{background:var(--hot)}
.urg.d30{background:#fdf0e4;color:#bf6a1c}.urg.d30 .sq{background:#ef7f43}
.urg.d60{background:var(--warn-l);color:#9c6f17}.urg.d60 .sq{background:var(--warn)}
.urg.d90{background:var(--brand-l);color:var(--brand-d)}.urg.d90 .sq{background:var(--brand)}
.urg.d180{background:#e8f1fc;color:#2f6fb5}.urg.d180 .sq{background:var(--info)}
.urg.future{background:#eef1f2;color:#6c7c81}.urg.future .sq{background:var(--cold)}

.tag{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:600;padding:2px 8px;border-radius:7px;background:var(--canvas);color:var(--muted)}
.tag.poa1{background:#fdeceb;color:#c63d35}
.tag.poa2{background:var(--warn-l);color:#9c6f17}
.tag.poa3{background:var(--brand-l);color:var(--brand-d)}
.tag.alert{background:var(--purple-l);color:#5a48b0}
.tag svg{width:12px;height:12px}

.pill{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;background:var(--canvas);color:var(--muted)}
.pill .dot{width:7px;height:7px;border-radius:50%}
/* An unsized svg falls back to the browser's replaced-element default and dwarfs the chip —
   every other icon container in this sheet sizes its svg, and .pill is no exception. */
.pill svg{width:12px;height:12px;flex:0 0 12px}

/* status colours */
.st-new{--c:#3e8ede;--cl:#e8f1fc}.st-contacted{--c:#7b6bd1;--cl:#eee9fb}
.st-pre_tour_wl{--c:#d98a2b;--cl:#fbf2dd}.st-tour_scheduled{--c:#168a6f;--cl:#e7f4ef}
.st-tour_completed{--c:#1fae8c;--cl:#e2f6f0}.st-offered{--c:#ef9a55;--cl:#fdf0e4}
.st-enrolled{--c:#2e9e6b;--cl:#e6f5ee}.st-lost{--c:#9aa8ad;--cl:#eef1f2}
.st-waitlisted{--c:#d98a2b;--cl:#fbf2dd}
.status-pill{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;padding:3px 10px;border-radius:20px;background:var(--cl);color:var(--c)}
.status-pill .dot{width:7px;height:7px;border-radius:50%;background:var(--c)}

/* ---------- Pipeline (kanban) ---------- */
.pipe-funnel{display:flex;gap:7px;margin-bottom:20px;overflow-x:auto;padding-bottom:4px}
.funnel-step{flex:1;min-width:120px;background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:13px 14px;cursor:pointer;transition:.15s;position:relative}
.funnel-step:hover{border-color:var(--c);box-shadow:var(--shadow-sm);transform:translateY(-1px)}
.funnel-step.sel{border-color:var(--c);background:var(--cl)}
.funnel-step .ft{display:flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;color:var(--muted)}
.funnel-step .ft .dt{width:8px;height:8px;border-radius:50%;background:var(--c)}
.funnel-step .fn{font-family:var(--font-d);font-size:23px;font-weight:800;color:var(--ink);margin-top:7px;line-height:1}
.funnel-step .fb{height:3px;border-radius:3px;background:var(--c);margin-top:10px;opacity:.85}

/* The pipeline board's own styles live at the end of this file, with the drop affordances. */

/* ---------- Tables ---------- */
.tbl{width:100%;border-collapse:collapse}
.tbl th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--faint);font-weight:700;padding:11px 14px;border-bottom:1px solid var(--line);white-space:nowrap}
.tbl td{padding:12px 14px;border-bottom:1px solid var(--line-soft);font-size:13px;vertical-align:middle}
.tbl tr:last-child td{border-bottom:none}
.tbl tbody tr{transition:.1s}
.tbl tbody tr.clk{cursor:pointer}
.tbl tbody tr.clk:hover{background:var(--brand-ll)}
.cell-name{display:flex;align-items:center;gap:10px}
.cell-name .nm{font-weight:600;color:var(--ink)}
.cell-name .sub{font-size:11.5px;color:var(--muted)}

/* ---------- Lead detail drawer/view ---------- */
.detail-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}
.detail-id{width:54px;height:54px;border-radius:15px;display:grid;place-items:center;color:#fff;font-weight:800;font-size:20px;font-family:var(--font-d);flex:0 0 54px}
.detail-h-main{flex:1;min-width:200px}
.detail-h-main h2{font-size:22px}
.detail-h-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:9px}
.detail-actions{display:flex;gap:8px;flex-wrap:wrap}
.det-grid{display:grid;grid-template-columns:1.6fr 1fr;gap:18px;margin-top:20px;align-items:start}
.fld{margin-bottom:14px}
.fld .k{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--faint);font-weight:700;margin-bottom:3px}
.fld .v{font-size:13.5px;color:var(--text);font-weight:500}
.fld-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}

.timeline{position:relative;padding-left:6px}
.tl-item{position:relative;padding:0 0 18px 30px}
.tl-item::before{content:"";position:absolute;left:9px;top:22px;bottom:-4px;width:2px;background:var(--line)}
.tl-item:last-child::before{display:none}
.tl-dot{position:absolute;left:0;top:2px;width:20px;height:20px;border-radius:50%;display:grid;place-items:center;background:var(--surface);border:2px solid var(--line)}
.tl-dot svg{width:11px;height:11px}
.tl-dot.email{border-color:var(--info);color:var(--info)}
.tl-dot.sms{border-color:var(--ok);color:var(--ok)}
.tl-dot.call{border-color:var(--purple);color:var(--purple)}
.tl-dot.tour{border-color:var(--brand);color:var(--brand)}
.tl-dot.offer{border-color:var(--warm);color:var(--warm-d)}
.tl-dot.status{border-color:var(--ink-soft);color:var(--ink-soft)}
.tl-dot.note{border-color:var(--cold);color:var(--cold)}
.tl-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tl-title{font-weight:600;font-size:13px;color:var(--ink)}
.tl-time{font-size:11.5px;color:var(--faint);margin-left:auto}
/* pre-wrap because a pasted email is the first body with meaningful line breaks — without it a
   forty-line thread collapses into one paragraph. Clamped because the same thread would otherwise
   push every call, stage change and sent email below the fold. */
.tl-body{font-size:12.5px;color:var(--muted);margin-top:3px;white-space:pre-wrap;overflow-wrap:anywhere}
.tl-body.clamped{display:-webkit-box;-webkit-line-clamp:8;-webkit-box-orient:vertical;overflow:hidden}
.tl-more{font-size:11.5px;color:var(--brand-d);font-weight:600;margin-top:4px}

/* A transcription is not one of ours. Dashed and faint, so it reads as different before a word
   of it is read. */
.tl-dot.transcribed{border-style:dashed;color:var(--faint);background:var(--surface)}
.tl-note{font-size:11px;color:var(--faint);line-height:1.5;margin-top:4px}
.tl-engage{display:inline-flex;gap:8px;margin-top:6px}
.eng{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:600;color:var(--muted)}
.eng svg{width:13px;height:13px}
.eng.yes{color:var(--ok)}.eng.no{color:var(--faint)}

.score-bd{display:flex;flex-direction:column;gap:11px}
.score-line{display:flex;align-items:center;gap:10px}
.score-line .sl-lbl{font-size:12px;color:var(--muted);font-weight:500;width:120px;flex:0 0 120px}
.score-line .sl-bar{flex:1;height:7px;border-radius:7px;background:var(--line-soft);overflow:hidden}
.score-line .sl-bar i{display:block;height:100%;border-radius:7px;background:var(--brand)}
.score-line .sl-v{font-size:12px;font-weight:700;color:var(--ink);width:34px;text-align:right}

.subtabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:4px;overflow-x:auto}
.subtab{padding:10px 14px;font-size:13px;font-weight:600;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;white-space:nowrap;transition:.13s}
.subtab:hover{color:var(--ink)}
.subtab.active{color:var(--brand-d);border-bottom-color:var(--brand)}

/* child cards */
.kid{display:flex;align-items:center;gap:12px;padding:12px;border:1px solid var(--line);border-radius:12px;margin-bottom:10px}
.kid .ka{width:40px;height:40px;border-radius:11px;display:grid;place-items:center;font-weight:700;color:#fff;flex:0 0 40px;font-size:15px}
.kid .kn{font-weight:700;color:var(--ink);font-size:14px}
.kid .km{font-size:12px;color:var(--muted)}
.kid .kr{margin-left:auto;text-align:right}

/* docs */
.doc-row{display:flex;align-items:center;gap:11px;padding:10px 12px;border:1px solid var(--line);border-radius:11px;margin-bottom:8px}
.doc-row .di{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:0 0 34px}
.doc-row .di svg{width:17px;height:17px}

/* ---------- Journey builder ---------- */
.journey-pick{display:flex;gap:9px;flex-wrap:wrap;margin-bottom:20px}
.jchip{padding:10px 15px;border:1px solid var(--line);border-radius:11px;background:var(--surface);font-weight:600;font-size:13px;cursor:pointer;transition:.14s;display:flex;align-items:center;gap:8px;color:var(--muted)}
.jchip:hover{border-color:var(--brand);color:var(--ink)}
.jchip.active{background:var(--ink);color:#fff;border-color:var(--ink)}
.jchip .jc-dot{width:8px;height:8px;border-radius:50%}
.journey-stage{margin-bottom:8px}
.jstage-head{display:inline-flex;align-items:center;gap:9px;background:var(--ink);color:#fff;padding:7px 15px;border-radius:20px;font-weight:700;font-size:13px;font-family:var(--font-d);margin-bottom:4px}
.jstage-head .jd{font-size:11px;font-weight:600;opacity:.7;background:rgba(255,255,255,.15);padding:1px 8px;border-radius:20px}
.jrail{border-left:2px dashed var(--line);margin-left:14px;padding:10px 0 18px 26px;position:relative}
.jnode{background:var(--surface);border:1px solid var(--line);border-radius:13px;padding:13px 15px;margin-bottom:11px;position:relative;box-shadow:var(--shadow-sm)}
.jnode::before{content:"";position:absolute;left:-33px;top:18px;width:9px;height:9px;border-radius:50%;background:var(--brand);border:2px solid var(--surface);box-shadow:0 0 0 2px var(--brand-l)}
.jnode-head{display:flex;align-items:center;gap:9px;margin-bottom:4px}
.jnode-ic{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;flex:0 0 28px}
.jnode-ic svg{width:15px;height:15px}
.jnode-t{font-weight:700;font-size:13px;color:var(--ink)}
.jnode-body{font-size:12.5px;color:var(--muted);line-height:1.55}
.jbranch{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px}
.jbr{border:1px solid var(--line);border-radius:11px;padding:11px;background:var(--surface-2)}
.jbr.yes{border-left:3px solid var(--ok)}
.jbr.no{border-left:3px solid var(--warm)}
.jbr .jbr-h{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;margin-bottom:5px;display:flex;align-items:center;gap:5px}
.jbr.yes .jbr-h{color:var(--ok)}.jbr.no .jbr-h{color:var(--warm-d)}
.jbr .jbr-b{font-size:12px;color:var(--muted);line-height:1.5}
.jnode-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}

/* ---------- Misc ---------- */
.empty{text-align:center;padding:50px 20px;color:var(--muted)}
.empty svg{width:46px;height:46px;color:var(--line);margin-bottom:12px}
.empty h3{color:var(--ink);font-size:15px;margin-bottom:5px}
.bar-mini{height:8px;border-radius:8px;background:var(--line-soft);overflow:hidden;display:flex}
.bar-mini i{display:block;height:100%}
.legend{display:flex;flex-wrap:wrap;gap:14px;font-size:11.5px;color:var(--muted);font-weight:500}
.legend .li{display:flex;align-items:center;gap:5px}
.legend .li .sw{width:10px;height:10px;border-radius:3px}
.list-row{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--line-soft)}
.list-row:last-child{border-bottom:none}

.task-row{display:flex;align-items:center;gap:11px;padding:11px 0;border-bottom:1px solid var(--line-soft)}
.task-row:last-child{border-bottom:none}
.task-check{width:19px;height:19px;border:2px solid var(--line);border-radius:6px;flex:0 0 19px;cursor:pointer;transition:.13s;display:grid;place-items:center}
.task-check:hover{border-color:var(--brand)}
.task-check.done{background:var(--brand);border-color:var(--brand)}
.task-check svg{width:12px;height:12px;color:#fff;opacity:0}
.task-check.done svg{opacity:1}
.task-row .tt{font-size:13px;font-weight:600;color:var(--ink)}
.task-row.done .tt{text-decoration:line-through;color:var(--faint)}
.task-row .tm{font-size:11.5px;color:var(--muted)}
.due{font-size:11px;font-weight:700;padding:2px 8px;border-radius:7px;margin-left:auto;white-space:nowrap}
.due.over{background:var(--danger-l);color:var(--danger)}
.due.today{background:var(--warm-l);color:var(--warm-d)}
.due.soon{background:var(--canvas);color:var(--muted)}

.ai-card{background:linear-gradient(135deg,#163a44 0%,#0f2a31 100%);border-radius:var(--radius);padding:18px;color:#d7e6e7;position:relative;overflow:hidden}
.ai-card::after{content:"";position:absolute;right:-30px;top:-30px;width:140px;height:140px;border-radius:50%;background:radial-gradient(circle,rgba(47,198,160,.25),transparent 70%)}
.ai-head{display:flex;align-items:center;gap:9px;margin-bottom:14px;position:relative}
.ai-spark{width:30px;height:30px;border-radius:9px;background:rgba(47,198,160,.18);display:grid;place-items:center}
.ai-spark svg{width:17px;height:17px;color:#3fdcb4}
.ai-head .at{font-family:var(--font-d);font-weight:700;color:#fff;font-size:14.5px}
.ai-head .as{font-size:11px;color:#7fb3ab}
.ai-insight{display:flex;gap:11px;padding:11px 0;border-top:1px solid rgba(255,255,255,.08);position:relative}
.ai-insight .aii{width:26px;height:26px;border-radius:8px;flex:0 0 26px;display:grid;place-items:center;font-size:13px}
.ai-insight .ait{font-size:12.5px;font-weight:600;color:#F0F6F5;line-height:1.4}
.ai-insight .aib{font-size:11.5px;color:#9cc4bd;margin-top:2px;line-height:1.45}
.ai-insight .aic{margin-top:7px;display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:700;color:#3fdcb4;cursor:pointer}
.ai-insight .aic svg{width:12px;height:12px}

.donut{width:130px;height:130px;border-radius:50%;flex:0 0 130px;position:relative;display:grid;place-items:center}
.donut .dh{width:84px;height:84px;border-radius:50%;background:var(--surface);display:grid;place-items:center;text-align:center}
.donut .dh .dv{font-family:var(--font-d);font-weight:800;font-size:20px;color:var(--ink);line-height:1}
.donut .dh .dl{font-size:10px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.04em}

.match-row{display:flex;align-items:center;gap:12px;padding:12px;border:1px solid var(--line);border-radius:12px;margin-bottom:9px;transition:.14s;background:var(--surface)}
.match-row:hover{border-color:var(--brand);box-shadow:var(--shadow-sm)}
.match-meta{flex:1;min-width:0}
/* An Icon inside a row has no intrinsic size, so without this it stretches to fill the flex line. */
.match-row svg{flex:0 0 16px;width:16px;height:16px;color:var(--faint)}

.seg{display:inline-flex;background:var(--canvas);border-radius:10px;padding:3px;gap:2px}
.seg button{padding:6px 13px;border-radius:8px;font-size:12.5px;font-weight:600;color:var(--muted);transition:.13s}
.seg button.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sm)}

/* Page-level actions, right-aligned above the content. */
.view-bar{display:flex;justify-content:flex-end;align-items:center;gap:9px;margin-bottom:14px}

/* "New" action menu. The sheet sits under the popup and over everything else, so an outside
   click lands on it and closes the menu instead of on whatever it was covering. */
.menu-wrap{position:relative;display:inline-flex}
.menu-caret{display:inline-flex;margin:0 -3px 0 1px;transition:transform .15s}
.menu-caret svg{width:14px;height:14px}
.menu-caret.up{transform:rotate(180deg)}
.menu-sheet{position:fixed;inset:0;z-index:40}
.menu{position:absolute;top:calc(100% + 6px);right:0;z-index:41;min-width:252px;background:var(--surface);border:1px solid var(--line);border-radius:13px;box-shadow:var(--shadow-lg);padding:5px;animation:menuIn .13s ease}
@keyframes menuIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.menu-item{display:flex;align-items:flex-start;gap:11px;width:100%;text-align:left;padding:9px 10px;border-radius:9px;transition:.12s;background:none}
.menu-item:hover:not(:disabled){background:var(--brand-ll)}
.menu-item:disabled{opacity:.55;cursor:not-allowed}
.menu-item .mi-ico{flex:0 0 30px;height:30px;border-radius:9px;background:var(--brand-l);color:var(--brand-d);display:grid;place-items:center}
.menu-item .mi-ico svg{width:15px;height:15px}
.menu-item .mi-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
.menu-item .mi-l{font-size:13px;font-weight:650;color:var(--ink)}
.menu-item .mi-d{font-size:11.5px;color:var(--muted);line-height:1.35}

.calbar{display:flex;align-items:center;gap:8px;height:30px;border-radius:8px;background:var(--brand-l);color:var(--brand-d);font-size:11.5px;font-weight:600;padding:0 10px;cursor:pointer;border-left:3px solid var(--brand)}
.calbar.warm{background:var(--warm-l);color:var(--warm-d);border-color:var(--warm)}
.calbar.info{background:var(--info-l);color:#2f6fb5;border-color:var(--info)}
.cal-grid{display:grid;grid-template-columns:64px repeat(5,1fr);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.cal-grid .ch{padding:10px;font-size:12px;font-weight:700;text-align:center;border-bottom:1px solid var(--line);border-right:1px solid var(--line-soft);background:var(--surface-2)}
.cal-grid .ct{padding:8px 6px;font-size:11px;color:var(--faint);text-align:right;border-right:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);font-weight:600}
.cal-grid .cc{border-right:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);padding:4px;min-height:46px;display:flex;flex-direction:column;gap:3px}

/* progress bar (offer countdown) */
.prog{height:9px;border-radius:9px;background:var(--line-soft);overflow:hidden}
.prog i{display:block;height:100%;border-radius:9px;transition:width .4s}

.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(80px);background:var(--ink);color:#fff;padding:13px 20px;border-radius:12px;font-weight:600;font-size:13.5px;display:flex;align-items:center;gap:10px;box-shadow:var(--shadow-lg);z-index:100;opacity:0;transition:.3s}
.toast.show{transform:translateX(-50%) translateY(0);opacity:1}
.toast svg{width:18px;height:18px;color:#3fdcb4}

/* drawer for log/compose */
.drawer-bg{position:fixed;inset:0;background:rgba(20,40,46,.45);z-index:60;opacity:0;pointer-events:none;transition:.25s}
.drawer-bg.show{opacity:1;pointer-events:auto}
/* Closed drawers sit just off-screen at translateX(100%) — several of them, on every page.
   The shadow lives on .show only, and visibility goes with it, or every parked drawer bleeds
   its box-shadow back across the viewport edge as a permanent band down the right side. The
   visibility transition delays hiding until the slide-out finishes. */
.drawer{position:fixed;top:0;right:0;bottom:0;width:440px;max-width:92vw;background:var(--surface);z-index:61;transform:translateX(100%);visibility:hidden;transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .3s;display:flex;flex-direction:column}
.drawer.drawer-wide{width:640px}
.drawer.show{transform:none;visibility:visible;box-shadow:var(--shadow-lg);transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s}
.drawer-head{padding:18px 20px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.drawer-body{flex:1;overflow-y:auto;padding:20px}
.drawer-foot{padding:16px 20px;border-top:1px solid var(--line);display:flex;gap:10px}
.inp{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface);transition:.14s;font-size:13.5px}
.inp:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-l)}
textarea.inp{resize:vertical;min-height:90px}
.lbl-f{font-size:12px;font-weight:700;color:var(--ink);margin-bottom:6px;display:block}
.fgroup{margin-bottom:16px}
.opt-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.opt{border:1px solid var(--line);border-radius:10px;padding:11px;cursor:pointer;transition:.13s;text-align:center;font-weight:600;font-size:12.5px;color:var(--muted)}
.opt:hover{border-color:var(--brand)}
.opt.sel{border-color:var(--brand);background:var(--brand-l);color:var(--brand-d)}

.coverage{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px}
.cov-item{display:flex;gap:10px;padding:13px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.cov-item .ci{width:30px;height:30px;border-radius:9px;background:var(--brand-l);color:var(--brand-d);display:grid;place-items:center;flex:0 0 30px}
.cov-item .ci svg{width:16px;height:16px}
.cov-item .ct{font-weight:700;font-size:13px;color:var(--ink)}
.cov-item .cd{font-size:11.5px;color:var(--muted);margin-top:2px;line-height:1.4}

.note-box{background:var(--info-l);border:1px solid #cfe2f7;border-radius:12px;padding:13px 15px;display:flex;gap:11px;font-size:12.5px;color:#2f6fb5;line-height:1.5}
.note-box svg{width:18px;height:18px;flex:0 0 18px;margin-top:1px}
.note-box.warm{background:var(--warm-l);border-color:#f4dcc2;color:var(--warm-d)}
.note-box.brand{background:var(--brand-l);border-color:#cce8de;color:var(--brand-d)}

.mobile-only{display:none}
.hamburger{display:none}
@media(max-width:1000px){
  .det-grid{grid-template-columns:1fr}
  .sidebar{transform:translateX(-100%);transition:.25s}
  .sidebar.open{transform:none}
  .main{margin-left:0}
  .hamburger{display:grid}
  .search{display:none}
}
@media(max-width:600px){
  .content{padding:16px 14px 50px}
  .topbar{padding:0 14px}
  .fld-row,.opt-grid,.jbranch{grid-template-columns:1fr}
  .kpi .v{font-size:22px}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ============================================================
   Blazor additions
   The rules above are the prototype's design system, lifted verbatim so the two can be
   compared side by side. Everything below exists only because this is a Blazor Server app.
   ============================================================ */

/* Blazor's built-in error strip, restyled to match the palette. */
#blazor-error-ui {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 200;
  background: var(--danger-l); color: #8c2f2f; border-top: 1px solid #f0c3c3;
  padding: 12px 20px; font-size: 13px; font-weight: 600;
  display: none; align-items: center; gap: 12px;
}
#blazor-error-ui .dismiss { margin-left: auto; cursor: pointer; font-size: 18px; line-height: 1; }

/* Anchors used as nav items and table rows must not inherit link colouring. */
.nav-item, .subtab { user-select: none; }
.nav-item:disabled, .nav-item.disabled { opacity: .45; cursor: default; }
.nav-item.disabled:hover { background: none; color: #A9C2C1; }

/* The router's FocusOnNavigate moves focus to the page heading on every navigation, so screen
   readers announce the new page instead of leaving the user stranded where the last one was.
   Being focusable means the heading is given tabindex="-1", and the browser then draws its
   default focus ring around it — visible to everyone, useful to no one.

   Suppressing the ring costs nothing in accessibility: tabindex="-1" keeps the heading out of
   the tab order, so a keyboard user never lands on it, and assistive tech announces on focus
   rather than on the outline. Interactive elements keep their rings, below. */
[tabindex="-1"]:focus { outline: none; }

/* The prototype fakes rows with JS click handlers; here they are real buttons/links. */
.tbl tbody tr.clk:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.row-link { display: contents; color: inherit; }

/* .inp is sized for drawer form fields (width:100%). In a wrapping flex toolbar that makes
   every control claim its own row, so toolbar controls opt out and size to their content. */
.inp-inline { width: auto; }

/* Form controls the prototype renders as divs but which must be real inputs here. */
.opt-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.opt-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.opt-grid.cols-5 { grid-template-columns: repeat(5, 1fr); }

/* Groups a long capture form into the sections the prototype uses — Guardian, Child, Enquiry —
   so it reads as three short asks rather than one intimidating column of fields. */
.section-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); font-weight: 700; margin: 4px 0 10px;
}

/* Explanatory line under a field. Says why the field exists or what happens to it — the
   prototype leans on these heavily and they carry real rules, not decoration. */
.field-hint { font-size: 11.5px; color: var(--muted); margin-top: 6px; line-height: 1.5; }
.opt { background: var(--surface); font: inherit; font-weight: 600; font-size: 12.5px; width: 100%; }
.opt:disabled { opacity: .5; cursor: not-allowed; }
fieldset { border: none; padding: 0; margin: 0; min-width: 0; }
.validation-message { color: var(--danger); font-size: 12px; font-weight: 600; margin-top: 5px; display: block; }

/* Drawer close button. */
.drawer-head .drawer-close { margin-left: auto; }

/* Loading state for views waiting on Mongo. */
.loading { display: flex; align-items: center; gap: 10px; padding: 40px; color: var(--muted); font-size: 13.5px; }
.spinner {
  width: 18px; height: 18px; border-radius: 50%; flex: 0 0 18px;
  border: 2px solid var(--line); border-top-color: var(--brand);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Startup / connection failure panel. */
.fatal { max-width: 640px; margin: 60px auto; }
.fatal pre {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; font-size: 12px; overflow-x: auto; margin-top: 10px; white-space: pre-wrap;
}

/* Chrome-free shell for sign-in and invitation acceptance. */
.auth-shell {
  min-height: 100vh; display: grid; place-items: center; padding: 24px;
  background: linear-gradient(160deg, var(--canvas) 0%, #E4EEEC 100%);
}
.auth-card {
  width: 100%; max-width: 420px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 30px 30px 34px;
}
/* Same stacked arrangement as the sidebar, in full colour on the white card. */
.auth-brand { margin-bottom: 24px; }
.auth-brand .brand-lockup { height: 38px; margin: -1px 0 -1px -1px; }
.auth-brand-sub { font-size: 10.5px; color: var(--faint); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; margin-top: 8px; }
.auth-title { font-size: 21px; margin-bottom: 5px; }
.auth-sub { font-size: 13px; color: var(--muted); line-height: 1.55; margin-bottom: 20px; }
.auth-card .fgroup { margin-bottom: 15px; }
.auth-foot { font-size: 12px; color: var(--faint); line-height: 1.55; margin-top: 18px; text-align: center; }

/* Sign-out control inside the sidebar's user chip. */
.user-chip .signout {
  width: 30px; height: 30px; border-radius: 8px; margin-left: auto; flex: 0 0 30px;
  color: #8FADAC;
}
.user-chip .signout:hover { background: rgba(255, 255, 255, .1); color: #F0F6F5; }
.user-chip .signout svg { width: 15px; height: 15px; }

/* Which centres the signed-in person can see. Two colleagues see different numbers on the
   same page, so the reason is stated rather than left to look like missing data. */
.scope-note {
  font-size: 10.5px; color: #9CB6B5; padding: 6px 10px 2px; letter-spacing: .02em;
}

/* ---------- Pipeline settings ---------- */

/* Up/down controls sit in their own narrow column so the step name still starts on the same
   left edge whether or not a row can be moved. */
.stage-order { display: flex; flex-direction: column; gap: 2px; flex: 0 0 30px; margin-right: 4px; }
.drag-grip { cursor: grab; color: var(--faint); }
.drag-grip:hover { color: var(--muted); }
.drag-grip:active { cursor: grabbing; }
/* The row in flight: dimmed where it currently sits, so the live reshuffle reads as "this one
   is moving" rather than the list mysteriously rearranging itself. */
.list-row.dragging { opacity: .45; background: var(--brand-ll); }
.icon-btn.btn-xs { width: 26px; height: 26px; border-radius: 7px; }
.icon-btn.btn-xs svg { width: 14px; height: 14px; }
.icon-btn:disabled { opacity: .3; cursor: default; }
.icon-btn:disabled:hover { background: none; color: var(--muted); }

/* A step taken out of use. Dimmed rather than hidden: families are still standing in it and
   the manager needs to see that it exists to put it back. */
.list-row.retired { opacity: .62; }

/* Fallback pill colour for a step an organisation invented — the palette classes only cover
   the eight built-ins, so custom steps carry their colour inline over this. */
.status-pill.st-custom { background: var(--surface-2); color: var(--muted); }

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

/* Two columns on a desktop, one when there is not room. The left is the working column
   (tasks, sources) and gets the extra width. */
.dash-grid{display:grid;grid-template-columns:1.5fr 1fr;gap:18px;align-items:start}
@media (max-width:1180px){ .dash-grid{grid-template-columns:1fr} }

/* The caveat under a KPI whose number stands in for something not yet modelled. Small and
   quiet, but present — the alternative is a figure that quietly means something else. */
.kpi-note{
  font-size:10.5px;color:var(--faint);margin-top:7px;line-height:1.4;
  border-top:1px solid var(--line-soft);padding-top:6px;
}

/* Funnel steps are buttons here rather than divs, so reset the button chrome. */
.funnel-step{font-family:inherit;text-align:left;width:100%;display:block}

/* A panel whose data does not exist yet. Dashed and desaturated on purpose: it must not be
   mistaken at a glance for a card showing real figures. */
.card.pending{background:var(--surface-2);border-style:dashed;box-shadow:none}
.card.pending .card-head{border-bottom-color:var(--line-soft)}
.card.pending .card-head h3{color:var(--muted)}
.pending-pill{background:var(--canvas);color:var(--faint);font-size:10.5px;font-weight:700;letter-spacing:.03em}
.pending-body{display:flex;flex-direction:column;gap:11px}
.pending-what{font-size:12.5px;color:var(--muted);line-height:1.6}
.pending-needs{
  display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--faint);
  border-top:1px dashed var(--line);padding-top:10px;
}
.pending-needs svg{width:14px;height:14px;flex:0 0 14px}
.pending-needs b{color:var(--muted);font-weight:600}

/* ---------- Pipeline board ---------- */

.kanban{display:flex;gap:14px;overflow-x:auto;padding:2px 2px 14px;align-items:flex-start}
.kcol{
  flex:0 0 288px;width:288px;background-color:var(--surface-2);
  border:1px solid var(--line);border-radius:14px;
  display:flex;flex-direction:column;max-height:calc(100vh - 250px);
  transition:border-color .13s,background-color .13s,box-shadow .13s;
}
.kcol-head{display:flex;align-items:center;gap:8px;padding:13px 14px 11px;position:sticky;top:0}
.kcol-head .dt{width:9px;height:9px;border-radius:50%;background:var(--c)}
.kcol-head .nm{font-weight:700;font-size:13px;color:var(--ink)}
.kcol-head .ct{
  margin-left:auto;font-size:12px;font-weight:700;color:var(--muted);
  background:var(--surface);border:1px solid var(--line);padding:1px 9px;border-radius:20px;
}
.kcol-body{overflow-y:auto;padding:2px 10px 12px;display:flex;flex-direction:column;gap:9px;min-height:70px}
.kcol-empty{padding:18px 6px;text-align:center;color:var(--faint);font-size:12px}

/* --- Drop affordances ---

   A card in flight sits under the pointer and hides it, so "can I drop here?" has to be
   answered by the columns themselves rather than by the cursor. Three signals, escalating:

   1. Every column that can take the card gets a dashed outline the moment a drag begins, so
      the whole board reads as available at a glance.
   2. The column under the pointer fills in, lifts, and shows a landing strip naming the stage.
   3. The column the card came from stays plain — dropping it back is a no-op, and offering it
      as a target would be a lie. */
.kanban.dragging .kcol{border-style:dashed;border-color:var(--line)}

/* The in-flight dock: fixed drop pads for every stage, because the board scrolls sideways and
   a browser will not auto-scroll it mid-drag — without this, the far columns are unreachable. */
.kdock{position:fixed;left:50%;transform:translateX(-50%);bottom:18px;z-index:55;
  display:flex;gap:7px;align-items:center;flex-wrap:wrap;justify-content:center;
  background:var(--surface);border:1px solid var(--line);border-radius:14px;
  box-shadow:var(--shadow-lg);padding:10px 14px;max-width:min(94vw,1100px);animation:menuIn .13s ease}
.kdock-label{font-size:11.5px;font-weight:650;color:var(--muted);margin-right:4px;white-space:nowrap}
.kdock-pad{--c:var(--muted);--cl:var(--canvas);font-size:12px;font-weight:650;color:var(--c);
  background:var(--cl);border:1.5px dashed var(--c);border-radius:999px;padding:7px 12px;
  white-space:nowrap;transition:.12s}
.kdock-pad.over{border-style:solid;transform:scale(1.06)}

/* The stage-entry remove control: present but quiet until the row is hovered, because the
   timeline is read far more often than it is corrected. */
.tl-remove{opacity:.4;transition:opacity .12s}
.tl-item:hover .tl-remove,.tl-remove:focus-visible{opacity:1}
/* Available-but-not-hovered. Excluding .drop-over as well as .drop-source makes the three
   states mutually exclusive in the selectors themselves, so they cannot fight over a property
   and leave the outcome to source order. */
.kanban.dragging .kcol:not(.drop-source):not(.drop-over){
  border-color:color-mix(in srgb, var(--c, var(--brand)) 45%, var(--line));
  background-color:var(--surface);
}
/* Scoped under .kanban.dragging so it out-specifies the "any column will do" rule above —
   otherwise the plain white of that rule wins and the hovered column loses its tint, which is
   the strongest signal of the three. */
.kanban.dragging .kcol.drop-over{
  border-style:solid;
  border-color:var(--c,var(--brand));
  background-color:var(--cl,var(--brand-l));
  box-shadow:0 0 0 3px color-mix(in srgb, var(--c, var(--brand)) 18%, transparent), var(--shadow);
  transform:translateY(-1px);
}
.kcol.drop-source{opacity:.55}

/* Where the card would land. Sits at the top of the column because that is where a dropped
   card goes once the board re-sorts by score. */
.drop-strip{
  display:flex;align-items:center;justify-content:center;gap:6px;
  border:1.5px dashed var(--c,var(--brand));border-radius:11px;
  padding:13px 10px;font-size:11.5px;font-weight:700;
  color:var(--c,var(--brand-d));background:var(--surface);
  animation:drop-pulse 1.1s ease-in-out infinite;
}
.drop-strip svg{width:14px;height:14px}
@keyframes drop-pulse{50%{opacity:.62}}

@media (prefers-reduced-motion:reduce){ .drop-strip{animation:none} }

/* --- Cards --- */
.lead-card{
  background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:12px;
  cursor:grab;transition:box-shadow .14s,transform .14s,opacity .14s;border-left:3px solid var(--c);
}
.lead-card:hover{box-shadow:var(--shadow);transform:translateY(-1px)}
.lead-card:active{cursor:grabbing}
.lead-card:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.lead-card.dragging{opacity:.4;box-shadow:none;transform:none}
.lead-card .lc-top{display:flex;align-items:flex-start;gap:9px}
.lead-card .lc-nm{font-weight:700;font-size:13.5px;color:var(--ink);line-height:1.25}
.lead-card .lc-meta{font-size:11.5px;color:var(--muted);margin-top:2px}
.lead-card .lc-tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:10px}
.lead-card .lc-foot{
  display:flex;align-items:center;gap:8px;margin-top:11px;padding-top:10px;
  border-top:1px solid var(--line-soft);
}
.lead-card .lc-foot .av{width:22px;height:22px;border-radius:50%;font-size:9.5px;display:grid;place-items:center;color:#fff;font-weight:700;flex:0 0 22px}
.lead-card .lc-foot .ch{font-size:11px;color:var(--muted);font-weight:500}
.lead-card .lc-foot .nxt{margin-left:auto;font-size:11px;font-weight:600;display:flex;align-items:center;gap:4px}

/* The grab handle. Faint until hover, so the card is not shouting at rest but the affordance
   is there the moment somebody reaches for it. */
.lc-grip{color:var(--line);flex:0 0 auto;display:inline-flex;transition:color .13s}
.lc-grip svg{width:15px;height:15px}
.lead-card:hover .lc-grip{color:var(--faint)}

.board-hint{
  display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--faint);
  padding:0 4px;
}
.board-hint svg{width:14px;height:14px}
.board-note{margin-top:6px;font-size:11.5px;color:var(--faint);line-height:1.6}

.opt-grid.cols-1{grid-template-columns:1fr}

/* A row for a message that never reached the family. Tinted rather than merely pilled: on a
   list of mostly-fine correspondence, the ones that failed are the only rows worth scanning
   for, and they should be findable without reading the status column. */
.tbl tbody tr.row-failed { background: var(--danger-l); }
.tbl tbody tr.row-failed:hover { background: #f8dcdc; }

/* ---------- Header tools ---------- */

/* The three buttons as one group, so they sit 2px apart rather than at the topbar's 16px gap.
   .search keeps its own margin-left:auto and drags this along with it. */
.topbar-actions{display:flex;align-items:center;gap:2px}

/* The default pip is coral (--accent), which reads as "new" rather than "late". */
.icon-btn .pip.over{background:var(--danger)}
.icon-btn .pip.due{background:var(--warm)}

/* ---------- Global search typeahead ---------- */

/* Lifted above its own dismiss sheet while open, so the box itself stays clickable. Both
   numbers are local: .topbar is sticky with z-index:30 and paints in its own stacking context,
   so nothing here can fight the drawers at 60/61. */
.search.on{z-index:50}
.search-sheet{position:fixed;inset:0;z-index:49}

/* Anchored to the box's right edge and wider than it — 260px does not hold
   "Amara Okafor · 0412 345 678" — so it grows leftward into empty header. */
/* Above the dismiss sheet, and that is the whole point of the number. The sheet and this are
   both children of .search, which is its own stacking context while open — so these two z-indexes
   are compared against EACH OTHER, not against the page. At z-index:1 the sheet covered the
   results and swallowed every click on them, which reads as "clicking a result does nothing". */
.search-dd{
  position:absolute;top:calc(100% + 8px);right:0;width:360px;background:var(--surface);
  border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg);z-index:50;
  max-height:360px;overflow-y:auto;padding:4px;
}
.gs-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:8px 9px;
  border-radius:9px;background:none;transition:.12s}
.gs-row:hover,.gs-row.on{background:var(--brand-ll)}
.gs-row .avatar{width:30px;height:30px;flex:0 0 30px;font-size:11.5px}
.gs-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.gs-nm{font-weight:650;font-size:13px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-mt{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-note{padding:12px 11px;font-size:12.5px;color:var(--muted);line-height:1.45}
.gs-note b{color:var(--ink);font-weight:650}
.gs-more{display:block;width:100%;text-align:left;margin-top:4px;border-top:1px solid var(--line-soft);
  padding:9px 11px;font-size:11.5px;color:var(--muted);font-weight:600;transition:.12s}
.gs-more:hover{color:var(--brand-d)}

/* ---------- Task rows ---------- */

/* A task's TYPE. It sits BESIDE the tick, not in place of it: .task-check hides its svg until
   .done, so a type icon put inside one renders as an empty box. Both slots earn their place — the
   tick completes the task, the icon says what kind of work it is when the title is free text. */
.task-type{width:26px;height:26px;border-radius:8px;flex:0 0 26px;display:grid;place-items:center;
  background:var(--canvas);color:var(--muted)}
.task-type svg{width:14px;height:14px}

/* .task-check is a <button> now that completing a task exists. The global button reset clears
   border and background; the class re-declares both and wins on specificity. Focus is explicit
   because a 19px box with no visible ring is unreachable by keyboard in practice. */
button.task-check{padding:0}
.task-check:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.task-check:disabled{cursor:default;opacity:.5}

/* .clk on a task row had no rule at all — the only .clk rules are scoped to .tbl tbody tr — so
   clickable task rows have had no pointer, no hover and no focus ring. */
.task-row.clk{cursor:pointer;border-radius:9px;margin:0 -8px;padding-left:8px;padding-right:8px}
.task-row.clk:hover .tt{color:var(--brand-d)}
.task-row.clk:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}

/* ---------- Legend drawer ---------- */

/* Explanation, not data: no hairline between rows. Thirty bordered rows read as a table somebody
   is meant to scan, and this is a page somebody reads once. */
.legend-body .section-label{margin:20px 0 8px}
.legend-body .section-label:first-child{margin-top:0}

/* Two-column row, for swatches of predictable width — heat, urgency, priority, due, icons. The
   column is fixed so every sentence starts on the same left edge. */
.legend-row{display:flex;align-items:flex-start;gap:11px;padding:6px 0}
.legend-row .legend-swatch{flex:0 0 136px;display:flex;align-items:center;min-width:0}
.legend-row .legend-text{flex:1;min-width:0;font-size:12.5px;color:var(--ink-soft);line-height:1.5}
.legend-row .legend-text b{color:var(--ink);font-weight:650}

/* Stacked row, for stage pills. A stage name is the customer's and may run to the 40 characters
   the pipeline allows, which no fixed column survives. */
.legend-stack{padding:8px 0}
.legend-stack .legend-text{margin-top:5px;font-size:12.5px;color:var(--ink-soft);line-height:1.5}
.legend-stack .legend-text b{color:var(--ink);font-weight:650}
.legend-stack.retired{opacity:.62}

/* A note belonging to a section rather than to any one row. */
.legend-note{font-size:11.5px;color:var(--faint);line-height:1.5;padding:4px 0 2px}

/* ---------- SMS conversation thread ---------- */

/* The messaging-app shape: outbound right in the brand colour, inbound left on canvas, day
   separators between groups. Bubbles wrap their text; the column never exceeds three quarters
   of the drawer so the sides stay visually distinct. */
.sms-thread{display:flex;flex-direction:column;gap:2px;margin-bottom:18px;padding:4px 0}
.sms-day{text-align:center;font-size:10.5px;font-weight:700;letter-spacing:.05em;color:var(--faint);margin:12px 0 8px}
.sms-day:first-child{margin-top:0}
.sms-row{display:flex;flex-direction:column;margin-bottom:6px}
.sms-row.out{align-items:flex-end}
.sms-row.in{align-items:flex-start}
.sms-bubble{max-width:75%;padding:8px 13px;border-radius:16px;font-size:13px;line-height:1.45;
  white-space:pre-wrap;overflow-wrap:anywhere}
.sms-bubble.out{background:var(--brand);color:#fff;border-bottom-right-radius:5px}
.sms-bubble.in{background:var(--canvas);color:var(--text);border-bottom-left-radius:5px}

/* The unanswered-call rule logs an SMS it never sends. Hiding it would make the thread disagree
   with the timeline; drawing it solid would claim it went. Dashed, with its caption underneath. */
.sms-bubble.unsent{background:var(--surface);color:var(--muted);border:1.5px dashed var(--line);
  border-bottom-right-radius:5px}
.sms-time{font-size:10.5px;color:var(--faint);margin-top:3px;padding:0 4px}

/* ---------- Bulk selection bar ---------- */
.bulk-bar{display:flex;align-items:center;gap:10px;background:var(--brand-l);border:1px solid var(--brand);
  border-radius:12px;padding:9px 14px;margin-bottom:14px;animation:fade .2s ease}

/* ---------- Multi-value filter dropdown ---------- */
.mf-btn{display:inline-flex;align-items:center;gap:4px;padding:8px 10px;font-size:12.5px;cursor:pointer}
/* Left-aligned (unlike .menu): these sit at the start of a toolbar, and a right-anchored panel
   would open off the left edge of the screen. */
.mf-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:41;min-width:210px;max-height:320px;
  overflow-y:auto;background:var(--surface);border:1px solid var(--line);border-radius:13px;
  box-shadow:var(--shadow-lg);padding:5px;animation:menuIn .13s ease}
.mf-row{display:flex;align-items:center;gap:9px;width:100%;text-align:left;padding:8px 10px;
  border-radius:9px;font-size:12.5px;color:var(--ink);cursor:pointer;transition:.12s;background:none}
.mf-row:hover{background:var(--brand-ll)}
.mf-row input[type="checkbox"]{flex:0 0 auto}
.mf-all{font-weight:650;color:var(--muted);border-bottom:1px solid var(--line);border-radius:9px 9px 0 0;margin-bottom:3px}
.mf-all.sel{color:var(--brand-d)}

/* ---------- Message placeholders ---------- */
/* The chips row under a bulk compose box; clicking one drops its {{token}} into the draft. */
.ph-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:8px}
.ph-chips-label{font-size:11px;color:var(--faint);font-weight:600;letter-spacing:.02em}
.ph-chip{font-family:var(--mono,ui-monospace,monospace);font-size:11.5px;color:var(--brand);
  background:var(--brand-l);border:1px solid var(--brand);border-radius:999px;padding:3px 10px;
  cursor:pointer;line-height:1.4}
.ph-chip:hover{filter:brightness(.97)}
.ph-chip:disabled{opacity:.5;cursor:default}
/* The settings list's token badge. */
.ph-token{font-family:var(--mono,ui-monospace,monospace);font-size:12px;color:var(--brand);
  background:var(--brand-l);border-radius:6px;padding:3px 8px;white-space:nowrap}

/* ---- Rich text editor (email bodies) ---- */
.rte-bar{display:flex;gap:3px;align-items:center;border:1px solid var(--line);border-bottom:none;border-radius:10px 10px 0 0;padding:5px 7px;background:var(--canvas)}
.rte-btn{border:none;background:none;cursor:pointer;font-size:12.5px;color:var(--ink-soft);padding:4px 8px;border-radius:6px;line-height:1}
.rte-btn:hover{background:var(--paper);color:var(--ink)}
.rte-sep{width:1px;height:16px;background:var(--line);margin:0 3px}
.rte-area{border-radius:0 0 10px 10px;overflow-y:auto;line-height:1.55}
.rte-area img{max-height:64px}
.rte-area ul,.rte-area ol{padding-left:22px;margin:6px 0}
.rte-area a{color:var(--brand-d)}
.rte-area img[src^="cid:"]{min-width:110px;min-height:42px;background:var(--canvas);border:1px dashed var(--line);border-radius:8px;padding:4px 8px;font-size:11px;color:var(--muted)}

/* The CCMS badge mark: a small tile carrying the provider monogram, standing in for a real
   logo the product does not ship. Sized to sit inside a .pill without stretching it. */
.ccms-mark{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:5px;color:#fff;font-size:8px;font-weight:800;letter-spacing:.2px;flex:0 0 16px}

/* ---- The public enquiry form: a page that lives inside other people's websites. ---- */
.enquiry-shell{min-height:100vh;background:var(--canvas);padding:26px 16px;display:flex;justify-content:center;align-items:flex-start}
.enquiry-card{width:100%;max-width:640px;background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:28px 30px;box-shadow:var(--shadow-sm)}
.enquiry-head h1{font-size:21px;font-weight:800;color:var(--ink);margin:0}
.enquiry-sub{font-size:13px;color:var(--muted);margin-top:3px;margin-bottom:18px}
.enquiry-section{font-size:12px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--brand-d);margin:20px 0 10px;padding-top:14px;border-top:1px solid var(--line-soft)}
.enquiry-section:first-of-type{border-top:none;padding-top:0;margin-top:6px}
.enquiry-privacy{font-size:11.5px;color:var(--muted);margin-top:20px;padding-top:14px;border-top:1px solid var(--line-soft);line-height:1.5}
.enquiry-powered{font-size:10.5px;color:var(--faint);margin-top:10px;text-align:center;letter-spacing:.3px}
/* The honeypot: parked far off-canvas rather than display:none, which smarter bots skip. */
.hp-field{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}

/* ---- Campaign preview: the email as an inbox shows it. Styles mirror what the renderer and
   the sanitizer's button constant actually emit, so the preview never flatters. ---- */
.email-frame{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#ffffff}
.email-frame-subject{padding:10px 16px;border-bottom:1px solid var(--line-soft);font-weight:700;font-size:13px;color:#1c2b2e;background:#fafbfb}
.email-frame-body{padding:20px 22px;font-size:14px;line-height:1.6;color:#243438}
.email-frame-body h2{font-size:19px;margin:14px 0 8px;color:#16292d}
.email-frame-body p{margin:0 0 12px}
.email-frame-body hr{border:none;border-top:1px solid #e3e9e9;margin:16px 0}
.email-frame-body img{max-height:64px}
.email-frame-body a.email-btn{display:inline-block;background-color:#2b6968;color:#ffffff;padding:11px 24px;border-radius:8px;text-decoration:none;font-weight:600}
/* The preview's stand-in for the logo, which only exists at send time. */
.email-frame-body .email-logo-ph{display:inline-flex;align-items:center;justify-content:center;width:130px;height:52px;border-radius:9px;background:#e8ecec;color:#7b8b90;font-weight:700;font-size:12px;letter-spacing:.5px;text-transform:uppercase}
