/* Tupperty PMO board -- hosted stylesheet.
 *
 * board-shared.css IN FULL (the artifact board's own rules, extracted from
 * phase-board.html), plus the handful of classes that exist only here.
 * Owner, three times: the hosted board did not look like the artifact board.
 * The first attempt matched only the palette; the second appended only the
 * structural rules I had newly introduced, which left the masthead and panels
 * on my own hand-port. Using the whole sheet is the thing that actually works.
 *
 * [hidden] must be neutralised FIRST: board.js toggles the gate, app and
 * composer with the hidden attribute, and any class rule setting `display`
 * beats it. The artifact host injects this rule; a hosting page does not.
 */

[hidden]{display:none!important}

:root{
    --ground:#EFF2F3;
    --surface:#FFFFFF;
    --surface-sunk:#E6EAEB;
    --ink:#101418;
    --ink-soft:#3D474E;
    --slate:#5A6570;
    --slate-faint:#8B959C;
    --rule:#D3D9DA;
    --rule-strong:#B9C2C4;
    --accent:#2E5A73;
    --accent-soft:#DCE6EB;
    --ok:#3F7A54;
    --info:#2F6FB0;
    --ok-bg:#DEEBE2;
    --warn:#9A6716;
    --warn-bg:#F3E6CE;
    --crit:#A8443C;
    --crit-bg:#F4DEDC;
    --void:#77818A;
    --void-bg:#E3E7E8;
    --shadow:0 1px 2px rgba(16,20,24,.06),0 4px 16px rgba(16,20,24,.05);
  }
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]){
      --ground:#0D1114;
      --surface:#161C20;
      --surface-sunk:#11171A;
      --ink:#E8EDEF;
      --ink-soft:#BAC4C9;
      --slate:#939EA5;
      --slate-faint:#6C767D;
      --rule:#252E33;
      --rule-strong:#364248;
      --accent:#7FB2CE;
      --accent-soft:#1B2C36;
      --ok:#76B98C;
    --info:#8FBEE8;
      --info:#8FBEE8;
      --ok-bg:#1A2C21;
      --warn:#D5A44F;
      --warn-bg:#2E2415;
      --crit:#DE8B83;
      --crit-bg:#311D1B;
      --void:#7D878E;
      --void-bg:#1B2226;
      --shadow:0 1px 2px rgba(0,0,0,.4),0 4px 18px rgba(0,0,0,.3);
    }
  }
  :root[data-theme="dark"]{
    --ground:#0D1114;
    --surface:#161C20;
    --surface-sunk:#11171A;
    --ink:#E8EDEF;
    --ink-soft:#BAC4C9;
    --slate:#939EA5;
    --slate-faint:#6C767D;
    --rule:#252E33;
    --rule-strong:#364248;
    --accent:#7FB2CE;
    --accent-soft:#1B2C36;
    --ok:#76B98C;
    --ok-bg:#1A2C21;
    --warn:#D5A44F;
    --warn-bg:#2E2415;
    --crit:#DE8B83;
    --crit-bg:#311D1B;
    --void:#7D878E;
    --void-bg:#1B2226;
    --shadow:0 1px 2px rgba(0,0,0,.4),0 4px 18px rgba(0,0,0,.3);
  }

  *{box-sizing:border-box}
  body{
    background:var(--ground);
    color:var(--ink);
    font-family:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
    font-size:15px;
    line-height:1.55;
    -webkit-font-smoothing:antialiased;
  }
  .wrap{max-width:1180px;margin:0 auto;padding:48px 28px 80px;display:flex;flex-direction:column;gap:40px}

  /* ---- masthead ---- */
  .mast{display:flex;flex-direction:column;gap:14px;border-bottom:2px solid var(--ink);padding-bottom:22px}
  .eyebrow{
    font-family:"IBM Plex Mono",ui-monospace,monospace;
    font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--slate);display:flex;flex-wrap:wrap;gap:8px 18px;
  }
  h1{
    font-family:"IBM Plex Serif",Georgia,serif;
    font-weight:600;font-size:clamp(30px,4.4vw,46px);line-height:1.08;
    margin:0;letter-spacing:-.015em;text-wrap:balance;
  }
  .standfirst{
    font-size:17px;color:var(--ink-soft);max-width:64ch;margin:0;
    text-wrap:pretty;
  }

  /* ---- owner action panel ---- */
  .owner{border:2px solid var(--accent);border-radius:4px;background:var(--surface);box-shadow:var(--shadow);overflow:hidden}
  .owner-head{padding:14px 22px;background:var(--accent);display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
  .owner-head h2{margin:0;font-family:"IBM Plex Serif",Georgia,serif;font-size:19px;font-weight:600;color:#fff;letter-spacing:-.01em}
  .owner-head .count{font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:#fff;opacity:.85;margin-left:auto;letter-spacing:.06em}
  .owner-body{display:flex;flex-direction:column}
  .act{display:flex;gap:14px;padding:16px 22px;border-bottom:1px solid var(--rule);align-items:flex-start}
  .act:last-child{border-bottom:none}
  .act .mark{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.09em;text-transform:uppercase;padding:3px 8px;border-radius:2px;flex:none;font-weight:600;margin-top:1px}
  .act.now .mark{background:var(--crit-bg);color:var(--crit)}
  .act.soon .mark{background:var(--warn-bg);color:var(--warn)}
  .act.idle .mark{background:var(--void-bg);color:var(--void)}
  .act .txt{display:flex;flex-direction:column;gap:3px}
  .act .t{font-size:14.5px;font-weight:600;color:var(--ink);text-wrap:pretty}
  .act .w{font-size:13px;color:var(--ink-soft);text-wrap:pretty;max-width:76ch}
  .act code{font-family:"IBM Plex Mono",monospace;font-size:.88em;background:var(--surface-sunk);padding:1px 5px;border-radius:2px;border:1px solid var(--rule)}

  .decide{display:flex;gap:7px;margin-top:9px;flex-wrap:wrap;align-items:center}
  .decide button{
    font-family:"IBM Plex Sans",sans-serif;font-size:12.5px;font-weight:600;
    padding:5px 14px;border-radius:3px;border:1px solid var(--rule-strong);
    background:var(--surface);color:var(--ink-soft);cursor:pointer;
    transition:background .12s ease,border-color .12s ease,color .12s ease;
  }
  .decide button:hover:not(:disabled){border-color:var(--ink-soft);color:var(--ink)}
  .decide button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .decide button.approve:hover:not(:disabled){background:var(--ok-bg);border-color:var(--ok);color:var(--ok)}
  .decide button.hold:hover:not(:disabled){background:var(--warn-bg);border-color:var(--warn);color:var(--warn)}
  .decide button.reject:hover:not(:disabled){background:var(--crit-bg);border-color:var(--crit);color:var(--crit)}
  .decide button:disabled{opacity:.4;cursor:default}
  .decide .verdict{font-family:"IBM Plex Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.05em;padding:4px 10px;border-radius:3px}
  .decide .verdict.approve{background:var(--ok-bg);color:var(--ok)}
  .decide .verdict.hold{background:var(--warn-bg);color:var(--warn)}
  .decide .verdict.reject{background:var(--crit-bg);color:var(--crit)}
  .decide .verdict.preapprove{background:var(--accent-soft);color:var(--accent)}
  .decide button.preapprove:hover:not(:disabled){background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  .decide .hint{font-size:11.5px;color:var(--slate-faint)}

  /* ---- comments console ---- */
  .talk{margin-top:9px;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
  .talk button{
    font-family:"IBM Plex Sans",sans-serif;font-size:12.5px;font-weight:600;
    padding:5px 13px;border-radius:3px;border:1px solid var(--rule-strong);
    background:var(--surface);color:var(--ink-soft);cursor:pointer;
    display:inline-flex;align-items:center;gap:7px;
    transition:background .12s ease,border-color .12s ease,color .12s ease;
  }
  .talk button:hover:not(:disabled){background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  .talk button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .talk button:disabled{opacity:.4;cursor:default}
  .talk .tally{
    font-family:"IBM Plex Mono",monospace;font-size:10.5px;font-weight:600;
    background:var(--accent);color:#fff;border-radius:9px;padding:1px 6px;letter-spacing:.03em;
  }
  /* A CIRCLE, matching the count beside the tab labels. Owner, 4 September.
     min-width equal to the height keeps a single digit round rather than
     pill-shaped, and lets a three-digit count stretch instead of clipping. */
  .talk .tally.unseen{
    border-radius:50%;padding:0;min-width:17px;height:17px;
    display:inline-flex;align-items:center;justify-content:center;
    letter-spacing:0;
  }
  .talk .dot{width:7px;height:7px;border-radius:50%;background:var(--crit);flex:none}
  .talk .hint{font-size:11.5px;color:var(--slate-faint)}

  .head-actions{display:flex;gap:8px;align-items:center}
  .head-actions button{
    font-family:"IBM Plex Sans",sans-serif;font-size:12px;font-weight:600;
    padding:4px 11px;border-radius:3px;cursor:pointer;
    background:rgba(255,255,255,.14);color:#fff;border:1px solid rgba(255,255,255,.38);
    display:inline-flex;align-items:center;gap:6px;
    transition:background .12s ease,border-color .12s ease;
  }
  .head-actions button:hover:not(:disabled){background:rgba(255,255,255,.26);border-color:#fff}
  .head-actions button:focus-visible{outline:2px solid #fff;outline-offset:2px}
  .head-actions button:disabled{opacity:.45;cursor:default}
  .head-actions .tally{
    font-family:"IBM Plex Mono",monospace;font-size:10px;font-weight:600;
    background:rgba(255,255,255,.9);color:var(--accent);border-radius:9px;padding:0 5px;
  }
  .head-actions .dot{width:6px;height:6px;border-radius:50%;background:#fff}

  .rows{display:flex;flex-direction:column;gap:2px}
  .row{
    display:flex;flex-direction:column;gap:3px;align-items:flex-start;width:100%;
    padding:12px 13px;border:1px solid transparent;border-radius:4px;
    background:none;text-align:left;cursor:pointer;font:inherit;color:inherit;
  }
  .row:hover{background:var(--surface-sunk);border-color:var(--rule)}
  .row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .row .rt{font-size:13.5px;font-weight:600;color:var(--ink);line-height:1.35;text-wrap:pretty}
  .row .rn{font-size:12.5px;color:var(--ink-soft);line-height:1.45;text-wrap:pretty}
  .row .rm{
    font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--slate-faint);
    letter-spacing:.05em;display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:2px;
  }
  .row .rm .tag{background:var(--surface-sunk);border:1px solid var(--rule);border-radius:2px;padding:1px 6px;color:var(--slate)}
  .row .rm .has{color:var(--accent);font-weight:600}
  .back{
    background:none;border:none;cursor:pointer;font:inherit;color:var(--accent);
    font-size:12px;font-weight:600;padding:0;margin-bottom:5px;display:none;
  }
  .back:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .console[data-mode="list"] .composer{display:none}
  .console[data-mode="thread"] .back.avail{display:block}

  .scrim{
    position:fixed;inset:0;background:rgba(16,20,24,.42);
    opacity:0;pointer-events:none;transition:opacity .18s ease;z-index:40;
  }
  .scrim.open{opacity:1;pointer-events:auto}
  .console{
    position:fixed;top:0;right:0;bottom:0;width:min(460px,100vw);
    background:var(--surface);border-left:1px solid var(--rule-strong);
    box-shadow:-8px 0 32px rgba(16,20,24,.14);
    display:flex;flex-direction:column;z-index:41;
    transform:translateX(100%);transition:transform .22s cubic-bezier(.32,.72,0,1);
  }
  .console.open{transform:translateX(0)}
  @media (prefers-reduced-motion:reduce){
    .scrim,.console{transition:none}
  }
  .console-head{
    padding:16px 20px;border-bottom:1px solid var(--rule);
    display:flex;align-items:flex-start;gap:12px;flex:none;background:var(--surface-sunk);
  }
  .console-head .who{
    font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.13em;
    text-transform:uppercase;color:var(--slate);display:block;margin-bottom:4px;
  }
  .console-head .subj{font-size:14px;font-weight:600;color:var(--ink);line-height:1.4;text-wrap:pretty}
  .console-head button{
    margin-left:auto;flex:none;background:none;border:none;cursor:pointer;
    color:var(--slate);font-size:20px;line-height:1;padding:2px 6px;border-radius:3px;
  }
  .console-head button:hover{background:var(--rule);color:var(--ink)}
  .console-head button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

  .thread{flex:1 1 auto;overflow-y:auto;padding:18px 20px;display:flex;flex-direction:column;gap:14px}
  .thread .empty{
    font-size:13px;color:var(--slate);text-wrap:pretty;margin:auto 0;
    border-left:3px solid var(--rule-strong);padding:2px 0 2px 12px;
  }
  .turn{display:flex;flex-direction:column;gap:4px;max-width:88%}
  .turn.mine{align-self:flex-end;align-items:flex-end}
  .turn.theirs{align-self:flex-start}
  .turn .body{
    font-size:13.5px;line-height:1.5;padding:9px 13px;border-radius:4px;
    text-wrap:pretty;white-space:pre-wrap;
  }
  .turn.mine .body{background:var(--accent);color:#fff;border-bottom-right-radius:1px}
  .turn.theirs .body{background:var(--surface-sunk);color:var(--ink);border:1px solid var(--rule);border-bottom-left-radius:1px}
  .turn .meta{font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--slate-faint);letter-spacing:.05em}
  .turn .body code{
    font-family:"IBM Plex Mono",monospace;font-size:.88em;
    background:rgba(127,127,127,.16);padding:1px 4px;border-radius:2px;
  }

  .tray{display:flex;flex-wrap:wrap;gap:7px;padding:0 16px 9px}
  .tray:empty{display:none}
  .chip{
    display:flex;align-items:center;gap:7px;padding:4px 6px 4px 4px;
    border:1px solid var(--rule-strong);border-radius:4px;background:var(--surface-sunk);
    font-size:11.5px;color:var(--ink-soft);max-width:210px;
  }
  .chip img{width:30px;height:30px;object-fit:cover;border-radius:2px;flex:none;display:block}
  .chip .cn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .chip .cx{
    background:none;border:none;cursor:pointer;color:var(--slate);
    font-size:15px;line-height:1;padding:0 3px;flex:none;
  }
  .chip .cx:hover{color:var(--crit)}
  .shots{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}
  .shot{padding:0;border:1px solid var(--rule);border-radius:3px;background:none;cursor:pointer;line-height:0;overflow:hidden}
  .shot img{max-width:150px;max-height:110px;display:block}
  .shot.big img{max-width:100%;max-height:none}
  .shot.loadingshot{min-width:90px;min-height:60px;background:var(--rule)}
  .shot.gone{opacity:.4}
  .shot:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .filelink{
    display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--ink-soft);
    border:1px solid var(--rule);border-radius:3px;padding:4px 8px;background:var(--surface);
  }
  .composer .attach{
    background:none;border:1px solid var(--rule-strong);color:var(--slate);
    font-size:15px;line-height:1;padding:8px 10px;border-radius:3px;cursor:pointer;flex:none;
  }
  .composer .attach:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}
  .composer.drop{outline:2px dashed var(--accent);outline-offset:-4px}
  .composer{border-top:1px solid var(--rule);padding:13px 16px;display:flex;gap:9px;align-items:flex-end;flex:none}
  .composer textarea{
    font-family:"IBM Plex Sans",sans-serif;font-size:13.5px;line-height:1.45;
    flex:1 1 auto;min-height:38px;max-height:180px;resize:none;
    padding:9px 11px;border-radius:3px;border:1px solid var(--rule-strong);
    background:var(--surface);color:var(--ink);
  }
  .composer textarea:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}
  .composer textarea::placeholder{color:var(--slate-faint)}
  .composer button{
    font-family:"IBM Plex Sans",sans-serif;font-size:12.5px;font-weight:600;
    padding:9px 16px;border-radius:3px;border:1px solid var(--accent);
    background:var(--accent);color:#fff;cursor:pointer;flex:none;
  }
  .composer button:disabled{opacity:.35;cursor:default}
  .composer button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .composer .note-hint{
    position:absolute;bottom:4px;left:18px;font-family:"IBM Plex Mono",monospace;
    font-size:9.5px;color:var(--slate-faint);letter-spacing:.05em;
  }

  /* ---- confidence banner ---- */
  .caveat{
    background:var(--surface);
    border:1px solid var(--rule-strong);
    border-left:4px solid var(--warn);
    border-radius:3px;
    padding:20px 24px;
    display:flex;flex-direction:column;gap:10px;
    box-shadow:var(--shadow);
  }
  .caveat h2{
    font-family:"IBM Plex Sans",sans-serif;
    font-size:12px;letter-spacing:.12em;text-transform:uppercase;
    color:var(--warn);margin:0;font-weight:600;
  }
  .caveat p{margin:0;max-width:78ch;color:var(--ink-soft);text-wrap:pretty}
  .caveat strong{color:var(--ink);font-weight:600}

  /* ---- tallies ---- */
  .tallies{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;background:var(--rule);border:1px solid var(--rule);border-radius:3px;overflow:hidden}
  .tally{background:var(--surface);padding:18px 20px;display:flex;flex-direction:column;gap:4px}
  .tally .n{
    font-family:"IBM Plex Mono",monospace;font-size:34px;font-weight:500;
    line-height:1;font-variant-numeric:tabular-nums;
  }
  .tally .lbl{font-size:12px;letter-spacing:.07em;text-transform:uppercase;color:var(--slate);font-weight:500}
  .tally .sub{font-size:12.5px;color:var(--slate-faint)}
  .n.ok{color:var(--ok)} .n.warn{color:var(--warn)} .n.crit{color:var(--crit)} .n.acc{color:var(--accent)}

  /* ---- legend ---- */
  .legend{display:flex;flex-wrap:wrap;gap:10px 26px;align-items:center;padding:14px 18px;background:var(--surface-sunk);border-radius:3px;border:1px solid var(--rule)}
  .legend .grp{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--ink-soft)}
  .legend .ttl{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--slate);margin-right:2px}
  .swatch{width:26px;height:16px;border-radius:2px;flex:none;border:1px solid var(--rule-strong)}
  .swatch.ok{background:var(--ok-bg);border-color:var(--ok)}
  .swatch.warn{background:var(--warn-bg);border-color:var(--warn)}
  .swatch.crit{background:var(--crit-bg);border-color:var(--crit)}
  .swatch.claimed{background:var(--surface);border-style:dashed;border-color:var(--slate)}

  /* ---- production + roster panels ---- */
  .panel{background:var(--surface);border:1px solid var(--rule);border-radius:4px;box-shadow:var(--shadow);overflow:hidden}
  .panel-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;padding:15px 20px;border-bottom:1px solid var(--rule);background:var(--surface-sunk)}
  .panel-head h3{font-family:"IBM Plex Serif",Georgia,serif;font-size:18px;font-weight:600;margin:0;letter-spacing:-.01em}
  .panel-head .meta{font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--slate);letter-spacing:.04em;margin-left:auto}
  .panel-note{padding:11px 20px;font-size:13.5px;color:var(--ink-soft);border-bottom:1px solid var(--rule);text-wrap:pretty}
  .panel-note b{color:var(--ink);font-weight:600}

  .facts{display:grid;grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:1px;background:var(--rule)}
  .fact{background:var(--surface);padding:13px 16px;display:flex;flex-direction:column;gap:4px;border-left:3px solid var(--rule-strong)}
  .fact.live{border-left-color:var(--ok)}
  .fact.dark{border-left-color:var(--void)}
  .fact.hold{border-left-color:var(--warn)}
  .fact.forbid{border-left-color:var(--crit)}
  .fact .k{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--slate)}
  .fact .v{font-size:14px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;text-wrap:pretty}
  .fact .d{font-size:12.5px;color:var(--ink-soft);text-wrap:pretty}
  .fact.live .v{color:var(--ok)} .fact.dark .v{color:var(--void)}
  .fact.hold .v{color:var(--warn)} .fact.forbid .v{color:var(--crit)}

  .roster{display:grid;grid-template-columns:repeat(auto-fill,minmax(288px,1fr));gap:1px;background:var(--rule)}
  .who{background:var(--surface);padding:15px 18px;display:flex;flex-direction:column;gap:7px}
  .who .nmrow{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
  .who .agent{font-family:"IBM Plex Serif",Georgia,serif;font-size:16px;font-weight:600;color:var(--ink)}
  .who .role{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--slate);border:1px solid var(--rule-strong);padding:1px 6px;border-radius:2px}
  .who .lane{font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--accent);font-weight:500}
  .who .task{font-size:13.5px;color:var(--ink-soft);text-wrap:pretty}
  .who .age{font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--slate-faint);font-variant-numeric:tabular-nums}
  .who .talk{margin-top:auto;padding-top:4px}
  .who .talk button{font-size:11.5px;padding:4px 11px}
  .who .talk .hint{display:none}
  .who.idle{background:var(--surface-sunk)}
  .unstaffed{padding:15px 20px;display:flex;flex-direction:column;gap:8px;border-top:1px solid var(--rule);background:var(--surface-sunk)}
  .unstaffed .ttl{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--crit);font-weight:600}
  .unstaffed ul{margin:0;padding-left:19px;display:flex;flex-direction:column;gap:5px;font-size:13.5px;color:var(--ink-soft)}
  .unstaffed b{color:var(--ink)}

  /* ---- paper bands ---- */
  .band{
    background:var(--surface);border:1px solid var(--rule);border-radius:4px;
    box-shadow:var(--shadow);overflow:hidden;
  }
  .band-head{
    display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;
    padding:16px 20px;border-bottom:1px solid var(--rule);background:var(--surface-sunk);
  }
  .band-head h3{
    font-family:"IBM Plex Serif",Georgia,serif;font-size:19px;font-weight:600;
    margin:0;letter-spacing:-.01em;
  }
  .band-head .meta{
    font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--slate);
    letter-spacing:.04em;margin-left:auto;font-variant-numeric:tabular-nums;
  }
  .band-note{
    padding:11px 20px;font-size:13.5px;color:var(--ink-soft);
    border-bottom:1px solid var(--rule);background:var(--surface);text-wrap:pretty;
  }
  .band-note b{color:var(--ink);font-weight:600}
  .chips{
    display:grid;grid-template-columns:repeat(auto-fill,minmax(212px,1fr));
    gap:1px;background:var(--rule);
  }
  .chip{
    background:var(--surface);padding:12px 14px;
    display:flex;flex-direction:column;gap:5px;position:relative;
    border-left:3px solid transparent;
  }
  .chip.ok{border-left-color:var(--ok);background:var(--ok-bg)}
  .chip.warn{border-left-color:var(--warn);background:var(--warn-bg)}
  .chip.crit{border-left-color:var(--crit);background:var(--crit-bg)}
  .chip.void{border-left-color:var(--void);background:var(--void-bg)}
  /* evidence encoding: claimed phases are hatched + dashed, verified are solid */
  .chip.claimed{
    background-image:repeating-linear-gradient(135deg,transparent 0 6px,rgba(128,138,145,.13) 6px 7px);
  }
  .chip.claimed .code::after{content:"·claim";color:var(--slate-faint);font-weight:400}
  .chip.verified .code::after{content:"·checked";color:var(--accent);font-weight:400}
  .code{
    font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.07em;
    color:var(--slate);display:flex;gap:5px;
  }
  .nm{font-size:13.5px;line-height:1.35;color:var(--ink);font-weight:500;text-wrap:pretty}
  .st{font-size:12px;color:var(--ink-soft)}
  .chip.ok .st{color:var(--ok)} .chip.warn .st{color:var(--warn)}
  .chip.crit .st{color:var(--crit)} .chip.void .st{color:var(--void)}

  .flag{
    display:inline-block;font-family:"IBM Plex Mono",monospace;font-size:10px;
    letter-spacing:.09em;text-transform:uppercase;padding:2px 6px;border-radius:2px;
    background:var(--accent-soft);color:var(--accent);font-weight:600;align-self:flex-start;
  }

  /* ---- footer ---- */
  .foot{border-top:1px solid var(--rule);padding-top:22px;display:flex;flex-direction:column;gap:12px}
  .foot h2{font-family:"IBM Plex Serif",Georgia,serif;font-size:17px;margin:0;font-weight:600}
  .foot p{margin:0;font-size:14px;color:var(--ink-soft);max-width:74ch;text-wrap:pretty}
  .foot ul{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:7px;font-size:14px;color:var(--ink-soft);max-width:74ch}
  .foot b{color:var(--ink)}
  code{font-family:"IBM Plex Mono",monospace;font-size:.9em;background:var(--surface-sunk);padding:1px 5px;border-radius:2px;border:1px solid var(--rule)}
  @media (prefers-reduced-motion:no-preference){
    .band{transition:border-color .15s ease}
  }


/* ---- classes that exist only on the hosted board: the token gate, the
 * composer drawer, and the few generic wrappers board.js still emits. The
 * rules above are board-shared.css in full, so layout and colour are the
 * artifact board's own rather than a second approximation of them. ---- */

.gate{max-width:520px;margin:0 auto;padding-top:8vh;display:flex;flex-direction:column;gap:16px}
.gate h1{font-family:"IBM Plex Serif",Georgia,serif;font-size:30px;font-weight:600;margin:0;letter-spacing:-.02em}
.gate p{margin:0;color:var(--ink-soft);text-wrap:pretty}
.gate label{display:flex;flex-direction:column;gap:6px;font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--slate)}
.gate input{font-family:"IBM Plex Mono",monospace;font-size:14px;padding:10px 12px;border:1px solid var(--rule-strong);border-radius:3px;background:var(--surface);color:var(--ink)}
.gate input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

button{font-family:"IBM Plex Sans",sans-serif;font-size:12.5px;font-weight:600;padding:6px 15px;border-radius:3px;border:1px solid var(--rule-strong);background:var(--surface);color:var(--ink-soft);cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}
button:hover{border-color:var(--ink);color:var(--ink)}
button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
button.ghost{background:none}
button[disabled]{opacity:.45;cursor:not-allowed}
#unlock,#compose-send{background:var(--accent);border-color:var(--accent);color:#fff}
#unlock:hover,#compose-send:hover{filter:brightness(1.08);color:#fff}
button.attach{font-size:16px;line-height:1;padding:5px 11px}

.section-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;padding:15px 20px;border-bottom:1px solid var(--rule);background:var(--surface-sunk)}
.section-head h2{font-family:"IBM Plex Serif",Georgia,serif;font-size:18px;font-weight:600;margin:0}
.card{padding:16px 21px;border-bottom:1px solid var(--rule);display:flex;flex-direction:column;gap:4px}
.card:last-child{border-bottom:none}
.card-actions{display:flex;gap:7px;margin-top:8px;flex-wrap:wrap;align-items:center}
.empty{padding:16px 21px;color:var(--slate);font-size:13.5px;margin:0}
.banner{padding:11px 21px;font-size:13px;color:var(--ink-soft);background:var(--accent-soft);border-bottom:1px solid var(--rule);text-wrap:pretty}
.foot-note{margin:0;font-size:12px;color:var(--slate);border-top:1px solid var(--rule);padding-top:14px;text-wrap:pretty}

.msg{display:flex;flex-direction:column;gap:5px;padding:13px 0;border-bottom:1px solid var(--rule)}
.msg:last-child{border-bottom:none}
.msg .who{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--slate);font-weight:600;background:none;padding:0;border:none}
.msg p{margin:0;font-size:14px;color:var(--ink);white-space:pre-wrap;text-wrap:pretty}
.atts{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
.thumb{padding:0;border:1px solid var(--rule);border-radius:3px;background:none;line-height:0;overflow:hidden;cursor:pointer}
.thumb img{max-width:150px;max-height:112px;display:block}
.thumb.big img{max-width:100%;max-height:none}

/* Only the affordances. Position, opacity, pointer-events and the transition
 * are declared once at :212; redeclaring them here is how the two rules came
 * to disagree, leaving the scrim permanently transparent and untappable. */
.scrim{cursor:pointer;touch-action:manipulation}
.compose{position:fixed;top:0;right:0;bottom:0;width:min(560px,100vw);z-index:41;background:var(--surface);border-left:1px solid var(--rule);box-shadow:-8px 0 34px rgba(16,20,24,.16);display:flex;flex-direction:column}
.compose-head{display:flex;align-items:flex-start;gap:12px;padding:16px 20px;border-bottom:1px solid var(--rule);background:var(--surface-sunk)}
.compose-head h2{font-family:"IBM Plex Serif",Georgia,serif;font-size:17px;font-weight:600;margin:0;text-wrap:pretty}
.compose-head .ghost{margin-left:auto;flex:none}
.compose-thread{flex:1;overflow-y:auto;padding:4px 20px 14px}
.composer{padding:14px 20px 18px;border-top:1px solid var(--rule);display:flex;flex-direction:column;gap:9px}
.composer textarea{font-family:"IBM Plex Sans",sans-serif;font-size:14px;line-height:1.5;padding:10px 12px;border:1px solid var(--rule-strong);border-radius:3px;background:var(--surface);color:var(--ink);resize:vertical;width:100%}
.composer textarea:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.composer-actions{display:flex;gap:8px;align-items:center}
.composer-actions #compose-send{margin-left:auto}
.tray{display:flex;flex-wrap:wrap;gap:6px}
.tray img{width:38px;height:38px;object-fit:cover;border-radius:2px;border:1px solid var(--rule)}
.error{margin:0;padding:9px 12px;border-radius:3px;font-size:13px;background:var(--crit-bg);color:var(--crit);border:1px solid var(--crit)}
.msg.undelivered{border-left:3px solid var(--crit);padding-left:9px}
.panel.waiting{border-left:3px solid var(--warn,#b26a00)}
.panel.waiting .act .mark{background:var(--warn-bg,#fff4e0);color:var(--warn,#b26a00);font-variant-numeric:tabular-nums}
.msg-undelivered{margin:6px 0 0;font-size:12.5px;color:var(--crit);line-height:1.45}

/* A-223b. The drawer LOCKED THE WHOLE PAGE while open, so the board behind it
 * could not be scrolled -- and the owner reported exactly that: "when the
 * comments pane is open i cant scroll the main pane". On a wide screen the
 * drawer is a 560px side panel with the board fully visible beside it, and
 * wanting to scroll the board while writing a comment about it is the normal
 * case, not an edge one. So the lock is now scoped to the width where the
 * drawer actually covers the page and there is nothing behind it to scroll. */
@media (max-width:640px){.compose{width:100vw}body.drawer-open{overflow:hidden}}

/* Assurance and actor badges. The artifact board's `.chip` is an ATTACHMENT
 * chip (thumbnail + filename), so reusing that name here rendered the labels
 * as broken image chips. These use `.flag`, which is the board's own pattern
 * for a small mono uppercase badge. */
.flag.f-verified{background:var(--ok-bg);color:var(--ok)}
.flag.f-claimed{background:var(--warn-bg);color:var(--warn)}
.flag.f-actor-owner{background:var(--accent-soft);color:var(--accent)}
.flag.f-actor-agent{background:var(--void-bg);color:var(--void)}
.flag.f-coordinator{background:var(--accent-soft);color:var(--accent)}
.talk .flag,.act .flag{align-self:center}

/* The owner head carries the item count AND the page actions. Both the
 * canonical .count and .head-actions would claim margin-left:auto, so the
 * count keeps it and the buttons simply follow. */
.owner-head .head-actions{margin-left:0;flex:none}
.owner-head .head-actions button{color:#fff}

/* The authored blocks live inside #board-content, which is ONE flex child of
 * .wrap -- so .wrap's 40px gap applied between the content and the panels
 * below it, and NOT between the blocks themselves. Owner: "the gaps between
 * the sections is missing". Mirror the container's own layout so nesting the
 * blocks costs nothing. */
#board-content{display:flex;flex-direction:column;gap:40px}

/* Tabs. Styled from the board's own vocabulary -- mono uppercase like the
 * eyebrow, the accent underline the owner panel already uses -- rather than
 * a new control language. */
.tabs{
  display:flex;gap:2px;flex-wrap:wrap;
  border-bottom:1px solid var(--rule);margin-bottom:-18px;
}
.tabs .tab{
  font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;font-weight:600;
  background:none;border:none;border-bottom:2px solid transparent;
  border-radius:0;color:var(--slate);padding:9px 14px;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;
}
.tabs .tab:hover{color:var(--ink);border-bottom-color:var(--rule-strong)}
.tabs .tab[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--accent)}
.tabs .tab:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.tabs .tab .tally{
  font-family:"IBM Plex Mono",monospace;font-size:10px;font-weight:600;
  background:var(--surface-sunk);color:var(--slate);border-radius:9px;
  padding:1px 6px;letter-spacing:.03em;
}
.tabs .tab[aria-selected="true"] .tally{background:var(--accent);color:#fff}
.tabpanel{display:flex;flex-direction:column;gap:40px}

/* Refresh and Lock live in the page corner. Fixed rather than in the flow so
 * they stay reachable on a long board, and pulled out of .wrap's column gap
 * so they do not push the masthead down. */
.page-actions{
  position:fixed;top:14px;right:18px;z-index:30;
  display:flex;gap:8px;
}
.page-actions button{
  background:var(--surface);border:1px solid var(--rule-strong);
  box-shadow:var(--shadow);
}
.page-actions button:hover{border-color:var(--ink);color:var(--ink)}
@media (max-width:640px){.page-actions{top:10px;right:12px}}

/* The comment line in an act card. Two defects the owner spotted:
 *  - .reply-thread carried margin-left:auto from the deleted Threads panel,
 *    which pushed the whole line 27px right of everything above it;
 *  - a bare .meta inherits 15px body type, so the attribution rendered
 *    larger than the button beside it. The board's meta is small mono.
 */
.talk .meta{
  font-family:"IBM Plex Mono",monospace;font-size:11.5px;
  color:var(--slate);letter-spacing:.04em;margin-left:0;
}
.talk .tally{align-self:center}

/* Mirrored paper text. Markdown as written, wrapped -- rendering it would
 * misrepresent the source, and the source is the point of a mirror. */
pre.paper{
  font-family:"IBM Plex Mono",monospace;font-size:12px;line-height:1.65;
  white-space:pre-wrap;word-break:break-word;margin:0;color:var(--ink-soft);
}

/* ---- Mailbox items -------------------------------------------------------
   One row per item, opening to the full text. The summary carries the four
   things you scan for -- id, who, when, status -- and the body is one click
   away, so 700 items stay navigable without hiding what they say. */
.mailbox .mb { border-bottom: 1px solid var(--line); padding: 0; }
.mailbox .mb:last-child { border-bottom: 0; }
.mailbox .mb > summary {
  display: grid;
  /* Two lines: who and when on the first, the description on the second,
     indented to the same 5.5rem gutter the opened body uses so the id column
     stays a marker rail rather than a column the text has to dodge. */
  grid-template-columns: 5.5rem minmax(9rem, auto) 1fr;
  gap: 2px 10px; align-items: baseline;
  padding: 9px 4px; cursor: pointer; list-style: none;
}
.mailbox .mb > summary::-webkit-details-marker { display: none; }
.mailbox .mb > summary:hover { background: var(--hover, rgba(127,127,127,.06)); }
.mailbox .mb[open] > summary { background: var(--hover, rgba(127,127,127,.06)); }
.mailbox .mb .mark { font-variant-numeric: tabular-nums; }
.mailbox .mb-who { font-weight: 600; }
.mailbox .mb-when {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; opacity: .72; font-variant-numeric: tabular-nums;
}
.mailbox .mb-status {
  grid-column: 2 / -1; grid-row: 2;
  font-size: 12.5px; opacity: .85; line-height: 1.45;
}
.mailbox .mb-status p { display: inline; margin: 0; }
.mailbox .mb-body { padding: 4px 4px 16px 5.5rem; }
.mailbox .mb-f { display: flex; gap: 8px; margin: 0 0 4px; font-size: 12.5px; }
.mailbox .mb-k {
  flex: 0 0 7.5rem; opacity: .6; text-transform: uppercase;
  letter-spacing: .04em; font-size: 10.5px; padding-top: 2px;
}
.mailbox .mb-v { flex: 1 1 auto; }
.mailbox .mb-f p, .mailbox .mb-v p { margin: 0; display: inline; }
.mailbox .mb-prose { margin-top: 10px; font-size: 13px; line-height: 1.55; }
.mailbox .mb-prose p { margin: 0 0 9px; }
.mailbox .mb-prose code, .mailbox .mb-v code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em; padding: 1px 4px; border-radius: 3px;
  background: var(--hover, rgba(127,127,127,.1));
}
@media (max-width: 720px) {
  .mailbox .mb > summary { grid-template-columns: 4.5rem 1fr; }
  .mailbox .mb-when { grid-column: 2; grid-row: 2; }
  .mailbox .mb-status { grid-column: 2; grid-row: 3; }
  .mailbox .mb-body { padding-left: 4px; }
}

/* ---- Derived roster ------------------------------------------------------
   The state is the marker, so holding vs free reads before any text does. */
/* THE STATUS COLUMN WRAPS. Owner, 4 September: "in who has what section wrap
   the coloured status column." `.act .mark` is flex:none, so it never shrinks
   and never wraps -- once a status read "REDELIVERED · awaiting review" the
   column stretched to fit it on one line and squeezed the agent name and lane
   list beside it. Bounded width and normal wrapping keeps the column narrow
   and lets the long states run to a second line instead. */
.roster .mark {
  font-size: 10.5px; letter-spacing: .04em;
  max-width: 13ch; white-space: normal; line-height: 1.35;
  text-align: left; hyphens: none; overflow-wrap: break-word;
}
.roster .mark.on { color: var(--ok, #1a7f37); font-weight: 700; }
.roster .mark.off { opacity: .55; }
/* A standing seat -- reviewer, coordinator, owner -- is not idle and is not
   holding a lane either. Owner direction, 4 Sep: blue, and ordered after the
   agents actually working. Grey read as "nothing happening here", which is
   wrong for the seat doing the reviewing. */
.roster .mark.seat { color: var(--info, #2F6FB0); font-weight: 700; }
/* Delivered and waiting on someone else. Not working, not free -- and the
   distinction is the one the owner needs to see to know who to chase. */
.roster .mark.review { color: var(--warn, #9A6716); font-weight: 700; }

/* THE TIMELINE. Three columns: what the package is, where it sits in time,
   and when it is due. The track is the only part that carries a claim about
   time, so a package with no authored window gets a word there rather than a
   bar -- a bar in a plausible place is indistinguishable from a real one. */
.timeline .tl-row {
  display: grid; grid-template-columns: minmax(180px, 22%) 1fr minmax(112px, 15%);
  gap: 12px; align-items: center;
  padding: 3px 22px; border-bottom: 1px solid var(--rule);
}
/* A row with no authored window carries no schedule, so it does not get the
   height of one that does. */
.timeline .tl-row.undated { padding-top: 1px; padding-bottom: 1px; }
.timeline .tl-row.undated .tl-track { height: 14px; }
.timeline .tl-id { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.timeline .tl-slug {
  display: block; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; font-size: 11px; line-height: 1.25;
}
.timeline .tl-row:last-child { border-bottom: none; }
.timeline .tl-head { padding-top: 8px; padding-bottom: 0; }
.timeline .tl-label { display: flex; flex-direction: column; gap: 0; min-width: 0; }
.timeline .tl-label .meta { font-size: 11.5px; }
.timeline .tl-label b { font-size: 13px; }
.timeline .tl-track {
  position: relative; height: 20px; border-radius: 3px;
  background: var(--surface-sunk, rgba(127,127,127,.10));
}
.timeline .tl-bar {
  position: absolute; top: 3px; height: 14px; border-radius: 3px;
  background: var(--ok, #3F7A54);
}
.timeline .tl-bar.queued { background: var(--info, #2F6FB0); opacity: .75; }
/* A group row: the phase, with a summary bar spanning its packages, drawn
   the way a sprint header is in a project plan. */
.timeline .tl-group { background: var(--surface-sunk, rgba(127,127,127,.06)); }
.timeline .tl-group .tl-label b { font-size: 13px; }
.timeline .tl-group { padding-top: 5px; padding-bottom: 5px; }
.timeline .tl-summary {
  position: absolute; top: 6px; height: 8px; border-radius: 2px;
  background: var(--slate, #7b8794); opacity: .85;
}
/* A zero-length package is a milestone, not a bar. */
.timeline .tl-diamond {
  position: absolute; top: 4px; width: 13px; height: 13px; margin-left: -6px;
  background: var(--warn, #D5A44F); transform: rotate(45deg); border-radius: 2px;
}
/* Now. */
.timeline .tl-now {
  position: absolute; top: -2px; bottom: -2px; width: 2px;
  background: var(--accent, #7FB2CE); opacity: .35;
}
/* The prerequisite lines, over the rows and never catching the mouse. */
.timeline { position: relative; }
.tl-links {
  position: absolute; inset: 0; pointer-events: none; overflow: visible;
}
.tl-links path {
  fill: none; stroke: var(--rule-strong, #8a949c); stroke-width: 1.25;
}
.tl-links polygon { fill: var(--rule-strong, #8a949c); }
.timeline .tl-none {
  position: absolute; left: 8px; top: 1px;
  font-size: 11px; font-style: italic; color: var(--slate-faint);
}
.timeline .tl-when { font-size: 11px; text-align: right; line-height: 1.3; }
.tl-axis { position: relative; height: 14px; }
.tl-axis .tick {
  position: absolute; top: 0; font-size: 10px; color: var(--slate-faint);
  transform: translateX(-50%); white-space: nowrap;
}
@media (max-width: 720px) {
  .timeline .tl-row { grid-template-columns: 1fr; gap: 4px; }
  .timeline .tl-when { text-align: left; }
}

/* The waiting panel folds behind its own heading. The button must read as a
   heading, not a form control -- it is the panel's title. */
.waiting .panel-head h3 { margin: 0; }
.waiting .panel-head h3 button {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; letter-spacing: inherit;
}
.waiting .panel-head h3 button:hover { text-decoration: underline; }
/* Idle is said in words, so it must stay legible rather than fade out. */
.roster .mark.off { opacity: .75; }

/* The assign / file strip at the top of the comment drawer. */
.compose-actions {
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  padding: .5rem .75rem; border-bottom: 1px solid var(--line, #e5e7eb);
}
.compose-actions .assign { display: inline-flex; align-items: center; gap: .3rem; }
.roster .act { align-items: baseline; }
.roster .w i { opacity: .6; }

/* A claim that has gone quiet must not read as a working one. */
.roster .mark.stale { color: var(--warn, #9a6700); font-weight: 700; }
.roster .talk b { color: var(--warn, #9a6700); font-weight: 600; }

/* ---- Per-phase comments --------------------------------------------------
   A comment affordance on every phase box. Quiet until hovered or until the
   phase actually has comments, so seven bands of chips do not turn into
   seven bands of buttons. */
.chip { position: relative; }
.chip .chip-comment {
  display: block; margin-top: 6px; padding: 2px 7px;
  font: inherit; font-size: 10.5px; letter-spacing: .03em;
  background: transparent; color: inherit; opacity: .45;
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
}
.chip:hover .chip-comment, .chip .chip-comment:focus-visible { opacity: 1; }
.chip .chip-comment:hover { background: var(--hover, rgba(127,127,127,.1)); }
.chip .chip-comment .tally {
  margin-left: 4px; font-variant-numeric: tabular-nums; font-weight: 700;
}
/* a phase that already has discussion should say so without a hover */
.chip .chip-comment:has(.tally) { opacity: 1; border-color: currentColor; }

/* Board feedback sits left of Lock so Lock stays the rightmost control and
   muscle memory for locking is unchanged. */
.page-actions{gap:8px}
.page-actions #board-feedback{opacity:.75}
.page-actions #board-feedback:hover{opacity:1}

/* WHO HAS WHAT: A BORDERED GRID, STATUS ON THE LANE LINE.
   Owner, 5 September, relayed through Opus 4 with a screenshot of the target:
   "not the counts on the messages and indicator there are new items. also not
   the status doesn't have its own column and the borders around the agents."
   Three things: message counts with an unread dot, status inline rather than
   in a gutter, and visible cell borders.
   The gutter was the expensive one -- `.act .mark` is flex:none, so every row
   paid a 13ch column, including the rows whose entire content was "no lane". */
.roster.grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  border-top: 1px solid var(--rule-strong, #8a949c);
  border-left: 1px solid var(--rule-strong, #8a949c);
}
.roster.grid .act {
  display: flex; flex-direction: column; gap: 5px; padding: 13px 15px;
  border-right: 1px solid var(--rule-strong, #8a949c);
  border-bottom: 1px solid var(--rule-strong, #8a949c);
  align-items: flex-start;
}
.roster.grid .act:last-child {
  border-bottom: 1px solid var(--rule-strong, #8a949c);
}
.roster.grid .t {
  font-family: "IBM Plex Serif", Georgia, serif; font-size: 15px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
/* The role is a fact about the seat, not a note about the row, so it reads as
   a label rather than as trailing prose. */
.roster.grid .role-chip {
  font-family: "IBM Plex Mono", monospace; font-size: 9.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--slate);
  border: 1px solid var(--rule); border-radius: 2px; padding: 2px 6px;
  white-space: nowrap;
}
.roster.grid .lane-line {
  display: block; font-size: 13px; line-height: 1.5;
}
.roster.grid .lane-id {
  font-family: "IBM Plex Mono", monospace; color: var(--info, #2F6FB0);
  font-weight: 600;
}
.roster.grid .lane-line .slug { color: var(--ink-soft); }
/* Inline now, so the 13ch clamp that kept the old column narrow would only
   truncate a phrase that has room to sit on the line. */
.roster.grid .mark {
  max-width: none; display: inline; padding: 0; background: none;
  font-size: 10.5px;
}
.roster.grid .w { font-size: 12.5px; max-width: none; }
.roster.grid .w.note {
  font-family: "IBM Plex Mono", monospace; font-size: 11px;
  color: var(--slate-faint, var(--slate)); opacity: .8;
}
.roster.grid .act-do { margin-top: auto; padding-top: 6px; display: flex;
  align-items: center; gap: 6px; }
/* The count is the traffic; the dot is the part that is new. Two marks, so a
   busy-but-read thread and a quiet-but-unread one do not look the same. */
.roster.grid .tally.count {
  background: var(--surface-sunk); color: var(--slate);
  border: 1px solid var(--rule); border-radius: 999px;
  font-family: "IBM Plex Mono", monospace; font-size: 11px;
  min-width: 20px; height: 18px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
}
.roster.grid .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--crit, #b3261e); display: inline-block;
}

/* AN EDGE SOMEBODY RULED ON, VERSUS ONE THE BOARD READ OUT OF A PARAGRAPH.
   C-2466: "Prose is not authoritative sequencing data... Show fallback-derived
   connectors distinctly." A solid line is a judgement; a dashed one is the
   board's reading of an item body, and has been wrong in both directions. */
#tl-chart .tl-links path.derived { stroke-dasharray: 4 3; opacity: .65; }
#tl-chart .tl-links path.authored { stroke-dasharray: none; }
.tl-note .dashed-key {
  display: inline-block; width: 22px; height: 0; vertical-align: middle;
  border-top: 1.5px dashed currentColor; opacity: .65; margin: 0 2px;
}

/* A COLLAPSIBLE PHASE. The summary bar still shows where the phase sits in
   time when its packages are folded away, so folding costs the reader the
   detail and not the phase. */
.timeline .tl-group[data-phase] { cursor: pointer; user-select: none; }
.timeline .tl-group[data-phase]:hover { background: var(--surface-hover, rgba(127,127,127,.10)); }
.timeline .tl-group[data-phase]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.timeline .tl-caret {
  display: inline-block; width: 10px; color: var(--slate);
  font-size: 10px; vertical-align: 1px;
}
.band-head.foldable { cursor: pointer; user-select: none; }
.band-head.foldable:hover h2, .band-head.foldable:hover h3 { color: var(--accent); }
.band-head.foldable:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* THE REVIEWER'S QUEUE. Owner, 5 September: "show the review queue against the
   reviewer." A wrapped run of lane chips rather than a list, so a backlog of
   eight still fits the cell the other agents' work fits in. */
.roster.grid .rq { display: flex; flex-wrap: wrap; gap: 3px 6px; }
.roster.grid .rq-item {
  font-size: 11px; line-height: 1.5; white-space: nowrap;
  border: 1px solid var(--rule); border-radius: 2px; padding: 0 5px;
  background: var(--surface-sunk);
}
.roster.grid .rq-item b {
  font-family: "IBM Plex Mono", monospace; color: var(--info, #2F6FB0);
}

/* WHICH BARS ARE BEING WORKED ON NOW. Owner, 5 September: "in plan show
   whether a bar is active (ie worked on now) vs queued (queued on an agent)."
   The two states already had different fills and nothing said so, which is a
   colour code no reader has been given the key to. */
.tl-key { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: center;
  margin: 6px 0 0; font-size: 11.5px; color: var(--slate); }
.tl-key .k { display: inline-flex; align-items: center; gap: 6px; }
.tl-key .sw { width: 22px; height: 10px; border-radius: 2px; flex: none; }
.tl-key .sw.on { background: var(--ok, #3F7A54); }
.tl-key .sw.queued { background: var(--info, #2F6FB0); opacity: .75; }
.tl-key .sw.phase { background: var(--slate, #7b8794); opacity: .85; height: 7px; }
.tl-key .sw.ms { width: 11px; height: 11px; border-radius: 2px;
  background: var(--warn, #D5A44F); transform: rotate(45deg); }
/* Queued bars carry a hatch as well as a hue, so the distinction survives a
   reader who does not separate green from blue. */
.timeline .tl-bar.queued {
  background-image: repeating-linear-gradient(45deg,
    rgba(255,255,255,.35) 0 3px, transparent 3px 7px);
}

/* WHAT THE ITEM IS. A collapsed mailbox row showed an id, two names, a time
   and a status word: enough to find an item you already knew about, nothing
   to tell you whether it is worth opening. */
.mailbox .mb-gist {
  grid-column: 1 / -1; font-size: 12px; color: var(--ink-soft);
  line-height: 1.4; margin-top: 2px;
}
.roster.grid .rq-item.next { border-color: var(--info, #2F6FB0); }
.roster.grid .rq-item.next i {
  font-style: normal; font-size: 9.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--info, #2F6FB0); font-weight: 600;
}

/* HOVER OR TAP A WORK PACKAGE NUMBER. Owner, 5 September. `title` answers a
   pointer and nothing else -- there is no hover on a phone and a keyboard user
   never fires one -- so the number is a control and the description is a real
   element. */
.roster.grid .lane-id { cursor: help; border-radius: 2px; }
.roster.grid .lane-id:hover b { text-decoration: underline dotted; }
.roster.grid .lane-id:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.lane-pop {
  position: absolute; z-index: 60; max-width: 340px;
  background: var(--surface, #fff); color: var(--ink);
  border: 1px solid var(--rule-strong, #8a949c); border-radius: 3px;
  padding: 7px 10px; font-size: 12px; line-height: 1.45;
  box-shadow: 0 6px 20px rgba(0,0,0,.22);
}
.roster.grid .rq-item.in-review {
  border-color: var(--ok, #3F7A54); background: var(--ok-bg, transparent);
}
.roster.grid .rq-item.in-review i {
  font-style: normal; font-size: 9.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ok, #3F7A54); font-weight: 600;
}
