/* =====================================================================
   Mirabel — design system

   One accent, one neutral ramp, one type scale, one spacing scale.
   Everything below is built from the tokens; nothing hard-codes a colour
   or a size. Dark is a token swap, not a second stylesheet.
   ===================================================================== */

:root{
  /* neutrals — a single ramp, so every surface and border is a step on it */
  --n0:#ffffff; --n1:#fbfbfc; --n2:#f4f5f7; --n3:#eceef1; --n4:#dfe2e7;
  --n5:#b9bec7; --n6:#6d7480; --n7:#3f4652; --n8:#1c2029;

  --bg:var(--n2); --surface:var(--n0); --raised:var(--n1);
  --line:var(--n3); --line-strong:var(--n4);
  --ink:var(--n8); --ink-2:var(--n7); --ink-3:var(--n6); --ink-4:var(--n5);

  --accent:#00a862; --accent-ink:#00794a; --accent-wash:#e8f6ef;
  --run:#5b5bd6; --run-wash:#eeeefc;
  --bad:#d5341f; --bad-wash:#fdeceb;
  --warn:#a4610a; --warn-wash:#fdf2e3;

  /* type — 1.125 ratio, capped at what a UI actually needs */
  --t-xs:11.5px; --t-sm:12.5px; --t-md:13.5px; --t-base:14px;
  --t-prose:15px; --t-lg:17px; --t-xl:21px; --t-2xl:27px;
  --lh-tight:1.25; --lh-ui:1.45; --lh-prose:1.7;

  /* space — 4pt grid */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px;

  --r-sm:6px; --r-md:10px; --r-lg:14px; --r-full:999px;
  --shadow:0 1px 2px rgba(16,20,28,.04), 0 4px 16px rgba(16,20,28,.06);
  --sidebar:264px; --measure:72ch;

  --sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,system-ui,sans-serif;
  --mono:ui-monospace,SFMono-Regular,'SF Mono',Menlo,monospace;
}

@media (prefers-color-scheme: dark){
  :root{
    --n0:#14161b; --n1:#181b21; --n2:#101216; --n3:#252932; --n4:#333945;
    --n5:#4e5563; --n6:#949cab; --n7:#c9cfd9; --n8:#f0f2f5;
    --accent:#2fbd80; --accent-ink:#5fd3a0; --accent-wash:#122a20;
    --run:#8f8ff0; --run-wash:#1d1d33;
    --bad:#f0705c; --bad-wash:#331c19;
    --warn:#d9963f; --warn-wash:#2e2314;
    --shadow:0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.25);
  }
}

*,*::before,*::after{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--bg);color:var(--ink);
  font:var(--t-base)/var(--lh-ui) var(--sans);
  -webkit-font-smoothing:antialiased}
button,input,textarea,select{font:inherit;color:inherit}
a{color:var(--accent-ink)}

/* ---- app frame: a rail you navigate, a stage you read ---------------- */
.app{display:grid;grid-template-columns:var(--sidebar) 1fr;flex:1;min-height:0;overflow:hidden}

.rail{background:var(--raised);border-right:1px solid var(--line);
  display:flex;flex-direction:column;min-height:0}
.brand{display:flex;align-items:center;gap:var(--s2);
  padding:var(--s4) var(--s4) var(--s3);font-size:var(--t-lg);font-weight:600;
  letter-spacing:-.015em}
.brand .dot{width:9px;height:9px;border-radius:var(--r-full);background:var(--accent)}
.newbtn{margin:0 var(--s3) var(--s3);padding:9px var(--s3);border:1px solid var(--line-strong);
  background:var(--surface);border-radius:var(--r-md);cursor:pointer;text-align:left;
  color:var(--ink);font-weight:500;display:flex;align-items:center;gap:var(--s2);
  transition:border-color .12s,background .12s}
.newbtn:hover{border-color:var(--accent);background:var(--accent-wash)}
.newbtn .plus{color:var(--accent);font-weight:600}

.railscroll{flex:1;overflow-y:auto;padding:0 var(--s2) var(--s3);min-height:0}
.railgroup{margin-top:var(--s4)}
.railgroup h3{font-size:var(--t-xs);text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-3);font-weight:600;margin:0 0 var(--s1);padding:0 var(--s2)}
.convo{display:flex;align-items:center;gap:var(--s2);width:100%;text-align:left;
  background:none;border:0;border-radius:var(--r-sm);padding:7px var(--s2);
  cursor:pointer;color:var(--ink-2);font-size:var(--t-md);line-height:var(--lh-tight)}
.convo:hover{background:var(--n2)}
.convo.on{background:var(--accent-wash);color:var(--ink);font-weight:500}
.convo .label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.convo .state{width:6px;height:6px;border-radius:var(--r-full);flex:none;background:transparent}
.convo .state.run{background:var(--run);animation:breathe 1.6s ease-in-out infinite}
.convo .state.bad{background:var(--bad)}
@keyframes breathe{0%,100%{opacity:1}50%{opacity:.25}}

.railfoot{border-top:1px solid var(--line);padding:var(--s2) var(--s3);
  display:flex;flex-direction:column;gap:2px}
.footrow{display:flex;align-items:center;gap:var(--s2);width:100%;background:none;border:0;
  padding:6px var(--s2);border-radius:var(--r-sm);cursor:pointer;color:var(--ink-3);
  font-size:var(--t-md);text-align:left}
.footrow:hover{background:var(--n2);color:var(--ink)}
.footrow.on{color:var(--ink);font-weight:500}
.footrow .n{margin-left:auto;color:var(--ink-4);font-variant-numeric:tabular-nums}

/* ---- stage ----------------------------------------------------------- */
.stage{overflow-y:auto;min-width:0;display:flex;flex-direction:column}
.stagehead{position:sticky;top:0;z-index:2;background:color-mix(in srgb,var(--bg) 86%,transparent);
  backdrop-filter:saturate(160%) blur(10px);border-bottom:1px solid var(--line);
  padding:var(--s3) var(--s5);display:flex;align-items:center;gap:var(--s3)}
.stagehead h1{font-size:var(--t-base);font-weight:600;margin:0;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stagehead .where{color:var(--ink-3);font-size:var(--t-sm);white-space:nowrap}
.stagebody{flex:1;padding:var(--s5) var(--s5) var(--s7);width:100%}
.column{max-width:var(--measure);margin:0 auto}

/* ---- the composer, as the front door -------------------------------- */
.opening{max-width:var(--measure);margin:0 auto;padding:12vh 0 0}
.opening h2{font-size:var(--t-2xl);font-weight:600;letter-spacing:-.02em;margin:0 0 var(--s2)}
.opening p{color:var(--ink-3);margin:0 0 var(--s5);font-size:var(--t-prose)}

.composer{border:1px solid var(--line-strong);background:var(--surface);
  border-radius:var(--r-lg);padding:var(--s3);box-shadow:var(--shadow);
  transition:border-color .12s}
.composer:focus-within{border-color:var(--accent)}
.composer textarea{width:100%;border:0;background:none;resize:none;outline:none;
  font-size:var(--t-prose);line-height:var(--lh-prose);min-height:26px;max-height:40vh;
  padding:var(--s1) var(--s1) 0}
.composer textarea::placeholder{color:var(--ink-4)}
.composerbar{display:flex;align-items:center;gap:var(--s2);margin-top:var(--s2)}
.composerbar .spacer{flex:1}
.hint{color:var(--ink-4);font-size:var(--t-sm)}

/* ---- controls -------------------------------------------------------- */
.btn{background:var(--accent);color:#fff;border:0;border-radius:var(--r-full);
  padding:8px 16px;font-weight:600;font-size:var(--t-md);cursor:pointer;
  display:inline-flex;align-items:center;gap:6px}
.btn:hover{filter:brightness(.95)}
.btn:disabled{opacity:.5;cursor:default;filter:none}
.btn.quiet{background:none;color:var(--ink-3);border:1px solid var(--line-strong);font-weight:500}
.btn.quiet:hover{color:var(--ink);border-color:var(--ink-4);filter:none}
.btn.bare{background:none;border:0;color:var(--ink-3);padding:6px 8px;font-weight:500}
.btn.bare:hover{color:var(--ink);background:var(--n2);border-radius:var(--r-sm);filter:none}
.link{background:none;border:0;padding:0;color:var(--accent-ink);cursor:pointer;
  font-weight:500;font-size:var(--t-sm)}
.link:hover{text-decoration:underline}

.field{width:100%;background:var(--surface);border:1px solid var(--line-strong);
  border-radius:var(--r-md);padding:9px 11px;outline:none}
.field:focus{border-color:var(--accent)}
select.field{cursor:pointer}

.tag{font-size:var(--t-xs);font-weight:600;padding:3px 9px;border-radius:var(--r-full);
  background:var(--n2);color:var(--ink-3);white-space:nowrap;letter-spacing:.01em}
.tag.ok{color:var(--accent-ink);background:var(--accent-wash)}
.tag.run{color:var(--run);background:var(--run-wash)}
.tag.bad{color:var(--bad);background:var(--bad-wash)}
.tag.warn{color:var(--warn);background:var(--warn-wash)}

.chip{font-size:var(--t-sm);padding:4px 10px;border-radius:var(--r-full);
  border:1px solid var(--line-strong);background:var(--surface);color:var(--ink-2);cursor:pointer}
.chip.on{border-color:var(--accent);background:var(--accent-wash);color:var(--accent-ink)}
.chips{display:flex;flex-wrap:wrap;gap:6px}

/* ---- a turn ---------------------------------------------------------- */
.turn{padding:var(--s5) 0;border-bottom:1px solid var(--line)}
.turn:last-of-type{border-bottom:0}
.asked{background:var(--n2);border-radius:var(--r-md);padding:var(--s3) var(--s4);
  white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.6;color:var(--ink-2)}
/* a fade rather than a guillotine: a hard cut mid-word reads as a bug */
.asked.clamp{display:-webkit-box;-webkit-line-clamp:8;-webkit-box-orient:vertical;overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom,#000 72%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 72%,transparent 100%)}
.replied{margin-top:var(--s4)}
.replied .byline{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s3);
  font-size:var(--t-sm);color:var(--ink-3)}

/* ---- prose ----------------------------------------------------------- */
.prose{font-size:var(--t-prose);line-height:var(--lh-prose);color:var(--ink-2)}
.prose>*:first-child{margin-top:0}
.prose>*:last-child{margin-bottom:0}
.prose p{margin:0 0 var(--s3)}
.prose h3{font-size:var(--t-prose);font-weight:650;color:var(--ink);margin:var(--s5) 0 var(--s2);
  letter-spacing:-.01em}
.prose h4{font-size:var(--t-base);font-weight:650;color:var(--ink);margin:var(--s4) 0 6px}
.prose ul,.prose ol{margin:0 0 var(--s3);padding-left:var(--s5)}
.prose li{margin:0 0 6px}
.prose li::marker{color:var(--ink-4)}
.prose code{font:var(--t-md)/1.4 var(--mono);background:var(--n2);color:var(--ink);
  border:1px solid var(--line);border-radius:var(--r-sm);padding:.5px 5px;overflow-wrap:anywhere}
.prose pre{background:var(--n8);border-radius:var(--r-md);padding:var(--s3) var(--s4);
  overflow-x:auto;margin:0 0 var(--s3)}
.prose pre code{background:none;border:0;color:var(--n0);padding:0;white-space:pre;font-size:var(--t-sm)}
.prose strong{font-weight:650;color:var(--ink)}
.prose.bad{color:var(--bad)}

/* ---- evidence, folded away ------------------------------------------- */
details.evidence{margin-top:var(--s3)}
details.evidence>summary{cursor:pointer;list-style:none;font-size:var(--t-sm);
  color:var(--ink-3);display:inline-flex;align-items:center;gap:6px;padding:4px 0}
details.evidence>summary::-webkit-details-marker{display:none}
details.evidence>summary::before{content:'›';font-size:var(--t-base);
  transition:transform .12s;display:inline-block}
details.evidence[open]>summary::before{transform:rotate(90deg)}
details.evidence>summary:hover{color:var(--ink)}
.feed{margin-top:var(--s2);border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--raised);padding:var(--s3);max-height:360px;overflow-y:auto;
  font:var(--t-sm)/1.65 var(--mono)}
.feed .e{margin-bottom:5px;overflow-wrap:anywhere}
.feed .say{color:var(--ink-2);white-space:pre-wrap;font-family:var(--sans);line-height:var(--lh-ui)}
.feed .think{color:var(--ink-4);font-style:italic;font-family:var(--sans)}
.feed .you{color:var(--accent-ink);font-family:var(--sans)}
.feed .tool{color:var(--ink-3)}
.feed .tool b{color:var(--run);font-weight:600}
.feed .idle{color:var(--ink-4)}
.meta{font-size:var(--t-sm);color:var(--ink-3);margin-top:var(--s3);
  display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap}

/* ---- knowledge / system panes ---------------------------------------- */
.pane h2{font-size:var(--t-xl);font-weight:600;letter-spacing:-.015em;margin:0 0 var(--s1)}
.pane .lede{color:var(--ink-3);margin:0 0 var(--s5);font-size:var(--t-prose)}
.pane section{margin-bottom:var(--s6)}
.pane section>h3{font-size:var(--t-sm);text-transform:uppercase;letter-spacing:.08em;
  color:var(--ink-3);font-weight:600;margin:0 0 var(--s3)}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);
  padding:var(--s4);margin-bottom:var(--s2)}
.card .title{font-weight:600;margin-bottom:2px}
.card .body{color:var(--ink-3);font-size:var(--t-md);line-height:var(--lh-ui)}
.row{display:flex;gap:var(--s3);align-items:center}
.row .grow{flex:1;min-width:0}
.stat{display:flex;align-items:baseline;gap:var(--s2)}
.stat .n{font-size:var(--t-xl);font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.stat .l{color:var(--ink-3);font-size:var(--t-md)}
.empty{color:var(--ink-3);font-size:var(--t-md);padding:var(--s3) 0}
.form{display:grid;gap:var(--s2);margin-top:var(--s3)}
.flash{font-size:var(--t-sm);color:var(--accent-ink);font-weight:500;min-height:16px}

/* ---- narrow ---------------------------------------------------------- */
@media (max-width:820px){
  .app{grid-template-columns:1fr}
  .rail{position:fixed;inset:0 auto 0 0;width:var(--sidebar);z-index:10;
    transform:translateX(-100%);transition:transform .18s ease;box-shadow:var(--shadow)}
  .rail.open{transform:none}
  .stagebody{padding:var(--s4)}
}
.menubtn{display:none}
@media (max-width:820px){.menubtn{display:inline-flex}}

/* ---- the splash -----------------------------------------------------
   Dark ground, her on the right, the name doing the work. Fades out on its
   own; nothing waits for a click. */
.splash{position:fixed;inset:0;z-index:50;overflow:hidden;cursor:default;
  background:radial-gradient(120% 100% at 78% 40%, #1e2a52 0%, #141a33 42%, #0c0f1c 100%);
  display:flex;align-items:center;justify-content:center;
  opacity:1;transition:opacity .42s ease}
.splash.ready{cursor:pointer}
.splash.going{opacity:0;pointer-events:none}
/* the way in. Disabled while the first payload is still in flight, so the
   screen says which of "nothing yet" and "not yet" you are looking at. */
.enter{margin-top:var(--s6);display:inline-flex;align-items:center;gap:.6em;
  background:#ffc83d;color:#20180a;border:0;border-radius:var(--r-full);
  padding:13px 26px;font-size:var(--t-base);font-weight:700;letter-spacing:-.005em;
  cursor:pointer;transition:transform .12s ease, box-shadow .12s ease, opacity .2s ease;
  box-shadow:0 6px 22px rgba(255,200,61,.22)}
.enter:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 10px 30px rgba(255,200,61,.3)}
.enter:disabled{background:transparent;color:#8e9ab7;box-shadow:none;cursor:default;
  border:1px solid rgba(255,255,255,.16);font-weight:500}
.enter .arrow{font-weight:600}
.enterhint{margin:var(--s3) 0 0;min-height:1.2em;color:#7c88a6;font-size:var(--t-sm)}
.splashinner{width:min(1180px,92vw);display:flex;align-items:center;
  min-height:100vh;padding:var(--s5) 0}
/* the figure is positioned against the viewport and out of flow, so the text
   is kept clear of it by its OWN width — padding-right squeezed this column to
   one word per line */
.splashtext{flex:0 1 auto;max-width:min(34rem,52vw);z-index:1}
.splash .kicker{margin:0 0 var(--s4);color:#ffc83d;font-size:var(--t-sm);font-weight:700;
  letter-spacing:.18em;text-transform:uppercase}
.splash h1{margin:0 0 var(--s5);color:#fff;font-size:clamp(40px,7vw,116px);line-height:.92;
  font-weight:800;letter-spacing:-.045em;display:flex;align-items:flex-end;gap:.12em}
.splash h1 .stop{width:.19em;height:.19em;background:#ffc83d;display:inline-block;margin-bottom:.06em}
.splash .lede{margin:0 0 var(--s5);color:#c9d2e6;font-size:clamp(15px,1.5vw,19px);
  line-height:1.62;max-width:30rem}
.splash .lede em{color:#fff;font-style:italic}
.splash .tagline{margin:0;font-size:clamp(15px,1.5vw,19px);font-weight:600;
  display:flex;flex-wrap:wrap;gap:.5em}
.splash .tagline .a{color:#2fbd80}
.splash .tagline .b{color:#ffc83d}
.splash .tagline .c{color:#b58cf0}
/* positioned against .splash (fixed, inset 0), NOT against the content column
   — so bottom:0 unambiguously means the bottom of the screen. Cropped mid-skirt
   in open space it reads as a mistake; cropped at the frame it reads as a frame. */
.splashfig{position:absolute;right:4vw;bottom:0;height:min(88vh,860px);width:auto;
  filter:drop-shadow(0 30px 60px rgba(0,0,0,.55));
  animation:arrive .9s cubic-bezier(.2,.8,.25,1) both}
@keyframes arrive{from{opacity:0;transform:translateY(18px) scale(.985)}to{opacity:1;transform:none}}
@media (max-width:820px){
  .splashtext{max-width:100%}
  .splashfig{opacity:.15;right:-16vw}
}
@media (prefers-reduced-motion:reduce){
  .splashfig{animation:none}
  .splash{transition:none}
}

/* ---- selecting ------------------------------------------------------- */
.selecttoggle{margin:0 var(--s3) var(--s2);padding:5px var(--s2);background:none;border:0;
  color:var(--ink-3);font-size:var(--t-sm);cursor:pointer;text-align:left;border-radius:var(--r-sm)}
.selecttoggle:hover{color:var(--ink);background:var(--n2)}
.selbar{display:flex;align-items:center;gap:var(--s2);margin:0 var(--s3) var(--s2);
  padding:var(--s2);background:var(--n2);border-radius:var(--r-md)}
.selbar .selcount{font-size:var(--t-sm);color:var(--ink-3);font-variant-numeric:tabular-nums}
.selbar .spacer{flex:1}
.selbar .btn{padding:5px 11px;font-size:var(--t-sm)}
.btn.danger{background:var(--bad);color:#fff}
.btn.danger:hover{filter:brightness(.94)}
.convowrap{display:flex;align-items:center;gap:6px;padding-left:var(--s2)}
.convowrap .convo{flex:1;min-width:0}
.convowrap .pick{accent-color:var(--accent);cursor:pointer;flex:none}
.convo.picked{background:var(--accent-wash)}
.selbar.confirming{background:var(--bad-wash)}
.selbar.confirming .selcount{color:var(--bad);font-weight:500}

/* ---- Local: the app, its mail, its logs -----------------------------
   These screens are about the PRODUCT, not about Mirabel. Same furniture
   as the rest of the dashboard, but state has to read at a glance: a
   person here is asking "is it up, and where do I click". */

.railsection{
  font-size:var(--t-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-4);padding:var(--s4) var(--s4) var(--s2);
}
.railempty{padding:0 var(--s4) var(--s3);color:var(--ink-4);font-size:var(--t-sm)}

.footrow .n.ok{color:var(--accent-ink);background:var(--accent-wash)}
.footrow .n.idle{color:var(--ink-3)}

/* state, as a word and a colour rather than a colour alone */
.pill{
  margin-left:var(--s2);padding:.1em .5em;border-radius:var(--r-full);
  font-size:var(--t-xs);font-weight:600;letter-spacing:.02em;vertical-align:.08em;
}
.pill.ok{background:var(--accent-wash);color:var(--accent-ink)}
.pill.warn{background:var(--warn-wash);color:var(--warn)}
.pill.bad{background:var(--bad-wash);color:var(--bad)}
.pill.idle{background:var(--n3);color:var(--ink-3)}

.card.hero{border-color:var(--line-strong)}
.path{font-family:var(--mono);font-size:var(--t-xs);color:var(--ink-4);margin-top:var(--s1);
  overflow-wrap:anywhere}
.footnote{margin-top:var(--s3)}

.chips{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s2)}
.chip{font-family:var(--mono);font-size:var(--t-xs);color:var(--ink-3);
  background:var(--n2);border:1px solid var(--line);border-radius:var(--r-sm);padding:.1em .4em}

/* the drop-a-document form */
.field{display:flex;flex-direction:column;gap:var(--s1);margin-bottom:var(--s3)}
.field .lbl{font-size:var(--t-xs);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)}
.field input[type=text],.field textarea{
  font:inherit;color:var(--ink);background:var(--surface);
  border:1px solid var(--line-strong);border-radius:var(--r-md);padding:.5rem .6rem;width:100%;
}
.field input[type=file]{font-size:var(--t-sm);color:var(--ink-2)}

.tools{gap:var(--s2);margin-bottom:var(--s4);flex-wrap:wrap}
.tools .btn.on{background:var(--accent-wash);color:var(--accent-ink);border-color:var(--accent)}

/* mail */
.maillist{display:flex;flex-direction:column;gap:var(--s2)}
.mailitem .row{cursor:pointer}
.mailitem.open{border-color:var(--accent)}
.code{
  font-family:var(--mono);font-weight:700;font-size:var(--t-lg);
  letter-spacing:.12em;color:var(--accent-ink);
  background:var(--accent-wash);border-radius:var(--r-sm);padding:.1em .45em;
}
.maildetail{border-top:1px solid var(--line);margin-top:var(--s3);padding-top:var(--s3);
  display:flex;flex-direction:column;gap:var(--s2)}
.maildetail p{margin:0}

/* logs — a terminal, so it looks like one */
.logblock{margin-bottom:var(--s5)}
.logblock h3{margin-bottom:var(--s2)}
pre.log{
  margin:0;padding:var(--s3);
  background:var(--n8);color:#d7dbe3;
  border-radius:var(--r-md);
  font-family:var(--mono);font-size:var(--t-xs);line-height:1.55;
  max-height:26rem;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere;
}

/* ---- the three rooms ------------------------------------------------
   Jobs, Local and Mirabel are different rooms, not different filters on
   one list, so they get the top of the window. Local then takes the FULL
   width: a development surface sitting next to a conversation rail is
   neither one thing nor the other. */

.shell{display:flex;flex-direction:column;height:100vh;overflow:hidden}

/* The chrome is the lit stage from the splash and the portal, and it is
   DELIBERATELY single-theme — the same choice portal.css makes and for the same
   reason: it is a stage, not a document. The ground beneath it still follows the
   viewer's preference, which is right, because that is where the logs and diffs
   are and those are documents.

   So the identity a person recognises from mirabel.stub.africa — navy ground,
   the gold square after the name — is what they now sit under all day, while
   the surface they actually read stays a surface you can read. */
.topbar{
  display:flex;flex-direction:column;
  background:linear-gradient(90deg,#141a33 0%,#0c0f1c 62%);
  border-bottom:1px solid rgba(255,255,255,.10);
  flex:none;
}
.toprow{display:flex;align-items:center;gap:var(--s5);padding:0 var(--s5)}

.topbar .brand{
  padding:var(--s3) 0;font-size:var(--t-base);
  background:none;border:0;cursor:pointer;color:#fff;
  font-family:inherit;font-weight:600;letter-spacing:-.015em;
  display:flex;align-items:baseline;gap:.14em;
}
.topbar .brand:hover{color:#ffc83d}
/* the mark: the gold square that ends the wordmark on the splash and the
   portal, at the size a 14px line can carry */
.topbar .brand .stop{
  width:.34em;height:.34em;background:#ffc83d;
  display:inline-block;flex:none;
}

.tabs{display:flex;gap:var(--s1)}
.tab{
  font:inherit;font-size:var(--t-base);font-weight:600;
  color:#8e9ab7;background:none;border:0;cursor:pointer;
  padding:var(--s4) var(--s3) calc(var(--s4) - 2px);
  border-bottom:2px solid transparent;
  display:flex;align-items:center;gap:var(--s2);
}
.tab:hover{color:#fff}
.tab.on{color:#fff;border-bottom-color:#ffc83d}
.tab .n{
  font-size:var(--t-xs);font-weight:600;padding:.1em .45em;
  border-radius:var(--r-full);background:rgba(255,255,255,.13);color:#c9d2e6;
}
.tab .n.ok{background:rgba(47,189,128,.22);color:#7ce0b0}

/* A SECOND ROW, under the tab it belongs to — not the far end of the tab row,
   which is where these used to sit and why they read as peers of Local rather
   than as parts of it. Its own ground and a rule above it are what make the
   nesting visible at a glance. */
.subtabs{
  display:flex;gap:var(--s1);flex-wrap:wrap;
  padding:var(--s2) var(--s5);
  background:rgba(255,255,255,.05);
  border-top:1px solid rgba(255,255,255,.08);
}
.subtab{
  font:inherit;font-size:var(--t-sm);
  color:#8e9ab7;background:none;border:1px solid transparent;
  border-radius:var(--r-full);padding:.28rem .7rem;cursor:pointer;
}
.subtab:hover{color:#fff;background:rgba(255,255,255,.10)}
.subtab.on{color:#0c0f1c;background:#ffc83d;border-color:#ffc83d;font-weight:600}

.app{min-height:0}
/* Local and Mirabel: no rail, and the content gets a comfortable measure
   rather than sprawling the full width of a wide monitor. */
.app.wide{grid-template-columns:1fr}
/* Mirabel's own pages stay readable; Local uses the glass. */
.app.wide .stagebody{max-width:72rem;margin:0 auto}
/* A log is not prose, so the measure that makes prose readable is wrong for it.
   `--measure` is 72ch and a Java stack frame is about 110 characters, so every
   line wrapped two or three times and a trace read as a paragraph. Both caps
   have to go: the stage's 72rem AND the .column measure inside it — the log
   sits in a .column nested in another one.
   (This replaces the same escape for `.localgrid`, which was the three-column
   Local that sub-tabs removed; the class is gone from the client, so the rule
   had quietly stopped matching anything.) */
.app.wide .stagebody:has(.logview){max-width:none}
.column:has(.logview),
.column.logview{max-width:none}

@media (max-width:44rem){
  .topbar{flex-wrap:wrap;gap:var(--s3)}
  .subtabs{margin-left:0;width:100%;padding-bottom:var(--s2);overflow-x:auto}
}

/* the rail starts with the New button now that the brand lives up top */
.rail > .newbtn:first-child{margin-top:var(--s4)}

/* ---- Local: one thing at a time, full width ------------------------
   This was three columns read together — the app, its mail and its logs, on
   the theory that a code arrives, you glance over and paste it. True on a
   maximised window; at any normal width each column came to about thirty
   characters. Sub-tabs replaced it, and `.localgrid`, `.lcol` and `h2.colhead`
   went with it — the client renders none of them now.

   Deleted rather than left lying around, because one rule in here was still
   load-bearing: `.stagebody:has(.localgrid)` was what let Local use the full
   width, and it had silently stopped matching anything, which is how the log
   panes ended up folded into a 72-character measure.
   `the-log-view-escapes-the-prose-measure` fails if a rule keyed on a class
   nobody renders comes back. */

/* handing a session to the phone sits with the other ticket metadata */
.btn.tiny{font-size:var(--t-xs);padding:.2rem .6rem}
.flashinline{margin-left:var(--s2);color:var(--accent-ink);font-size:var(--t-sm)}

/* her diff, read where the ticket is */
.changes{display:flex;flex-direction:column;gap:var(--s2);margin-top:var(--s2)}
pre.diffstat{
  margin:var(--s2) 0 0;font-family:var(--mono);font-size:var(--t-xs);
  color:var(--ink-2);white-space:pre-wrap;overflow-wrap:anywhere;
}

/* ---- ship bar: the step between "she finished" and "open a PR" -------- */
/* Unfolded rather than behind a disclosure, because it is the one action a
   person should take on a finished job and an action nobody sees is an action
   nobody takes. Warm ground so it reads as a prompt, not as more evidence. */
.shipbar{display:flex;gap:var(--s3);align-items:center;flex-wrap:wrap;
  margin-top:var(--s4);padding:var(--s3) var(--s4);
  background:var(--accent-wash);border:1px solid var(--line);
  border-radius:var(--r-md)}
.shipbar .shiptitle{font-weight:600;font-size:var(--t-md)}
.shipbar .shipbody{color:var(--ink-3);font-size:var(--t-sm);line-height:var(--lh-ui)}
.shipbar .btn{white-space:nowrap}

/* The rendered review harness, shown as evidence of the standard applied. */
pre.protocol{margin-top:var(--s2);padding:var(--s3);max-height:420px;overflow:auto;
  background:var(--n2);border:1px solid var(--line);border-radius:var(--r-sm);
  font-size:var(--t-xs);line-height:1.5;white-space:pre-wrap;color:var(--ink-3)}

/* ---- Local: the status strip above the sub-tabs ----------------------- */
/* HQ puts its figures above its sub-tabs; same reason here. You read a log to
   find out what is wrong, and "is it even up" is the question you need
   answered at that moment without navigating away from the log. */
.strip{
  display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;
  padding:var(--s3) var(--s4);margin-bottom:var(--s5);
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-md);
}
.strip .strippart{display:flex;align-items:center;gap:var(--s2);min-width:0}
.strip .stripn{
  font-weight:600;font-size:var(--t-lg);font-variant-numeric:tabular-nums;
  letter-spacing:-.02em;
}
.strip .stripn.ok{color:var(--accent-ink)}
.strip .stripn.warn{color:var(--warn)}
.strip .stripn.idle{color:var(--ink-4)}
.strip .stripl{color:var(--ink-3);font-size:var(--t-sm)}
.strip .striplink{font-size:var(--t-md);color:var(--accent-ink)}
.strip .waiting{color:var(--ink-3);font-size:var(--t-sm);gap:var(--s2)}
.strip .stripclock{
  font-variant-numeric:tabular-nums;color:var(--ink);font-weight:600;
  background:var(--n3);border-radius:var(--r-full);padding:1px var(--s2);
  font-size:var(--t-xs);
}
/* A dot that breathes, so a long wait reads as moving rather than frozen. */
.strip .dot.pulse{
  width:7px;height:7px;border-radius:50%;background:var(--warn);flex:none;
  animation:strippulse 1.6s ease-in-out infinite;
}
@keyframes strippulse{0%,100%{opacity:.35}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.strip .dot.pulse{animation:none;opacity:.8}}

/* A log gets the whole stage now, not a third of it. */
pre.log.full{
  margin:0;max-height:calc(100vh - 260px);overflow:auto;
  padding:var(--s4);background:var(--n8);color:var(--n2);
  border-radius:var(--r-md);
  font-family:var(--mono);font-size:var(--t-sm);line-height:1.55;
  white-space:pre-wrap;word-break:break-word;
}
.row.tools .aside{color:var(--ink-3);font-size:var(--t-sm)}


/* Remote Control on a job's card. The pills carry state and the pre carries
   the one instruction a person has to act on, so a parked session explains
   itself where it is blocking. */
.rcbar{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.rcgroup{display:flex;align-items:center;gap:var(--s2)}
.rcbar pre.protocol{flex-basis:100%;margin:var(--s2) 0 0}

/* A setup gap in the status strip. It wraps onto its own line and keeps its
   full sentence — the point is that it is readable, not that it is compact. */
.strip .strippart.gap{flex-basis:100%;align-items:flex-start;gap:var(--s2);
  color:var(--warn);font-size:var(--t-sm);line-height:var(--lh-tight)}

/* The branch picker on a service card. One line, wrapping when the message is
   a sentence rather than a name — the dirty-repo explanation is long on
   purpose and truncating it would defeat the point. */
.branchrow{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;
  margin-top:var(--s2);font-size:var(--t-sm)}
.branchname{font-family:var(--mono);font-size:var(--t-xs);
  background:var(--n2);border-radius:var(--r-sm);padding:.1em .4em;color:var(--ink-2)}
.field.inline{width:auto;max-width:22rem;padding:.2rem .4rem;font-size:var(--t-sm)}

/* The branch search. The hits wrap below a row that stays put, so typing
   narrows the list without moving the buttons under the cursor. */
.branchfind{display:flex;flex-direction:column;gap:var(--s2);flex-basis:100%}
.branchhits{display:flex;flex-wrap:wrap;gap:var(--s1);align-items:center}
.branchhit{font-family:var(--mono);font-size:var(--t-xs);
  border:1px solid var(--line);border-radius:var(--r-sm);padding:.15rem .45rem}
.branchhit:hover{border-color:var(--line-strong);background:var(--n2)}
.branchhit.on{border-color:var(--accent);background:var(--accent-wash);
  color:var(--accent-ink);font-weight:600}

/* Inside a log: the time, and which stream a line came out of.
   Dim for the timestamp because it repeats on every line and is read by
   scanning, not by looking. Tinted for stderr and for `repl` — that is the
   difference between what the process said on its own and what Mirabel made it
   say, and it is the first thing you want to know about a line. */
.ltime{color:#7b8494}
.lerr{color:#ffb4a2}
.lrepl{color:#9ad0ff}
