@import url("https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap");

/* ==========================================================================
   TOTAL KITCHENS COMPANY OS — theme
   Brand: lime #83F511, charcoal #50524F, white. The ground is a darkened
   derivative of their charcoal so the lime can stay loud without shouting.
   ========================================================================== */
:root{
  color-scheme:dark;

  --ground:#12150F;
  --panel:#1A1E17;
  --panel-2:#222720;
  --panel-3:#2A302A;
  --line:#2F3630;
  --line-soft:#252B25;

  --ink:#ECEFE6;
  --ink-2:#A7AFA2;
  --ink-3:#8D968A;

  /* TWO ROLES FOR ONE BRAND COLOUR, AND THEY ARE NOT INTERCHANGEABLE.

     --lime       accent for TEXT, borders and icons. On a dark ground the raw
                  brand lime is perfect. On a light ground #83F511 sits at about
                  1.7:1 against white, which is not a contrast problem so much as
                  an invisibility problem, so in light mode this becomes a deep
                  green and everything that reads as text follows it.

     --lime-fill  the SOLID fill behind dark text: buttons, the active segment,
                  comment pins. Near-black on brand lime is about 12:1, so this
                  one stays the real brand colour in both themes and the console
                  keeps its signature.

     Anything that paints lime and then puts dark text on top must use
     --lime-fill and --on-lime. Getting that backwards is what makes a light
     theme ship with unreadable controls. */
  --lime:#83F511;
  --lime-dim:#6BC70E;
  --lime-fill:#83F511;
  --lime-fill-hover:#6BC70E;
  --on-lime:#12150F;
  --lime-ghost:rgba(131,245,17,.12);
  --char:#50524F;

  --good:#83F511;   --good-bg:rgba(131,245,17,.13);
  --warn:#E0A83A;   --warn-bg:rgba(224,168,58,.14);
  --crit:#F4715C;   --crit-bg:rgba(244,113,92,.10);
  --info:#5FB0E8;   --info-bg:rgba(95,176,232,.14);
  --on-crit:#12150F;

  /* Everything below used to be written straight into a rule. A hardcoded
     colour is invisible to a theme, which is exactly how a light mode ships
     with a scrim nobody can see through or a fade that smears grey. */
  --ground-0:rgba(18,21,15,0);
  --scrim:rgba(0,0,0,.62);
  --cmt-tint:rgba(131,245,17,.03);
  --ribbon-line:rgba(224,168,58,.30);
  --fill-shade:rgba(0,0,0,.18);
  --fill-shade-2:rgba(0,0,0,.22);
  --pin-shadow:0 2px 7px rgba(0,0,0,.5);
  --qr-bg:#FFFFFF;
  --qr-ink:#555555;

  --r:6px;
  --sans:Archivo,"Helvetica Neue",Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px -16px rgba(0,0,0,.75);
}

/* ==========================================================================
   LIGHT
   Not an inversion. The ground keeps a warm green cast so the brand still owns
   the page, the accent drops to a deep green so it can be read, and the status
   colours are darkened until they carry on white. js/theme.js resolves the
   system preference into an explicit data-theme before first paint, so there is
   exactly one light palette here rather than the same values written twice.
   ========================================================================== */
:root[data-theme="light"]{
  color-scheme:light;

  --ground:#F3F5EF;
  --panel:#FFFFFF;
  --panel-2:#F5F7F1;
  --panel-3:#E7EBE1;
  --line:#D5DBCC;
  --line-soft:#E9EDE3;

  --ink:#14180F;
  --ink-2:#4A5342;
  --ink-3:#626B58;

  --lime:#3B7804;
  --lime-dim:#2E5E03;
  --lime-fill:#83F511;
  --lime-fill-hover:#74DC0D;
  --on-lime:#12150F;
  --lime-ghost:rgba(59,120,4,.10);
  --char:#50524F;

  --good:#3B7804;   --good-bg:rgba(59,120,4,.11);
  --warn:#8A5A05;   --warn-bg:rgba(138,90,5,.11);
  --crit:#BE3319;   --crit-bg:rgba(190,51,25,.09);
  --info:#1B6BA5;   --info-bg:rgba(27,107,165,.10);
  --on-crit:#FFFFFF;

  --ground-0:rgba(243,245,239,0);
  --scrim:rgba(20,24,15,.42);
  --cmt-tint:rgba(59,120,4,.05);
  --ribbon-line:rgba(138,90,5,.28);
  --fill-shade:rgba(0,0,0,.14);
  --fill-shade-2:rgba(0,0,0,.16);
  --pin-shadow:0 2px 8px rgba(20,24,15,.26);
  --qr-bg:#FFFFFF;
  --qr-ink:#555555;

  --shadow:0 1px 2px rgba(20,24,15,.06),0 12px 30px -18px rgba(20,24,15,.30);
}

*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{height:100%}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--sans);font-size:14px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
body.pre-auth .app{display:none}
button{font-family:inherit}
a{color:var(--lime)}
:focus-visible{outline:2px solid var(--lime);outline-offset:2px}
::selection{background:var(--lime-fill);color:var(--on-lime)}

/* ------------------------------------------------------------------ shell */
.app{display:grid;grid-template-columns:230px minmax(0,1fr);min-height:100vh}
@media(max-width:900px){.app{grid-template-columns:minmax(0,1fr)}}

.side{
  background:var(--panel);border-right:1px solid var(--line);
  display:flex;flex-direction:column;padding:18px 0;
  position:sticky;top:0;height:100vh;overflow-y:auto
}
@media(max-width:900px){.side{position:static;height:auto}}

.brand{display:flex;gap:11px;align-items:center;padding:0 18px 18px;border-bottom:1px solid var(--line-soft)}
.brand-mark{width:34px;height:34px;flex:none;display:grid;place-items:center;background:var(--lime-ghost);border-radius:var(--r)}
.brand-mark svg{width:22px;height:19px;fill:var(--lime)}
.brand-name{font-weight:800;font-size:14.5px;letter-spacing:-.015em;line-height:1.15}
.brand-sub{font-size:10.5px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin-top:2px}

nav{padding:14px 10px;flex:1}
.nav-grp{font-size:9.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);padding:14px 8px 6px}
.nav-grp:first-child{padding-top:0}
.navi{
  display:flex;align-items:center;gap:9px;width:100%;text-align:left;
  background:none;border:0;color:var(--ink-2);font-size:13.5px;font-weight:500;
  padding:8px 9px;border-radius:var(--r);cursor:pointer;line-height:1.3
}
.navi:hover{background:var(--panel-2);color:var(--ink)}
.navi.on{background:var(--lime-ghost);color:var(--lime);font-weight:600}
.navi .ico{width:15px;height:15px;flex:none;opacity:.85}
.navi .ico svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.navi .badge{
  margin-left:auto;font-family:var(--mono);font-size:10px;font-weight:700;
  background:var(--panel-3);color:var(--ink-2);padding:1px 6px;border-radius:9px
}
.navi.on .badge{background:var(--lime-fill);color:var(--on-lime)}
.navi .badge.hot{background:var(--crit);color:var(--on-crit)}

.side-foot{padding:12px 16px 0;border-top:1px solid var(--line-soft);display:flex;flex-direction:column;gap:7px}
.chip{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--ink-2)}
.chip.muted{color:var(--ink-3);font-size:10.5px}
.chip .dot{width:6px;height:6px;border-radius:50%;background:var(--warn);flex:none}
body:not(.not-live) .chip .dot{background:var(--lime)}

/* ------------------------------------------------------------------- main */
.main{min-width:0;display:flex;flex-direction:column}
.top{
  display:flex;gap:20px;align-items:flex-start;padding:26px 30px 20px;
  border-bottom:1px solid var(--line);position:sticky;top:var(--ribbon,0px);
  background:var(--ground);z-index:20
}
@media(max-width:700px){.top{padding:18px}}
.top-l{min-width:0;flex:1}
.crumb{font-size:10px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--lime);margin-bottom:5px}
.top h1{margin:0;font-size:25px;font-weight:800;letter-spacing:-.025em;line-height:1.1}
.view-lede{margin:6px 0 0;font-size:13px;color:var(--ink-2);max-width:74ch;line-height:1.5}
.top-r{display:flex;align-items:center;gap:9px;flex:none}
.whoami{display:flex;align-items:center;gap:9px;padding-left:9px;border-left:1px solid var(--line)}
.who-name{font-size:12px;color:var(--ink-2);font-weight:500}

.views{padding:24px 30px 90px;flex:1}
@media(max-width:700px){.views{padding:18px 18px 90px}}
.view{position:relative}

/* ---------------------------------------------------------------- buttons */
.btn{
  background:var(--lime-fill);color:var(--on-lime);border:0;border-radius:var(--r);
  padding:7px 13px;font-size:12.5px;font-weight:700;cursor:pointer;line-height:1.3
}
.btn:hover{background:var(--lime-fill-hover)}
.btn.ghost{background:transparent;color:var(--ink-2);border:1px solid var(--line)}
.btn.ghost:hover{background:var(--panel-2);color:var(--ink)}
.btn.sm{padding:5px 9px;font-size:11.5px}
.btn:disabled{opacity:.5;cursor:not-allowed}

/* ------------------------------------------------------------------ cards */
.grid{display:grid;gap:14px}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:17px 19px}
.card h3{margin:0 0 3px;font-size:14.5px;font-weight:700;letter-spacing:-.01em}
.card .sub{font-size:11.5px;color:var(--ink-3);margin:0 0 13px}
.card.pad0{padding:0;overflow:hidden}
.card-h{padding:15px 19px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px}
.card-h h3{margin:0;flex:1}

.kpi{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:16px 18px}
.kpi .k{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.kpi .v{font-size:29px;font-weight:800;letter-spacing:-.03em;line-height:1.1;margin-top:8px;font-variant-numeric:tabular-nums}
.kpi .v.lime{color:var(--lime)}
.kpi .v.warn{color:var(--warn)}
.kpi .v.crit{color:var(--crit)}
.kpi .n{font-size:11.5px;color:var(--ink-3);margin-top:6px;line-height:1.4}

/* ----------------------------------------------------------------- tables */
.tw{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r);background:var(--panel)}
table{border-collapse:collapse;width:100%;font-size:13px}
th{
  text-align:left;font-size:9.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-3);padding:10px 14px;background:var(--panel-2);
  border-bottom:1px solid var(--line);white-space:nowrap
}
td{padding:11px 14px;border-bottom:1px solid var(--line-soft);vertical-align:top;line-height:1.45}
tr:last-child td{border-bottom:0}
tbody tr.clickable{cursor:pointer}
tbody tr.clickable:hover{background:var(--panel-2)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--mono);font-size:12px}
td small{display:block;color:var(--ink-3);font-size:11px;margin-top:2px}
td .mono,.mono{font-family:var(--mono)}

/* ------------------------------------------------------------------ pills */
.pill{
  display:inline-block;font-size:9.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  padding:3px 7px;border-radius:3px;white-space:nowrap;line-height:1.35
}
.pill.good{background:var(--good-bg);color:var(--good)}
.pill.warn{background:var(--warn-bg);color:var(--warn)}
.pill.crit{background:var(--crit-bg);color:var(--crit)}
.pill.info{background:var(--info-bg);color:var(--info)}
.pill.mute{background:var(--panel-3);color:var(--ink-3)}

/* ------------------------------------------------------------- empty/note */
.empty{padding:34px 20px;text-align:center;color:var(--ink-3);font-size:13px}
.note{
  background:var(--panel-2);border:1px solid var(--line);border-left:3px solid var(--lime);
  border-radius:var(--r);padding:13px 16px;font-size:12.5px;color:var(--ink-2);line-height:1.55
}
.note.warn{border-left-color:var(--warn)}
.note.crit{border-left-color:var(--crit)}
.note b{color:var(--ink)}
.sec-h{display:flex;align-items:baseline;gap:12px;margin:26px 0 12px}
.sec-h:first-child{margin-top:0}
.sec-h h2{margin:0;font-size:16px;font-weight:700;letter-spacing:-.015em}
.sec-h .hint{font-size:11.5px;color:var(--ink-3)}
.stack{display:flex;flex-direction:column;gap:14px}

/* ------------------------------------------------------------------ toolbar */
.toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:14px}
.seg{display:inline-flex;flex-wrap:wrap;max-width:100%;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);padding:2px}
.seg button{
  background:none;border:0;color:var(--ink-2);font-size:12px;font-weight:600;
  padding:5px 11px;border-radius:4px;cursor:pointer;white-space:nowrap
}
.seg button:hover{color:var(--ink)}
.seg button.on{background:var(--lime-fill);color:var(--on-lime)}
.srch{
  background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);
  color:var(--ink);padding:6px 11px;font-size:12.5px;font-family:inherit;min-width:190px
}
.srch::placeholder{color:var(--ink-3)}

/* ------------------------------------------------------------------ kanban */
.kan{display:grid;grid-template-columns:repeat(4,minmax(190px,1fr));gap:12px;overflow-x:auto}
@media(max-width:860px){.kan{grid-template-columns:repeat(2,minmax(180px,1fr))}}
@media(max-width:520px){.kan{grid-template-columns:1fr}}
.kan-col{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);display:flex;flex-direction:column;min-height:120px}
.kan-h{padding:10px 13px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px}
.kan-h .t{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2)}
.kan-h .c{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}
.kan-b{padding:9px;display:flex;flex-direction:column;gap:8px}
.tk{background:var(--panel-2);border:1px solid var(--line);border-radius:5px;padding:10px 11px;cursor:pointer}
.tk:hover{border-color:var(--lime)}
.tk .tt{font-size:12.5px;font-weight:600;line-height:1.35;margin-bottom:6px}
.tk .tm{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.tk .tm .who{font-size:10px;color:var(--ink-3);font-weight:600}

/* ---------------------------------------------------------------- calendar */
.cal-head{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:12px}
.cal-title{font-size:16px;font-weight:700;letter-spacing:-.01em;min-width:150px}
.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.cal .dow{background:var(--panel-2);padding:7px 8px;font-size:9.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3);text-align:center}
.cal .day{background:var(--panel);min-height:96px;padding:6px 7px;display:flex;flex-direction:column;gap:4px}
.cal .day.out{background:var(--ground);opacity:.5}
.cal .day.today{box-shadow:inset 0 0 0 2px var(--lime)}
.cal .dn{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);font-weight:600}
.cal .day.today .dn{color:var(--lime)}
.ev{font-size:10.5px;padding:3px 6px;border-radius:3px;line-height:1.3;cursor:pointer;border-left:2px solid}
.ev.install{background:var(--lime-ghost);border-color:var(--lime);color:var(--ink)}
.ev.measure{background:var(--info-bg);border-color:var(--info);color:var(--ink)}
.ev.delivery{background:var(--warn-bg);border-color:var(--warn);color:var(--ink)}
.ev.deadline{background:var(--crit-bg);border-color:var(--crit);color:var(--ink)}
.ev.consult,.ev.meeting,.ev.other{background:var(--panel-3);border-color:var(--ink-3);color:var(--ink-2)}

/* ----------------------------------------------------------------- roadmap */
/* ---- FORM KIT ------------------------------------------------------------
   The error band replaces alert(), which cannot be themed, cannot point at a
   field and stops the world. The undo strip is the single delete idiom: the
   action happens, and it can be taken back for eight seconds. */
.frm-err{display:none;background:var(--crit-bg);border:1px solid var(--crit);color:var(--crit);border-radius:5px;padding:9px 12px;font-size:12px;line-height:1.45;margin-bottom:12px}
.frm-err.show{display:block}
.frm .btnrow{margin-top:4px}
/* NEXT STEP. One solid button at the top of the job drawer, labelled with the
   physical next thing. It is the only solid button in a drawer, deliberately,
   because it is the one action that is almost always the right one. */
.nextstep{display:flex;align-items:center;gap:14px;flex-wrap:wrap;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);padding:13px 15px;margin-bottom:16px}
.ns-k{font-size:9.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
/* A stage in the Move it list is a card you press, not a row with a button. */
.rule.mv{display:block;width:100%;text-align:left;cursor:pointer;font:inherit;color:inherit}
.rule.mv:hover{border-color:var(--lime)}
.rule.mv[disabled]{cursor:default;opacity:.75}
.r-tick{margin-left:8px;background:transparent;border:1px solid var(--line);border-radius:3px;color:var(--ink-2);font:inherit;font-size:10px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:2px 7px;cursor:pointer}
.r-tick:hover{border-color:var(--lime);color:var(--lime)}
/* A checkbox reads as a row, not as a stacked label: the box sits beside the
   words it applies to, and the hint sits under both. */
.frm label.chk{flex-direction:row;align-items:flex-start;gap:9px;text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:500;color:var(--ink);flex-wrap:wrap}
.frm label.chk input{width:auto;margin-top:1px}
.frm label.chk small{flex-basis:100%;margin-left:25px}
.frm label small{font-size:10.5px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--ink-3);line-height:1.45}
/* One live line under a money field, not a growing stack of paragraphs. */
.frm-live{font-size:11.5px;line-height:1.5;color:var(--ink-2);padding:8px 11px;border-radius:5px;background:var(--panel-2);border:1px solid var(--line)}
.frm-live.warn{color:var(--warn);border-color:var(--warn);background:var(--warn-bg)}
.frm-live.crit{color:var(--crit);border-color:var(--crit);background:var(--crit-bg)}
.blank-a{margin-top:18px}

.undo-strip{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:60;display:flex;align-items:center;gap:14px;background:var(--panel-3);border:1px solid var(--line);border-radius:7px;padding:10px 14px;box-shadow:0 8px 26px rgba(0,0,0,.34);font-size:12.5px;max-width:calc(100vw - 32px)}
@media(max-width:520px){.undo-strip{left:16px;right:16px;transform:none;justify-content:space-between}}

/* ---- PROMPT BAR ----------------------------------------------------------
   Sits above the real content instead of replacing it, so an empty screen still
   shows its own structure. */
.prompt{display:flex;align-items:center;gap:18px;flex-wrap:wrap;background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--lime);border-radius:var(--r);padding:14px 17px;margin-bottom:16px}
.prompt-x{flex:1;min-width:240px}
.prompt-t{font-size:13px;font-weight:700;letter-spacing:-.005em;margin-bottom:3px}
.prompt-b{font-size:12px;color:var(--ink-2);line-height:1.5}
.prompt-a{flex:none}
.tr-empty td{color:var(--ink-3);text-align:center;padding:44px 14px!important;font-size:12.5px}
/* An empty pipeline still has to look like a board rather than a row of tabs. */
.kan.empty .kan-col{min-height:230px}
.kan.empty .kan-b{flex:1;justify-content:center}

/* ---- DRAG AND DROP -------------------------------------------------------
   The ghost follows the pointer; the original stays put and dimmed so you can
   still see where it came from. */
.drag-ghost{position:fixed!important;z-index:80;pointer-events:none;opacity:.95;
  box-shadow:0 12px 30px rgba(0,0,0,.38);transform:rotate(1.4deg);cursor:grabbing}
.drag-src{opacity:.34}
.dragging .tk,.dragging .rmr{cursor:grab}
body.is-dragging{cursor:grabbing;user-select:none}
/* Stop a finger scrolling the board out from under the card being dragged. */
.dragging{touch-action:none}
/* A column being aimed at. */
.drop-on{outline:2px solid var(--lime);outline-offset:-2px;background:var(--panel-2)}
/* WHILE A DRAG IS RUNNING, an empty stage stops being a sliver and becomes a
   target. It goes back to a sliver afterwards, because a gap in a busy pipeline
   is information that does not deserve the width. */
/* An empty stage collapses to a 34px sliver so fifteen of them stay readable,
   then opens to a real 150px target the moment a card is picked up. That part is
   right: you cannot aim at a 34px sliver. What was wrong is that it happened
   instantly, so on the builder board nine stages snapped open at once and the
   whole thing appeared to lurch sideways, which reads as a glitch rather than as
   the board making room. It is NOT animated, deliberately: dragBoard measures the
   source column immediately before and after this class lands so it can hold that
   column still under the pointer, and a transition would make that measurement
   read the old width. Anchoring the column you are holding is what stops this
   looking like a lurch anyway, because the thing under your hand does not move. */
.kan.dragging .kan-col.nil{min-width:150px!important;max-width:none!important;width:150px;
  align-items:stretch;padding:0;background:var(--panel);border-style:dashed}
.kan.dragging .kan-col.nil .nil-t{writing-mode:horizontal-tb;padding:12px 13px;display:block;
  max-height:none;text-align:left}
.rml.dragging .rmr{cursor:grab}
.rmp.drop-on{outline:2px solid var(--lime);outline-offset:3px;border-radius:var(--r)}

/* ---- EMPTY SCREEN --------------------------------------------------------
   Every operations screen starts here, because the console ships with no
   invented data in it. It has to read as deliberate rather than broken. */
.blank{border:1px solid var(--line);border-radius:var(--r);background:var(--panel);padding:46px 32px;text-align:center}
.blank-t{font-size:15px;font-weight:700;letter-spacing:-.01em;margin-bottom:9px}
.blank-b{font-size:12.8px;color:var(--ink-2);line-height:1.6;max-width:56ch;margin:0 auto}
.blank-h{font-size:11.5px;color:var(--ink-3);line-height:1.55;max-width:56ch;margin:12px auto 0}

/* ---- STAT STRIP ----------------------------------------------------------
   A row of bare numbers under a heading. Used by the Overview "Right now"
   band. It lived under a .rm- prefix when the roadmap was the only caller,
   which made it look deletable when the roadmap stopped using it. It is not. */
.strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-bottom:16px}
.strip-i{background:var(--panel);padding:13px 15px}
.strip-i .n{font-size:23px;font-weight:800;letter-spacing:-.03em;font-variant-numeric:tabular-nums;line-height:1}
.strip-i .k{font-size:9.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3);margin-top:6px}
.strip-i .n.lime{color:var(--lime)}
.strip-i .n.info{color:var(--info)}
.strip-i .n.warn{color:var(--warn)}
.strip-i .n.crit{color:var(--crit)}

/* ---- ROADMAP -------------------------------------------------------------
   A phase is a chapter, a kind is a subheading inside it, an item is one quiet
   row. Everything that used to be shouted on a card badge now lives in the
   detail drawer, so the page reads as a document rather than a wall. */
.rmp{margin-bottom:24px}
.rmp-h{width:100%;display:flex;align-items:center;gap:10px;background:transparent;border:0;border-bottom:2px solid var(--line);padding:0 2px 9px;margin-bottom:13px;cursor:pointer;color:inherit;font:inherit;text-align:left}
.rmp-x{width:15px;height:15px;flex:none;fill:none;stroke:var(--ink-3);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;transform:rotate(90deg);transition:transform .15s ease}
.rmp.shut .rmp-x{transform:rotate(0deg)}
.rmp-h:hover .rmp-x{stroke:var(--lime)}
.rmp-t{font-size:15px;font-weight:800;letter-spacing:-.015em}
.rmp-h:hover .rmp-t{color:var(--lime)}
.rmp-n{font-family:var(--mono);font-size:10.5px;color:var(--ink-3)}
.rmp-d{margin-left:auto;font-size:10.5px;font-weight:600;color:var(--good)}

.rmg{display:flex;align-items:baseline;gap:8px;margin:0 0 7px 2px}
.rmg-t{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2)}
.rmg-n{font-family:var(--mono);font-size:10px;color:var(--ink-3)}

.rml{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-bottom:15px}
.rmr{width:100%;display:flex;align-items:flex-start;gap:11px;text-align:left;background:transparent;border:0;border-bottom:1px solid var(--line-soft);padding:11px 14px;cursor:pointer;color:inherit;font:inherit}
.rmr:last-child{border-bottom:0}
.rmr:hover{background:var(--panel-2)}
.rmr-s{width:7px;height:7px;border-radius:50%;flex:none;margin-top:6px;background:var(--ink-3)}
.rmr-s.not-started{opacity:.45}
.rmr-s.in-progress{background:var(--info)}
.rmr-s.blocked{background:var(--crit)}
.rmr-s.shipped{background:var(--good)}
.rmr-x{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.rmr-t{font-size:12.8px;font-weight:650;line-height:1.35;letter-spacing:-.005em;overflow-wrap:anywhere}
.rmr-q{display:inline-block;margin-left:7px;font-size:9px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--good);vertical-align:1px}
.rmr-g{font-size:11.3px;color:var(--ink-3);line-height:1.45;overflow-wrap:anywhere}
.rmr-b{font-size:10.6px;color:var(--warn);line-height:1.4}
.rmr-m{flex:none;display:flex;align-items:center;gap:8px;padding-top:3px}
.rmr-e{font-family:var(--mono);font-size:10px;font-weight:700;color:var(--ink-3);border:1px solid var(--line);padding:1px 5px;border-radius:3px}
@media(max-width:620px){.rmr-m{display:none}}

/* Task board: who a task is on, said once and quietly. */
.own{font-size:9.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:2px 6px;border-radius:3px}
.own.zayn{color:var(--info);background:var(--info-bg)}
.own.adam{color:var(--warn);background:var(--warn-bg)}
.mt14{margin-top:14px}

/* ------------------------------------------------------------------ agents */
.ag{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:16px 18px;display:flex;flex-direction:column;gap:9px;cursor:pointer}
.ag:hover{border-color:var(--lime)}
.ag-top{display:flex;align-items:center;gap:11px}
.ag-av{
  width:38px;height:38px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:var(--lime-ghost);color:var(--lime);font-weight:800;font-size:14px;letter-spacing:-.02em
}
.ag.off .ag-av{background:var(--panel-3);color:var(--ink-3)}
.ag-nm{font-size:14.5px;font-weight:700;letter-spacing:-.01em;line-height:1.2;flex:1;min-width:0}
.ag-role{font-size:12px;color:var(--ink);font-weight:600;line-height:1.45}
.ag-remit{font-size:12px;color:var(--ink-2);line-height:1.5}
.ag-stats{display:flex;gap:16px;padding-top:8px;border-top:1px solid var(--line-soft)}
.ag-stat .n{font-family:var(--mono);font-size:15px;font-weight:700;line-height:1}
.ag-stat .k{font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);margin-top:4px}

/* ------------------------------------------------------------------ drawer */
#scrim{position:fixed;inset:0;background:var(--scrim);opacity:0;pointer-events:none;transition:opacity .16s;z-index:60}
#scrim.on{opacity:1;pointer-events:auto}
#drawer{
  position:fixed;top:0;right:0;height:100vh;width:min(560px,94vw);background:var(--panel);
  border-left:1px solid var(--line);transform:translateX(100%);transition:transform .2s ease;
  z-index:61;display:flex;flex-direction:column;box-shadow:var(--shadow)
}
#drawer.on{transform:none}
.dw-head{display:flex;gap:14px;align-items:flex-start;padding:20px 22px;border-bottom:1px solid var(--line)}
.dw-title{margin:0;font-size:17px;font-weight:700;letter-spacing:-.015em;line-height:1.25}
.dw-sub{font-size:11.5px;color:var(--ink-3);margin-top:3px}
.dw-x{background:none;border:0;color:var(--ink-3);font-size:24px;cursor:pointer;line-height:1;padding:0 2px}
.dw-x:hover{color:var(--ink)}
.dw-body{padding:20px 22px 40px;overflow-y:auto;flex:1}
.dl{display:grid;grid-template-columns:130px 1fr;gap:8px 14px;font-size:12.5px;margin-bottom:18px}
.dl dt{color:var(--ink-3);font-weight:600}
.dl dd{margin:0;color:var(--ink)}
.dw-body h4{font-size:11px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-3);margin:20px 0 9px}
.dw-body p{font-size:13px;line-height:1.6;color:var(--ink-2);margin:0 0 11px}
.dw-body p b,.dw-body p strong{color:var(--ink)}

/* ------------------------------------------------------- comment layer ---- */
.cmt-fab{
  position:fixed;right:18px;bottom:18px;z-index:70;display:flex;align-items:center;gap:8px;
  background:var(--panel-2);color:var(--ink);border:1px solid var(--line);border-radius:22px;
  padding:9px 15px;font-size:12.5px;font-weight:600;cursor:pointer;box-shadow:var(--shadow)
}
.cmt-fab:hover{border-color:var(--lime)}
.cmt-fab.on{background:var(--lime-fill);color:var(--on-lime);border-color:var(--lime-fill)}
.cmt-fab svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2}
.cmt-count{font-family:var(--mono);font-size:10px;font-weight:700;background:var(--panel-3);padding:1px 6px;border-radius:9px}
.cmt-fab.on .cmt-count{background:var(--fill-shade-2)}
.cmt-banner{
  position:fixed;left:50%;transform:translateX(-50%);top:-60px;z-index:70;
  background:var(--lime-fill);color:var(--on-lime);border-radius:0 0 var(--r) var(--r);
  padding:9px 16px;font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:14px;
  transition:top .18s
}
body.cmt-on .cmt-banner{top:0}
.cmt-banner button{background:var(--fill-shade);border:0;color:var(--on-lime);font-weight:700;font-size:11.5px;padding:3px 9px;border-radius:4px;cursor:pointer}
.cmt-layer{position:absolute;inset:0;z-index:40;pointer-events:none}
body.cmt-on .cmt-layer{pointer-events:auto;cursor:crosshair;background:var(--cmt-tint)}
.cmt-pin{
  position:absolute;transform:translate(-50%,-50%);width:23px;height:23px;border-radius:50% 50% 50% 2px;
  background:var(--lime-fill);color:var(--on-lime);font-size:11px;font-weight:800;display:grid;place-items:center;
  cursor:pointer;pointer-events:auto;box-shadow:var(--pin-shadow);z-index:41
}
.cmt-pin.new{background:var(--ink);color:var(--ground)}
.cmt-pop{
  position:absolute;transform:translate(-50%,calc(-100% - 14px));width:262px;background:var(--panel-2);
  border:1px solid var(--line);border-radius:var(--r);padding:13px;z-index:42;pointer-events:auto;
  box-shadow:var(--shadow)
}
.cmt-pop textarea{
  width:100%;min-height:66px;background:var(--panel);border:1px solid var(--line);border-radius:4px;
  color:var(--ink);font-family:inherit;font-size:12.5px;padding:8px;resize:vertical
}
.cmt-pop-foot{display:flex;gap:7px;justify-content:flex-end;margin-top:9px}
.cmt-cancel{background:none;border:1px solid var(--line);color:var(--ink-2);font-size:11.5px;font-weight:600;padding:5px 10px;border-radius:4px;cursor:pointer}
.cmt-save{background:var(--lime-fill);border:0;color:var(--on-lime);font-size:11.5px;font-weight:700;padding:5px 11px;border-radius:4px;cursor:pointer}
.cmt-save:disabled{opacity:.45;cursor:not-allowed}
.cmt-pop-x{position:absolute;top:5px;right:7px;background:none;border:0;color:var(--ink-3);font-size:17px;cursor:pointer;line-height:1}
.cmt-pop-x:hover{color:var(--crit)}
.cmt-read-note{font-size:12.5px;line-height:1.55;color:var(--ink);padding-right:14px;white-space:pre-wrap}
.cmt-read-meta{font-size:10.5px;color:var(--ink-3);margin-top:8px;font-weight:600}

/* ------------------------------------------------------------- auth gate -- */
.auth-overlay{position:fixed;inset:0;background:var(--ground);display:grid;place-items:center;z-index:100;padding:20px}
.auth-card{width:min(400px,100%);background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:32px 30px;box-shadow:var(--shadow)}
.auth-brand{display:flex;flex-direction:column;align-items:center;gap:9px;margin-bottom:18px}
.auth-brand .brand-mark{width:44px;height:44px}
.auth-brand .brand-mark svg{width:28px;height:24px}
.auth-sub{font-size:10.5px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;color:var(--ink-3)}
.auth-steps{display:flex;gap:6px;justify-content:center;margin-bottom:20px}
.auth-steps span{width:22px;height:3px;border-radius:2px;background:var(--panel-3)}
.auth-steps span.on{background:var(--lime)}
.auth-h{margin:0 0 7px;font-size:19px;font-weight:800;letter-spacing:-.02em;text-align:center}
.auth-lede{margin:0 0 18px;font-size:12.5px;color:var(--ink-2);text-align:center;line-height:1.55}
.auth-err{display:none;background:var(--crit-bg);color:var(--crit);border-radius:5px;padding:9px 12px;font-size:12px;margin-bottom:14px;line-height:1.45}
.auth-err.show{display:block}
.auth-field{margin-bottom:13px}
.auth-field label{display:block;font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px}
.auth-field input{
  width:100%;background:var(--panel-2);border:1px solid var(--line);border-radius:5px;
  color:var(--ink);padding:10px 12px;font-family:inherit;font-size:14px
}
.auth-field input.code{font-family:var(--mono);font-size:20px;letter-spacing:.34em;text-align:center}
.auth-btn{width:100%;background:var(--lime-fill);color:var(--on-lime);border:0;border-radius:5px;padding:11px;font-size:13.5px;font-weight:700;cursor:pointer;margin-top:4px}
.auth-btn:hover{background:var(--lime-fill-hover)}
.auth-btn:disabled{opacity:.55;cursor:not-allowed}
.auth-btn.secondary{background:none;color:var(--ink-3);border:1px solid var(--line);margin-top:9px;font-weight:600}
.auth-btn.secondary:hover{background:var(--panel-2);color:var(--ink)}
.auth-note{font-size:11px;color:var(--ink-3);text-align:center;margin:16px 0 0;line-height:1.5}
.auth-qr{display:grid;place-items:center;background:var(--qr-bg);border-radius:7px;padding:13px;margin-bottom:14px;min-height:150px}
.auth-qr img{width:150px;height:150px;display:block}
.auth-qr .mini{font-size:11.5px;color:var(--qr-ink)}
.auth-secret{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);text-align:center;word-break:break-all;margin-bottom:13px}

/* The demo ribbon is gone along with the demo data. It used to reserve
   --ribbon px at the top for a sticky warning strip; leaving that reservation
   behind offset the sticky header and quietly clipped the row underneath it. */

@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ==========================================================================
   VIEW COMPONENTS
   Everything below is used by views-ops.js and views-pylon.js. Grouped by the
   screen that introduced it so a class is easy to trace back.
   ========================================================================== */

/* ------------------------------------------------------------- utilities */
.mt18{margin-top:18px}
.mt22{margin-top:22px}
.tb-n{font-family:var(--mono);font-size:11px;color:var(--ink-3);margin-left:auto}
.plain{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px;font-size:12.5px;color:var(--ink-2)}
.plain li{line-height:1.5}
.rules-list li{padding-left:0}
.rules-list b{color:var(--ink)}
.btnrow{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:10px}
span.bad{color:var(--crit);font-weight:700}
span.gd{color:var(--lime);font-weight:700}

/* ----------------------------------------------------------- Today alerts */
.alerts{display:flex;flex-direction:column;gap:8px}
.alert{
  display:flex;align-items:center;gap:13px;width:100%;text-align:left;cursor:pointer;
  background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--ink-3);
  border-radius:var(--r);padding:12px 15px;color:var(--ink);font-family:inherit
}
.alert:hover{background:var(--panel-2);border-color:var(--line)}
.alert.crit{border-left-color:var(--crit)}
.alert.warn{border-left-color:var(--warn)}
.alert.info{border-left-color:var(--info)}
.a-kind{
  flex:none;width:78px;font-size:9.5px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--ink-3)
}
.alert.crit .a-kind{color:var(--crit)}
.alert.warn .a-kind{color:var(--warn)}
.a-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.a-t{font-size:13px;font-weight:600;line-height:1.35}
.a-s{font-size:11.5px;color:var(--ink-3);line-height:1.45}
.a-go{flex:none;color:var(--ink-3);font-size:19px;line-height:1}

/* --------------------------------------------------------- activity feed */
.feed{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.feed li{
  display:grid;grid-template-columns:64px 1fr;gap:4px 11px;padding:10px 0;
  border-bottom:1px solid var(--line-soft);font-size:12.5px
}
.feed li:last-child{border-bottom:0}
.f-w{font-size:11px;font-weight:700;color:var(--lime);letter-spacing:.02em}
.feed li.flag .f-w{color:var(--warn)}
.feed li.err .f-w{color:var(--crit)}
.f-t{color:var(--ink-2);line-height:1.5}
.f-d{grid-column:2;font-size:10.5px;color:var(--ink-3);font-family:var(--mono)}

/* --------------------------------------------------------------- agenda */
.agenda{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.agenda li{
  display:flex;align-items:center;gap:12px;padding:9px 0;cursor:pointer;
  border-bottom:1px solid var(--line-soft)
}
.agenda li:last-child{border-bottom:0}
.agenda li:hover .agn-t{color:var(--lime)}
.agn-d{
  flex:none;width:34px;text-align:center;font-family:var(--mono);font-size:9.5px;
  color:var(--ink-3);text-transform:uppercase;line-height:1.15
}
.agn-d b{display:block;font-size:15px;color:var(--ink);font-weight:700}
.agn-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.agn-t{font-size:12.5px;font-weight:600;line-height:1.35}
.agn-s{font-size:11px;color:var(--ink-3)}
.agenda .ev{flex:none;pointer-events:none}

/* --------------------------------------------------------------- kanban */
.kan.kflow{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:minmax(178px,1fr);padding-bottom:8px}
.kan.k4{grid-template-columns:repeat(4,minmax(190px,1fr))}
@media(max-width:860px){.kan.k4{grid-template-columns:repeat(2,minmax(180px,1fr))}}
@media(max-width:520px){.kan.k4{grid-template-columns:1fr}}
.kan-none{color:var(--ink-3);font-size:11px;text-align:center;padding:12px 0}
.tk .tm .who.late{color:var(--crit);font-weight:700}
.tk-blk{margin-top:7px;font-size:10.5px;color:var(--warn);line-height:1.4}

/* ----------------------------------------------------- extraction confidence */
.conf{display:inline-flex;align-items:center;gap:7px}
.conf-b{display:block;height:5px;border-radius:3px;background:var(--ink-3);min-width:2px;max-width:64px;flex:none}
.conf-b.good{background:var(--lime)}
.conf-b.warn{background:var(--warn)}
.conf-b.crit{background:var(--crit)}
.conf-n{font-size:10.5px;color:var(--ink-3)}
.po-h .conf{margin-left:auto}
.po-h .conf-b{width:56px}

/* -------------------------------------------------------- verify queue card */
.po-card{
  background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--info);
  border-radius:var(--r);padding:14px 16px;display:flex;flex-direction:column;gap:9px
}
.po-card.low{border-left-color:var(--crit)}
.po-h{display:flex;align-items:center;gap:10px}
.po-no{font-size:13.5px;font-weight:700;letter-spacing:-.01em}
.po-m{font-size:11.5px;color:var(--ink-3)}
.po-flag{
  background:var(--crit-bg);color:var(--crit);border-radius:4px;padding:7px 10px;
  font-size:11.5px;line-height:1.45
}
.po-lines{display:flex;flex-direction:column;gap:5px;border-top:1px solid var(--line-soft);padding-top:9px}
.po-l{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--ink-2);line-height:1.4}
.po-l.muted{color:var(--ink-3);font-style:italic}
.po-f{display:flex;align-items:center;gap:10px;flex-wrap:wrap;border-top:1px solid var(--line-soft);padding-top:10px}
.po-t{font-size:13px;font-weight:700;white-space:nowrap}
.po-btns{margin-left:auto;display:flex;gap:6px}

/* ------------------------------------------------------------- compliance */
.rules{display:flex;flex-direction:column;gap:8px;margin-bottom:18px}
.rule{background:var(--panel-2);border:1px solid var(--line);border-left:3px solid var(--ink-3);border-radius:var(--r);padding:11px 13px}
.rule.ok{border-left-color:var(--lime)}
.rule.due{border-left-color:var(--warn)}
.rule.crit{border-left-color:var(--crit);background:var(--crit-bg)}
.rule.off{opacity:.5}
.r-h{display:flex;align-items:center;gap:9px;margin-bottom:5px}
.r-t{font-size:12.5px;font-weight:700;flex:1}
.r-d{font-size:11.5px;color:var(--ink-2);line-height:1.5}
.dotr{
  display:inline-grid;place-items:center;width:19px;height:19px;border-radius:4px;
  font-size:11px;font-weight:800;background:var(--panel-3);color:var(--ink-3)
}
.dotr.ok{background:var(--good-bg);color:var(--good)}
.dotr.due{background:var(--warn-bg);color:var(--warn)}
.dotr.crit{background:var(--crit-bg);color:var(--crit)}
.dotr.off{opacity:.4}

/* ------------------------------------------------------------------- bars */
.bars{display:flex;flex-direction:column;gap:9px}
.bar{display:grid;grid-template-columns:96px 1fr 58px;gap:11px;align-items:center;font-size:11.5px}
.b-l{color:var(--ink-3)}
.b-t{background:var(--panel-3);border-radius:3px;height:8px;overflow:hidden}
.b-f{display:block;height:100%;background:var(--lime);border-radius:3px;min-width:1px}
.b-f.crit{background:var(--crit)}
.b-n{text-align:right;color:var(--ink-2);font-size:11px}

/* -------------------------------------------------------- three pane tasks */
.tri{display:grid;grid-template-columns:196px minmax(0,1fr);gap:16px;align-items:start}
@media(max-width:820px){.tri{grid-template-columns:1fr}}
.rail{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:12px 10px;display:flex;flex-direction:column;gap:14px;position:sticky;top:132px
}
@media(max-width:820px){.rail{position:static}}
.rail-h{font-size:9.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);padding:0 6px 6px}
.rail-i{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:none;border:0;
  color:var(--ink-2);font-size:12.5px;font-weight:500;padding:6px 8px;border-radius:4px;cursor:pointer
}
.rail-i span:first-child{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rail-i:hover{background:var(--panel-2);color:var(--ink)}
.rail-i.on{background:var(--lime-ghost);color:var(--lime);font-weight:700}
.rail-n{font-size:10px;color:var(--ink-3);flex:none}
.rail-i.on .rail-n{color:var(--lime)}
.tri-main{min-width:0}

/* ------------------------------------------------------------------ forms */
.frm{display:flex;flex-direction:column;gap:11px}
.frm label{display:flex;flex-direction:column;gap:5px;font-size:10.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
.frm input,.frm textarea,.frm select{
  background:var(--panel-2);border:1px solid var(--line);border-radius:5px;color:var(--ink);
  padding:9px 11px;font-family:inherit;font-size:13px;font-weight:400;letter-spacing:normal;text-transform:none
}
.frm textarea{resize:vertical;line-height:1.5}
.frm input::placeholder,.frm textarea::placeholder{color:var(--ink-3)}
.frm-2{display:grid;grid-template-columns:1fr 1fr;gap:11px}
@media(max-width:520px){.frm-2{grid-template-columns:1fr}}
.frm .btn{align-self:flex-start;margin-top:2px}

/* ----------------------------------------------------------------- agents */
.ag-st{margin-left:auto}
.ag-stat .n.sm{font-size:11px;font-weight:600}
.ag-blk{font-size:11.5px;color:var(--warn);line-height:1.45}

/* ----------------------------------------------------------- integrations */
.intg{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:15px 17px;display:flex;flex-direction:column;gap:8px}
.intg.connected{border-left:3px solid var(--lime)}
.intg.error{border-left:3px solid var(--crit)}
.intg.degraded{border-left:3px solid var(--warn)}
.intg-h{display:flex;align-items:center;gap:10px}
.intg-t{font-size:14px;font-weight:700;letter-spacing:-.01em;flex:1}
.intg-d{font-size:12px;color:var(--ink-2);line-height:1.5}
.intg-e{font-size:11.5px;color:var(--crit);line-height:1.45}
.intg-u{font-size:11.5px;color:var(--ink-3);line-height:1.5;border-top:1px solid var(--line-soft);padding-top:9px}
.intg-ag{display:block;color:var(--lime);font-weight:600;margin-top:5px}

/* --------------------------------------------------------------- printing */
@media print{
  .side,.top-r,.cmt-fab,.cmt-banner,.toolbar,.rail{display:none!important}
  .app{grid-template-columns:1fr}
  body{background:#fff;color:#111}
  .card,.kpi,.tw,.rml,.ag,.intg{border-color:#ccc;background:#fff}
}
.rail-g{display:flex;flex-direction:column;gap:1px}

/* --------------------------------------------------------------- scrollbars
   The default light scrollbar on a dark board reads as a bug. */
*{scrollbar-color:var(--panel-3) transparent;scrollbar-width:thin}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--panel-3);border-radius:6px;border:2px solid var(--ground)}
::-webkit-scrollbar-thumb:hover{background:var(--line)}
.kan.kflow::-webkit-scrollbar-thumb{border-color:var(--ground)}

/* A hint that the job board runs past the right edge. */
.kan-wrap{position:relative}
.kan-wrap::after{
  content:"";position:absolute;top:0;right:0;bottom:10px;width:42px;pointer-events:none;
  background:linear-gradient(to right,var(--ground-0),var(--ground))
}
span.susp{color:var(--warn);font-weight:700}
.kan.k3{grid-template-columns:repeat(3,minmax(200px,1fr))}
@media(max-width:860px){.kan.k3{grid-template-columns:repeat(2,minmax(180px,1fr))}}
@media(max-width:520px){.kan.k3{grid-template-columns:1fr}}
.ag-stats{margin-top:auto}

/* The month grid is the one thing that genuinely cannot compress to a phone
   without becoming unreadable, so let it scroll inside its own box instead of
   dragging the page sideways. */
@media(max-width:640px){
  .cal-scroll{overflow-x:auto}
  .cal-scroll .cal{min-width:560px}
  .views{padding:16px 14px 90px}
  .top{padding:16px 14px 14px}
}
.tk.wait{border-color:var(--warn)}
.tk-wait{margin-top:7px;font-size:10.5px;color:var(--ink-3);line-height:1.4}
.tk-wait.over{color:var(--warn);font-weight:600}

/* An empty stage still has to be on the board, because a gap in the pipeline is
   information. It just does not deserve a full column. */
.kan-col.nil{
  min-width:34px;max-width:34px;background:var(--ground);border-style:dashed;
  align-items:center;justify-content:flex-start;padding:10px 0;overflow:hidden
}
.kan-col.nil .nil-t{
  writing-mode:vertical-rl;font-size:9.5px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--ink-3);white-space:nowrap;
  max-height:100%;overflow:hidden;text-overflow:ellipsis
}
.kan.kflow{grid-auto-columns:min-content}
.kan.kflow .kan-col:not(.nil){min-width:186px;width:186px}
span.dim{color:var(--ink-3);font-style:italic;font-weight:400}

/* ------------------------------------------------------- period control ---
   Two questions live on the Overview: one about a stretch of time and one
   about right now. The control has to make it obvious which one it governs. */
.per{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin-bottom:18px}
.per-l{display:flex;flex-direction:column;line-height:1.25;margin-right:auto;padding-left:4px}
.per-l b{font-size:15px;font-weight:700;letter-spacing:-.015em}
.per-l span{font-size:11px;color:var(--ink-3)}
.strip-note{margin:8px 0 0;font-size:11.5px;color:var(--ink-3)}

/* period summary table: dense, no chrome, zero rows dimmed rather than hidden */
.sumt{width:100%;font-size:12.5px}
.sumt td{padding:6px 0;border-bottom:1px solid var(--line-soft);vertical-align:baseline}
.sumt tr:last-child td{border-bottom:0}
.sumt tr.nil{opacity:.42}
.sumt td.num{text-align:right;width:74px;font-size:12px}

/* ----------------------------------------------------------- theme toggle */
.theme-tog{
  display:flex;align-items:center;gap:8px;width:100%;text-align:left;cursor:pointer;
  background:none;border:1px solid var(--line);border-radius:var(--r);
  color:var(--ink-2);font-family:inherit;font-size:11.5px;font-weight:600;
  padding:6px 9px;margin-top:3px
}
.theme-tog:hover{background:var(--panel-2);color:var(--ink);border-color:var(--line)}
.tt-i{width:14px;height:14px;flex:none;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round}
.tt-sun{display:none}
.theme-tog.is-light .tt-sun{display:block}
.theme-tog.is-light .tt-moon{display:none}
.tt-lab{flex:1}

/* ---------------------------------------------------- contrast corrections
   Each of these was measured failing 4.5:1 against its own composited
   background, in one theme or both. A pill nobody can read is not a subtle
   pill, it is a missing label. */
.pill.mute{color:var(--ink-2)}
.ag.off .ag-av{color:var(--ink-2)}
.dotr.off{opacity:1;color:var(--ink-2)}

/* ------------------------------------------------------------ info marker */
.ihelp{
  display:inline-grid;place-items:center;width:17px;height:17px;flex:none;
  background:none;border:0;padding:0;cursor:pointer;color:var(--ink-3);vertical-align:middle
}
.ihelp:hover{color:var(--lime)}
.ihelp svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round}
.sec-h .ihelp{margin-left:-4px}
.card h3 .ihelp{margin-left:6px}
#viewInfo{display:inline-flex;margin-left:8px;vertical-align:middle}
#viewInfo .ihelp{width:19px;height:19px}
#viewInfo .ihelp svg{width:17px;height:17px}
.top h1{display:inline}

.ipop{
  position:fixed;z-index:80;width:min(340px,calc(100vw - 16px));
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--shadow)
}
.ipop-h{
  display:flex;align-items:center;gap:10px;padding:11px 13px 9px;border-bottom:1px solid var(--line-soft);
  font-size:12px;font-weight:700;letter-spacing:.02em
}
.ipop-h span{flex:1}
.ipop-x{background:none;border:0;color:var(--ink-3);font-size:18px;line-height:1;cursor:pointer;padding:0 2px}
.ipop-x:hover{color:var(--ink)}
.ipop-b{padding:12px 13px 14px;font-size:12.5px;line-height:1.6;color:var(--ink-2)}
.ipop-b p{margin:0 0 9px}
.ipop-b p:last-child{margin-bottom:0}
.ipop-b b{color:var(--ink)}
.ipop-b ul{margin:0;padding-left:16px;display:flex;flex-direction:column;gap:6px}
.ag-av svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}

/* ---------------------------------------------------------------- files
   A file list has three jobs on one line: say what it is, open it, remove it.
   The name is the target, because on a phone the whole row being tappable is
   how you open the wrong thing. */
.files li{display:flex;align-items:center;gap:10px}
.files li small{color:var(--ink-3);font-size:11.5px;white-space:nowrap}
.files li .btn{margin-left:auto}
.lnk{background:none;border:0;padding:0;font:inherit;color:var(--ink);
     text-align:left;cursor:pointer;text-decoration:underline;
     text-underline-offset:2px;text-decoration-color:var(--line)}
.lnk:hover{text-decoration-color:currentColor}
.lnk:disabled{opacity:.5;cursor:default}

/* ============================================================================
   THE PHONE
   ----------------------------------------------------------------------------
   Adam works off a phone standing in a half built kitchen. Measured signed in at
   390x844 and 360x800, the console was close to unusable there and none of it
   showed up on a laptop:

     · every screen opened on 700px of navigation and no content at all. The
       first pixel of an actual view sat between 881px and 1447px down a 844px
       screen, on 13 screens out of 13.
     · once you scrolled to the content the nav was gone, and getting back to it
       from the bottom of the Agents screen was a 4,779px scroll.
     · the sticky header ate between 42% and 91% of the screen and stayed there.
       On Jobs at 360px it left 70px of jobs.
     · Money showed the job name and title, with Outstanding, Due and Margin all
       off the right hand edge. Contacts hid the phone number, which is the only
       reason to open Contacts on a phone.
     · the jobs board showed one stage column out of six.

   Everything below is additive and lives at the end of the file, so nothing
   above 900px changes.
   ============================================================================ */

/* ----------------------------------------------------- phone: navigation
   The sidebar was stacking as a 700px block on top of every screen, and once it
   scrolled away there was no second copy of the nav anywhere. It becomes a bar
   along the bottom, where a thumb already is. */
@media(max-width:900px){
  .side{
    position:fixed;left:0;right:0;bottom:0;top:auto;height:auto;width:auto;
    flex-direction:row;padding:0 0 env(safe-area-inset-bottom);z-index:75;
    border-right:0;border-top:1px solid var(--line);
    overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch
  }
  .side .brand,.side .side-foot,.side .nav-grp{display:none}
  .side nav{display:flex;flex:0 0 auto;padding:0;gap:0}
  .navi{
    position:relative;flex-direction:column;gap:4px;width:auto;
    min-width:76px;min-height:56px;justify-content:center;text-align:center;
    border-radius:0;padding:8px 6px;font-size:11px;line-height:1.2
  }
  .navi .ico,.navi .ico svg{width:19px;height:19px}
  .navi .badge{position:absolute;top:4px;right:12px;margin-left:0}
  .views{padding-bottom:calc(74px + env(safe-area-inset-bottom))}

  /* A floating page control must not sit on top of the nav bar. */
  .cmt-fab{bottom:calc(74px + env(safe-area-inset-bottom));min-height:44px;padding:12px 16px}
  /* The undo strip had the same z-index as nothing in particular and lost to the
     comment button, so the eight second window expired with the button
     underneath it and unreachable. */
  .undo-strip{z-index:78;bottom:calc(84px + env(safe-area-inset-bottom))}
}

/* A floating page control has no business existing while a record is open.
   Both are appended to body by comments.js, so they are always later siblings
   than the static #drawer. Correct at every width, not just on a phone. */
#drawer.on ~ .cmt-fab,#drawer.on ~ .cmt-banner{display:none}

/* The banner parked itself at top:-60px, which is the only number in this file
   that assumed it wraps to one line. It measures 95px on a phone, so 35px of
   lime sat permanently over the wordmark. Park it by its own height instead. */
.cmt-banner{top:0;transform:translate(-50%,-100%);transition:transform .18s}
body.cmt-on .cmt-banner{transform:translate(-50%,0)}

/* A lede-only info marker is a phone affordance and has no business beside a
   title whose lede is already on screen. */
#viewInfo.lede-only{display:none}

@media(max-width:700px){
  /* ------------------------------------------------------- phone: the header
     .top was a flex row that could not wrap, so a fixed width Export and sign
     out cluster squeezed the title down to 71px, and a 350 character lede
     reflowed into a 640px ribbon that then pinned itself over the content. The
     lede moves behind the info marker, which is already where explanatory copy
     lives in this product. */
  .top{flex-wrap:wrap;gap:10px;padding:14px 16px}
  .top-l{flex:1 1 100%}
  .top-r{flex:1 1 100%;justify-content:flex-start}
  .top h1{font-size:21px}
  .view-lede{display:none}
  #viewInfo.lede-only{display:inline-flex}

  /* --------------------------------------------------------- phone: tables
     th{white-space:nowrap} was the single biggest contributor: nine headers
     refusing to wrap set the intrinsic minimum width, and 28px of padding per
     column ate 252px of the compliance table before a character of data. */
  th{white-space:normal;font-size:11px;padding:9px 10px}
  td{padding:12px 10px}
  .pill{font-size:11px;padding:4px 8px}
  /* Keep the identity column in place while swiping sideways, so you do not
     lose track of which row you are reading. */
  .tw thead th:first-child,.tw tbody td:first-child{position:sticky;left:0;z-index:1}
  .tw thead th:first-child{background:var(--panel-2)}
  .tw tbody td:first-child{background:var(--panel)}

  /* ---------------------------------------------------- phone: the jobs board
     Fifteen stages at a fixed 186px is 1,590px of board in a 362px box, and
     nine of them collapsed to 34px slivers of sideways 9.5px text. Written
     against .kan.kflow rather than .kan: the two class selector further up this
     file beats the 520px rule, which is why that rule has never once fired. It
     stacks instead, which is the one gesture a phone does perfectly. */
  .kan.kflow{grid-auto-flow:row;grid-auto-columns:auto;grid-template-columns:1fr;overflow-x:visible}
  .kan.kflow .kan-col:not(.nil){min-width:0;width:auto}
  .kan.kflow .kan-col.nil{min-width:0;max-width:none;width:auto;align-items:stretch;padding:0}
  .kan.kflow .kan-col.nil .nil-t{
    writing-mode:horizontal-tb;font-size:11px;padding:10px 13px;
    max-height:none;white-space:normal;text-align:left
  }
  .kan-wrap::after{display:none}

  /* ---------------------------------------------------------- phone: drawer
     It wasted half its width on a 130px label column, and height:100vh put its
     bottom under the browser chrome. Full width removes the scrim strip, which
     was one of the two ways to close it, so .dw-x has to grow in the same
     change or the only way out becomes a 19x24 target. */
  #drawer{width:100%;height:100dvh}
  .dw-body{padding:18px 16px 40px}
  .dl{grid-template-columns:1fr;gap:2px 0}
  .dl dt{margin-top:11px}
  .dl dt:first-of-type{margin-top:0}
  .btnrow{flex-direction:column;align-items:stretch}
  .btnrow .btn{width:100%;min-height:48px}

  /* ----------------------------------------------------- phone: tap targets
     Only the ones that block a task. Widths are left alone; the vertical hit
     area grows. */
  .btn,.btn.sm,.seg button{
    min-height:44px;padding-top:0;padding-bottom:0;
    display:inline-flex;align-items:center;justify-content:center
  }
  .navi{min-height:44px}
  .theme-tog,.rail-i,.r-tick,.cmt-cancel,.cmt-save{min-height:44px}
  .dw-x{width:44px;height:44px;display:grid;place-items:center;font-size:26px;padding:0;margin:-10px -10px -10px 0}
  /* Grow the info marker's hit area with a pseudo element. A negative margin
     would shift the baseline of the .sec-h it sits inside. */
  .ihelp{position:relative}
  .ihelp::after{content:"";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}

  /* ---------------------------------------------------------- phone: sign in
     14px inputs make iOS zoom the page the instant the email field is tapped,
     and it has to be pinched back out before the password field is reachable.
     16px is the exact threshold, which is why the six digit code box at 20px
     was the one control on that screen that measured fine. */
  .auth-field input{min-height:48px;font-size:16px}
  .auth-btn{min-height:48px}

  /* ------------------------------------------------------ phone: comment pop
     262px centred means any pin outside the middle fifth of the screen hangs
     off the edge. It becomes a sheet at the bottom, which is also where a thumb
     is. The z-index on the layer is required, not optional: .cmt-layer creates
     a stacking context that would otherwise trap Save behind the comment button. */
  .cmt-pop{position:fixed;left:8px;right:8px;bottom:8px;top:auto;width:auto;transform:none}
  body.cmt-on .cmt-layer{z-index:72}
}

/* ------------------------------------------------------- phone: table -> cards
   A table is a desktop shape. On a phone the console was showing the job name
   and the title, with every number off the right hand edge behind an overlay
   scrollbar that draws two pixels, so nothing on screen even said the columns
   existed. Each row becomes a labelled block instead, using the data-l written
   by U.table. No per-row control is added, so the no-edit-on-a-row rule holds.
   This deliberately sits AFTER the sticky-first-column stopgap above and turns
   it off, because there is no longer a sideways scroll to keep your place in. */
@media(max-width:700px){
  .tw{overflow-x:visible}
  .tw table,.tw thead,.tw tbody,.tw tr,.tw td{display:block;width:auto}
  .tw thead{display:none}
  .tw tbody tr{
    border:1px solid var(--line);border-radius:12px;background:var(--panel);
    padding:12px 14px;margin:0 0 10px
  }
  .tw tbody tr:last-child{margin-bottom:0}
  .tw td{
    position:static;padding:5px 0;border:0;text-align:left;
    display:grid;grid-template-columns:minmax(0,42%) minmax(0,1fr);gap:12px;align-items:baseline
  }
  .tw td::before{
    content:attr(data-l);color:var(--ink-3);font-size:11px;letter-spacing:.04em;
    text-transform:uppercase;font-weight:600
  }
  /* The first cell is the row's identity, so it reads as a heading rather than
     as another label/value pair. */
  .tw td.td-1st{
    display:block;font-weight:700;font-size:15px;padding:0 0 8px;
    margin:0 0 6px;border-bottom:1px solid var(--line)
  }
  .tw td.td-1st::before{display:none}
  .tw td.num{text-align:left}
  .tw td:empty{display:none}
  .tw tr.tr-empty{border:0;background:none;padding:0}
  .tw tr.tr-empty td{display:block;padding:14px 0}
  .tw tr.tr-empty td::before{display:none}
}

/* The compliance answer used to live only in a title attribute, which a touch
   screen never shows: there is no long press tooltip on iOS Safari or Chrome
   Android, so on a phone the reasoning did not exist at any scroll position.
   The words are always in the markup now, hidden beside the dot on a desktop
   where the tooltip works, and shown on a phone where it does not. */
.dot-say{display:none}
@media(max-width:700px){
  .dot-say{display:block;font-size:12px;line-height:1.45;color:var(--ink-2);margin-top:3px}
  .tw td .dotr{margin-right:6px}
}

/* ------------------------------------------------------------------ pricing
   The Pricing screen. Every colour is a token, so the light theme follows
   without a second set of rules — see the --lime / --lime-fill note at the top
   for why a fill and a text accent are not interchangeable. */
.pr-tabs{margin-bottom:16px}

/* The profit and risk gate. Deliberately the loudest thing on the screen: it is
   the one output that answers "do I send this or not". */
.pr-gate{
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  border:1px solid var(--line);border-left-width:4px;border-radius:var(--r);
  padding:14px 18px;margin:14px 0
}
.pr-gate-l{font-size:13px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}
.pr-gate-b{font-size:12.5px;color:var(--ink-2);line-height:1.55;flex:1;min-width:220px}
.pr-gate-b b{color:var(--ink)}
.pr-gate.green {border-left-color:var(--good);background:var(--good-bg)}
.pr-gate.green  .pr-gate-l{color:var(--good)}
.pr-gate.orange{border-left-color:var(--warn);background:var(--warn-bg)}
.pr-gate.orange .pr-gate-l{color:var(--warn)}
.pr-gate.red   {border-left-color:var(--crit);background:var(--crit-bg)}
.pr-gate.red    .pr-gate-l{color:var(--crit)}

/* An unconfirmed rate is not an error and not a warning about something going
   wrong — it is a number waiting on a person, so it gets its own weight. */
.pr-amber{background:var(--warn-bg)}

.pr-cplx{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:6px;margin-top:12px}

/* Install lines. A row is one editable line of the subcontractor order, so the
   amount sits on the same line as the inputs that produce it. */
.pr-lines{display:flex;flex-direction:column;gap:8px;margin-bottom:8px}
.pr-line{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.pr-line select{
  flex:1;min-width:170px;background:var(--panel-2);border:1px solid var(--line);
  border-radius:var(--r);color:var(--ink);padding:7px 10px;font-size:12.5px;font-family:inherit
}
.pr-line input{
  width:90px;background:var(--panel-2);border:1px solid var(--line);border-radius:var(--r);
  color:var(--ink);padding:7px 10px;font-size:12.5px;font-family:inherit
}
.pr-line-a{min-width:88px;text-align:right;font-variant-numeric:tabular-nums;font-weight:700;font-size:13px}

@media(max-width:700px){
  /* 16px or iOS zooms the page the moment one of these is tapped, and the
     field next to it has to be pinched back into reach. */
  .pr-line select,.pr-line input{font-size:16px}
  .pr-line input{width:100%}
  .pr-line-a{text-align:left}
  .pr-gate{padding:12px 14px}
}

/* A rate path like risk_gate.complexity_loadings.two_pac_doors has no space in
   it to break at. On a phone the table stacks into labelled lines, so an
   unbreakable string drags the whole page sideways — measured at 216px of
   overflow before this rule existed. */
.pr-path{overflow-wrap:anywhere;word-break:break-word}
