:root{
  --ground:#FFFFFF; --paper:#FBF9F4; --cream:#F7F3EA; --rule:#E4E0D6; --rule-strong:#CFC8B8; --agg-tint:rgba(184,153,90,.07);
  --ink:#1A1A1A; --body:#3A3A3A; --muted:#6E6E6E; --faint:#9A9A9A;
  --gold:#B8995A; --gold-ink:#86682F; --agent:#F4ECDB;
  --built:#2E6B4A; --built-bg:#E7F1EA; --prog:#8A6212; --prog-bg:#FAEFD8; --pend:#8A8477; --pend-bg:#F2F0EA;
  --stated:#2E6B4A; --inferred:#8A6212; --assume:#A2412F;
  --sans:"Poppins","Helvetica Neue",Arial,sans-serif; --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;
}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){
  --ground:#14120E; --paper:#1A1713; --cream:#211D17; --rule:#39322A; --rule-strong:#52493C; --agg-tint:rgba(184,153,90,.10);
  --ink:#F3EEE4; --body:#D8D1C3; --muted:#A39A8B; --faint:#7C7466;
  --gold:#C9AA6B; --gold-ink:#D8BD86; --agent:#352B1B;
  --built:#86C7A1; --built-bg:#1E2C24; --prog:#E2B55E; --prog-bg:#2E2617; --pend:#8F8879; --pend-bg:#211E19;
  --stated:#86C7A1; --inferred:#E2B55E; --assume:#EB9580;
}}
:root[data-theme="dark"]{
  --ground:#14120E; --paper:#1A1713; --cream:#211D17; --rule:#39322A; --rule-strong:#52493C; --agg-tint:rgba(184,153,90,.10);
  --ink:#F3EEE4; --body:#D8D1C3; --muted:#A39A8B; --faint:#7C7466;
  --gold:#C9AA6B; --gold-ink:#D8BD86; --agent:#352B1B;
  --built:#86C7A1; --built-bg:#1E2C24; --prog:#E2B55E; --prog-bg:#2E2617; --pend:#8F8879; --pend-bg:#211E19;
  --stated:#86C7A1; --inferred:#E2B55E; --assume:#EB9580;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;scrollbar-gutter:stable}
@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}}
body{background:var(--ground);color:var(--body);font:400 15px/1.6 var(--sans);-webkit-font-smoothing:antialiased}
a{color:var(--gold-ink);text-underline-offset:3px}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}
[hidden]{display:none!important}
.mono{font-family:var(--mono);font-size:.86em}
.muted{color:var(--muted)} .small{font-size:13px}
.page{max-width:1560px;margin:0 auto;padding:22px 28px 80px}
.rail{position:sticky;top:0;align-self:start;height:100vh;padding-block:30px 24px;display:flex;flex-direction:column;gap:26px}
.brand{font-weight:200;letter-spacing:.42em;font-size:15px;color:var(--ink)}
.brand small{display:block;letter-spacing:.16em;font-size:9.5px;font-weight:500;color:var(--gold-ink);text-transform:uppercase;margin-top:4px}
nav{display:flex;flex-direction:column;gap:8px}
.rail nav a{display:block;text-decoration:none;color:var(--muted);padding:10px 12px;border-radius:10px;border:1px solid transparent}
.rail nav a b{display:block;font-weight:500;color:var(--ink);font-size:14.5px}
.rail nav a span{display:block;font-size:12px;line-height:1.45;margin-top:2px}
.rail nav a .cnt{font:500 11px/1 var(--mono);font-style:normal;color:var(--gold-ink);display:block;margin-top:4px}
.rail nav a:hover{border-color:var(--rule)}
.rail nav a.on{background:var(--cream);border-color:var(--rule-strong)}
.editor{display:flex;flex-direction:column;gap:5px;font:500 11px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.editor input{font:400 13px/1.2 var(--sans);letter-spacing:0;text-transform:none;padding:8px 10px;border-radius:8px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);width:100%}
.regnote{font-size:12px;color:var(--muted);line-height:1.5;border-top:1px solid var(--rule);padding-top:14px;margin:0}
main{min-width:0;padding-block:30px 90px}
.topline{display:flex;justify-content:space-between;align-items:baseline;border-bottom:1px solid var(--rule);padding-bottom:10px;margin-bottom:34px;font-size:12px;color:var(--muted)}
.topline em{font-style:italic}
h1{font-weight:200;font-size:clamp(32px,4.6vw,46px);line-height:1.06;letter-spacing:-.015em;color:var(--ink);margin:0 0 12px;text-wrap:balance}
h2{font-weight:200;font-size:26px;color:var(--ink);margin:0 0 8px}
h3{font-weight:500;font-size:15px;color:var(--ink);margin:0 0 8px}
h4{font:500 11px/1.3 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:0 0 10px}
.lead{font-weight:300;font-size:16.5px;color:var(--body);max-width:66ch;margin:0 0 22px}
p{max-width:68ch;margin:0 0 12px}
.vhead{margin-bottom:24px}
footer{margin-top:70px;padding-top:16px;border-top:1px solid var(--rule);display:flex;justify-content:space-between;font-size:12px;color:var(--faint)}
.scroll{overflow-x:auto}
/* How old the view is, and the way to make it new. Visible because nothing refreshes on a
   timer any more: staleness you can see is a different thing from staleness hidden from you. */
.age{font:400 11.5px/1 var(--mono);color:var(--muted);background:transparent;border:1px solid transparent;
  border-radius:6px;padding:4px 7px;margin-left:10px;cursor:pointer}
.age:hover{color:var(--ink);border-color:var(--rule)}
.age.stale{color:var(--gold-ink);border-color:var(--gold)}
.age:empty{display:none}

.notice{background:var(--cream);border-radius:10px;padding:14px 16px;font-size:14px;margin-bottom:18px}
/* A read that failed is not an empty catalogue. It gets room, a heading and a way out,
   and everything it could not load stays off the screen rather than showing as zero. */
.notice.big{padding:22px 24px;display:flex;flex-direction:column;gap:10px;max-width:760px}
.notice.big b{font-weight:500;font-size:17px;color:var(--ink)}
.notice.big span{font-size:14px;line-height:1.55;color:var(--muted)}
.notice.big .mono{font-family:var(--mono);font-size:12.5px;color:var(--ink)}
.notice.big .acts{display:flex;gap:10px;align-items:center;margin-top:4px}
.notice.bad{background:var(--cream);border:1px solid var(--gold)}
body.unreadable .coverwrap,body.unreadable .agents,body.unreadable .bar,
body.unreadable .scroll,body.unreadable footer{display:none}
.btn{font:500 13px/1 var(--sans);border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);padding:9px 14px;border-radius:8px;cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;gap:6px}
.btn:hover{border-color:var(--gold)}
.btn.primary{background:var(--ink);color:var(--ground);border-color:var(--ink)}
.btn.danger{color:var(--assume)}
.btn:disabled{opacity:.5;cursor:default}
.tip{width:17px;height:17px;flex:none;border-radius:50%;border:1px solid var(--rule-strong);background:var(--ground);color:var(--muted);font:500 10px/1 var(--mono);cursor:pointer;padding:0;vertical-align:1px}
.tip:hover{border-color:var(--gold);color:var(--gold-ink)}
.pop{position:fixed;z-index:70;max-width:min(420px,calc(100vw - 24px));background:var(--ground);border:1px solid var(--rule-strong);border-radius:12px;box-shadow:0 18px 40px rgba(20,18,14,.16);padding:16px 18px;font-size:13.5px;line-height:1.55;max-height:70vh;overflow:auto}
.pop h5{font:500 14px/1.3 var(--sans);color:var(--ink);margin:0 0 8px}
.pop p{margin:0 0 8px;max-width:none}
.pop ul{margin:0 0 8px;padding-left:18px}
.pop li{margin:3px 0}
.pop .k{font-weight:500;color:var(--ink)}
.pop .close{position:absolute;top:8px;right:10px;border:0;background:none;color:var(--faint);font-size:16px;cursor:pointer}

/* coverage cards */
.cover{display:grid;grid-template-columns:repeat(auto-fit,minmax(184px,1fr));gap:12px;margin-bottom:26px}

.cov{border:1px solid var(--rule);border-radius:12px;padding:14px 16px}
.cov .t{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.cov .t b{font-weight:500;color:var(--ink);font-size:15px}
.cov .t span{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.cov .barline{display:flex;height:8px;border-radius:999px;overflow:hidden;background:var(--pend-bg);margin:10px 0 8px}
.cov .barline i{display:block;height:100%}
.cov .barline .b{background:var(--built)} .cov .barline .p{background:var(--prog)}
.cov .k{display:flex;flex-wrap:wrap;gap:10px;font-size:11.5px;color:var(--muted)}
.cov .k b{font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums}
.cov .mat{margin-top:8px;font-size:11.5px;color:var(--muted);display:flex;gap:8px;flex-wrap:wrap}

/* filter bar */
.bar{display:flex;flex-wrap:wrap;gap:10px 14px;align-items:center;margin-bottom:12px}
.srch input{font:400 13.5px/1.2 var(--sans);padding:9px 12px;border-radius:999px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);width:280px;max-width:100%}
.fpills{display:flex;flex-wrap:wrap;gap:4px;border:1px solid var(--rule);border-radius:999px;padding:3px}
.fpills button{font:500 12.5px/1 var(--sans);border:0;background:transparent;color:var(--muted);padding:7px 11px;border-radius:999px;cursor:pointer}
.fpills button[aria-pressed="true"]{background:var(--ink);color:var(--ground)}
.count{font-size:12.5px;color:var(--muted);margin-left:auto}
.bar2{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:14px}
.legend2{display:flex;flex-wrap:wrap;gap:12px;font-size:11.5px;color:var(--muted);margin-left:auto}
.legend2 span{display:inline-flex;align-items:center;gap:5px}
.legend2 i{width:10px;height:10px;border-radius:3px;display:inline-block}

/* table */
table.tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.tbl th{font:500 10.5px/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);text-align:left;padding:0 12px 8px 0;border-bottom:1px solid var(--rule-strong);vertical-align:bottom;white-space:nowrap}
.tbl td{padding:10px 12px 10px 0;border-bottom:1px solid var(--rule);vertical-align:top}
.tbl td.num{font-variant-numeric:tabular-nums}
.cat tbody tr{cursor:pointer}
.cat tbody tr:hover td{background:var(--paper)}
.cat tbody tr:focus-visible{outline:2px solid var(--gold);outline-offset:-2px}
.cat .wf{min-width:230px}
.cat .wf b{font-weight:500;color:var(--ink);display:block;font-size:14px}
.cat .wf .mono{color:var(--gold-ink);font-size:11px}
.cat .wf .o{color:var(--muted);font-size:12.5px;line-height:1.4;margin-top:2px}
.cell-cls{white-space:nowrap}
.state{display:inline-flex;align-items:center;gap:6px;font:500 11.5px/1 var(--sans);padding:5px 8px;border-radius:6px;border:1px solid transparent}
.state.Built{background:var(--built-bg);color:var(--built);border-color:var(--built)}
.state.In-progress{background:var(--prog-bg);color:var(--prog);border-color:var(--prog)}
.state.Pending{background:var(--pend-bg);color:var(--pend);border-color:var(--rule-strong)}
.state.NA{color:var(--faint);border:1px dashed var(--rule)}
.state.TBC{color:var(--gold-ink);border:1px dashed var(--gold);background:transparent}
/* undecided, but somebody has argued for a mark: the argument shows, the decision does not */
.state.TBC.prop{gap:5px}
.state.TBC .pr{font:500 9.5px/1 var(--mono);letter-spacing:.04em;padding:2px 4px;border-radius:4px;
  background:var(--cream);color:var(--gold-ink)}
.cov .k .tbcn{color:var(--gold-ink)}
.state .dots{letter-spacing:1px;font-size:9px}
.state .mk{font:500 9.5px/1 var(--mono);opacity:.75}
.st-chip{font:500 11px/1 var(--sans);padding:4px 8px;border-radius:999px;border:1px solid var(--rule-strong);color:var(--muted);white-space:nowrap}
.st-chip.s-Drafting,.st-chip.s-In-review{color:var(--inferred);border-color:currentColor}
.st-chip.s-Signed-off,.st-chip.s-In-build{color:var(--stated);border-color:currentColor}
.pill{display:inline-flex;align-items:center;gap:5px;font:500 11px/1 var(--sans);padding:4px 8px;border-radius:999px;border:1px solid var(--rule-strong);color:var(--muted);white-space:nowrap}
.pill.stated{color:var(--stated);border-color:currentColor}
.pill.inferred{color:var(--inferred);border-color:currentColor}
.pill.assumption{color:var(--assume);border-color:currentColor;border-style:dashed}
.chip{display:inline-block;font:400 12px/1.2 var(--sans);padding:5px 9px;border-radius:6px;background:var(--ground);border:1px solid var(--rule);color:var(--ink)}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip.ag{background:var(--agent);border-color:var(--gold)}

/* flow list (shared by drawer + builder preview) */
ol.flow{list-style:none;padding:0;margin:0}
ol.flow li{position:relative;padding:0 0 14px 34px;border-left:2px solid var(--rule);margin-left:10px}
ol.flow li:last-child{border-left-color:transparent}
/* A phase header inside a merged flow. It is a list item so the border rail runs through it
   unbroken — the phases are one process, and a gap in the rail would say otherwise. No number
   bubble, because it is not a step. */
ol.flow li.phasehd{padding:16px 0 8px 34px;display:flex;align-items:baseline;gap:10px}
ol.flow li.phasehd:first-child{padding-top:2px}
ol.flow li.phasehd b{font-size:12px;letter-spacing:.04em;text-transform:uppercase}
ol.flow li.phasehd::before{content:"";position:absolute;left:-5px;top:50%;width:8px;height:8px;
  border-radius:50%;background:var(--rule)}
ol.flow .n{position:absolute;left:-11px;top:0;width:20px;height:20px;border-radius:50%;background:var(--ink);color:var(--ground);font:500 10px/20px var(--mono);text-align:center}
ol.flow li.gate .n{border-radius:3px;transform:rotate(45deg)}
ol.flow li.gate .n span{display:block;transform:rotate(-45deg)}
.sb .hd{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.sb .hd b{font-weight:500;color:var(--ink);font-size:14px}
.sb .act{font:500 11.5px/1 var(--sans);padding:4px 8px;border-radius:6px;border:1px solid var(--rule)}
.sb .act.agent{background:var(--agent);border-color:var(--gold);color:var(--gold-ink)}
.sb .act.system{border-style:dashed;color:var(--muted)}
.sb .act.external{background:var(--paper);color:var(--muted)}
.sb .act.human{color:var(--ink)}
.sb .slot{font:500 10.5px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.sb p{margin:5px 0 4px;font-size:13.5px;max-width:72ch}
.sb .io{font-family:var(--mono);font-size:11.5px;color:var(--muted)}
.sb .io b{color:var(--gold-ink);font-weight:400}
.sb .rule{font-size:12.5px;color:var(--muted);margin-top:3px}
.sb .br{font-size:12px;color:var(--gold-ink);margin-top:4px;font-family:var(--mono)}

/* drawer */
.scrim{position:fixed;inset:0;background:rgba(20,18,14,.28);z-index:40}
/* The drawer is where the work happens — reading a flow, comparing seven classes across —
   so it takes the width it needs. Prose inside it is still capped: a 1,400px line of text
   is unreadable however much room there is. Tables use the whole thing. */
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(1500px,97vw);background:var(--ground);border-left:1px solid var(--rule-strong);z-index:41;overflow-y:auto;padding:24px 34px 70px;box-shadow:-18px 0 40px rgba(20,18,14,.10)}
.drawer .needs,.drawer .rels,.drawer .syslist,.drawer .hist{max-width:86ch}
.drawer .lead,.drawer .sec > p{max-width:76ch}
.drawer .dh{display:flex;justify-content:space-between;gap:12px;align-items:flex-start;position:sticky;top:-24px;background:var(--ground);padding:8px 0 10px;margin:-8px 0 6px;z-index:2;border-bottom:1px solid var(--rule)}
.drawer .dh .save{font-size:12px;color:var(--muted);align-self:center}
.drawer .dh .save.ok{color:var(--built)}
.drawer h2{margin:2px 0 4px}
.drawer .acts{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 18px}
.sec{border-top:1px solid var(--rule);padding:18px 0 4px}
.sec:first-of-type{border-top:0}
@media (max-width:640px){.drawer{padding:16px 16px 70px}}

/* forms */
.fgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px;margin-bottom:16px}
.fgrid .full{grid-column:1/-1}
@media (max-width:640px){.fgrid{grid-template-columns:minmax(0,1fr)}}
.fld{display:flex;flex-direction:column;gap:5px;font-size:11.5px;color:var(--muted);min-width:0}
.fld > span{font-weight:500;letter-spacing:.04em;display:flex;align-items:center;gap:6px}
.fld input,.fld select,.fld textarea{font:400 13.5px/1.45 var(--sans);padding:8px 10px;border-radius:8px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);width:100%;min-width:0}
.fld textarea{resize:vertical;min-height:56px}
.fld input:focus,.fld select:focus,.fld textarea:focus{outline:2px solid var(--gold);outline-offset:0;border-color:var(--gold)}
.fld .hint{font-size:11px;color:var(--faint)}
.checks{display:flex;flex-wrap:wrap;gap:6px}
.checks label{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink);padding:5px 9px;border:1px solid var(--rule);border-radius:6px;cursor:pointer;background:var(--ground)}
.checks label:has(input:checked){border-color:var(--gold);background:var(--agent)}
.checks input{accent-color:var(--gold);margin:0;width:auto;padding:0}
.clsgrid{display:grid;grid-template-columns:150px repeat(3,minmax(0,1fr));gap:8px 10px;align-items:center;font-size:12.5px}
.clsgrid.cls5{grid-template-columns:150px repeat(4,minmax(0,1fr))}
.clsgrid select:disabled{opacity:.42;cursor:not-allowed}
.clsgrid .hd{font:500 10.5px/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.clsgrid .nm{font-weight:500;color:var(--ink);font-size:13.5px}
.clsgrid select{font:400 13px/1.2 var(--sans);padding:7px 8px;border-radius:7px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);width:100%}
@media (max-width:700px){.clsgrid,.clsgrid.cls5{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.clsgrid .hd{display:none}.clsgrid .nm{grid-column:1/-1;margin-top:8px}}
.rowcard{border:1px solid var(--rule);border-radius:10px;padding:10px 12px;margin-bottom:8px;background:var(--ground)}
.rowcard .rh{display:grid;grid-template-columns:26px minmax(0,1.5fr) minmax(0,1fr) minmax(0,1fr) auto;gap:8px;align-items:end}
.rowcard .rb{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:8px}
.rowcard .rb .wide{grid-column:1/-1}
.rowcard .num{font:500 12px/1 var(--mono);color:var(--gold-ink);align-self:center}
.rowcard .tools{display:flex;gap:4px}
.rowcard.two .rh{grid-template-columns:minmax(0,2fr) minmax(0,1fr) auto}
.cell{display:flex;flex-direction:column;gap:3px;font-size:10.5px;color:var(--faint);min-width:0}
.cell input,.cell select,.cell textarea{font:400 13px/1.4 var(--sans);padding:7px 9px;border-radius:7px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);width:100%;min-width:0}
.cell textarea{resize:vertical;min-height:48px}
.ib{font:500 12px/1 var(--sans);border:1px solid var(--rule);background:var(--ground);color:var(--muted);width:28px;height:30px;border-radius:7px;cursor:pointer}
.ib:hover{color:var(--ink);border-color:var(--gold)}
@media (max-width:760px){.rowcard .rh,.rowcard.two .rh{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.rowcard .rh .num{grid-column:1/-1}.rowcard .rb{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}

/* builder */
.bstart{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-bottom:20px}
.bstart .opt{border:1px solid var(--rule);border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:10px;font-size:13.5px}
.bstart .opt b{font-weight:500;color:var(--ink);font-size:16px}
.bstart .opt select{font:400 13px var(--sans);padding:8px;border-radius:8px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);max-width:100%}
.bstart .opt .grow{flex:1}
@media (max-width:860px){.bstart{grid-template-columns:minmax(0,1fr)}}
.bbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;padding:12px 0;border-top:1px solid var(--rule-strong);border-bottom:1px solid var(--rule);margin-bottom:16px}
.bbar .who{font-size:15px;color:var(--ink)}
.bbar .who .mono{color:var(--gold-ink);margin-right:6px}
.bbar .who small{display:block;font-size:12px;color:var(--muted)}
.bbar .acts{display:flex;flex-wrap:wrap;gap:8px}
.btabs{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:20px;border-bottom:1px solid var(--rule)}
.btabs button{font:400 14px/1 var(--sans);border:0;background:transparent;color:var(--muted);padding:10px 14px 12px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;display:flex;gap:7px;align-items:center}
.btabs button i{font:500 11px/1 var(--mono);font-style:normal;color:var(--faint)}
.btabs button[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--gold);font-weight:500}
.btabs .dot{width:6px;height:6px;border-radius:50%;background:var(--rule-strong)}
.btabs .dot.ok{background:var(--built)}
.bgrid{display:grid;grid-template-columns:minmax(0,1fr) 270px;gap:32px;align-items:start}
@media (max-width:1100px){.bgrid{grid-template-columns:minmax(0,1fr)}}
.health{position:sticky;top:16px;border:1px solid var(--rule);border-radius:12px;padding:16px}
.health .score{font-weight:200;font-size:32px;color:var(--ink);line-height:1}
.health .score small{font-size:13px;color:var(--muted);font-weight:400}
.health ul{list-style:none;padding:0;margin:12px 0 14px}
.health li{font-size:12.5px;padding:6px 0;border-bottom:1px solid var(--rule);display:flex;gap:8px;align-items:flex-start;cursor:pointer}
.health li .ic{flex:none;width:13px;height:13px;border-radius:50%;border:1.5px solid var(--rule-strong);margin-top:2px}
.health li.ok .ic{background:var(--built);border-color:var(--built)}
.health li.ok{color:var(--muted)}
.bsec{margin:0 0 24px}
.bsec > h3{font-size:16px;margin-bottom:4px;display:flex;align-items:center;gap:8px}
.bsec > p.muted{font-size:13px;margin-bottom:12px}
.seg{display:inline-flex;border:1px solid var(--rule-strong);border-radius:999px;padding:3px;gap:2px;flex-wrap:wrap;background:var(--ground)}
.seg button{font:500 13px/1 var(--sans);border:0;background:transparent;color:var(--muted);padding:8px 14px;border-radius:999px;cursor:pointer}
.seg button[aria-pressed="true"]{background:var(--ink);color:var(--ground)}

/* the admin page's three tabs — the same segmented control, given room to breathe and a count
   that reads as a badge rather than as part of the label */
.atabs{margin:4px 0 18px}
.atabs .acnt{margin-left:7px;font:600 10.5px/15px var(--mono);background:var(--cream);
  color:var(--gold-ink);border-radius:8px;padding:0 5px;min-width:15px;display:inline-block;text-align:center}
.atabs button[aria-pressed="true"] .acnt{background:var(--paper);color:var(--ink)}
.atabs .acnt:empty{display:none}
/* A panel takes the focus ring only when somebody has actually tabbed to it: it carries
   tabindex="0" so the keyboard can reach the content after the strip, and a permanent outline
   around a third of the page would read as an error. */
.atab:focus{outline:none}
.atab:focus-visible{outline:2px solid var(--gold);outline-offset:6px;border-radius:4px}
.atab>h2:first-child{margin-top:0}
.slotcov{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 14px}
.slotcov span{font:500 12px/1 var(--sans);padding:6px 9px;border-radius:6px;border:1px dashed var(--rule-strong);color:var(--muted)}
.slotcov span.ok{border-style:solid;border-color:var(--gold);background:var(--agent);color:var(--ink)}
/* A phase's own shape, under the primary one. Named, because "Source, Classify, Extract" with
   nothing above it reads as the record's own vocabulary rather than as the phase's. */
.slotcov.phase{margin:-6px 0 12px;align-items:baseline}
.slotcov.phase i{font:600 11px/1.4 var(--sans);color:var(--muted);font-style:normal;
  text-transform:uppercase;letter-spacing:.04em;margin-right:2px}
.slotcov.phase span{font-size:11.5px;padding:5px 8px}

/* Vetted — has a person outside this tool said this flow is right. Sits under the meta row
   because it is the first thing somebody reading a flow needs to know about it, and because an
   unvetted flow should not look finished. */
.vetrow{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin:0 0 14px}
.vet{font:600 11.5px/1.5 var(--sans);padding:3px 10px;border-radius:999px;border:1px solid var(--rule)}
.vet.no{color:var(--muted);border-style:dashed}
.vet.yes{color:var(--ink);border-color:var(--gold);background:var(--agent)}
.vetnote{font:400 12.5px/1.5 var(--sans);color:var(--muted)}
.vetstamp{margin:-4px 0 10px}

/* The new form: one ideal flow, with the distance from it on every step. */
.ideal{margin:0 0 16px}
.imeta{font:400 12.5px/1.5 var(--sans);color:var(--muted);margin:0 0 10px}
.itiles{display:grid;gap:9px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.itile{border:1px solid var(--rule);border-radius:9px;padding:11px 12px 10px;background:var(--paper);
  display:flex;flex-direction:column;gap:3px;min-width:0}
.itile .ik{font:600 10.5px/1.4 var(--sans);letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
.itile .iv{font:600 20px/1.15 var(--sans);font-variant-numeric:tabular-nums;color:var(--ink)}
.itile .iv.small{font-size:14.5px;line-height:1.3}
.itile .inote{font:400 11.5px/1.45 var(--sans);color:var(--muted)}
.itile.unans .iv{color:var(--muted)}

/* THE STORY CARRIES THE MARKS. The actor and the surface are words in the sentence, coloured by
   whether each is right — so changing the reading changes the colours, which is the point: the
   same step is correct today and wrong against the ideal, and that is one sentence read twice. */
.sstory .sact,.sstory .ssurf{border-radius:6px;padding:1px 6px;border:1px solid transparent}
.sstory .sact{font-weight:500}
.sstory .ssurf{font-size:12.5px;white-space:nowrap}
/* RIGHT, NEARLY, WRONG, UNSAID — one set of colours for the actor and the surface, used both
   inside the story and on the closed step line: "red or green based on if it's the correct or
   not, and yellow if it's the correct but some others are missing". Unsaid stays grey and
   dashed: nobody has answered is not an answer, and colouring it would invent one. */
.a-ok,.s-ok{background:var(--built-bg);border-color:var(--built)!important;color:var(--built)}
.a-onway,.a-part,.s-part{background:var(--prog-bg);border-color:var(--prog)!important;color:var(--prog)}
.a-bad,.s-bad{background:var(--cream);border-color:var(--assume)!important;color:var(--assume)}
.a-none,.s-none{background:transparent;border-style:dashed!important;border-color:var(--rule-strong)!important;color:var(--faint)}
/* In the rails key the actor is a word, not a chip: it takes the colour and no box. */
.dotted.a-ok,.dotted.a-onway,.dotted.a-bad,.dotted.a-none{background:none;border:0!important}
/* The surface badge on a closed step. */
.sbadge{font:500 10px/1.6 var(--sans);letter-spacing:.02em;border:1px solid var(--rule);
  border-radius:999px;padding:0 7px;white-space:nowrap;flex:none}
.sstory.gone{opacity:.8}
.sstory .smiss{margin-left:7px;font-weight:600;font-size:10.5px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--assume);border:1px solid var(--assume);
  border-radius:6px;padding:1px 5px;white-space:nowrap}
.sstory .smiss.out{color:var(--muted);border-color:var(--rule-strong)}
/* What the sentence cannot carry: when it starts, whether it must ship, and how far the code is
   trusted. Below the story rather than above it, because none of them is the step. */
.sbits{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center;margin:2px 0 10px;font-size:12px}
.sbits .gbit{color:var(--ink)}
.sbits .gbit em{font-style:normal;color:var(--faint);margin-right:3px}
.trust{display:inline-flex;align-items:center;gap:2px}
.trust.none{font-size:11px;color:var(--faint);font-style:italic}
.trust i{width:6px;height:6px;border-radius:50%;background:var(--rule-strong);display:inline-block}
.trust i.on{background:var(--gold)}
/* A step nobody is standing in, at the reading picked, or one this version does not read.
   MARKED, NOT STRUCK, from 25 October: "i don't want the steps that are actually other flows to
   be strikethrough — it's ok to have them marked but not specifically that way." A line through
   a sentence reads as deleted, and none of these is deleted: one is work nobody does yet, the
   other is work another version of the flow does. Faded, with a dashed edge, says set aside. */
.sb.absent > .hd > b,.rrow.absent .rlab,.llegend > li.absent .llab{color:var(--muted)}
.sb.absent,.rrow.absent,.llegend > li.absent{opacity:.72;border-left:2px dashed var(--rule-strong)}
.gph{font:600 10.5px/1.5 var(--sans);border:1px solid var(--rule-strong);border-radius:999px;
  padding:1px 8px;color:var(--muted)}
.gph-must{border-color:var(--gold);color:var(--gold)}
.gtrust{font:600 10.5px/1.5 var(--sans);border:1px solid var(--rule-strong);border-radius:999px;
  padding:1px 8px;color:var(--muted);font-variant-numeric:tabular-nums}

.surfs{display:flex;flex-wrap:wrap;gap:4px 12px;margin-top:4px}
.surfs label{display:inline-flex;align-items:center;gap:5px;font:400 12px/1.5 var(--sans);color:var(--muted)}

/* THE PENCIL, one per section. Edit where the thing is rather than on a different page. */
.secedit{appearance:none;border:1px solid var(--rule);background:var(--ground);color:var(--muted);
  border-radius:7px;width:26px;height:24px;margin-left:8px;cursor:pointer;font-size:13px;line-height:1;
  vertical-align:middle;padding:0}
.secedit:hover{border-color:var(--gold);color:var(--gold-ink);background:var(--cream)}
.secedit[aria-pressed="true"]{border-color:var(--gold);background:var(--agent);color:var(--gold-ink)}
.secedit:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* The editor's own section, dropped into the view page where that section was. Marked, so it is
   obvious which part is open and the rest is plainly not. */
.secopen{border:1px solid var(--gold);border-radius:10px;background:var(--cream);padding:4px 14px 10px;
  margin:0 0 18px}
.secopen > details.sec{border:0;background:transparent;margin:0}
.metawrap{display:flex;align-items:baseline;gap:4px;flex-wrap:wrap}
.metawrap .meta{flex:1 1 auto;min-width:0}
.secopenbar{display:flex;justify-content:flex-end;gap:8px;margin:2px 0 -6px}
.btn.small{font-size:12px;padding:5px 10px}
/* THE ACTION ROW, SHUT. Six things that happen once in a record's life, behind one line that
   says so — not a row of buttons above the flow with Delete at the end of it. */
.acts2{border:1px solid var(--rule);border-radius:10px;background:var(--paper);margin:0 0 18px}
.acts2>summary{cursor:pointer;list-style:none;padding:9px 14px;font-size:13px;color:var(--muted);
  display:flex;align-items:center;gap:8px}
.acts2>summary::-webkit-details-marker{display:none}
.acts2>summary:hover{color:var(--ink)}
.acts2>summary .atw{transition:transform .14s ease;color:var(--faint);display:inline-block;font-size:15px}
.acts2[open]>summary .atw{transform:rotate(90deg)}
.acts2 .acts{margin:0;padding:0 14px 14px}
.withpen{position:relative}
.withpen .penfloat{position:absolute;top:14px;right:14px}
.ai{border:1px solid var(--rule);border-left:2px solid var(--gold);border-radius:0 10px 10px 0;padding:12px 14px;margin:0 0 16px;background:var(--paper);font-size:13.5px}
.ai .row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:8px}
.ai .msg{font-size:12.5px;color:var(--muted)}
.inline-warn{background:var(--cream);border-radius:8px;padding:10px 12px;font-size:13px;display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:8px}
.toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);background:var(--ink);color:var(--ground);padding:10px 16px;border-radius:999px;font-size:13px;z-index:60;display:flex;gap:12px;align-items:center;max-width:calc(100% - 32px)}
.toast:empty{display:none}
.toast button{font:500 12.5px var(--sans);background:transparent;border:1px solid currentColor;color:inherit;border-radius:999px;padding:4px 10px;cursor:pointer}
ul.hist{list-style:none;padding:0;margin:0;font-size:13px}
ul.hist li{padding:7px 0;border-bottom:1px solid var(--rule);display:flex;flex-wrap:wrap;gap:4px 10px}
ul.hist .mono{color:var(--muted);font-size:11.5px}
ul.hist b{font-weight:500;color:var(--ink)}
textarea.csv{width:100%;min-height:130px;font:400 12px/1.4 var(--mono);padding:10px;border-radius:8px;border:1px solid var(--rule-strong);background:var(--paper);color:var(--ink)}
@media (max-width:980px){
  .shell{grid-template-columns:1fr;gap:0;padding-inline:16px}
  .rail{position:sticky;top:0;height:auto;z-index:10;background:var(--ground);padding-block:10px;border-bottom:1px solid var(--rule);flex-direction:row;align-items:center;gap:10px;overflow-x:auto}
  .rail .brand,.rail .regnote,.rail .editor{display:none}
  nav{flex-direction:row;gap:6px}
  .rail nav a{padding:7px 10px;white-space:nowrap}
  .rail nav a span{display:none}
  main{padding-top:18px}
}



.fsel{font:500 12.5px/1 var(--sans);padding:8px 10px;border-radius:999px;border:1px solid var(--rule);background:var(--ground);color:var(--ink);max-width:220px}

.cat .wf .u{font:500 10px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;padding:3px 6px;border-radius:4px;border:1px solid var(--rule)}
.cat .wf .u.ok{color:var(--ink);border-color:var(--rule-strong);background:var(--paper)}
.cat .wf .u.tbc{color:var(--faint);border-style:dashed}
.cat .wf .u.na{color:var(--faint);text-decoration:line-through;opacity:.65}
.clsgrid input{font:400 13px/1.2 var(--sans);padding:7px 8px;border-radius:7px;border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);width:100%}

.railnote{font-size:12px;color:var(--muted);line-height:1.5}
.railnote b{display:block;font:500 12px/1.4 var(--mono);color:var(--gold-ink);margin-bottom:6px}
.ph2{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;position:sticky;top:-24px;background:var(--ground);padding:10px 0;margin:-10px 0 8px;z-index:3;border-bottom:1px solid var(--rule)}
.ph2 .idline{display:flex;gap:8px;align-items:center;font-size:13px}
.ph2 .idline .mono{color:var(--gold-ink)}
.ph2 .save{font-size:12px;color:var(--muted)}
.ph2 .save.ok{color:var(--built)}
.drawer h2{font-weight:200;font-size:28px;margin:6px 0 6px}
.drawer h2.editing::after{content:" · editing";font-size:13px;color:var(--faint);font-weight:400;letter-spacing:.06em}
details.sec{border-top:1px solid var(--rule);padding:0;margin:0}
details.sec > summary{cursor:pointer;list-style:none;padding:16px 0 12px;display:flex;align-items:center;gap:8px}
details.sec > summary::-webkit-details-marker{display:none}
details.sec > summary h4{margin:0}
details.sec > summary::before{content:"+";font:400 15px/1 var(--mono);color:var(--faint)}
details.sec[open] > summary::before{content:"–"}
details.sub{border:1px solid var(--rule);border-radius:10px;padding:10px 12px;margin:0 0 14px}
details.sub > summary{cursor:pointer;font:500 13px/1 var(--sans);color:var(--ink);list-style:none}
details.sub > summary::-webkit-details-marker{display:none}
.tbl.mini td{padding:8px 12px 8px 0;font-size:13px}
.chip.off{opacity:.55;text-decoration:line-through}
ul.checklist{list-style:none;padding:0;margin:8px 0 0;font-size:13px}
ul.checklist li{display:flex;gap:8px;align-items:flex-start;padding:6px 0;border-bottom:1px solid var(--rule)}
ul.checklist .ic{flex:none;width:13px;height:13px;border-radius:50%;border:1.5px solid var(--rule-strong);margin-top:3px}
ul.checklist li.ok .ic{background:var(--built);border-color:var(--built)}
ul.checklist li.ok{color:var(--muted)}

/* single-column header */
.top{display:flex;flex-wrap:wrap;gap:12px 18px;align-items:center;justify-content:space-between;border-bottom:1px solid var(--rule);padding-bottom:12px;margin-bottom:26px}
.top .tl{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.top .brand{font-weight:200;letter-spacing:.38em;font-size:14px;color:var(--ink)}
.top .sub{font:500 9.5px/1 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold-ink)}
.top .cnt{font:500 11.5px/1 var(--mono);color:var(--muted)}
.top .tr{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.top .editor{flex-direction:row;align-items:center;gap:8px}
.top .editor span{font:500 10px/1 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.top .editor input{width:150px}
h1{margin-bottom:8px}
.cov{cursor:pointer;transition:border-color .12s}
.cov:hover{border-color:var(--gold)}
.cov[aria-pressed="true"]{border-color:var(--ink);background:var(--paper);box-shadow:inset 0 0 0 1px var(--ink)}
.cov .t b{display:flex;align-items:center;gap:6px}

footer{margin-top:60px}
@media (max-width:980px){
  .page{padding:14px 16px 70px}
  .top .editor input{width:120px}
}

/* accordion */
.cat{border-collapse:separate;border-spacing:0}
.cat tr.grp td{padding:0;border-bottom:0}
.cat tr.grp{cursor:pointer;user-select:none}
/* A HEADING IS A BAND, NOT A CARD, and that changed on 20 October 2026 when the lane view grew
   a second level. Each heading used to be a rounded bordered box with a margin, which reads
   cleanly at one level and falls apart at three: a lane holding a group holding rows drew three
   nested boxes with gaps between them, every box a different width, and the hierarchy lived in
   the nesting rather than in the alignment. Four pixels of rounded corner cannot carry a
   hierarchy that the eye has to follow down a page.
   So it is laid out the way GAP lays out nested goals, which she pointed at: one grid, every
   band full width, the CONTENT indented a step per level, and a hairline rail down the left
   marking which parent a row belongs to. The rails are what do the work — they run unbroken
   from a heading through its rows, so the eye follows a line instead of counting boxes. */
.cat tr.grp .gh{display:flex;align-items:center;gap:14px;margin:0;padding:11px 14px;
  border:0;border-bottom:1px solid var(--rule);border-radius:0;background:transparent;
  transition:background .12s}
.cat tr.grp:hover .gh{background:var(--paper)}
.cat tr.grp:focus-visible{outline:none}
.cat tr.grp:focus-visible .gh{outline:2px solid var(--gold);outline-offset:-2px}

/* THE RAILS. Drawn as background gradients on the first cell rather than borders, because a
   border belongs to one row and a rail has to read as one continuous line down many of them —
   and because the two rails sit at fixed x positions that no amount of border-left can reach.
   14px is the lane's rail, 36px the group's. */
.cat tbody.lv2 .rail{--rail:var(--rule-strong)}
.cat tbody.lv2 tr.gsub .gh{background-image:linear-gradient(var(--rule-strong),var(--rule-strong));
  background-size:2px 100%;background-position:14px 0;background-repeat:no-repeat}

/* LEVEL 1 — the GAP lane. Cream, the heaviest type on the page, flush to the left edge. */
.cat tr.grp.glane .gh{background:var(--cream);border-bottom-color:var(--rule-strong);padding-top:13px;padding-bottom:13px}
.cat tr.grp.glane:hover .gh{background:var(--agent)}
.cat tr.grp.glane .gt b{font-size:15px;font-weight:600}
.cat tr.grp.glane + tr.grp.glane .gh{border-top:0}

/* LEVEL 2 — the group inside it. Indented one step, its eyebrow dropped: the rail and the indent
   already say which lane it belongs to, and repeating the lane's name on every one of its groups
   is the noise this layout exists to remove. */
.cat tbody.lv2 tr.grp.gsub .gh{padding-left:36px;background-color:var(--paper)}
.cat tbody.lv2 tr.grp.gsub:hover .gh{background-color:var(--cream)}
.cat tr.grp.gsub .gt b{font-weight:500;font-size:14px}
.cat tbody.lv2 tr.grp.gsub .ph{display:none}

/* LEVEL 3 — the records. Two rails, because a row hangs off both a group and a lane. */
.cat tbody.lv2 tr.in td:first-child{padding-left:58px;
  background-image:linear-gradient(var(--rule-strong),var(--rule-strong)),linear-gradient(var(--rule),var(--rule));
  background-size:2px 100%,1px 100%;background-position:14px 0,36px 0;background-repeat:no-repeat}
/* The last row of a group closes its rail with a foot, so a group ends where it ends rather
   than bleeding into the next one. */
.cat tbody.lv2 tr.in.last td:first-child{background-size:2px 100%,1px 100%}
.cat tbody.lv2 tr.in.last td{border-bottom:1px solid var(--rule-strong)}
.cat tr.grp .tw{font:400 17px/1 var(--sans);color:var(--faint);transition:transform .16s ease;flex:none}
.cat tr.grp.open .tw{transform:rotate(90deg);color:var(--gold-ink)}
.cat tr.grp .gt{min-width:0;flex:1}
.cat tr.grp .ph{display:block;font:500 9.5px/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold-ink);margin-bottom:3px}
.cat tr.grp b{font-weight:500;color:var(--ink);font-size:16px}
.cat tr.grp .gm{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end}
.cat tr.grp .gpill{font:500 11px/1 var(--sans);padding:5px 9px;border-radius:999px;border:1px solid var(--rule-strong);color:var(--muted);white-space:nowrap}
.cat tr.grp .gpill.on{color:var(--built);border-color:var(--built)}
/* A category with nothing in this view still occupies its place, because the shape of the
   catalogue is information: eight categories in phase order, whatever the filter says. */
.cat tr.grp.bare{cursor:default}
.cat tr.grp.bare .gh{opacity:.55}
.cat tr.grp.bare .tw{visibility:hidden}
.cat tr.grp.bare .gpill.none{border-style:dashed;color:var(--faint)}
.cat tr.grp .gbar{display:flex;width:120px;height:6px;border-radius:999px;overflow:hidden;background:var(--pend-bg);flex:none}
.cat tr.grp .gbar i{display:block;height:100%}
.cat tr.grp .gbar .b{background:var(--built)} .cat tr.grp .gbar .p{background:var(--prog)}
.cat tr.grp .gnum{font:500 12px/1 var(--mono);color:var(--muted);min-width:34px;text-align:right}
/* The rows no longer sit inside a bordered box with rounded feet — the box was the other half
   of the card look, and with a rail doing the job it only drew a second edge beside the rail.
   `background-color` and not `background`, because the shorthand would wipe out the rails. */
.cat tr.in td{background-color:var(--ground);border-bottom:1px solid var(--rule)}
.cat tr.in td:first-child{padding-left:18px}
.cat tr.in td:last-child{padding-right:14px}
.cat tr.in:hover td{background-color:var(--paper)}
/* The step counts are one token — 8/17/13/14/12 — and wrapping them mid-number turns a
   measurement into two half-numbers on two lines. */
.cat tr.in td.mono{white-space:nowrap}
.cat thead th{padding-bottom:10px}
.btn.ghost{border-color:transparent;color:var(--muted);padding:8px 10px}
.btn.ghost:hover{color:var(--ink);border-color:var(--rule)}
@media (max-width:760px){.cat tr.grp .gm .gbar,.cat tr.grp .gm .gnum{display:none}}

/* fixed columns so nothing shifts when a group opens */
.cat{table-layout:fixed;min-width:1240px}
.cat col{min-width:0}
.cat col.c-def{width:9%}
.cat col.c-flow{width:8%}
.cat th,.cat td{overflow-wrap:anywhere}
.cat .state{max-width:100%}

.coverwrap{display:flex;flex-direction:column;gap:8px;margin-bottom:22px}
.coverwrap .cover{margin-bottom:0}
.clsall{align-self:flex-start}
.clsall[aria-pressed="true"]{color:var(--faint)}
.cat tfoot .tot td{border-top:2px solid var(--rule-strong);border-bottom:0;padding-top:14px;font-size:12.5px;color:var(--muted)}
.cat tfoot .tot td:first-child{font-weight:500;color:var(--ink)}
.cat tfoot .tnum{display:block;font:500 15px/1.2 var(--sans);color:var(--ink);font-variant-numeric:tabular-nums}
.cat tfoot .tsub{display:block;font-size:11px;color:var(--muted)}
.state b{font-weight:600}

.cat tr.in td.aggc,.cat th.aggc,.cat tfoot .tot td.aggc{background:var(--agg-tint)}
.cat tr.in:hover td.aggc{background:var(--agg-tint)}

/* ---- journey ---- */
.jhead{border:1px solid var(--rule);border-radius:12px;padding:14px 16px;margin-bottom:16px;background:var(--paper)}
.jwho{display:flex;flex-direction:column;gap:3px;margin-bottom:10px}
.story{margin:0 0 4px;font-size:13.5px;line-height:1.6;color:var(--ink)}
.story span{color:var(--faint)}
.story b{font-weight:500}
.story em{color:var(--faint);font-style:normal}
.story.big{font-size:16px;line-height:1.55;margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid var(--rule)}
.story.big b{color:var(--gold-ink)}
.jwho span,.jse span{font:500 10px/1 var(--sans);letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
.jwho b{font:500 16px/1.3 var(--sans);color:var(--ink)}
.jse{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.jse div{display:flex;flex-direction:column;gap:4px;min-width:0}
.jse p{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink)}
.sb .mom{display:flex;gap:9px;align-items:baseline;margin:2px 0 6px;padding:7px 10px;border-radius:8px;background:var(--cream)}
.sb .mom > span{font:500 9.5px/1.5 var(--sans);letter-spacing:.13em;text-transform:uppercase;color:var(--gold-ink);flex:none;white-space:nowrap}
.sb .mom p{margin:0;font-size:13px;line-height:1.5;color:var(--ink)}
/* The phrase inside it is prose, not a label: once the line became editable its value arrived
   wrapped in a span, and `.mom span` was dressing the sentence as a heading. */
.sb .mom p .lineval{font:inherit;letter-spacing:normal;text-transform:none;color:inherit;white-space:normal}

/* ---- agents ---- */
.agents{border:1px solid var(--rule);border-radius:12px;background:var(--ground);margin:0 0 18px;overflow:hidden}
.agents>summary{list-style:none;cursor:pointer;display:flex;align-items:baseline;gap:10px;padding:13px 16px;font-size:13.5px}
.agents>summary::-webkit-details-marker{display:none}
.agents>summary:hover{background:var(--paper)}
.agents>summary b{font:500 14px/1.2 var(--sans);color:var(--ink)}
.agents .atw{color:var(--gold-ink);transition:transform .16s ease;display:inline-block;font-size:15px}
.agents[open] .atw{transform:rotate(90deg)}
.agents .asub{color:var(--muted);font-size:12.5px;flex:1;min-width:0}
.agents .acnt{font:400 11.5px/1 var(--mono);color:var(--faint);white-space:nowrap}
/* One class at a time. The pills decide who is on screen; the note under them says what that
   class IS, in one sentence, instead of three paragraphs nobody reads twice. */
.aroles{display:flex;flex-wrap:wrap;align-items:flex-start;gap:10px 14px;padding:10px 16px 14px;
  border-bottom:1px solid var(--rule)}
.aroles .anote{margin:0;flex:1 1 320px;min-width:0;font-size:12.5px;line-height:1.5;color:var(--muted)}
.fpills.roles{flex:0 0 auto}
.fpills.roles i{font-style:normal;font-family:var(--mono);font-size:11px;opacity:.65;margin-left:4px}
.rolechip{display:inline-flex;align-items:center;align-self:flex-start;font:500 10px/1 var(--sans);letter-spacing:.1em;text-transform:uppercase;padding:5px 9px;border-radius:999px;border:1px solid var(--rule-strong);color:var(--muted);background:var(--ground)}
.rolechip.Fragent{border-color:var(--gold);color:var(--gold-ink);background:var(--cream)}
.rolechip.Stagent{border-color:var(--rule-strong);color:var(--ink);background:var(--paper)}
.rolechip.Magent{border-color:var(--ink);color:var(--ink)}
.rolechip.TBC{border-style:dashed;color:var(--faint)}
.agrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px;padding:14px 16px 16px}
.ag{border:1px solid var(--rule);border-radius:10px;padding:12px 13px;background:var(--paper);cursor:pointer;min-width:0}
.ag:hover{border-color:var(--rule-strong)}
.ag[aria-pressed="true"]{border-color:var(--ink);background:var(--ground);box-shadow:0 0 0 1px var(--ink)}
.ag.tbc{border-style:dashed}
.agh{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}
.agh b{font:500 15px/1.2 var(--sans);color:var(--ink)}
.agn{font-size:12.5px;color:var(--muted);margin-bottom:9px}
.agn b{color:var(--ink);font-weight:500}
.agd{display:grid;grid-template-columns:minmax(0,72px) minmax(0,1fr);gap:3px 10px;margin:0;font-size:11.5px;line-height:1.45}
.agd dt{color:var(--faint);text-transform:uppercase;letter-spacing:.08em;font-size:9.5px;padding-top:2px}
.agd dd{margin:0;color:var(--ink);overflow-wrap:anywhere}
.agempty{margin:0;font-size:12px;color:var(--faint)}
/* Why a face is missing — information, not an alarm. It is usually somebody else's to fix,
   and often nobody's: an agent nobody has drawn yet is a normal state. */
.agnoface{margin:4px 0 0;font-size:11px;line-height:1.5;color:var(--faint)}

.cat thead th{white-space:normal;overflow-wrap:anywhere;line-height:1.35;padding-right:8px}
.syslist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.syslist li{display:grid;grid-template-columns:minmax(0,auto) minmax(0,auto) minmax(0,1fr);gap:10px;align-items:baseline;font-size:13px;border-bottom:1px solid var(--rule);padding-bottom:8px}
.syslist li:last-child{border-bottom:0;padding-bottom:0}
.syslist b{font-weight:500;color:var(--ink)}
.syslist .sysw{font:500 9.5px/1.6 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--gold-ink);border:1px solid var(--gold);border-radius:999px;padding:2px 8px;white-space:nowrap}
@media(max-width:560px){.syslist li{grid-template-columns:minmax(0,1fr)}}


/* ------------------------------------------------------------------ core / class / jurisdiction
   The flow on screen is one resolution of three layers, so the page has to say which one and
   mark what the class changed. A difference nobody can see is a difference nobody acts on. */
/* THE JOURNEY SECTION IN THREE PARTS — what the flow is, where it stands, how you are looking
   at it. The third one is set apart because it is the only one that is not a fact about the
   flow: everything in it changes the picture and nothing in it changes the record. */
/* A question is one line and its owner. Not a card — a list somebody can read down. */
.qlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.qlist li{font-size:13.5px;line-height:1.55;color:var(--ink);padding-left:14px;position:relative}
.qlist li::before{content:"";position:absolute;left:0;top:9px;width:5px;height:5px;border-radius:50%;
  background:var(--gold)}
.qowner{font-size:11.5px;color:var(--muted);margin-left:8px}
.sec.quiet h4{color:var(--muted)}
.jstands{border:1px solid var(--rule);border-radius:12px;background:var(--paper);
  padding:14px 16px 4px;margin:0 0 14px}
.jstands .itiles{margin-bottom:12px}
.jstands .runsnow{margin:0 0 12px}
.lensbar2.jlens{background:var(--cream);border-radius:12px;padding:10px 14px;margin:0 0 14px}
.lenslead{font:500 10px/1 var(--sans);letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
/* ONE LINE OF THE JOURNEY AT A TIME. The pencil is quiet until the line is hovered or focused,
   because five pencils down a five-line story is a form with extra steps. */
.jedit .lineval.none{color:var(--faint);font-style:italic}
.linepen{border:0;background:transparent;color:var(--faint);cursor:pointer;font-size:12px;
  padding:0 3px;line-height:1;opacity:0;transition:opacity .12s ease}
.jedit:hover .linepen,.linepen:focus-visible,.linepen.on{opacity:1}
.linepen:hover{color:var(--gold-ink)}
.linepen.on{color:var(--gold-ink);opacity:1}
.lineopen{display:inline-flex;align-items:center;gap:6px;vertical-align:baseline}
.lineinp{font:inherit;color:var(--ink);background:var(--ground);border:1px solid var(--gold);
  border-radius:7px;padding:3px 7px;min-width:220px;max-width:100%}
textarea.lineinp{width:100%;resize:vertical;font:400 13.5px/1.5 var(--sans)}
.lensbar2{display:flex;gap:16px;flex-wrap:wrap;align-items:center;margin:12px 0 4px}
.lensbar2 label{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--muted)}
.lensbar2 select{font:400 13px/1.2 var(--sans);padding:7px 9px;border-radius:8px;
  border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink)}
.lensnote{font-size:13px;line-height:1.55;color:var(--gold-ink);background:var(--cream);
  border-radius:9px;padding:10px 13px;margin:12px 0 4px}
.lensnote b{font-weight:500}
.dropped{margin:14px 0 4px;padding:12px 14px;border:1px dashed var(--rule-strong);border-radius:10px;background:var(--paper)}
.dropped>span{display:block;font:500 10.5px/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:8px}
.dropped ul{margin:0;padding:0;list-style:none}
.dropped li{font-size:13px;color:var(--muted);padding:3px 0 3px 11px;border-left:2px dashed var(--rule-strong)}
.dropped li .mono{font:400 11.5px/1 var(--mono);display:inline-block;margin-right:8px;opacity:.7}
.flow li.varied{border-left:2px solid var(--gold)}
.flow li.added{border-left:2px dashed var(--gold)}
.was{font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--gold-ink);
  background:var(--cream);border-radius:4px;padding:2px 5px;margin-left:6px;vertical-align:middle}
.wasline{display:block;font-size:12px;line-height:1.5;color:var(--muted);margin-top:5px;font-style:italic}
.onlyc{font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--gold-ink);
  border:1px dashed var(--gold);border-radius:999px;padding:3px 7px}

/* a step somebody has to confirm — not an open question, not a deletion.
   Dashed like the scope chip, because both say "read this before you rely on it", and in the
   in-progress colour rather than the gold: gold is this page's voice for "decided". */
.revc{font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--prog);
  border:1px dashed var(--prog);border-radius:999px;padding:3px 7px;white-space:nowrap}
.revbox{border-left:2px solid var(--prog);background:var(--prog-bg);border-radius:0 6px 6px 0;
  padding:8px 10px;margin:10px 0 0;font-size:12.5px}
.revbox b{color:var(--prog)}
.revbox p{margin:4px 0 0;color:var(--ink)}
.ib.on{color:var(--prog);border-color:var(--prog);background:var(--prog-bg)}
.cmtall.rev{border-color:var(--prog);background:var(--prog-bg);color:var(--prog)}
.cmtall.rev:hover{background:var(--prog-bg);border-color:var(--prog);filter:brightness(.97)}

/* the per-step layer editor */
.layers{margin-top:12px}
.layers>summary{font-size:13px;color:var(--ink)}
.lcount{font:400 11.5px/1 var(--mono);color:var(--gold-ink);background:var(--cream);border-radius:4px;padding:3px 6px;margin-left:6px}
.layer{border-top:1px solid var(--rule);padding:10px 0}
.layer.on{background:var(--paper);border-radius:8px;padding:10px 12px;margin:6px 0;border-top:0}
.layer .lh{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.layer .lh b{font:500 13.5px/1.3 var(--sans);min-width:130px}
.layer .lh select{font:400 12.5px/1.2 var(--sans);padding:6px 8px;border-radius:7px;
  border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink)}
.layer .lb{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 10px;margin-top:10px}
.layer .lb .cell.wide{grid-column:1/-1}
.layer.jur{border-top:1px solid var(--rule-strong);margin-top:6px}
@media (max-width:700px){.layer .lb{grid-template-columns:minmax(0,1fr)}}


/* ------------------------------------------------------------------ drag to reorder
   The grip stays out of the way until the row is hovered: a permanent handle on sixty rows
   is sixty pieces of furniture nobody asked for. */
.cat td.wf{position:relative}
.grip{position:absolute;left:-2px;top:14px;width:16px;text-align:center;cursor:grab;
  font:400 13px/1 var(--mono);color:var(--rule-strong);opacity:0;transition:opacity .12s}
.cat tr.in:hover .grip,.cat tr.in:focus-within .grip{opacity:1}
.grip:hover{color:var(--gold-ink)}
.grip:active{cursor:grabbing}
.cat tr.dragging{opacity:.45}
.cat tr.dragging .grip{opacity:1;color:var(--gold-ink)}
/* While a row is being dragged, nothing else on the page is being selected. */
body.rowdrag .cat{user-select:none;-webkit-user-select:none}
.cat tr.dropbefore td{box-shadow:inset 0 2px 0 var(--gold)}
.cat tr.dropafter td{box-shadow:inset 0 -2px 0 var(--gold)}
/* Nobody who cannot save should be shown a handle that silently does nothing. */
body.readonly .grip,body.lensed .grip{display:none}


/* ------------------------------------------------------------------ before and after
   Which workflows lead into this one and which it leads on to. The sentence that says so
   is shown with each: a link nobody can check is a link nobody should trust. */
.relhd{font:500 10.5px/1.3 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--gold-ink);margin:14px 0 8px}
.relhd:first-child{margin-top:0}
.rels{list-style:none;margin:0;padding:0}
.rel{border:1px solid var(--rule);border-radius:10px;padding:11px 13px;margin-bottom:7px;background:var(--paper)}
.rel.k-hands-over{border-left:2px solid var(--gold)}
.rel .rh{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin-bottom:5px}
.rel .rh .mono{font:400 11.5px/1 var(--mono);color:var(--gold-ink)}
.rel .rh b{font:500 13.5px/1.35 var(--sans);flex:1 1 auto}
.relk{font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--rule-strong);border-radius:999px;padding:3px 7px;cursor:help}
.rel.k-hands-over .relk{color:var(--gold-ink);border-color:var(--gold);background:var(--cream)}
.relm{font:400 10px/1 var(--mono);color:var(--gold-ink)}
.reln{font:400 10.5px/1 var(--mono);color:var(--muted)}
.relq{font-size:12.5px;line-height:1.6;color:var(--muted);margin:4px 0 8px;padding-left:10px;border-left:2px solid var(--rule)}
.relq span{display:block;font:400 10px/1.5 var(--mono);color:var(--gold-ink);text-transform:lowercase}
.rel-go{padding:5px 9px;font-size:12px}

/* ------------------------------------------------------------------ is it built?
   Never louder than the evidence: a marker somebody wrote reads differently from a model's
   recognition, and both read differently from nothing at all. */
.built td{vertical-align:top}
.built .bn{width:26px;font:400 11.5px/1.8 var(--mono);color:var(--muted)}
.bchip{display:inline-block;font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;
  border-radius:999px;padding:4px 8px;border:1px solid var(--rule-strong);color:var(--muted);white-space:nowrap}
.bchip.built{color:var(--built);border-color:var(--built);background:color-mix(in srgb,var(--built) 8%,transparent)}
.bchip.partly{color:var(--gold-ink);border-color:var(--gold);background:var(--cream)}
.bchip.differs{color:var(--assume);border-color:var(--assume)}
.bchip.not-found{opacity:.6;border-style:dashed}
.bchip.na{opacity:.5}
.cat tr.bs-differs td,.built tr.bs-differs td{background:color-mix(in srgb,var(--assume) 5%,transparent)}
.bstale{font-size:12.5px;line-height:1.6;color:var(--gold-ink);background:var(--cream);
  border-radius:8px;padding:9px 12px;margin:0 0 10px}
.bstale .mono{font:400 11.5px/1 var(--mono)}

/* ------------------------------------------------------------------ what it needs
   The flow already says what every step takes in and puts out. Read across the catalogue
   that answers "what has to have happened first, and which workflow made it happen" — and,
   where nothing did, it names a workflow that has not been written. A gap is shown as a gap:
   marked, countable and answerable, not softened into a note. */
.needs{list-style:none;margin:0;padding:0}
.need{border:1px solid var(--rule);border-radius:10px;padding:10px 13px;margin-bottom:7px;background:var(--paper)}
.need.gap{border-left:2px solid var(--assume);background:color-mix(in srgb,var(--assume) 4%,var(--paper))}
.need.settled{border-left:2px solid var(--gold)}
.need.br.out{border-left:2px solid var(--gold)}
.need .nh{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.need .nh b{font:500 13.5px/1.35 var(--sans)}
.nsrc{font:400 11.5px/1.5 var(--mono);color:var(--muted)}
.nsrc .mono{color:var(--gold-ink)}
.nwhy{font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;color:var(--assume);
  border:1px solid currentColor;border-radius:999px;padding:3px 7px;cursor:help}
.need.settled .nwhy{color:var(--gold-ink)}
.nself{font:400 10.5px/1 var(--mono);color:var(--muted)}
.nsays{font-size:12.5px;line-height:1.6;color:var(--muted);margin:5px 0 0;padding-left:10px;border-left:2px solid var(--rule)}
.nsays .mono{font:400 11.5px/1 var(--mono);color:var(--gold-ink)}
.nat{font:400 10.5px/1.6 var(--mono);color:var(--muted);margin-top:4px}
.nacts{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:9px}
.btn.tiny{padding:5px 9px;font-size:12px}

/* ------------------------------------------------------------------ the line under the title
   One line, and it stays one line. What a workflow is — agent, category, shape, layer — is
   prose, so it truncates under pressure; whether each use case applies is a status and keeps
   its width, because a status that has been squeezed out of the row is worse than no row. */
.meta{display:flex;align-items:center;gap:6px;margin-bottom:16px;min-width:0}
.mt{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:400 12px/1.2 var(--sans);padding:5px 9px;border-radius:6px;
  background:var(--ground);border:1px solid var(--rule);color:var(--ink)}
.mt.ag{flex:0 0 auto;background:var(--agent);border-color:var(--gold)}
/* The lane, which replaced the layer in this row on 20 October 2026. It is the longest of the
   four chips — "Property and facility flows · Vacancy management" — and it is the one most worth
   reading, so it gets the room: it keeps its full width where the others truncate, and drops to
   truncating only when the row genuinely cannot hold it. Tinted rather than outlined, so the
   filing reads as a different kind of fact from the shape and the category beside it. */
.mt.ln{flex:0 1 auto;max-width:46ch;background:var(--paper);border-color:var(--rule-strong);
  color:var(--gold-ink);font-weight:500}
@media (max-width:720px){.mt.ln{max-width:none}}
.uses{flex:0 0 auto;display:flex;gap:4px;margin-left:auto;padding-left:6px}
.u{display:inline-flex;align-items:baseline;gap:4px;white-space:nowrap;
  font:400 10.5px/1 var(--mono);padding:5px 7px;border-radius:6px;border:1px solid}
.u b{font:500 11px/1 var(--sans)}
.u.ap{color:var(--built);border-color:var(--built);background:var(--built-bg)}
.u.tbc{color:var(--gold-ink);border-color:var(--gold);border-style:dashed;background:transparent}
.u.na{color:var(--faint);border-color:var(--rule);border-style:dashed;background:transparent}
@media(max-width:560px){
  .meta{flex-wrap:wrap}
  .uses{margin-left:0;padding-left:0;flex-basis:100%;order:-1}
}

/* what the source code says, against what the catalogue claims */
.codestrip{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;margin:0 0 12px;
  font-size:12.5px;line-height:1.6;color:var(--muted)}
.codestrip b{font-weight:600;color:var(--ink)}
.codestrip.clash{background:color-mix(in srgb,var(--assume) 6%,transparent);
  border-radius:8px;padding:9px 12px}
.clashw{flex-basis:100%;color:var(--assume);font-weight:500}

.saidgap{margin-top:18px;border-left:2px solid var(--assume);
  background:color-mix(in srgb,var(--assume) 4%,transparent);border-radius:0 10px 10px 0;padding:12px 16px}
.saidgap h5{font:500 11px/1.3 var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--assume);margin:0 0 6px}
.saidgap .prose{white-space:pre-wrap;font-size:13px;line-height:1.65;margin:8px 0 0;max-width:80ch}
.seg.small button{font-size:12.5px;padding:7px 11px}

/* how far a step reaches, on the step's own row in the editor */
.reach{flex:0 0 auto;align-self:center;font:500 9.5px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;
  border:1px solid;border-radius:999px;padding:4px 8px;white-space:nowrap;cursor:help}
.reach.core{color:var(--built);border-color:var(--built);background:var(--built-bg)}
.reach.varies{color:var(--gold-ink);border-color:var(--gold);background:var(--cream)}
.reach.scoped{color:var(--assume);border-color:var(--assume)}
.reach.loose{border-style:dashed}

/* ------------------------------------------------------------------ class lanes
   One lane per class, under the step it belongs to. The shape carries the meaning: a single
   quiet bar means every class runs this step as written; a row of separate lanes means the
   step splits, and the gold ones are where. Read down a flow and the steps that have been
   thought about class by class are the ones that look different. */
.flow li.haslanes{padding-bottom:14px}
.lanes{display:flex;gap:4px;flex-wrap:wrap;margin:12px 0 0}
.lanes.all{display:flex;align-items:center;gap:8px;font:400 12px/1.4 var(--sans);color:var(--built);
  background:var(--built-bg);border-radius:8px;padding:8px 12px}
.lanes.all .alltick{font-size:12px;font-weight:700}
.lane{flex:1 1 92px;min-width:82px;display:flex;align-items:baseline;justify-content:center;gap:5px;
  border:1px solid var(--rule);border-radius:8px;padding:7px 8px;background:var(--ground);
  font:400 10.5px/1.2 var(--mono);color:var(--muted);cursor:help}
.lane b{font:500 11.5px/1.2 var(--sans)}
.lane.same{color:var(--built);border-color:color-mix(in srgb,var(--built) 35%,var(--rule));
  background:color-mix(in srgb,var(--built) 6%,var(--ground))}
.lane.diff{color:var(--gold-ink);border-color:var(--gold);background:var(--cream);font-weight:500}
.lane.diff i{font-style:normal;font:500 10px/1 var(--mono);border:1px solid var(--gold);
  border-radius:999px;padding:2px 5px}
.lane.out{color:var(--assume);border-color:var(--assume);border-style:dashed;background:transparent}
.lane.out b{text-decoration:line-through}
.lanedetail{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.ld{border-left:2px solid var(--gold);background:var(--cream);border-radius:0 8px 8px 0;padding:8px 12px;
  font-size:12.5px;line-height:1.6}
.ld.out{border-left-color:var(--assume);background:color-mix(in srgb,var(--assume) 5%,transparent)}
.ld b{display:block;font:500 12px/1.4 var(--sans);color:var(--ink);margin-bottom:3px}
.ld .lv{display:block;color:var(--body)}
.ld .lv i{font-style:normal;display:inline-block;min-width:62px;font:500 9.5px/1.6 var(--sans);
  letter-spacing:.06em;text-transform:uppercase;color:var(--gold-ink)}
.lanelead{margin:0 0 12px}
@media(max-width:700px){.lane{flex-basis:calc(50% - 4px)}}

/* ------------------------------------------------------------------ the catalogue's lanes
   The grid speaks the same visual language as the flow: one lane per class, coloured by
   where that class has got to. Read a column and you see how far one class has come; read a
   row and you see which classes a workflow is actually for. What the source code says sits
   beside it in its own column rather than being folded into the claim. */
.wl{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font:500 11px/1 var(--sans);border:1px solid;border-radius:7px;padding:6px 9px;
  /* The level names are long words. Let the chip drop onto a second line inside its own
     column rather than run over the class beside it. */
  max-width:100%;flex-wrap:wrap;row-gap:4px}
.wl.built{color:var(--built);border-color:var(--built);background:var(--built-bg)}
.wl.doing{color:var(--prog);border-color:var(--prog);background:var(--prog-bg)}
.wl.build{color:var(--gold-ink);border-color:var(--gold);background:var(--cream)}
.wl.define{color:var(--gold-ink);border-color:var(--gold);border-style:dashed;background:transparent}
.wl.tbc{color:var(--muted);border-color:var(--rule-strong);border-style:dashed;background:transparent}
.wl.na{color:var(--faint);border-color:var(--rule);background:transparent}
.wl.none{color:var(--faint);border-color:transparent}
.wl.tbc i{font-style:normal;font:500 9.5px/1 var(--mono);color:var(--gold-ink);
  border:1px solid var(--gold);border-radius:4px;padding:2px 4px}
.wl .dots{letter-spacing:1px;font-size:9px;opacity:.85}
/* the maturity, named. Quieter than the state it sits beside, because the state is the
   answer and the level is the detail. */
.wl .mat{font:400 9.5px/1 var(--mono);letter-spacing:.02em;opacity:.9;
  border-left:1px solid currentColor;padding-left:6px;margin-left:1px}
/* on a second line the divider would point at nothing, so it becomes an indent instead */
.wl .mat:not(:nth-child(2)),.wl.wrapped .mat{border-left:0;padding-left:0}
/* what the code says — deliberately a different family of colour from the claim */
.wl.incode{color:var(--stated);border-color:var(--stated);background:var(--built-bg)}
.wl.partcode{color:var(--gold-ink);border-color:var(--gold);background:var(--cream);font-family:var(--mono);font-size:10.5px}
.wl.nocode{color:var(--assume);border-color:var(--assume);border-style:dashed;background:transparent}
.cat th.codec,.cat td.codec{border-left:1px solid var(--rule-strong)}
.legend2 i.wl{width:14px;height:14px;padding:0;border-radius:4px;display:inline-block}
.legend2 .matnote{color:var(--faint)}

/* a section that folds away — the journey is the point of the panel, the rest is reference */
details.foldsec{margin-bottom:26px}
details.foldsec > summary{display:flex;align-items:baseline;gap:10px;cursor:pointer;list-style:none;
  padding-bottom:8px;border-bottom:1px solid var(--rule)}
details.foldsec > summary::-webkit-details-marker{display:none}
details.foldsec > summary::before{content:"›";color:var(--faint);font-size:14px;transition:transform .15s}
details.foldsec[open] > summary::before{transform:rotate(90deg)}
details.foldsec > summary h4{margin:0}
details.foldsec > *:not(summary){margin-top:14px}
/* the writing conventions, where somebody is actually writing a step */
.convention{background:var(--cream);border-radius:8px;padding:10px 13px;margin:0 0 14px;max-width:none;line-height:1.6}
.convention b{color:var(--ink);font-weight:500}

/* ------------------------------------------------------------------ save or discard
   Changes are held rather than written on a timer, so the panel has to say plainly that
   something is waiting and offer both ways out. It sits under the panel header and stays
   there while you scroll: an unsaved change you cannot see is how work gets lost. */
/* THE HOST IS WHAT STICKS, 25 October 2026 — "leave the save as sticky so if there is something
   to save on editing I can trigger that all the time". The bar was sticky inside a wrapper only
   as tall as itself, and a sticky child can only stick while its parent is on screen: it slid
   away with the wrapper on the first scroll. */
#pBarHost{position:sticky;top:46px;z-index:5}
.savebar{position:static;top:52px;z-index:3;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 18px;padding:11px 14px;border-radius:10px;
  background:var(--cream);border:1px solid var(--gold)}
.savebar .sb{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.savebar .sb b{font:500 13px/1.3 var(--sans);color:var(--gold-ink)}
.savebar.asking{background:color-mix(in srgb,var(--assume) 7%,transparent);border-color:var(--assume)}
.savebar.asking .sb b{color:var(--assume)}
.save.un{color:var(--gold-ink)}

/* ---------------------------------------------------------------- the vocabulary switch
   Two names for one rung: the vehicles the build runs on, and what a client would be told.
   It changes the words on screen and nothing in any record. */
.viewsw{display:inline-flex;border:1px solid var(--rule);border-radius:7px;overflow:hidden;background:var(--ground)}
.viewsw button{border:0;background:transparent;color:var(--muted);font:500 11.5px/1 var(--sans);
  padding:7px 11px;cursor:pointer;letter-spacing:.01em}
.viewsw button+button{border-left:1px solid var(--rule)}
.viewsw button[aria-pressed="true"]{background:var(--ink);color:var(--ground)}
.viewsw button:hover:not([aria-pressed="true"]){color:var(--ink);background:var(--cream)}

/* the components a journey runs on, and the ladder in their own words */
.complist{list-style:none;margin:0 0 14px;padding:0;display:grid;gap:8px}
.complist li{border:1px solid var(--rule);border-left:3px solid var(--rule);border-radius:8px;
  padding:9px 12px;background:var(--ground)}
.complist li.weak{border-left-color:var(--prog);background:var(--prog-bg)}
.complist .ch{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.complist .ch b{font-size:13.5px;color:var(--ink)}
.complist .cuse,.complist .cst{font:500 10.5px/1.5 var(--sans);color:var(--muted);
  border:1px solid var(--rule);border-radius:4px;padding:0 5px;white-space:nowrap}
.complist p{margin:5px 0 0;max-width:none}
.sec .complist .mat,.ladder .mat{font:500 11px/1.4 var(--sans);color:var(--gold-ink);white-space:nowrap}
.derived{font-size:12.5px;line-height:1.55;color:var(--body);margin:0 0 4px;padding:10px 12px;
  max-width:none;border:1px solid var(--rule);border-radius:8px;background:var(--cream)}
.derived.spread{border-color:var(--prog);background:var(--prog-bg)}
.derived b{color:var(--ink)}
.derived .btn{margin-top:8px;display:inline-block}
.ladder{margin:0 0 8px;padding:0;list-style:none;display:grid;gap:0}
.ladder li{display:grid;grid-template-columns:130px minmax(0,1fr);gap:12px;align-items:baseline;
  font-size:12.5px;line-height:1.55;padding:9px 0;border-top:1px solid var(--rule)}
.ladder li:first-child{border-top:0}
.ladder li.at{background:var(--cream)}
.ladder li.at span:last-child{color:var(--ink);font-weight:500}
@media(max-width:700px){.ladder li{grid-template-columns:1fr;gap:3px}}

/* ---------------------------------------------------------------- the rung a class is at
   The grid used to say "to build" and then print "Scooter" beside it. One fact, said twice,
   in two vocabularies. The word is the rung now, and the only other answers are a decided
   no and a small mark saying somebody is on it this week. */
.wl.at{background:var(--cream);border-color:var(--rule-strong);color:var(--ink)}
.wl.discovery{background:transparent;border-style:dashed;color:var(--muted)}
.wl.r-Discovery{border-style:dashed;color:var(--muted);background:transparent}
.wl.r-Manual{background:#F3EFE6;border-color:#D9CFB8;color:#6B5A34}
.wl.r-Assisted{background:#EFEFE4;border-color:#CFCEB2;color:#5C5C34}
.wl.r-Automated{background:#E8F0E9;border-color:#B9D2BF;color:#2E6B4A}
.wl.r-Orchestrated{background:#E4EDF2;border-color:#AFCBD9;color:#2A5A72}
.wl.r-Autonomous{background:#EAE6F1;border-color:#C3B8D9;color:#4A3B70}
/* "Somebody is building this now" is one fact and was being said twice — a dot inside the
   chip AND a second ring around it. The dot sat in the chip's flex row, so on a narrow column
   it wrapped onto a line of its own and pushed the row taller than its neighbours. It is one
   pip now, pinned to the corner and out of the flow, so every chip is the same box whether or
   not somebody is on it. The legend keeps its own inline dot. */
.now{color:var(--prog);font-size:9px;line-height:1;margin-left:4px;vertical-align:middle}
.wl{position:relative}
/* The flow is written for this class. A left edge rather than anything in the chip's own row,
   for the same reason as the pip: the chip has to stay the same box. It reads as a spine — the
   class has something of its own holding it up — and it is deliberately quieter than the rung,
   because the rung is the claim and this is the footnote. */
.wl.own{border-left-width:3px;padding-left:7px}
.wl.own.discovery{border-left-style:solid;border-left-color:var(--gold)}
.wl.own.at{border-left-color:var(--gold-ink)}
.legend2 i.wl.own{border-left-width:3px;padding:0}
.wl .now{position:absolute;top:-3px;right:-3px;margin:0;width:7px;height:7px;border-radius:50%;
  background:var(--prog);box-shadow:0 0 0 2px var(--paper);font-size:0;overflow:hidden}
.state[class*="r-"] .dots{opacity:.65}
.legend2 .wl{display:inline-block;width:11px;height:11px;padding:0;margin-right:5px;vertical-align:-1px}
.legend2 .matnote b{color:var(--ink);font-weight:500}
.cov .barline .seg{display:inline-block;height:100%}
.cov .barline .seg.r-Manual{background:#D9CFB8}
.cov .barline .seg.r-Assisted{background:#CFCEB2}
.cov .barline .seg.r-Automated{background:#7FB393}
.cov .barline .seg.r-Orchestrated{background:#7FA8BF}
.cov .barline .seg.r-Autonomous{background:#A99BC6}
.cov .movingn{color:var(--prog)}

/* which rung a workflow is actually AT, on its own tab */
.seg button.atnow{box-shadow:inset 0 0 0 2px var(--gold)}
.seg button .segmark{font:600 8.5px/1 var(--sans);letter-spacing:.08em;text-transform:uppercase;
  color:var(--gold-ink);margin-left:6px;vertical-align:1px}
.seg button[aria-pressed="true"] .segmark{color:var(--paper)}
.seg button.wired::after{content:"⇄";margin-left:5px;opacity:.8}
.seg button.standalone::after{content:"⌁";margin-left:5px;opacity:.55}

/* where it runs today */
.runs{display:inline-block;margin-left:7px;font:500 10px/1.5 var(--sans);letter-spacing:.02em;
  color:var(--gold-ink);border:1px solid var(--rule);border-radius:4px;padding:0 5px;vertical-align:1px;
  white-space:nowrap}
.runs.none{color:var(--faint)}
.runs i{font-style:normal;color:var(--prog);font-weight:700}

/* the same fact said properly, under the lane marked NOW */
.runsnow{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;margin:10px 0 0;
  padding:9px 12px;background:var(--cream);border:1px solid var(--rule);border-radius:8px}
.runsnow .rl{font:500 9.5px/1.9 var(--sans);letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted);flex:0 0 auto}
.runsnow .rsys{display:flex;align-items:baseline;gap:7px;flex:0 0 auto;min-width:0;font-size:12.5px;line-height:1.55}
.runsnow.bare .rsys{flex:1 1 260px}
.runsnow .rsys+.rsys{margin-left:12px}
.runsnow .rsys b{font-weight:600;color:var(--ink);flex:0 0 auto}
.runsnow .rsys em{font-style:normal;color:var(--muted);min-width:0}
.runsnow .rsys.blank b,.runsnow .rsys.blank em{color:var(--faint)}
.runsnow .rsys.blank .bchip{border-style:dashed;opacity:.7}
.runsnow .star{font-style:normal;color:var(--prog);font-weight:700}
.runsnow .rclash{flex-basis:100%;font-size:12px;line-height:1.5;color:var(--assume)}
.runsnow .rclash b{font-weight:600}

/* ---------------------------------------------------------------- what changes at this rung
   Most steps survive from one rung to the next. Fading those is what lets the handful that
   do not be the thing you see, instead of five flows to read side by side. */
.flow li.d-carried{opacity:.52}
.flow li.d-carried:hover,.flow li.d-carried:focus-within{opacity:1}
.flow li.d-new{border-left:3px solid var(--gold)}
.flow li.d-changed{border-left:3px solid var(--prog)}
.dchip{font:500 9.5px/1.6 var(--sans);letter-spacing:.03em;border-radius:4px;padding:0 5px;
  border:1px solid var(--rule);color:var(--muted);white-space:nowrap}
.dchip.new{border-color:var(--gold);color:var(--gold-ink)}
.dchip.changed{border-color:var(--prog);color:var(--prog)}
.dchip.carried{opacity:.7}
.lanelead.diffn{border-left:2px solid var(--rule-strong);padding-left:10px}
/* the use-case reading of a flow: which of the three products these steps are for */
.lanelead.useread{border-left:2px solid var(--gold);padding-left:10px}
/* "Show the detail" — the drawings' step bodies, open or behind a click */
/* the use case, above the asset-class cards */
.usebar{margin:0 0 10px;display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.usebar .seg.uses button{font-size:12.5px;padding:7px 13px}
.usebar .ucnt{margin-left:7px;font:600 10.5px/15px var(--mono);background:var(--cream);
  color:var(--gold-ink);border-radius:8px;padding:0 5px;display:inline-block}
.usebar .seg.uses button[aria-pressed="true"] .ucnt{background:var(--paper);color:var(--ink)}
.usenote{margin:0;font-size:12.5px;color:var(--muted)}
.usenote b{color:var(--ink)}
.detailall{padding:6px 12px;font-size:12.5px}
.detailall[aria-pressed="true"]{background:var(--ink);color:var(--ground);border-color:var(--ink)}
.lanelead.useread b{color:var(--gold-ink)}

/* remarks — what was said about the tool, not about one workflow */
.unsup li{display:flex;gap:10px;align-items:baseline;justify-content:space-between}
.unsup li>span{flex:1}
.btn.keepr{padding:2px 8px;font-size:11px}
.btn.keepr.kept{color:var(--built);border-color:var(--built)}
.remarks{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.remarks .rm{border:1px solid var(--rule);border-left:3px solid var(--gold);border-radius:8px;padding:10px 12px;background:var(--ground)}
.remarks .rm.s-done,.remarks .rm.s-dropped{border-left-color:var(--rule);opacity:.6}
.remarks .rm.s-doing{border-left-color:var(--prog)}
.remarks .rm p{margin:0 0 8px;font-size:13px;line-height:1.55}
.remarks .rmm{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.remarks .rmm .btn{padding:1px 7px;font-size:10.5px}
.remarks .rmm .btn[aria-pressed="true"]{background:var(--ink);color:var(--ground);border-color:var(--ink)}

/* ---------------------------------------------------------------- the margins
   A question against one step, answered by somebody else, closed when it is settled. Open
   threads are drawn where somebody will trip over them: on the step, on the lane, on the row
   and in the header — because nothing here sends anybody anything. */
.cbox{margin-top:10px;padding-top:8px;border-top:1px dashed var(--rule)}
.cbox .cadd{padding:2px 9px;font-size:11px;color:var(--muted);border-style:dashed}
.cbox .cadd:hover{color:var(--ink);border-style:solid}
.cbox.open{border-top-color:var(--rule-strong)}
.cbox .chead{font:500 10.5px/1.6 var(--sans);letter-spacing:.02em;color:var(--muted);margin-bottom:8px}
.cbox .chead b{color:var(--gold-ink)}
.thread{border:1px solid var(--rule);border-left:3px solid var(--gold);border-radius:8px;
  padding:9px 11px;margin-bottom:8px;background:var(--ground)}
.thread.closed{border-left-color:var(--rule);opacity:.65}
.thread.adrift{border-left-color:var(--prog);background:var(--prog-bg)}
.thread .tnote{margin:0 0 8px;font-size:11.5px;line-height:1.5;color:var(--prog)}
.thread .msg+.msg{margin-top:9px;padding-top:9px;border-top:1px solid var(--rule)}
.thread .mh{display:flex;gap:8px;align-items:baseline}
.thread .mh b{font-size:12px;color:var(--ink)}
.thread .mh span{font-size:10.5px;color:var(--faint)}
.thread .msg p{margin:3px 0 0;font-size:12.5px;line-height:1.55;white-space:pre-wrap}
.thread .tact{display:flex;gap:6px;align-items:center;margin-top:9px}
.thread .tact .btn{padding:1px 8px;font-size:10.5px}
.replybox,.newbox{margin-top:9px}
.replybox textarea,.newbox textarea{width:100%;min-height:62px;font:400 12.5px/1.55 var(--sans);
  border:1px solid var(--rule);border-radius:7px;padding:8px 10px;background:var(--ground);color:var(--ink);resize:vertical}
.replybox .row,.newbox .row{display:flex;gap:7px;margin-top:7px}
.replybox .btn,.newbox .btn{padding:3px 11px;font-size:11.5px}
.adriftsec{border:1px solid var(--prog);border-radius:10px;padding:14px 16px;background:var(--prog-bg)}

/* where an open thread is counted */
.cat .wf .cmt{display:inline-block;margin-left:7px;min-width:17px;text-align:center;
  font:600 10px/16px var(--sans);color:var(--paper);background:var(--gold-ink);border-radius:9px;padding:0 5px}
.seg button.hascomments .segmark{color:var(--gold-ink);background:var(--cream);
  border-radius:8px;padding:0 5px;line-height:15px;display:inline-block}
.seg button[aria-pressed="true"].hascomments .segmark{color:var(--ink);background:var(--paper)}
.cmtall{border:1px solid var(--gold);background:var(--cream);color:var(--gold-ink);
  font:500 11px/1 var(--sans);border-radius:6px;padding:5px 9px;cursor:pointer;margin-left:10px}
.cmtall:hover{background:var(--agent)}
.seg button .segcount{margin-left:6px;min-width:15px;text-align:center;display:inline-block;
  font:600 9.5px/15px var(--sans);color:var(--paper);background:var(--gold-ink);border-radius:8px;padding:0 4px}
.seg button[aria-pressed="true"] .segcount{color:var(--ink);background:var(--paper)}
.fpills.runs button[aria-pressed="true"]{background:var(--gold-ink);border-color:var(--gold-ink);color:var(--paper)}

/* ---------------------------------------------------------------- the flow as a flow
   A list is right for reading a step and wrong for seeing one. Both drawings read the same
   steps and the same branches as the list — one flow, three ways to look at it. */
.seg.mini button{font-size:11.5px;padding:5px 10px}

/* rails — one per actor, the git network graph with actors as branches */
.rails{margin-top:12px}
.rkey{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
.rkey .act.back{opacity:.6;border-style:dashed}
.rlist{list-style:none;margin:0;padding:0}
/* The row is a block holding a summary and a detail, stacked. It used to BE the summary and
   was display:flex; leaving it that way put the open detail beside the row instead of under it,
   and the two overlapped. */
.rails .rrow{display:block;border-radius:7px;padding-right:8px;position:relative}
.rails .rsum{min-height:34px;gap:8px;padding-right:8px}
.rails .rg{flex:none;overflow:visible}
.rails .rg path{fill:none;stroke:var(--rule-strong);stroke-width:1.6}
.rails .rg .nd{stroke:var(--paper);stroke-width:2}
.rails .rg circle.nd{fill:var(--muted)}
.rails .rg circle.nd.agent{fill:var(--gold)}
.rails .rg circle.nd.system{fill:var(--gold-ink)}
.rails .rg circle.nd.external{fill:var(--assume)}
.rails .rg circle.nd.human{fill:var(--built)}
.rails .rg path.nd.gate{fill:var(--prog);stroke:var(--paper)}
.rails .rn{flex:none;width:22px;text-align:right;font:400 11px/1 var(--mono);color:var(--faint)}
.rails .rlab{flex:none;font-weight:600;font-size:13px}
.rails .rwant{color:var(--muted);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1 1 auto}
/* ------------------------------------------------------------ a step opens where it is drawn
   The drawing answers "who, and where does it go"; the detail answers everything else. Both
   views put the detail in the same block, from the same function, so the list is no longer the
   only place the full step can be read. */
.rsum,.lsum{display:flex;align-items:center;gap:8px;cursor:pointer;border-radius:8px;min-width:0}
.rsum:hover,.lsum:hover{background:var(--cream)}
.rsum:focus-visible,.lsum:focus-visible{outline:2px solid var(--gold-ink);outline-offset:1px}
.rcar{margin-left:auto;flex:none;color:var(--faint);font-size:15px;line-height:1;
  transition:transform .12s ease;padding:0 4px}
li.open > .rsum .rcar,li.open > .lsum .rcar{transform:rotate(90deg);color:var(--gold-ink)}
/* The summary row is ONE line, always. It had grown an actor chip, a slot, a Stated pill, a
   "not everywhere" chip and the branches, and at that point it wrapped — rows came out at
   different heights and the ragged edge was the thing she had just asked me to fix on the
   maturity chips. So the row carries only what a DRAWING is read for: who, what it is called,
   where it goes, and what they do. Everything else is in the detail, which is where the list's
   full heading now sits too. Nothing wraps; the label and the action truncate instead. */
.rsum{flex-wrap:nowrap}
.rsum .rlab{flex:0 1 auto;min-width:3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rsum .act{font:500 10.5px/1 var(--sans);padding:3px 7px;border-radius:5px;
  border:1px solid var(--rule);flex:none;white-space:nowrap}
.rsum .act.agent{background:var(--agent);border-color:var(--gold);color:var(--gold-ink)}
.rsum .act.system{border-style:dashed;color:var(--muted)}
.rsum .act.external{background:var(--paper);color:var(--muted)}
.rsum .act.human{color:var(--ink)}
/* The detail opens with the same heading the list gives a step, so the two are one thing. */
.rdet > .hd{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid var(--rule)}
@container (min-width: 620px){ .rdet > .hd{grid-column:1/-1} }
.rdet{padding:4px 0 14px 46px;margin:2px 0 6px;position:relative}
/* The rail, carried down past an open step so the picture is never cut in half. --gx is the
   column the flow is running in at this row, set per row when it draws. */
.rails li.open > .rdet::before{content:"";position:absolute;left:var(--gx);top:0;bottom:0;
  width:1.6px;background:var(--rule-strong)}
.lanes .rdet{padding-left:22px;border-left:2px solid var(--rule);margin-left:10px}
/* Two columns when the step opens across the full width: the story on the left, what it runs
   on to the right, and anything about the whole step underneath both. It is a container query,
   not a media query — what matters is how wide the PANEL is, not the window, and the panel is
   narrower than the window by a sidebar's worth. Where container queries are not supported the
   grid simply never applies and the detail stays one column, which is the honest fallback. */
/* The container is the ROW, not the detail: an element is never its own container, so putting
   container-type on .rdet and querying it matched nothing and the grid silently never applied.

   And a size container cannot contribute its own width — that is what containment means — so a
   parent that sizes to its contents gets nothing to size to and collapses to zero. The lanes
   key did exactly that and vanished. Both lists are given a definite width so there is a real
   number for the rows to be measured against. */
.rails .rlist,.lanes .llegend{width:100%}
.rails .rrow,.lanes .llegend > li{container-type:inline-size}
.rdet > .sb-tale{min-width:0}
.rdet > .sb-mech{min-width:0}
.rdet > .sb-tail:empty{display:none}
@container (min-width: 620px){
  .rdet{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
    column-gap:26px;row-gap:2px;align-items:start}
  .rdet > .sb-tale{grid-column:1}
  .rdet > .sb-mech{grid-column:2;padding-left:18px;border-left:1px solid var(--rule)}
  .rdet > .sb-tail{grid-column:1/-1}
  .rdet .sb-mech .io{margin-top:2px}
}
/* The list stays one column — it is a column by nature and she said it reads right as it is. */
ol.flow .sb-tale,ol.flow .sb-mech,ol.flow .sb-tail{display:contents}
.rdet .story{margin-top:6px}
.vhint{margin:10px 0 0}
/* The actor, said the same way in both drawings: a dot in the rail's colour, then the name. */
.rdot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--muted);
  flex:none;margin-right:5px;vertical-align:0}
.rdot.agent{background:var(--gold)}.rdot.system{background:var(--gold-ink)}
.rdot.external{background:var(--assume)}.rdot.human{background:var(--built)}
.rdot.back{background:transparent;box-shadow:inset 0 0 0 1px var(--rule-strong)}
.rails .rkey{display:flex;flex-wrap:wrap;gap:4px 14px;align-items:center;margin-bottom:8px}
.rkeyi{display:inline-flex;align-items:center;font:500 11.5px/1.6 var(--sans);color:var(--body)}
.rkeyi em{font-style:normal;font:400 9.5px/1 var(--mono);color:var(--faint);margin-left:4px}
.rails .rail-a{flex:none;display:inline-flex;align-items:center;font:500 11px/1.6 var(--sans);
  color:var(--muted);max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ltbl th .rdot{margin-right:6px}
.llegend li{break-inside:avoid;list-style:none}
.llegend{list-style:none}
.llegend .llab{font-weight:500}
.llegend li.open{columns:initial}
/* A step open in the key needs the full width — two columns of expanded prose is unreadable.
   Set as a class when a step opens rather than with :has(), so it does not depend on which
   browser the person is reading this in. */
.lanes .llegend.anyopen{columns:1}
/* A gate's answers. One chip per answer, because two answers run together read as one. */
.rails .rbr{display:inline-flex;gap:4px;flex:none}
.rails .rbr i{font:500 10.5px/1.6 var(--sans);font-style:normal;color:var(--prog);
  border:1px solid var(--prog);border-radius:4px;padding:0 5px;white-space:nowrap}
/* A branch that hands the work to ANOTHER workflow, and one that stops without going on. */
.rails .rbr i.toflow{color:var(--gold-ink);border-color:var(--gold-ink);background:var(--gold-wash,transparent)}
.rails .rbr i.outb{color:var(--faint);border-style:dashed}
.rails .rrow.gate .rlab{color:var(--prog-ink,var(--prog))}

/* lanes — a row per actor, time left to right */
.lanes{margin-top:12px}
.ltbl{border-collapse:collapse;font-size:12px}
.ltbl th{text-align:right;padding:0 10px 0 0;white-space:nowrap;font:500 12px/1.9 var(--sans);color:var(--body);position:sticky;left:0;background:var(--ground)}
.ltbl td{padding:3px 2px;min-width:26px}
.ltbl .lb{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;
  font:500 11px/1 var(--mono);color:var(--paper);background:var(--muted);cursor:default}
.ltbl .lb.agent{background:var(--gold)}
.ltbl .lb.system{background:var(--gold-ink)}
.ltbl .lb.external{background:var(--assume)}
.ltbl .lb.human{background:var(--built)}
.ltbl .lb.gate{border-radius:50%;background:var(--prog)}
.ltime{font-size:11px;color:var(--faint)}
.llegend{margin:12px 0 0;padding:0;list-style:none;columns:2;column-gap:28px;font-size:12.5px;line-height:1.9}
.llegend li{break-inside:avoid}
/* The step number in the key. Scoped to the summary row: unscoped, it also caught the <b> that
   the story uses for the actor, and "As Platform" came out in the monospace of a line number. */
.llegend .lsum > b{display:inline-block;min-width:20px;font:400 11px/1 var(--mono);color:var(--faint);flex:none}
@media (max-width:760px){.llegend{columns:1}}
.rails .rg path.out{stroke-dasharray:3 3;stroke:var(--prog)}
/* The stub for a branch that hands to another workflow is solid and gold: it is not the flow
   petering out, it is the work carrying on somewhere else. */
.rails .rg path.out.toflow{stroke-dasharray:none;stroke:var(--gold-ink)}
.ltbl .lb.hands{box-shadow:0 0 0 2px var(--paper),0 0 0 3.5px var(--gold-ink)}
.llegend .toflow{margin-left:6px;font:500 10.5px/1.6 var(--mono);color:var(--gold-ink)}
.ltbl tbody tr{background:linear-gradient(to bottom,transparent calc(50% - .5px),var(--rule) calc(50% - .5px),var(--rule) calc(50% + .5px),transparent calc(50% + .5px))}
.ltbl tbody th{background:var(--ground)}

/* ------------------------------------------------------------------ the agent roster
   The card used to carry a name and one role word. It now carries the role itself — title,
   department, reporting line, the radar dimension the agent owns — because "Clare runs six
   workflows" and "Clare is the community officer and four of those six are Risk" are different
   facts, and only the second one can be acted on. */
.agrole{margin:6px 0 4px;font-size:12.5px;line-height:1.45;color:var(--ink)}
/* Department, reporting line and dimension on one muted line rather than a three-row table.
   They are context for the role above them, not three separate questions. */
.agsub{margin:0 0 9px;font-size:11.5px;line-height:1.5;color:var(--faint)}
/* One line per use case, from GAP. A label column narrow enough that the sentences line up,
   because the point of showing both is reading one against the other. */
.aguse{margin:0 0 9px;display:grid;grid-template-columns:auto 1fr;gap:2px 9px;align-items:baseline}
.aguse dt{font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);
  white-space:nowrap}
.aguse dd{margin:0;font-size:12px;line-height:1.5;color:var(--ink)}
/* A roster entry, not a filter. A Fragent owns no workflow here, so its card must not look
   pressable: a button that empties the grid is worse than no button. */
.ag.info{cursor:default;background:transparent;border-style:dashed}
.ag.info:hover{border-color:var(--rule)}
/* A role still written in hotel language. A gap somebody has to close, so it looks like a
   gap rather than like decoration. */
.agpend{margin:0 0 8px;padding:6px 9px;border-radius:7px;background:var(--cream);
  border-left:2px solid var(--gold);font-size:11.5px;line-height:1.5;color:var(--gold-ink)}
.agwarn{font:500 9.5px/1.6 var(--sans);color:var(--prog);border:1px dashed var(--prog);
  border-radius:5px;padding:1px 6px;white-space:nowrap}
.agoff{color:var(--prog);border-bottom:1px dotted var(--prog);cursor:help}
/* Owner and runner are two facts. A flow Ralph owns and Holly runs is correct, not a fault, so
   this reads as information rather than as a warning. */
.agrun{margin:0 0 6px;font-size:11.5px;line-height:1.5;color:var(--gold-ink)}
.agrun span{border-bottom:1px dotted var(--gold);cursor:help}
/* The archetype from the Agent Registry 2026. Agents pair on it, so it is worth showing. */
.agarch{font:500 9.5px/1.6 var(--sans);color:var(--muted);border:1px solid var(--rule);
  border-radius:5px;padding:1px 6px;white-space:nowrap}
/* The lane a workflow is filed under, for the other app. A proposed filing is dashed and
   carries a question mark: the API says the same thing in `laneConfidence`, and a reader
   deciding whether to build on it should be able to see which is which without asking. */
.lanec{display:inline-block;margin-left:8px;font:500 9.5px/1.6 var(--mono);letter-spacing:.02em;
  color:var(--gold-ink);border:1px solid var(--gold);border-radius:5px;padding:0 5px;
  background:var(--cream);vertical-align:1px}
.lanec.proposed{border-style:dashed;color:var(--muted);border-color:var(--rule-strong);background:transparent}

/* ------------------------------------------- the class list, and what to do when it changes
   A panel that asks rather than tells. Every row says what disagrees and how many workflows
   carry the thing, because "remove `hospitality`" and "remove `hospitality` from 64 records"
   are the same click and very different decisions. A row waiting on an answer is marked; one
   already settled says who settled it and when, and stays visible — a decision you cannot see
   is one nobody can revisit. */
.classes .clshead{padding:12px 16px 10px;border-bottom:1px solid var(--rule)}
.classes .clshead p{margin:0 0 4px;font-size:12.5px;line-height:1.55;color:var(--muted);max-width:76ch}
.clslist{display:grid;gap:10px;padding:14px 16px}
.clsrow{border:1px solid var(--rule);border-radius:10px;padding:11px 13px;background:var(--paper)}
.clsrow.pend{border-color:var(--gold);background:var(--cream)}
.clsh{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 9px;margin-bottom:5px}
.clsh b{font:500 14.5px/1.2 var(--sans);color:var(--ink)}
.clsh code{font:400 11px/1.4 var(--mono);color:var(--muted)}
.clsk{font:500 9.5px/1.6 var(--sans);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--rule-strong);border-radius:999px;padding:1px 8px}
.clsn{margin-left:auto;font:400 11.5px/1.4 var(--mono);color:var(--faint);white-space:nowrap}
.clsn b{color:var(--ink);font-weight:500}
.clsw{margin:0;font-size:12px;line-height:1.55;color:var(--muted);max-width:80ch}
.clsw b{color:var(--ink);font-weight:500}
/* An answer that was given about a different GAP entry than the one on screen. It is not an
   answer to this question, so it is said out loud rather than silently reused. */
.clsstale{color:var(--prog)}
.clsdone{margin:6px 0 0;font-size:11.5px;line-height:1.5;color:var(--faint)}
.clsdone code{font-family:var(--mono);color:var(--muted)}
.clspick{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.clspick select{font:500 12px/1 var(--sans);padding:7px 9px;border-radius:7px;
  border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink);max-width:100%}
/* The dry run, said per item. A total at the bottom tells you how big it is; this tells you
   which choice made it that big. */
.clsplan{margin:8px 0 0;padding:6px 9px;border-radius:7px;background:var(--ground);
  border-left:2px solid var(--rule-strong);font:400 11.5px/1.5 var(--mono);color:var(--ink)}
.clsfoot{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:0 16px 16px}
.clsfoot .btn[disabled]{opacity:.45;cursor:not-allowed}
/* The suggested match. It sits above the dropdowns because it is the reason they are set the
   way they are — a pre-selected action with no stated reason is just a default somebody has to
   second-guess. */
.clssug{margin:7px 0 0;padding:7px 10px;border-radius:7px;background:var(--paper);
  border-left:2px solid var(--gold);font-size:11.5px;line-height:1.55;color:var(--ink)}
.clssug b{font-weight:500;color:var(--gold-ink)}
/* The ghost button sits beside a solid one here, so it needs an edge of its own — without it
   "Use GAP's for all" reads as a label rather than as the thing that sets every row at once. */
.clsfoot .btn.ghost{border:1px solid var(--rule-strong);background:var(--ground)}
.clsfoot .btn.ghost:hover{border-color:var(--ink)}
/* The preview lists one move per line and the newlines are in the text, so they have to
   survive. Run together, "WF-19 helpdesk: Holly → Rebecca WF-20 helpdesk: Holly → Rebecca"
   reads as one sentence about four workflows. */
.clsplan{white-space:pre-line}
/* The lane filter is a panel of checkboxes rather than a select, because a lane filter that
   takes one value asks the catalogue twice for "finance and the work filed across all four".
   The button carries the state: a closed panel with three boxes ticked inside it looks exactly
   like one with none. */
.fdrop{position:relative}
.fdropb{cursor:pointer;text-align:left;min-width:150px}
.fdropb::after{content:"▾";float:right;opacity:.5;margin-left:8px}
.fdropb.on{border-color:var(--ink);background:var(--paper);font-weight:500}
.fdropp{position:absolute;z-index:40;top:calc(100% + 6px);left:0;min-width:300px;max-height:60vh;
  overflow:auto;background:var(--ground);border:1px solid var(--rule-strong);border-radius:10px;
  box-shadow:0 10px 30px rgba(0,0,0,.14);padding:6px}
.fckg{padding:4px 0;border-bottom:1px solid var(--rule)}
.fckg:last-of-type{border-bottom:0}
.fck{display:flex;align-items:center;gap:8px;padding:5px 9px 5px 26px;border-radius:7px;cursor:pointer;
  font:400 12.5px/1.3 var(--sans);color:var(--ink)}
.fck:hover{background:var(--paper)}
.fck.main{padding-left:9px;font-weight:500}
.fck input{margin:0}
.fck span{flex:1;min-width:0}
.fck i{font-style:normal;font-family:var(--mono);font-size:11px;color:var(--faint)}
.fckf{display:flex;justify-content:flex-end;padding:6px 4px 2px}

/* A heading inside a filter panel, for the People list where "our side" and "outside" are
   two different questions and a flat list of twenty-one roles answers neither. */
.fckh{display:block;padding:6px 9px 3px;font:500 10.5px/1 var(--sans);letter-spacing:.08em;
  text-transform:uppercase;color:var(--faint)}
/* Why something is NOT in the list. The Platform acts in all 63 workflows, so offering it as
   a filter offers a control that selects everything — worth saying once, in place, rather
   than leaving somebody to look for it. */
.fckn{margin:8px 4px 2px;padding-top:7px;border-top:1px solid var(--rule);
  font:400 11px/1.45 var(--sans);color:var(--faint)}
/* The group-by control. Labelled, because an unlabelled select beside four filters reads as a
   fifth filter. */
.grpby{display:flex;align-items:center;gap:7px;margin-left:auto}
.grpby>span{font:400 11.5px/1 var(--sans);color:var(--faint);white-space:nowrap}
.grpby .fsel{min-width:132px}

/* ------------------------------------------------------------------ the agents' faces
   The ball beside an agent's name. 20px inline, larger on the roster card. An agent without
   artwork gets a lettered ball in a colour derived from its id, so the gap looks deliberate
   rather than broken — and so it keeps the same colour as the roster grows. */
.aball{display:inline-block;width:20px;height:20px;border-radius:50%;vertical-align:-5px;
  margin-right:5px;flex:0 0 auto;object-fit:cover;background:var(--paper)}
.aball.none{display:inline-flex;align-items:center;justify-content:center;
  font:600 10px/1 var(--sans);color:hsl(var(--bh) 42% 32%);
  background:hsl(var(--bh) 54% 90%);box-shadow:inset 0 0 0 1px hsl(var(--bh) 40% 78%)}
.aball.big{width:30px;height:30px;vertical-align:-9px;margin-right:8px;font-size:13px}
/* The face is a look-up. Hovering says who it is in one line; clicking opens the rest, which
   is why it takes a pointer and a focus ring of its own rather than looking like decoration. */
.aball[data-agent]{cursor:pointer}
.aball[data-agent]:hover{box-shadow:0 0 0 2px var(--gold)}
.aball.none[data-agent]:hover{box-shadow:inset 0 0 0 1px hsl(var(--bh) 40% 78%),0 0 0 2px var(--gold)}
.agpop{position:absolute;z-index:60;width:min(340px,calc(100vw - 16px));
  background:var(--ground);border:1px solid var(--rule-strong);border-top:3px solid var(--gold);
  border-radius:12px;padding:13px 15px 11px;box-shadow:0 14px 40px rgba(0,0,0,.17)}
.agpop[hidden]{display:none}
.agpoph{display:flex;align-items:center;gap:2px;flex-wrap:wrap;margin-bottom:2px}
.agpoph b{font:500 15px/1.3 var(--sans);margin-right:6px}
.agpopx{margin-left:auto;background:none;border:0;cursor:pointer;font-size:19px;line-height:1;
  color:var(--faint);padding:0 2px}
.agpopx:hover{color:var(--ink)}
.agpop .agrole{margin:4px 0 3px}
.agpop .agsub{margin:0 0 7px}
.agpopn{margin:0;font-size:12px;line-height:1.5;color:var(--muted);
  border-top:1px solid var(--rule);padding-top:8px}
.agpopn b{font-weight:500;color:var(--ink)}
.agpopmore{margin:7px 0 0;font-size:11.5px}
.agpopmore a{color:var(--gold-ink)}
.aname{vertical-align:baseline}
/* Inside a chip or a step's actor line the ball must not push the text off its baseline. */
.chip.ag .aball,.act .aball{vertical-align:-5px}
/* The head wraps rather than truncates. The ball took the width the name used to have, and
   "Rebecca" came out as "Rebe…" — an agent's name is the one thing on the card that must
   survive, so the chips drop to a second line instead. */
.agh{display:flex;align-items:center;justify-content:flex-start;gap:0 6px;flex-wrap:wrap;row-gap:5px}
/* The archetype goes to the right of whatever room is left, which is where it was before the
   ball pushed the row around. */
.agh .agarch{margin-left:auto}
.agh b{flex:0 1 auto;min-width:0;margin-right:2px}
/* The "more" button on a roster card. Everything the card used to list lives behind it. */
.agmore{margin-left:7px;width:16px;height:16px;border-radius:50%;border:1px solid var(--rule-strong);
  background:var(--ground);color:var(--faint);font:600 10px/1 var(--sans);cursor:help;padding:0}
.agmore:hover{border-color:var(--ink);color:var(--ink)}

/* ------------------------------------------------------------------ configuration
   The two reconciliation panels, behind one disclosure and shown only to an admin. Quieter
   than the catalogue's own sections on purpose: it is machinery, not the register. */
.cfg{border:1px dashed var(--rule-strong);border-radius:12px;background:var(--paper);margin:0 0 18px}
.cfg>summary{display:flex;align-items:center;gap:9px;padding:11px 16px;cursor:pointer;list-style:none}
.cfg>summary::-webkit-details-marker{display:none}
.cfg>summary b{font:500 13.5px/1.2 var(--sans)}
.cfg>summary .asub{font:400 12px/1.2 var(--sans);color:var(--faint)}
.cfg>summary .acnt{margin-left:auto;font:400 11.5px/1.2 var(--mono);color:var(--faint)}
.cfg>summary .acnt.on{color:var(--gold-ink);font-weight:500}
.cfg[open]>summary .atw{transform:rotate(90deg)}
.cfg>summary .atw{transition:transform .14s ease;color:var(--faint)}
.cfgbody{padding:0 14px 12px}
.cfgbody>.agents{margin-bottom:10px}

/* ------------------------------------------------------------------ the software mark
   `Platform` used to be the actor on 1,158 steps: it said which steps are software somebody
   has to build, and cost the reader any sense of who was accountable. The actor is the agent
   now and this is where the fact went, so both questions still have an answer on the same
   record. Quiet on purpose — it is a property of the step, not the step's subject. */
.plat{margin-left:5px;font:400 11px/1 var(--mono);color:var(--faint);cursor:help;
  opacity:.75;vertical-align:1px}
.plat:hover{opacity:1;color:var(--gold-ink)}

/* ------------------------------------------------------------------ what is wrong with a flow
   A defect that is a property of the record — a gate with no next step, no owner, a filing
   nobody confirmed — said on the row and listed in the panel. Nobody was going to find these
   by reading sixty-one workflows. */
.iss{display:inline-flex;align-items:center;gap:1px;margin-left:7px;padding:1px 6px;border-radius:999px;
  font:500 10.5px/1.5 var(--mono);color:var(--faint);border:1px solid var(--rule-strong);
  background:var(--ground);cursor:help;vertical-align:1px}
/* Loud only where it should be: an approval that cannot be refused is not untidiness. */
.iss.grave{color:#9a3412;border-color:#fdba74;background:#fff7ed;font-weight:600}
.issues h4{display:flex;align-items:center;gap:8px}
.isscnt{font:500 11px/1.6 var(--mono);color:var(--faint);border:1px solid var(--rule);
  border-radius:999px;padding:0 7px}
.issues.grave h4{color:#9a3412}
.issues.grave .isscnt{color:#9a3412;border-color:#fdba74;background:#fff7ed}
.isslist{list-style:none;margin:8px 0 0;padding:0}
.isslist li{padding:6px 0 6px 14px;border-left:2px solid var(--rule);margin-bottom:4px;
  font:400 13px/1.5 var(--sans);color:var(--muted)}
.isslist li.g{border-left-color:#fdba74;color:var(--ink)}
/* The lane and step sit in their own column so the sentence does not run into them. A lane
   label can be an emoji plus a word, so the gap is a margin and not a min-width alone. */
.issat{display:inline-block;min-width:124px;margin-right:10px;font:400 11px/1.5 var(--mono);color:var(--faint)}

/* ---------------------------------------------------------------- what these need
   A picker and an answer, side by side, because the point of the page is that changing the
   selection changes the answer — putting them on separate screens would hide the one thing
   it exists to show. */
.reqwrap{display:grid;grid-template-columns:minmax(0,310px) minmax(0,1fr);gap:26px;align-items:start}
.reqpick{position:sticky;top:18px;border:1px solid var(--rule);border-radius:13px;
  background:var(--paper);padding:13px 14px 12px}
.reqtabs{display:flex;gap:6px;margin-bottom:10px}
.reqtabs button{font:400 12.5px/1.2 var(--sans);padding:6px 10px;border-radius:999px;cursor:pointer;
  border:1px solid var(--rule-strong);background:var(--ground);color:var(--muted)}
.reqtabs button[aria-pressed=true]{background:var(--ink);border-color:var(--ink);color:var(--ground)}
.reqtabs i{font-style:normal;font-size:10.5px;opacity:.75}
.reqlist{max-height:min(58vh,520px);overflow:auto;margin:0 -4px 10px;padding:0 4px}
.reqsrch{display:block;margin-bottom:8px}
.reqsrch input{width:100%;font:400 13px/1.2 var(--sans);padding:7px 10px;border-radius:8px;
  border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink)}
.reqck{display:flex;gap:8px;align-items:baseline;font-size:13px;line-height:1.45;
  padding:4px 6px;border-radius:7px;cursor:pointer}
.reqck:hover{background:var(--cream)}
.reqck input{margin:0;accent-color:var(--gold-ink);flex:0 0 auto}
.reqck.sub{padding-left:22px;font-size:12.5px;color:var(--muted)}
.reqck.main span{font-weight:500}
.reqck .mono{font:400 11px/1 var(--mono);color:var(--gold-ink);margin-right:4px}
/* A use case is a narrowing, not a flow, so its rows read like the main lanes rather than
   like a list of things being added up. The count sits in the same `i` the tabs use. */
.reqck.use span{font-weight:500}
.reqck i{font-style:normal;font-weight:400;font-size:11px;color:var(--faint);margin-left:5px}
.reqlocal{font-style:normal;font-size:10px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--rule-strong);border-radius:4px;padding:1px 4px;
  margin-left:5px;vertical-align:1px}
.reqlane{margin-bottom:8px}
.reqbar{display:flex;gap:8px;align-items:center;margin-bottom:8px}
.reqbar .btn{font-size:13px}
.reqpick .note{margin:0;font-size:11.5px;line-height:1.55;color:var(--faint)}

.reqhead h2{font:300 23px/1.25 var(--sans);margin:0 0 9px}
.reqstats{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:7px}
.rs{font-size:12px;line-height:1.5;color:var(--muted);border:1px solid var(--rule);
  border-radius:999px;padding:4px 11px;background:var(--ground)}
.rs b{font-weight:500;color:var(--ink)}
.rs.bring{border-color:var(--gold);background:var(--cream)}
.rs.other{border-color:var(--rule-strong)}
.rs.none b{color:#8d3b2f}
.reqsec{margin-top:26px;border-top:1px solid var(--rule);padding-top:15px}
.reqsec h3{font:500 15px/1.3 var(--sans);margin:0 0 5px}
.reqsec h3 i{font-style:normal;font-size:11.5px;color:var(--muted);margin-left:6px}
.reqsec .lead{font-size:12.5px;line-height:1.6;color:var(--muted);margin:0 0 12px;max-width:62ch}
.reqsec.none h3,.reqsec.unc h3{color:#8d3b2f}
.reqrow{border:1px solid var(--rule);border-radius:10px;padding:9px 12px;margin-bottom:7px;
  background:var(--ground)}
.reqsec.none .reqrow{background:var(--paper);border-style:dashed}
.reqrowh{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap}
.reqrowh b{font:500 13.5px/1.4 var(--sans)}
.reqrowh .mono{font:400 11px/1.6 var(--mono);color:var(--gold-ink)}
.reqwhy{font-size:11px;color:var(--muted);border:1px solid var(--rule);border-radius:999px;
  padding:2px 8px}
.reqask{font-size:11px;color:var(--gold-ink);border:1px solid var(--gold);border-radius:999px;
  padding:2px 8px;background:var(--cream)}
.reqsub{margin:4px 0 0;font-size:11.5px;line-height:1.55;color:var(--muted)}
.reqflow{font:400 11px/1 var(--mono);color:var(--gold-ink);text-decoration:none;
  border-bottom:1px solid var(--rule-strong)}
.reqflow:hover{border-bottom-color:var(--gold-ink)}
.reqsup{margin:6px 0 0;padding-left:17px}
.reqsup li{font-size:12.5px;line-height:1.6;color:var(--ink)}
.reqsup li.blocks{color:#8d3b2f}
.reqund{margin:6px 0 0;padding:6px 9px;border-radius:7px;background:var(--cream);
  font-size:11.5px;line-height:1.55;color:var(--muted)}
/* A decision, not a gap — so it is plain rather than flagged. The cream panel above means
   "somebody still has to do something about this"; this one means the opposite. */
.reqnone{margin:6px 0 0;font-size:11.5px;line-height:1.55;color:var(--faint)}
.reqrow.closer .reqrowh{justify-content:space-between}
.btn.small{font-size:11.5px;padding:4px 10px}
@media (max-width:900px){.reqwrap{grid-template-columns:minmax(0,1fr)}.reqpick{position:static}}

/* The parties, in three groups — an outside party hands things over, our own people have to
   exist, and our own agents are asked nothing. One list sorted by size hid that. */
.reqside{margin-bottom:20px}
.reqside h4{font:500 13px/1.4 var(--sans);margin:0 0 3px}
.reqside h4 i{font-style:normal;font-size:11px;color:var(--muted);margin-left:5px}
.reqsidelead{font-size:11.5px;line-height:1.55;color:var(--faint);margin:0 0 9px;max-width:62ch}
.reqsup li{list-style:none;margin:0 0 9px;padding:0}
.reqsup{padding-left:0;margin:7px 0 0}
.reqwhat{font-size:12.5px;line-height:1.5;color:var(--ink)}
.reqsup li.blocks .reqwhat{font-weight:500}
.reqkind,.reqconf,.reqblocks{font:400 10px/1.6 var(--sans);border-radius:999px;padding:1px 7px;
  margin-left:5px;white-space:nowrap;vertical-align:1px}
.reqkind{border:1px solid var(--rule);color:var(--muted)}
.reqconf{border:1px solid var(--rule-strong);color:var(--muted)}
.reqconf.assumption{border-color:#c9a227;background:var(--cream);color:#8a6d1f}
.reqblocks{border:1px solid #d8b4ac;background:#fbf2f0;color:#8d3b2f}
.reqwhy2{margin:3px 0 0;font-size:11.5px;line-height:1.55;color:var(--muted);max-width:68ch}
.reqsrc{margin:2px 0 0;font:400 10.5px/1.5 var(--mono);color:var(--faint);max-width:68ch}

/* What you can do to the catalogue, next to the catalogue. These were in the top header, which
   is navigation — eleven things in one row, of which four were not navigation at all. */
.catacts{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:0 0 10px;flex-wrap:wrap}
.cag{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.cag.right{margin-left:auto}
/* The header reads as three groups: how you are reading the page, where else you can go, and
   who you are. A gap says so without a line down the middle of a row that already wraps. */
.top .tr .navgap{flex:0 0 14px}
@media (max-width:980px){.top .tr .navgap{flex-basis:0}}

/* The lanes editor on the admin page. A table that reads as a hierarchy without indenting
   itself into a corner: the main lane is the only bold row, a group is set in from it, and a
   retired or category row sits apart in lighter type. The count column is what somebody is
   actually here for — "what happens if this goes" — so it is the one thing right-aligned and
   the only thing that changes colour when it is zero. */
.letab{width:100%;border-collapse:collapse;margin:10px 0 14px;font-size:13px}
.letab th{text-align:left;font:600 10.5px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);padding:6px 10px;border-bottom:1px solid var(--rule)}
.letab th.num,.letab td.num{text-align:right;font-family:var(--mono)}
.letab td{padding:6px 10px;border-bottom:1px solid var(--rule)}
.letab tr.lemain td{background:var(--paper);border-top:1px solid var(--rule-strong)}
.letab tr.lesub td:first-child,.letab tr.lesub td:nth-child(2){padding-left:26px}
.letab tr.leret td,.letab tr.lecat td{color:var(--muted)}
.letab tr.leret td:first-child{text-decoration:line-through}
.letab td.num.zero{color:var(--muted);opacity:.55}
#laneEditJson{width:100%;font:400 12px/1.5 var(--mono);white-space:pre;overflow-x:auto}
.small.bad{color:var(--bad,#a3341f)}
.small.ok{color:var(--gold-ink)}

/* The small sheet: one thing being edited, over the page rather than beside it. Narrow on
   purpose — it holds a form of four fields, and a wide box invites more of them. */
.sheet{position:fixed;z-index:60;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(520px,calc(100vw - 32px));max-height:min(80vh,760px);overflow:auto;
  background:var(--card,#fff);border:1px solid var(--rule-strong);border-radius:10px;
  box-shadow:0 18px 50px rgba(0,0,0,.18);padding:16px 18px 18px}
.sheethead{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 12px}
.sheethead b{font-size:15px}
.sheet .fld{display:block;margin:0 0 12px}
.sheet .fld>span{display:block;font:600 10.5px/1 var(--mono);letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);margin:0 0 5px}
.sheet .fld input,.sheet .fld select{width:100%;padding:7px 9px;border:1px solid var(--rule);
  border-radius:6px;font:inherit;background:var(--paper)}
.sheet .fld .hint{display:block;margin:5px 0 0;font-size:11.5px;line-height:1.5;color:var(--muted)}
.sheet .addbar{display:flex;align-items:center;gap:10px;margin:12px 0 0;flex-wrap:wrap}
.clsedfoot{border-top:1px solid var(--rule);margin:14px 0 0;padding:12px 0 0}
.btn.off{opacity:.45;cursor:not-allowed}

/* The pencil inside a class box, and the box that adds one. The pencil only appears on hover
   or focus, because a row of permanent pencils reads as a toolbar and these boxes are first of
   all a filter. */
.cov .covedit{position:absolute;top:6px;right:6px;border:0;background:transparent;
  color:var(--muted);font-size:13px;line-height:1;padding:3px 5px;border-radius:5px;
  cursor:pointer;opacity:0;transition:opacity .12s}
.cov{position:relative}
.cov:hover .covedit,.cov:focus-within .covedit{opacity:1}
.cov .covedit:hover{background:var(--paper);color:var(--gold-ink)}
/* Looks like a class box and is deliberately not one — `.cov` is how the classes are counted. */
.covadd{display:flex;align-items:center;justify-content:center;gap:8px;border:1px dashed var(--rule);
  border-radius:8px;background:transparent;color:var(--muted);font:600 18px/1 var(--mono);
  cursor:pointer;min-height:84px;padding:10px}
.covadd span{font:600 11px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase}
.covadd:hover{color:var(--gold-ink);border-color:var(--rule-strong)}

/* The pencil beside a group heading. Hidden until the row is hovered or focused, for the same
   reason as the one on a class box: the heading is first of all a control that opens and
   closes the group, and a column of permanent pencils reads as a toolbar nobody asked for. */
.cat tr.grp .grpedit{border:0;background:transparent;color:var(--muted);font-size:12px;
  line-height:1;padding:2px 5px;margin-left:8px;border-radius:5px;cursor:pointer;opacity:0;
  transition:opacity .12s}
.cat tr.grp:hover .grpedit,.cat tr.grp:focus-within .grpedit{opacity:1}
.cat tr.grp .grpedit:hover{background:var(--cream);color:var(--gold-ink)}

/* The pencil on an agent card, and the card that adds one. */
.ag{position:relative}
.ag .agedit{position:absolute;top:8px;right:8px;border:0;background:transparent;color:var(--muted);
  font-size:12px;line-height:1;padding:3px 5px;border-radius:5px;cursor:pointer;opacity:0;transition:opacity .12s}
.ag:hover .agedit,.ag:focus-within .agedit{opacity:1}
.ag .agedit:hover{background:var(--cream);color:var(--gold-ink)}
/* It looks like a card and is deliberately not one — see the comment where it is built. */
.agadd{display:flex;align-items:center;justify-content:center;gap:8px;border:1px dashed var(--rule);
  border-radius:8px;background:transparent;color:var(--muted);font:600 18px/1 var(--mono);
  cursor:pointer;min-height:96px;padding:12px}
.agadd span{font:600 11px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase}
.agadd:hover{color:var(--gold-ink);border-color:var(--rule-strong)}

/* The reload summary. A table of what moves per workflow, under the three numbers — the numbers
   say whether anything is waiting, this says whether to apply it. */
.seeddiff{margin:12px 0 4px}
.seeddiff>summary{cursor:pointer;font-size:13px;padding:6px 0}
.difftab{width:100%;border-collapse:collapse;margin:8px 0 0;font-size:12.5px}
.difftab th{text-align:left;font:600 10px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);padding:5px 8px;border-bottom:1px solid var(--rule)}
.difftab td{padding:6px 8px;border-bottom:1px solid var(--rule);vertical-align:top}
.difftab td:first-child{white-space:nowrap}
.dif{display:inline-block;background:var(--paper);border:1px solid var(--rule);border-radius:4px;
  padding:2px 6px;margin:0 4px 4px 0;font-size:11.5px}

/* The catalogue's edit-legend rules were removed on 22 October with the legend they styled. */
/* A STEP EDITED WHERE IT IS READ, 25 October 2026 — "I would like to be able to edit
   individually each step or all the steps at once". The grid is the flow editor's own, so it
   is set apart from the prose above it rather than restyled. */
.sb .stepedit{margin-left:auto}
.sform{margin-top:10px;border-top:1px solid var(--rule);padding-top:10px}
.sform .rb{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:0}
.sform .rb + .rb{margin-top:8px}
.sform .rb .wide{grid-column:1/-1}
.sform .lenswarn{margin:0 0 8px}
@media (max-width:760px){.sform .rb{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}

/* The journey's two control rows: how it is drawn, then what is being read. The second row
   leads with its own word so the filters do not read as a continuation of the first. */
.jfilters{margin-top:-4px}
.jfilters::before{content:"Filtered to";font:500 9.5px/1.5 var(--sans);letter-spacing:.13em;
  text-transform:uppercase;color:var(--gold-ink);flex:none;white-space:nowrap}
/* Previous and next, in the panel's own header beside Close. */
.ph2 .pnav{display:flex;align-items:center;gap:6px;margin-left:auto}
.ph2 .pnav .btn.nav{padding:2px 10px;font-size:15px;line-height:1.4}
.ph2 .pnav .btn.nav[disabled]{opacity:.35;cursor:default}

/* ------------------------------------------------------------------ PARTNER LINKS, 30 October
   2026 — "i want to be able to create links with secrets form the admin panel". The link is
   shown in full and copied with one press: a credential you have to select by hand out of a
   table is one that gets half-copied and then pasted into a chat to ask why it does not work. */
.sl-make{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:10px 0 4px}
.sl-make input,.sl-make select{font:400 13px/1.2 var(--sans);padding:8px 10px;border-radius:8px;
  border:1px solid var(--rule-strong);background:var(--ground);color:var(--ink)}
.sl-make input{min-width:min(320px,100%);flex:1 1 240px}
.sl-make .note.bad{color:var(--gold-ink)}
.sl-tab td{vertical-align:top}
.sl-url{width:46%}
.sl-in{font:400 11.5px/1.3 var(--mono);width:calc(100% - 68px);padding:5px 7px;border-radius:6px;
  border:1px solid var(--rule);background:var(--paper);color:var(--body)}
.sl-copy{padding:4px 9px;font-size:11.5px;margin-left:6px;vertical-align:top}
tr.sl-off td{opacity:.6}
tr.sl-off td:first-child b{text-decoration:line-through;text-decoration-color:var(--faint)}
