/* Blackbox v2 — Blackbox's identity, Pings' manners.
   From Blackbox: the dark surface ladder, one action colour, the square mark.
   From Pings: 16px/1.6 body, 24px radii, 24-28px padding, a serif display face,
   pill buttons and room to breathe. The first version of this screen was a
   correct record rendered as a crash log; the information has not changed, the
   way it is said has. */
@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500&family=Inter:wght@400;500;600&display=swap");
*{box-sizing:border-box;margin:0;padding:0}
:root{
  /* LIGHT IS THE DEFAULT, because Pings is light and that is where the warmth
     comes from. Dark follows the system setting, and either can be forced with
     data-theme. The identity is the same in both: one action colour, a serif
     display face, a surface ladder with real steps between its rungs. */
  --bg:#f1f2ef; --card:#ffffff; --card2:#fbfbf9; --sunk:#f4f5f2;
  --line:#d8dcd8; --line2:#e6e9e5;
  --ink:#16201c; --ink2:#454f4a; --ink3:#6d7a73; --ink4:#8a968f;
  --cyan:#0a6e8a; --cyan-ink:#ffffff;
  --red:#a8402f; --amber:#8a6212; --green:#1d6e55;
  --r:22px; --r-sm:12px;
  --wrap:880px;
  color-scheme:light;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#0b0f16; --card:#141b26; --card2:#111823; --sunk:#0d131c;
    --line:#2b3545; --line2:#1f2835;
    --ink:#eef3fa; --ink2:#b9c6d8; --ink3:#8595ab; --ink4:#64748b;
    --cyan:#5cc8ff; --cyan-ink:#06212f;
    --red:#ff7b7b; --amber:#f3b765; --green:#5fd9ac;
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#0b0f16; --card:#141b26; --card2:#111823; --sunk:#0d131c;
  --line:#2b3545; --line2:#1f2835;
  --ink:#eef3fa; --ink2:#b9c6d8; --ink3:#8595ab; --ink4:#64748b;
  --cyan:#5cc8ff; --cyan-ink:#06212f;
  --red:#ff7b7b; --amber:#f3b765; --green:#5fd9ac;
  color-scheme:dark;
}
body{background:var(--bg);color:var(--ink);
  font:16px/1.62 Inter,ui-sans-serif,system-ui,sans-serif;-webkit-font-smoothing:antialiased}
h1,h2,.display{font-family:Fraunces,Georgia,serif;font-weight:400;letter-spacing:-.012em}
a{color:var(--cyan);text-underline-offset:3px}
.wrap{max-width:var(--wrap);margin:0 auto;padding:10px 24px 110px}

/* ── chrome ─────────────────────────────────────────────────────────────── */
.top{display:flex;align-items:center;gap:12px;padding:16px 24px;
  border-bottom:1px solid var(--line2);background:color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter:blur(8px);position:sticky;top:0;z-index:5}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--ink)}
.mark{width:14px;height:14px;border-radius:4px;background:var(--cyan);display:inline-block}
.word{font-weight:600;letter-spacing:.1px}
.v{font-size:11px;color:var(--ink4);border:1px solid var(--line);border-radius:99px;padding:1px 7px}
.scope{color:var(--ink3);font-size:14px}
.theme{margin-left:auto;background:transparent;border:1px solid var(--line2);
  color:var(--ink3);border-radius:99px;padding:7px;width:34px;height:34px;
  display:grid;place-items:center;cursor:pointer}
.theme:hover{color:var(--cyan);border-color:var(--line)}
.theme svg{width:17px;height:17px}
.local{font-size:12px;color:var(--amber);
  border:1px solid rgba(243,183,101,.3);border-radius:99px;padding:3px 11px}
.back{display:inline-block;margin:26px 0 0;font-size:14px;color:var(--ink3);
  text-decoration:none}
.back:hover{color:var(--cyan)}

/* ── 1. the complaint, as the subject of the page ───────────────────────── */
.issuehead{margin:18px 0 26px}
.refrow{display:flex}
.ref{display:inline-flex;align-items:center;font:600 12.5px ui-monospace,monospace;
  letter-spacing:.04em;color:var(--ink3);background:var(--sunk);
  border:1px solid var(--line2);border-radius:99px;padding:4px 12px}
.issuehead h1{font-size:36px;line-height:1.2;margin:12px 0 14px;max-width:24ch}
.byline{color:var(--ink3);font-size:14.5px;display:flex;align-items:center;
  flex-wrap:wrap;gap:0}

/* ── 2. where things stand ──────────────────────────────────────────────── */
section{margin:0 0 18px}
.stand{background:var(--card);border:1px solid var(--line2);border-radius:var(--r);
  padding:26px 28px;border-left:4px solid var(--line)}
.stand.you{border-left-color:var(--cyan)}
.stand.us{border-left-color:var(--amber)}
.stand.qc{border-left-color:var(--ink3)}
.stand.nobody{border-left-color:var(--green)}
.headline{font-family:Fraunces,Georgia,serif;font-size:21px;line-height:1.42;
  color:var(--ink);max-width:46ch}
.whonext{color:var(--ink2);margin-top:10px;font-size:15px}

/* ── 3. the proposal ────────────────────────────────────────────────────── */
.proposal{background:var(--card);border:1px solid var(--line2);border-radius:var(--r);
  padding:26px 28px}
.phead{display:flex;align-items:center;justify-content:space-between;gap:14px;
  margin-bottom:14px;flex-wrap:wrap}
.phead h2{font-size:22px}
.lede{font-size:19px;line-height:1.5;color:var(--ink)}
.why{color:var(--ink2);margin-top:12px}
.effect{margin-top:16px;color:var(--ink2)}
.effect .k{display:block;font:500 11.5px Inter;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink4);margin-bottom:4px}
.meta{color:var(--ink4);font-size:13.5px;margin-top:16px}
.tag{font-size:12.5px;border-radius:99px;padding:5px 12px;white-space:nowrap;
  border:1px solid var(--line);color:var(--ink3)}
.tag-awaiting_decision{border-color:rgba(92,200,255,.4);color:var(--cyan)}
.tag-verified{border-color:rgba(95,217,172,.4);color:var(--green)}
.tag-changes_requested{border-color:rgba(243,183,101,.4);color:var(--amber)}

/* ── 4. the action area ─────────────────────────────────────────────────── */
.act{background:var(--card2);border:1px solid var(--line2);border-radius:var(--r);
  padding:26px 28px}
.act h2{font-size:22px}
.prompt{color:var(--ink2);margin-top:8px;max-width:60ch}
.do{margin-top:20px}
.do+.do{margin-top:26px;padding-top:24px;border-top:1px solid var(--line2)}
.buttons{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px}
label{display:block;font:500 13px Inter;color:var(--ink3);margin-bottom:9px}
textarea{width:100%;min-height:92px;background:var(--sunk);color:var(--ink);
  border:1px solid var(--line2);border-radius:var(--r-sm);padding:14px 16px;
  font:15.5px/1.6 Inter,sans-serif;resize:vertical}
textarea::placeholder{color:var(--ink4)}
textarea:focus{outline:none;border-color:var(--cyan)}
button{font:600 13px Inter;letter-spacing:.04em;border-radius:99px;cursor:pointer;
  padding:12px 22px;border:1px solid var(--cyan);background:var(--cyan);
  color:var(--cyan-ink);transition:transform .1s,background-color .15s}
button:hover{background:#7ad3ff}
button:active{transform:scale(.975)}
.ghost{background:transparent;color:var(--cyan)}
.ghost:hover{background:rgba(92,200,255,.1)}
button:disabled{opacity:.45;cursor:default;transform:none}
.notebox{margin-top:16px}
.say{font-size:14px}
.say.ok{color:var(--green)} .say.bad{color:var(--red)} .say.working{color:var(--ink3)}

/* ── 5. the conversation, as a conversation ─────────────────────────────────
   It read as a list of records because every entry looked the same. A thread
   is people talking: Danny's own words sit on his side, everyone else answers
   from theirs, and the housekeeping lines get out of the way entirely. */
.talk{background:var(--card);border:1px solid var(--line2);border-radius:var(--r);
  padding:26px 28px}
.talk h2{font-size:22px;margin-bottom:6px}
.history{list-style:none;display:flex;flex-direction:column;gap:18px;margin-top:20px}

.ev{display:flex;flex-direction:column;max-width:78%}
.evhead{display:flex;align-items:baseline;gap:8px;margin:0 4px 5px}
.who{font-weight:600;font-size:13.5px}
.ago,.rev{font-size:12px;color:var(--ink4)}
.model{font-size:11px;color:var(--ink4);border:1px solid var(--line2);
  border-radius:99px;padding:0 7px}
.ev p{margin:0;padding:13px 17px;border-radius:18px;white-space:pre-wrap;
  font-size:15.3px;line-height:1.55}

/* them — left, on a raised surface */
.ev.builder,.ev.qc{align-self:flex-start}
.ev.builder p,.ev.qc p{background:var(--sunk);border:1px solid var(--line2);
  border-bottom-left-radius:6px;color:var(--ink2)}
.ev.builder .who{color:var(--ink2)}
.ev.qc .who{color:var(--green)}
.ev.qc p{border-color:color-mix(in srgb, var(--green) 32%, var(--line2))}

/* him — right, in the action colour, the way his own messages should feel */
.ev.owner{align-self:flex-end;align-items:flex-end}
.ev.owner .evhead{flex-direction:row-reverse}
.ev.owner .who{color:var(--cyan)}
.ev.owner p{background:color-mix(in srgb, var(--cyan) 14%, var(--card));
  border:1px solid color-mix(in srgb, var(--cyan) 35%, transparent);
  border-bottom-right-radius:6px;color:var(--ink)}

/* housekeeping — not a voice, so not a bubble */
.ev.system{align-self:center;max-width:100%;align-items:center}
.ev.system .evhead{display:none}
.ev.system p{background:transparent;border:0;padding:2px 0;font-size:12.5px;
  color:var(--ink4);text-align:center}


/* ── disclosures: everything technical lives in here ────────────────────── */
details.quiet{margin-top:20px;border-top:1px solid var(--line2);padding-top:16px}
details.quiet summary{cursor:pointer;color:var(--ink3);font-size:14px;
  list-style:none;display:flex;align-items:center;gap:7px}
details.quiet summary::-webkit-details-marker{display:none}
details.quiet summary::before{content:"›";color:var(--ink4);font-size:17px;
  transition:transform .15s;display:inline-block}
details.quiet[open] summary::before{transform:rotate(90deg)}
details.quiet summary:hover{color:var(--cyan)}
details.quiet h4{font:500 11.5px Inter;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink4);margin:18px 0 7px}
.unknowns{list-style:none;margin:16px 0 0;display:flex;flex-direction:column;gap:9px}
.unknowns li{color:var(--ink2);padding-left:18px;position:relative;max-width:64ch}
.unknowns li::before{content:"·";position:absolute;left:5px;color:var(--ink4)}
pre{background:var(--sunk);border:1px solid var(--line2);border-radius:var(--r-sm);
  padding:14px 16px;margin-top:8px;font:13px/1.6 ui-monospace,monospace;
  color:var(--ink3);white-space:pre-wrap;overflow-x:auto}
.old{margin-top:20px;padding-top:16px;border-top:1px dashed var(--line2)}
.old p{color:var(--ink3);margin-top:6px}

/* ── the queue (unchanged in structure; restyled to match) ──────────────── */
.answer{margin:26px 0 22px}
.answer h1{font-size:30px;line-height:1.25}
.answer p{color:var(--ink2);margin-top:10px;max-width:64ch}
a.issue{display:block;text-decoration:none;color:inherit;background:var(--card);
  border:1px solid var(--line2);border-radius:var(--r);padding:22px 26px;margin:14px 0;
  transition:transform .18s,border-color .18s}
a.issue:hover{transform:translateY(-2px);border-color:var(--line)}
a.issue h3{font-family:Fraunces,Georgia,serif;font-weight:400;font-size:19px;
  line-height:1.35}
.row{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.pill{font-size:12.5px;border-radius:99px;padding:5px 12px;white-space:nowrap;
  border:1px solid var(--line);color:var(--ink3)}
.pill.you{border-color:rgba(92,200,255,.4);color:var(--cyan)}
.pill.us{border-color:rgba(243,183,101,.4);color:var(--amber)}
.why{color:var(--ink3);font-size:14.5px;margin-top:10px}
.muted{color:var(--ink3)}

/* ── phone ──────────────────────────────────────────────────────────────── */
@media (max-width:640px){
  .wrap{padding:6px 16px 90px}
  .issuehead h1{font-size:26px;max-width:none}
  .headline{font-size:19px}
  .stand,.proposal,.act,.talk{padding:22px 20px;border-radius:18px}
  a.issue{padding:20px}
  .phead{align-items:flex-start}
  .buttons{gap:9px}
  button{width:100%;padding:14px 20px}
  .buttons .say{width:100%}
  .top{padding:14px 16px}
  .scope{display:none}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ── waiting for the builder ─────────────────────────────────────────────── */
.thinking{display:flex;align-items:center;gap:11px;margin-top:14px;
  color:var(--ink3);font-size:14px}
.dots{display:inline-flex;gap:4px}
.dots i{width:6px;height:6px;border-radius:50%;background:var(--cyan);
  display:inline-block;animation:pulse 1.25s ease-in-out infinite}
.dots i:nth-child(2){animation-delay:.18s}
.dots i:nth-child(3){animation-delay:.36s}
@keyframes pulse{0%,80%,100%{opacity:.25}40%{opacity:1}}
.ev.fresh{animation:land .45s cubic-bezier(.2,.7,.2,1) both}
@keyframes land{from{opacity:0;transform:translateY(-6px)}}
details.quiet.tight{margin-top:10px;border-top:0;padding-top:0}
details.quiet.tight summary{font-size:13px}
.sourcepill{display:inline-flex;align-items:center;gap:6px;margin-left:12px;
  vertical-align:middle;
  font:500 13px Inter;text-decoration:none;color:var(--ink2);
  border:1px solid var(--line);border-radius:99px;padding:4px 13px;
  transition:border-color .15s,color .15s,background-color .15s}
.sourcepill:hover{color:var(--cyan);border-color:var(--cyan);
  background:color-mix(in srgb, var(--cyan) 8%, transparent)}
.sourcepill span{font-size:11px;opacity:.75}
/* A quiet inline word, not a chip. As a styled control it caught the eye more
   than the sentence it belonged to, and selecting it looked like a highlight. */
.morebtn{background:none;border:0;padding:0;margin:0 0 0 2px;cursor:pointer;
  font:inherit;color:var(--ink4);text-decoration:none;
  border-bottom:1px solid var(--line);line-height:1.2}
.morebtn:hover{color:var(--cyan);border-bottom-color:var(--cyan)}
.morebtn:focus-visible{outline:2px solid var(--cyan);outline-offset:2px;border-radius:3px}
.morebtn::selection{background:transparent}
.ev p.rest{margin-top:10px}

/* ── faces ───────────────────────────────────────────────────────────────── */
.faces{display:inline-flex;align-items:center;margin-right:10px;vertical-align:middle}
.face{width:26px;height:26px;border-radius:50%;object-fit:cover;
  border:2px solid var(--card);background:var(--sunk);display:inline-block}
.faces.many .face+.face{margin-left:-9px}
.face.ini{display:inline-grid;place-items:center;font:600 10.5px Inter;
  color:var(--ink3);letter-spacing:.02em}
.face.sm{width:19px;height:19px;border-width:1px;margin-right:1px}
details.quiet.earlier{margin:0 0 18px;border-top:0;padding-top:0}
details.quiet.earlier summary{font-size:13.5px}
details.quiet.earlier .history{margin-top:16px}
/* `hidden` must win. .thinking sets display:flex, which overrides the hidden
   attribute — so the page showed "Reading the code…" permanently, claiming work
   was happening when nothing was. Exactly the false status this app exists to
   stop. */
.thinking[hidden]{display:none}

/* ── the proposal, when it is actually waiting on him ────────────────────── */
.proposal.state-awaiting_decision{
  background:color-mix(in srgb, var(--cyan) 7%, var(--card));
  border-color:color-mix(in srgb, var(--cyan) 38%, var(--line2));
  box-shadow:0 1px 0 color-mix(in srgb, var(--cyan) 14%, transparent)}
.proposal.state-verified{border-color:color-mix(in srgb, var(--green) 34%, var(--line2))}
.proposal.state-changes_requested{border-color:color-mix(in srgb, var(--amber) 30%, var(--line2))}

/* the two ways forward, on the card itself */
.jump{display:flex;gap:10px;flex-wrap:wrap;margin-top:20px}
.jump a{text-decoration:none;display:inline-flex;align-items:center}
.jump .btn{background:var(--cyan);color:var(--cyan-ink);border:1px solid var(--cyan);
  border-radius:99px;padding:11px 20px;font:600 13.5px Inter}
.jump .btn:hover{filter:brightness(1.06)}
.jump .ghost{background:transparent;color:var(--cyan);
  border:1px solid color-mix(in srgb, var(--cyan) 45%, transparent);
  border-radius:99px;padding:11px 20px;font:600 13.5px Inter}
.jump .ghost:hover{background:color-mix(in srgb, var(--cyan) 10%, transparent)}

/* a brief ring when you land, so it is obvious where you were sent */
.act.landed{box-shadow:0 0 0 2px color-mix(in srgb, var(--cyan) 50%, transparent)}
@media (max-width:640px){.jump a{flex:1 1 100%;justify-content:center}}

/* ── pasted screenshots ──────────────────────────────────────────────────── */
.shots{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.shots img{max-width:340px;max-height:260px;border-radius:12px;display:block;
  border:1px solid var(--line2);background:var(--sunk)}
.filechip{display:inline-flex;align-items:center;gap:6px;font-size:13px;
  text-decoration:none;color:var(--ink2);border:1px solid var(--line2);
  border-radius:99px;padding:6px 13px;background:var(--sunk)}
.tray{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.tray .pending{position:relative;display:inline-block}
.tray img{max-width:120px;max-height:96px;border-radius:10px;display:block;
  border:1px solid var(--line2)}
.tray .drop{position:absolute;top:-6px;right:-6px;width:20px;height:20px;
  border-radius:50%;border:1px solid var(--line);background:var(--card);
  color:var(--ink3);font:600 12px Inter;cursor:pointer;display:grid;
  place-items:center;padding:0}
.tray .name{font-size:12px;color:var(--ink3);border:1px solid var(--line2);
  border-radius:99px;padding:5px 11px;background:var(--sunk)}
.ask.dragging textarea{border-color:var(--cyan);
  background:color-mix(in srgb, var(--cyan) 7%, var(--sunk))}

/* The structured part of an answer: what is established, what is only likely.
   Deliberately quieter than the sentence above it — the answer leads, this is
   the working you look at when you want to check it. */
.findings { margin: 10px 0 2px; border-left: 2px solid var(--line);
            padding: 2px 0 2px 12px; }
.fblock { margin-bottom: 8px; }
.flabel { font-size: 12px; font-weight: 600; color: var(--ink3);
          letter-spacing: .01em; }
.findings ul { margin: 3px 0 0; padding-left: 16px; }
.findings li { font-size: 13.5px; color: var(--ink); margin: 2px 0; }
.fline { font-size: 13px; color: var(--ink3); margin: 4px 0; }

/* Independent review, stated. A blank where a verdict belongs reads like a
   pass, so the absence gets words and the same weight as a verdict would. */
.qcline { font-size: 13px; color: var(--ink3); margin: 8px 0 2px; }
.unreviewed { font-weight: 600; color: var(--ink2); }

/* ── Status ────────────────────────────────────────────────────────────────
   One badge, beside the issue number, describing the ISSUE. The page used to
   derive its status from the proposal, so a closed issue opened with "There's
   a change ready for you to look at" above a live Approve button, and the only
   line admitting it was closed sat at the bottom under two buttons offering to
   act on it. */
.chip { font-size: 11.5px; font-weight: 600; letter-spacing: .03em;
        text-transform: uppercase; padding: 3px 9px; border-radius: 999px;
        border: 1px solid transparent; }
.chip-closed  { background: var(--line2); color: var(--ink3); border-color: var(--line); }
.chip-you     { background: #fdf0d5; color: #7a5200; border-color: #f0dcaf; }
.chip-qc      { background: #e9eef8; color: #2f4878; border-color: #d3ddf0; }
.chip-done    { background: #e4f2ea; color: #1f5c3d; border-color: #c9e3d5; }
.chip-working { background: var(--line2); color: var(--ink2); border-color: var(--line); }
.chip-idle    { background: var(--line2); color: var(--ink3); border-color: var(--line); }
.chipwhen { font-size: 12px; color: var(--ink4); }
.refrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* A settled proposal is not a pending one. Whatever its stored state says, an
   issue that closed first means nobody ever decided this and nobody will. */
.proposal.is-closed { opacity: .72; }
.standing { font-size: 13.5px; color: var(--ink3); margin: 0 0 10px; }
.s-label { display: inline-block; font-weight: 600; color: var(--ink2);
           margin-right: 7px; }

/* The close is a state change, not a message. As a chat bubble it read like
   one more thing somebody said, when it is the thing that ended the thread. */
.ev.closed { display: flex; align-items: center; gap: 12px; list-style: none;
             margin: 18px 0 6px; }
.ev.closed .rule { flex: 1; height: 1px; background: var(--line); }
.ev.closed .evtext { font-size: 12.5px; color: var(--ink3); white-space: nowrap; }
@media (max-width: 560px) { .ev.closed .evtext { white-space: normal; } }

/* ── Queue lanes ───────────────────────────────────────────────────────────
   Grouped by whose move it is. A flat list sorted by date put a closed issue
   between three open ones, where it read as being just as live as they were. */
.lane { margin: 0 0 30px; }
.lanehead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
            margin: 0 0 10px; padding: 0 4px; }
.lanehead h2 { font-size: 15px; font-weight: 600; margin: 0; color: var(--ink); }
.lanecount { font-size: 12px; font-weight: 600; color: var(--ink3);
             background: var(--line2); border-radius: 999px; padding: 1px 8px; }
.laneblurb { font-size: 13px; color: var(--ink4); }
.lane .card { margin-bottom: 10px; }

/* A status badge never wraps. "Being worked on" broke across two lines on a
   card with a long title, which reads as a layout fault rather than a status. */
.chip { white-space: nowrap; flex: 0 0 auto; }
.card .row { display: flex; align-items: flex-start; gap: 14px; }
.card .row > div:first-child { min-width: 0; }

/* ── A machine filing's facts ──────────────────────────────────────────────
   A person's report carries its context in the thread. A watchdog's carries
   none, so the linked error row is the context: which job, how often, since
   when, and whether it will clear itself. 00078 showed one sentence. */
.ops dl { display: grid; grid-template-columns: minmax(130px, auto) 1fr;
          gap: 6px 18px; margin: 10px 0 14px; }
.ops dt { font-size: 12.5px; color: var(--ink3); }
.ops dd { font-size: 14px; color: var(--ink); margin: 0; }
@media (max-width: 520px) {
  .ops dl { grid-template-columns: 1fr; gap: 1px 0; }
  .ops dd { margin-bottom: 9px; }
}

/* What was reported, as a sentence rather than a table of column names. */
.ops h2 { margin-bottom: 6px; }
.opssaid { font-size: 15px; color: var(--ink); margin: 0 0 8px; }
.opsquote { font-size: 13.5px; color: var(--ink3); margin: 0 0 10px;
            padding-left: 12px; border-left: 2px solid var(--line); }
.opslinks { margin: 0 0 6px; }
.ops dl { display: grid; grid-template-columns: minmax(120px, auto) 1fr;
          gap: 4px 16px; margin: 8px 0 0; font-size: 13px; }
.ops dt { color: var(--ink4); }
.ops dd { color: var(--ink2); margin: 0; }

/* What you are actually approving, named next to the button rather than
   several screens up on a card. */
.whatfix { font-size: 14.5px; color: var(--ink); margin: 2px 0 12px;
           display: flex; gap: 9px; align-items: baseline; }
.whatfix .rev { font-size: 11.5px; font-weight: 600; color: var(--ink3);
                background: var(--line2); border-radius: 999px; padding: 1px 7px;
                flex: 0 0 auto; }
/* The way out, set apart from the ways to reply. */
.buttons .apart { margin-left: auto; }
.sortedbox { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line2); }


/* ONE text rail per card. The lede was capped at 56ch, the body at 62ch and
   the headline at 46ch, so three paragraphs in one card each stopped at a
   different place and the right edge looked broken. The card is the measure
   now, and every line in it ends in the same column. */
/* EDGE TO EDGE. Three paragraphs in one card were capped at 56ch, 62ch and
   46ch, and ch scales with font size, so a 19px lede and a 15px paragraph at
   the same ch still ended in different columns. Capping them all to one rail
   fixed the ragged edge and left a band of dead space instead. The card is
   already the measure — the page is capped at 880px — so nothing inside it
   needs a second cap. */
.proposal > *, .stand > *, .ops > * { max-width: none; }
.headline { max-width: none; }

/* What the job IS, before what it said. An internal job key names a thing
   without explaining it. */
.opsdoes { font-size: 15px; color: var(--ink); margin: 0 0 6px; }
.opswhen { font-size: 12.5px; color: var(--ink4); white-space: nowrap; }
.opssaid { font-size: 14px; color: var(--ink2); margin: 0 0 8px; }

/* With nothing to say, it stops looking like a panel. An empty card with a
   divider and one disclosure link reads as something that failed to load. */
.stand.bare { background: none; border: 0; border-radius: 0;
              padding: 0 0 4px; margin-top: -4px; }
.stand.bare > details { margin-top: 0; }
.stand.bare > details > summary { padding-left: 0; }
.stand.bare hr, .stand.bare .headline, .stand.bare .whonext { display: none; }
.stand.bare details.quiet { border-top: 0; padding-top: 0; margin-top: 0; }
.stand.bare { border-left: 0; }


/* The report itself, which is the thing this block is named after. It was a
   small grey quote under three paragraphs of context. */
.opsreport { font-size: 18px; line-height: 1.45; color: var(--ink);
             margin: 2px 0 10px; }
.opscadence { font-size: 14.5px; color: var(--ink2); margin: 0 0 4px; }
.opssource { font-size: 13.5px; color: var(--ink3); margin: 0 0 10px; }

/* The logged line, kept visible under its plain reading. The reading is only
   ever there when somebody worked out what the line meant; the raw words stay
   so the explanation can be checked against them. */
.opsraw { font-size: 13px; color: var(--ink4); margin: -4px 0 10px; }
.opsraw span { font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
               font-size: 12.5px; color: var(--ink3); }

/* Raised beside the decision, not instead of it. There is no generic .card
   rule — each card is styled by name — so this one needs its own. */
.updates { background: var(--card); border: 1px solid var(--line2);
           border-radius: var(--r); padding: 26px 28px;
           border-left: 4px solid var(--amber); }
.updates h2 { margin-top: 0; }
.upintro { font-size: 13.5px; color: var(--ink3); margin: 2px 0 14px; }
.up { padding: 14px 0 4px; border-top: 1px solid var(--line2); }
.up:first-of-type { border-top: 0; padding-top: 0; }
.upbody { font-size: 15px; color: var(--ink); margin: 0 0 10px; }

/* The proposal's state, said once, in the card it belongs to. */
.pstate { font-size: 13.5px; color: var(--ink3); margin: -2px 0 12px; }

/* A follow-up says what is happening to IT, where it is. */
.uplooking { display: flex; align-items: center; gap: 9px; font-size: 13.5px;
             color: var(--ink3); margin: 0 0 10px; }
.upanswer { font-size: 14.5px; color: var(--ink); background: var(--line2);
            border-radius: 12px; padding: 12px 14px; margin: 0 0 10px; }
.up.state-looking .upbody, .up.state-answered .upbody { color: var(--ink2); }

/* Where the approved fix has actually got to. */
.track { list-style: none; margin: 4px 0 14px; padding: 0; display: grid; gap: 4px; }
.track li { font-size: 13.5px; display: flex; gap: 9px; align-items: baseline; }
.track li.yes { color: var(--ink); }
.track li.no { color: var(--ink4); }
/* .step, not .mark — .mark is already the app's logo square, so the unfinished
   steps inherited its cyan fill and every row looked identical. */
.track .step { width: 13px; height: 13px; flex: 0 0 auto; border-radius: 50%;
               position: relative; top: 2px; box-sizing: border-box; }
.track li.no .step { border: 1.5px solid var(--line); }
.track li.yes .step { background: #0f6b73; }
.track li.yes .step::after { content: ""; position: absolute; left: 4px; top: 1.5px;
  width: 3.5px; height: 7px; border: solid #fff; border-width: 0 1.7px 1.7px 0;
  transform: rotate(45deg); }

/* Found on the way, filed elsewhere. One line — a finding does not get to
   compete with the fix this page is about. */
.spun { font-size: 13.5px; color: var(--ink3); margin: -6px 0 22px; }
.spun a { color: var(--ink2); }

/* The approve button in the proposal card is a button, not a link to one. */
.do.inline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
             margin: 4px 0 2px; }

/* What shipping would do, before it does it. */
.do.ship { margin: 6px 0 14px; }
.shipplan { margin-top: 12px; padding: 14px 16px; background: var(--line2);
            border-radius: 12px; font-size: 13.5px; color: var(--ink2); }
.shipplan ul { margin: 6px 0 10px; padding-left: 18px; }
.planhead { margin: 0 0 2px; color: var(--ink3); font-size: 13px; }

/* ── Status colour ─────────────────────────────────────────────────────────
   Every pill was the same grey, so a queue of six said nothing at a glance,
   and "Being worked on" covered an untouched ticket and one with the builder
   actively reading code. Each stage has its own word and its own colour. */
.chip-done     { background:#e3f2e8; color:#1c5c38; border-color:#c6e4d2; }
.chip-you      { background:#fdf0d5; color:#7a5200; border-color:#f0dcaf; }
.chip-running  { background:#e2effb; color:#1f4e79; border-color:#c6dcf2; }
.chip-queued   { background:#eceef2; color:#4a5568; border-color:#d9dee6; }
.chip-approved { background:#e0f1f2; color:#0f5b61; border-color:#c3e3e5; }
.chip-qc       { background:#e9eafb; color:#3b3f8f; border-color:#d3d6f2; }
.chip-stuck    { background:#fbe6e4; color:#8a2d23; border-color:#f2cdc9; }
.chip-answered { background:#e6f1ea; color:#2b5c42; border-color:#cbe3d5; }
.chip-new      { background:var(--line2); color:var(--ink3); border-color:var(--line); }

/* The lane says the same thing in the same colour, on its left edge. */
.lane { border-left: 3px solid transparent; padding-left: 14px; }
.lane.tone-you      { border-left-color:#e3b23c; }
.lane.tone-running  { border-left-color:#2f74b5; }
.lane.tone-queued   { border-left-color:#9aa5b1; }
.lane.tone-approved { border-left-color:#13767e; }
.lane.tone-qc       { border-left-color:#5a5fc7; }
.lane.tone-done     { border-left-color:#3f9163; }
.lane.tone-new      { border-left-color:var(--line); }

.lanefold > summary { cursor: pointer; list-style: none; }
.lanefold > summary::-webkit-details-marker { display: none; }
.lanefold > summary::after { content: "show"; font-size: 12px; color: var(--ink4); }
.lanefold[open] > summary::after { content: "hide"; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chip-done     { background:#15301f; color:#8fd6aa; border-color:#1e4a2e; }
  :root:not([data-theme="light"]) .chip-you      { background:#332706; color:#f0cd7a; border-color:#4d3b0b; }
  :root:not([data-theme="light"]) .chip-running  { background:#122c45; color:#8fc1ec; border-color:#1d4367; }
  :root:not([data-theme="light"]) .chip-queued   { background:#232833; color:#aab4c2; border-color:#333a48; }
  :root:not([data-theme="light"]) .chip-approved { background:#0d2f32; color:#79cdd3; border-color:#15474c; }
  :root:not([data-theme="light"]) .chip-qc       { background:#1d1f45; color:#a9adf0; border-color:#2e3168; }
  :root:not([data-theme="light"]) .chip-stuck    { background:#3a1612; color:#f0a79d; border-color:#58231c; }
  :root:not([data-theme="light"]) .chip-answered { background:#15301f; color:#8fd6aa; border-color:#1e4a2e; }
}

/* What the title had to leave out. The title used to BE the whole note, so a
   finding written as a paragraph became a nine-line headline. */
.subtitle { font-size: 16px; line-height: 1.5; color: var(--ink2);
            margin: -4px 0 14px; }

/* A ticket written for a person has sections. They were printed as one block,
   which is how readable prose still reads as a wall. */
.subtitle p { margin: 0 0 10px; }
.plabel { display: block; font-size: 12px; font-weight: 600; letter-spacing: .04em;
          text-transform: uppercase; color: var(--ink4); margin-bottom: 2px; }

/* Pick an order. */
.sorter { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 20px; }
.sortbtn { font-size: 13px; padding: 5px 12px; border-radius: 999px;
           border: 1px solid var(--line); color: var(--ink2);
           text-decoration: none; background: var(--card); }
.sortbtn.on { background: var(--ink); color: var(--card); border-color: var(--ink); }

/* What you are reading, kept in the bar once the heading scrolls away. */
.nowon { display: flex; align-items: baseline; gap: 9px; min-width: 0;
         margin-left: 18px; animation: nowin .18s ease-out; }
.nowon .nowref { font-family: var(--mono, ui-monospace, Menlo, monospace);
                 font-size: 11.5px; color: var(--ink4); flex: 0 0 auto; }
.nowon .nowtitle { font-size: 13.5px; font-weight: 600; color: var(--ink2);
                   white-space: nowrap; overflow: hidden;
                   text-overflow: ellipsis; max-width: 46ch; }
@keyframes nowin { from { opacity: 0; transform: translateY(-3px); } }
@media (max-width: 760px) { .nowon .nowtitle { max-width: 22ch; } }

/* The bar, once you have scrolled: what you are reading in the middle, its
   status and a way out on the right. */
.top { position: sticky; top: 0; z-index: 20; }
.nowon { position: absolute; left: 50%; transform: translateX(-50%);
         display: flex; align-items: baseline; gap: 9px;
         max-width: 52%; margin-left: 0; }
.nowchip { margin-left: auto; flex: 0 0 auto; }
.nowback { font-size: 13px; color: var(--ink2); text-decoration: none;
           white-space: nowrap; flex: 0 0 auto; }
.nowback:hover { color: var(--ink); }
@media (max-width: 860px) {
  .nowon { position: static; transform: none; margin-left: 14px; max-width: 40%; }
  .nowback { display: none; }
}

/* The header keeps its shape whatever it is handed. With an empty title the
   row collapsed and the ref, the status and the back link overlapped. */
.refrow { min-height: 26px; }
.issuehead h1 { min-height: 1em; }
.top { display: flex; align-items: center; gap: 10px; }
.top .nowon { pointer-events: none; }

/* What approving will do, before you approve it. */
.willdo:not(:empty) { margin: 8px 0 14px; padding: 14px 16px;
                      background: var(--line2); border-radius: 12px;
                      font-size: 13.5px; color: var(--ink2); }
.willdo ul { margin: 6px 0 8px; padding-left: 18px; }

/* Keep the scrolled title in layout so it cannot paint underneath status/actions. */
.top { flex-wrap: wrap; }
.top .nowon { position: static; transform: none; flex: 1 1 160px;
  min-width: 0; max-width: none; margin-left: 8px; }
.top .nowtitle { min-width: 0; max-width: none; }
.top .nowchip { margin-left: 0; }
.top > [hidden] { display: none !important; }
.top .brand, .top .theme, .top .local { flex-shrink: 0; }
@media (max-width: 760px) {
  .top .nowon { order: 10; flex-basis: 100%; margin-left: 0; }
  .top .scope, .top .local { display: none; }
}

.status-history { margin-top: 24px; }
.status-history summary { font-weight: 600; cursor: pointer; }
.status-history ol { list-style: none; margin: 18px 0; padding: 0 0 0 12px; }
.status-history li { border-left: 2px solid var(--line); padding: 0 0 18px 18px; }
.status-history time { display: block; color: var(--ink3); font-size: 13px; margin-top: 4px; }
.status-history .future-steps li { border-left: 2px dashed var(--ink4); color: var(--ink3); }

.status-history .chip { white-space: normal; max-width: 100%; }
.status-history .future-chip { background: transparent; border-style: dashed; }

/* Account screens: readable fields and comfortable touch targets in both themes. */
.auth-card{max-width:460px;margin:40px auto;background:var(--card);border:1px solid var(--line);border-radius:24px;padding:32px}
.auth-card h1{font-size:32px;line-height:1.2;margin-bottom:12px}
.auth-card>p{color:var(--ink2);font-size:16px;line-height:1.6}
.auth-form{display:grid;gap:20px;margin-top:28px}
.auth-field{display:grid;gap:8px;font-size:14px;font-weight:600;color:var(--ink2)}
.auth-field input{display:block;width:100%;min-width:0;min-height:48px;border:1px solid var(--line);border-radius:12px;background:var(--sunk);color:var(--ink);padding:12px 14px;font:400 16px/1.4 system-ui,sans-serif}
.auth-field input:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.auth-form button{min-height:48px;width:100%;font:600 16px/1.4 system-ui,sans-serif;letter-spacing:0}
#login-status{font-size:14px;color:var(--red);margin:0}
#login-status:empty{display:none}
.top .theme{flex:0 0 44px;width:44px;height:44px;padding:10px;background:var(--card);color:var(--ink);border:1px solid var(--line)}
.top .theme:hover{background:var(--sunk);color:var(--ink)}
.top .theme svg{width:21px;height:21px}
.top .theme:focus-visible{outline:2px solid var(--cyan);outline-offset:3px}
@media(max-width:600px){.auth-card{margin:24px auto;padding:24px 20px}.auth-card h1{font-size:28px}.wrap:has(.auth-card){padding:0 16px 40px}}
