/* ===========================================================================
   PROSPECTA · SHELL
   The design system, ported from the xolvea-builds console (see
   notes/knowledge/console-port-map.md: shell.css was PORT AS-IS). What carries
   over is the discipline, not the brand: a five-step type scale, a four-step
   spacing grid, ink levels that are measured rather than picked, and no shadow
   or gradient that is only decoration.

   The soul brief (planning/soul.md) decides the three things this file cannot:
   the field is light because the operator works in daylight between two light
   windows; the accent is one token because it measures over 4.5:1 both as fill
   and as text; and anything unmeasured is amber, never a zero.

   Every colour here has a floor and `npm run check:design` enforces it. If you
   change a value, run the check -- it fails, it does not warn.
   =========================================================================== */

:root{
  /* THE FIELD AND THE PAPER. #FAFAFA is the 98% grey that lets a white card
     separate itself without needing a border. */
  --field:#FAFAFA;
  --panel:#ffffff;
  --panel-2:#f2f3f5;
  --hair:#dfe1e6;
  --hair-soft:#eef0f2;

  /* THE INK LEVELS, measured against the field. `--rule` is never type: it is
     the one hairline colour, and it carries a name that says so. */
  --strong:#0B1020;   /* 18.1:1 -- the one thing that matters in a card      */
  --body:#1F2430;     /* 14.9:1 -- prose and every value                     */
  --mute:#5A6072;     /*  6.0:1 -- secondary prose, meta                     */
  --faint:#6B7180;    /*  4.7:1 -- the smallest type there is; still legible */
  --rule:#9AA0AE;     /*  2.5:1 -- LINES ONLY. Never a `color:`.             */

  /* THE ACCENT -- one token, not two. #3B4FE0 measures 6.2:1 under white ink
     (it is the button fill) and 6.0:1 as text on the field, so unlike the
     orange it replaces it never needs a darkened twin. It appears in exactly
     one place at a time: the decision. */
  --accent:#3B4FE0;
  --accent-ink:#ffffff;
  --accent-wash:#eceefc;

  /* THE FOUR SEMANTIC COLOURS. Amber is load-bearing: it is what "sin dato"
     is painted in, and the reason a zero is never printed for it. */
  --green:#2A7A34;
  --amber:#8A6410;
  --red:#C0392F;
  --sky:#2F6FA8;

  /* NO WEBFONT. The console loads nothing from a third party: a font request is
     egress, and egress is on an allow-list here. The system face is also the
     one already rendering the CRM tab next to this one, and it paints on the
     first frame -- there is no flash to sit through. */
  --sans:system-ui,-apple-system,"Segoe UI Variable Text","Segoe UI",sans-serif;
  --mono:ui-monospace,"Cascadia Mono","Segoe UI Mono",Consolas,monospace;

  /* THE TYPE SCALE, FIVE STEPS AND NOT SEVENTEEN. The meta, the secondary
     prose, the body, the one line that matters in a card, and the name of the
     open thing. A sixth exists only for a figure, because the numbers screen is
     the one screen read from further away than the rest. */
  --t-xs:11px;   /* mono: meta, state, shortcuts, section labels */
  --t-s:12px;    /* secondary prose and notes                    */
  --t-m:13px;    /* the body, and every value                    */
  --t-l:15px;    /* the only thing that matters inside a card    */
  --t-xl:22px;   /* the name of the open record                  */
  --t-num:26px;  /* a figure is not prose                        */

  /* THE RHYTHM, four steps. A spacing that is not on this scale is noise
     nobody decided on. */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px;
  --r-card:10px; --r-ctl:6px;

  /* THE FRAME. The open record takes the screen; the rail and the provenance
     column are supporting cast and are sized to say so. */
  --rail-w:296px;
  --side-w:252px;
  --top-h:44px;
  --crumb-h:34px;
  --act-h:52px;
  --stat-h:26px;
}

html,body{margin:0;height:100%;}
body{
  background:var(--field);
  color:var(--body);
  font-family:var(--sans);
  font-size:var(--t-m);
  line-height:1.45;
  -webkit-font-smoothing:antialiased;
}
*{box-sizing:border-box;}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.01em;}
.mute{color:var(--mute);}
.faint{color:var(--faint);}

/* THE FOCUS RING is soft and always present. A console driven by the keyboard
   that hides where the keyboard is does not work. */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-ctl);}

/* ---------------------------------------------------------------- the frame */
#app{
  display:grid;
  height:100%;
  grid-template-columns:var(--rail-w) 1fr var(--side-w);
  grid-template-rows:var(--top-h) var(--crumb-h) 1fr var(--act-h) var(--stat-h);
  grid-template-areas:
    "top   top   top"
    "crumb crumb crumb"
    "rail  main  side"
    "act   act   act"
    "stat  stat  stat";
}
#app[data-rail="0"]{grid-template-columns:0 1fr var(--side-w);}
#app[data-side="0"]{grid-template-columns:var(--rail-w) 1fr 0;}
#app[data-rail="0"][data-side="0"]{grid-template-columns:0 1fr 0;}
#app[data-act="0"]{grid-template-rows:var(--top-h) var(--crumb-h) 1fr 0 var(--stat-h);}

/* ------------------------------------------------------------------- topbar */
#top{
  grid-area:top;
  display:flex;align-items:center;gap:var(--s3);
  padding:0 var(--s3);
  background:var(--panel);
  border-bottom:1px solid var(--hair);
}
#brand{font-size:var(--t-s);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--strong);}
.sample{
  font-family:var(--mono);font-size:var(--t-xs);
  padding:2px var(--s2);border-radius:var(--r-ctl);
  border:1px solid var(--amber);color:var(--amber);
  white-space:nowrap;
}
.sample.live{border-color:var(--green);color:var(--green);}
#tabs{display:flex;gap:2px;flex-wrap:nowrap;overflow:hidden;}
.tab{
  font-family:var(--sans);font-size:var(--t-s);
  display:flex;align-items:center;gap:var(--s1);
  padding:var(--s1) var(--s2);
  background:none;border:0;border-radius:var(--r-ctl);
  color:var(--mute);cursor:pointer;white-space:nowrap;
}
.tab:hover{color:var(--body);background:var(--hair-soft);}
.tab[aria-current="page"]{color:var(--strong);background:var(--hair-soft);font-weight:600;}
.tab .ct{
  font-family:var(--mono);font-size:var(--t-xs);
  padding:0 var(--s1);border-radius:var(--r-ctl);
  background:var(--panel-2);color:var(--mute);
}
.tab[aria-current="page"] .ct{background:var(--accent-wash);color:var(--accent);}
.tab .ct.unmeasured{color:var(--amber);background:none;border:1px solid var(--amber);}
#topr{margin-left:auto;display:flex;align-items:center;gap:var(--s3);}
.tbtn{
  font-family:var(--sans);font-size:var(--t-s);
  padding:var(--s1) var(--s2);
  background:none;border:1px solid var(--hair);border-radius:var(--r-ctl);
  color:var(--mute);cursor:pointer;
}
.tbtn:hover{color:var(--body);border-color:var(--rule);}
#seat{display:flex;align-items:center;gap:var(--s2);font-size:var(--t-s);}
#seat b{color:var(--body);font-weight:600;}
#seat .sid{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);}
#seat .sid.warnt{color:var(--amber);}

/* ----------------------------------------------------------- the breadcrumb */
#crumb{
  grid-area:crumb;
  display:flex;align-items:center;gap:var(--s2);
  padding:0 var(--s3);
  background:var(--panel);
  border-bottom:1px solid var(--hair-soft);
  font-size:var(--t-s);
}
#crumb .cid{font-family:var(--mono);color:var(--faint);}
#crumb .cnm{color:var(--body);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
#crumb .sep{color:var(--faint);}
#crumbr{margin-left:auto;display:flex;align-items:center;gap:var(--s3);white-space:nowrap;}
#clock{font-family:var(--mono);font-size:var(--t-s);color:var(--mute);}
.jl{
  font-family:var(--mono);font-size:var(--t-xs);
  padding:1px var(--s2);border-radius:var(--r-ctl);
  border:1px solid var(--hair);color:var(--mute);
}
.jl.part{color:var(--amber);border-color:var(--amber);}
.jl.blocked{color:var(--red);border-color:var(--red);}

/* -------------------------------------------------------------- left: rail */
#rail{
  grid-area:rail;
  display:flex;flex-direction:column;min-width:0;
  background:var(--panel);
  border-right:1px solid var(--hair);
  overflow:hidden;
}
#railhd{
  padding:var(--s2) var(--s3);
  font-size:var(--t-xs);font-weight:600;color:var(--mute);
  border-bottom:1px solid var(--hair-soft);
  display:flex;align-items:center;gap:var(--s2);
}
#railq{position:relative;padding:var(--s2) var(--s3);border-bottom:1px solid var(--hair-soft);}
#railq input{
  width:100%;font-family:var(--sans);font-size:var(--t-s);
  padding:var(--s1) var(--s2);
  background:var(--field);border:1px solid var(--hair);border-radius:var(--r-ctl);
  color:var(--body);
}
#railq kbd{position:absolute;right:var(--s4);top:50%;transform:translateY(-50%);}
#railsc{overflow-y:auto;flex:1;min-height:0;}
.grp{
  display:flex;align-items:center;gap:var(--s2);
  padding:var(--s2) var(--s3) var(--s1);
  font-size:var(--t-xs);font-weight:600;color:var(--mute);
}
.grp .n{color:var(--faint);font-family:var(--mono);}
.grp .rt{margin-left:auto;}
.row{
  padding:var(--s2) var(--s3);
  border-bottom:1px solid var(--hair-soft);
  cursor:pointer;
}
.row:hover{background:var(--panel-2);}
.row[aria-current="true"]{background:var(--accent-wash);box-shadow:inset 2px 0 0 var(--accent);}
.row .r1{display:flex;align-items:center;gap:var(--s2);}
.row .nm{font-size:var(--t-m);color:var(--body);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.row .r2{display:flex;align-items:center;gap:var(--s2);margin-top:2px;font-size:var(--t-xs);color:var(--mute);}
.row .age{margin-left:auto;font-family:var(--mono);font-size:var(--t-xs);color:var(--mute);}
.row .age.hot{color:var(--red);}

.badge{
  font-family:var(--mono);font-size:var(--t-xs);
  padding:0 var(--s1);border-radius:var(--r-ctl);
  border:1px solid var(--hair);color:var(--mute);white-space:nowrap;
}
.badge.go{color:var(--green);border-color:var(--green);}
.badge.wait{color:var(--amber);border-color:var(--amber);}
.badge.stop{color:var(--red);border-color:var(--red);}
.badge.info{color:var(--sky);border-color:var(--sky);}
.badge.flat{color:var(--mute);border-color:var(--hair);}

/* ------------------------------------------------------------ centre: main */
#main{
  grid-area:main;
  overflow-y:auto;min-width:0;
  padding:var(--s4);
  background:var(--field);
}
#main h1{
  margin:0 0 var(--s1);
  font-size:var(--t-xl);font-weight:600;letter-spacing:-.02em;color:var(--strong);
}
/* THE QUESTION THE SCREEN ANSWERS, printed on the screen. A tab whose question
   nobody can state is a tab nobody needed. */
.idline{margin:0 0 var(--s4);font-size:var(--t-s);color:var(--mute);}
.sect{
  margin:var(--s4) 0 var(--s2);
  font-size:var(--t-xs);font-weight:600;color:var(--mute);
}
.card{
  background:var(--panel);
  border:1px solid var(--hair);
  border-radius:var(--r-card);
  padding:var(--s3);
  margin-bottom:var(--s2);
}
.card .ch{font-size:var(--t-l);font-weight:600;color:var(--strong);letter-spacing:-.01em;}
.card p{margin:var(--s1) 0 0;font-size:var(--t-s);color:var(--mute);}
.card.prep{border-left:2px solid var(--accent);}

/* THE FIGURE. `.nv.none` is the whole product argument in one rule: something
   unmeasured is amber words, never a digit. */
.nums{display:flex;flex-wrap:wrap;gap:var(--s2);}
.num{
  flex:1 1 160px;
  background:var(--panel);border:1px solid var(--hair);border-radius:var(--r-card);
  padding:var(--s3);
}
.num .nl{font-size:var(--t-xs);font-weight:600;color:var(--mute);}
.num .nv{
  font-family:var(--mono);font-size:var(--t-num);font-weight:600;
  color:var(--strong);letter-spacing:-.02em;line-height:1.15;
}
.num .nv.none{font-family:var(--sans);font-size:var(--t-l);font-weight:600;color:var(--amber);}
.num .nn{margin-top:var(--s1);font-size:var(--t-xs);color:var(--faint);}

/* PROVENANCE. A value cites where it came from, or it is marked as uncited. */
.cite{font-family:var(--mono);font-size:var(--t-xs);color:var(--mute);}
.cite.inf{color:var(--sky);}
.cite.human{color:var(--accent);}
.cite.stale{color:var(--amber);}
.uncited{font-family:var(--mono);font-size:var(--t-xs);color:var(--amber);}

/* THE DECLARED ABSENCE. This is what an empty console looks like: not a blank
   screen and not a zero, but a sentence that says what is missing and why. */
.absent{
  background:var(--panel);
  border:1px solid var(--amber);
  border-left-width:2px;
  border-radius:var(--r-card);
  padding:var(--s3);
  margin-bottom:var(--s2);
}
.absent .ah{font-size:var(--t-l);font-weight:600;color:var(--amber);margin-bottom:var(--s1);}
.absent p{margin:0 0 var(--s1);font-size:var(--t-s);color:var(--body);}
.absent p:last-child{margin-bottom:0;}
.absent .lex{color:var(--mute);font-size:var(--t-s);}

/* ------------------------------------------------------------- right: side */
#side{
  grid-area:side;
  overflow-y:auto;min-width:0;
  background:var(--panel);
  border-left:1px solid var(--hair);
}
.sidehd{
  padding:var(--s2) var(--s3);
  font-size:var(--t-xs);font-weight:600;color:var(--mute);
  border-bottom:1px solid var(--hair-soft);
}
.srow{
  display:flex;align-items:baseline;gap:var(--s2);
  padding:var(--s2) var(--s3);
  border-bottom:1px solid var(--hair-soft);
}
/* The same row shape is reused inside a card (Hoy's "cannot be measured yet"
   list); there it carries no side padding and the last line drops its rule. */
.card .srow{padding-left:0;padding-right:0;}
.card .srow:last-child{border-bottom:0;padding-bottom:0;}
.card .srow:first-child{padding-top:0;}
.srow .snm{font-size:var(--t-m);color:var(--body);}
.srow .sst{margin-left:auto;font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);}
.srow .sst.joined{color:var(--green);}
.srow .sst.no_data{color:var(--amber);}
.srow .sst.unreachable{color:var(--red);}
.srow .sst.not_wired{color:var(--faint);}

/* ---------------------------------------------------------- the action bar */
#act{
  grid-area:act;
  display:flex;align-items:center;gap:var(--s3);
  padding:0 var(--s3);
  background:var(--panel);
  border-top:1px solid var(--hair);
}
#app[data-act="0"] #act{display:none;}
.arm{
  font-family:var(--sans);font-size:var(--t-m);font-weight:600;
  padding:var(--s2) var(--s4);
  background:var(--accent);color:var(--accent-ink);
  border:0;border-radius:var(--r-ctl);cursor:pointer;
}
.arm:hover{filter:brightness(1.06);}
.arm:active{transform:scale(.985);}
.arm[disabled]{background:var(--panel-2);color:var(--faint);cursor:not-allowed;filter:none;}
.alt{
  font-family:var(--sans);font-size:var(--t-m);
  padding:var(--s2) var(--s3);
  background:none;color:var(--body);
  border:1px solid var(--hair);border-radius:var(--r-ctl);cursor:pointer;
}
.alt:hover{border-color:var(--rule);}
#actwhy{font-size:var(--t-s);color:var(--amber);}
#actwhy:empty{display:none;}
#actnote{margin-left:auto;font-size:var(--t-xs);color:var(--faint);text-align:right;}

/* ---------------------------------------------------------- the status bar */
#stat{
  grid-area:stat;
  display:flex;align-items:center;gap:var(--s3);
  padding:0 var(--s3);
  background:var(--panel-2);
  border-top:1px solid var(--hair);
  font-size:var(--t-xs);color:var(--mute);
}
#statr{margin-left:auto;display:flex;gap:var(--s3);}
kbd{
  font-family:var(--mono);font-size:var(--t-xs);
  padding:0 var(--s1);
  border:1px solid var(--hair);border-radius:var(--r-ctl);
  background:var(--panel);color:var(--faint);
}

/* ------------------------------------------------- the sheet: the opt-in log */
#sheet{
  position:fixed;inset:0;display:none;
  background:rgba(11,16,32,.28);
}
#sheet[data-open="1"]{display:block;}
#shpanel{
  position:absolute;right:0;top:0;bottom:0;width:min(560px,92vw);
  display:flex;flex-direction:column;
  background:var(--panel);border-left:1px solid var(--hair);
}
#shhd{
  display:flex;align-items:center;gap:var(--s2);
  padding:var(--s3);border-bottom:1px solid var(--hair);
}
#shhd h2{margin:0;font-size:var(--t-l);font-weight:600;color:var(--strong);}
#shhd .sub{font-size:var(--t-s);color:var(--mute);}
#shbody{overflow-y:auto;flex:1;min-height:0;padding:var(--s3);}
.step{
  display:grid;grid-template-columns:auto 1fr auto;gap:var(--s2);
  padding:var(--s2) 0;border-bottom:1px solid var(--hair-soft);
}
.step .t{font-family:var(--mono);font-size:var(--t-s);color:var(--faint);}
.step .w{color:var(--body);font-size:var(--t-s);}
.step .r{font-family:var(--mono);font-size:var(--t-s);color:var(--mute);text-align:right;}
.step .r.miss{color:var(--amber);}

/* ---------------------------------------------------------- the reason dialog
   arm -> written reason -> confirm. Nothing sends on one click, and the reason
   is stored next to the name. */
#why{position:fixed;inset:0;display:none;align-items:center;justify-content:center;background:rgba(11,16,32,.28);}
#why[data-open="1"]{display:flex;}
#whybox{
  width:min(520px,92vw);
  background:var(--panel);border:1px solid var(--hair);border-radius:var(--r-card);
  padding:var(--s4);
}
#whybox h3{margin:0 0 var(--s1);font-size:var(--t-l);font-weight:600;color:var(--strong);}
#whybox .cons{margin:0 0 var(--s3);font-size:var(--t-s);color:var(--mute);}
#whybox label{display:block;font-size:var(--t-s);color:var(--mute);margin-bottom:var(--s1);}
#whybox textarea{
  width:100%;min-height:88px;resize:vertical;
  font-family:var(--sans);font-size:var(--t-m);
  padding:var(--s2);
  background:var(--field);border:1px solid var(--hair);border-radius:var(--r-ctl);
  color:var(--body);
}
#whybox textarea:focus{border-color:var(--accent);}
#whyc{margin-top:var(--s1);font-size:var(--t-xs);color:var(--faint);}
#whyc.short{color:var(--amber);}
#whybtns{display:flex;align-items:center;gap:var(--s2);margin-top:var(--s3);}
.seatnote{margin-left:auto;font-size:var(--t-xs);color:var(--faint);text-align:right;}

/* ------------------------------------------------------ the command palette */
#pal{position:fixed;inset:0;display:none;align-items:flex-start;justify-content:center;background:rgba(11,16,32,.28);}
#pal[data-open="1"]{display:flex;}
#palbox{
  width:min(560px,92vw);margin-top:12vh;
  background:var(--panel);border:1px solid var(--hair);border-radius:var(--r-card);
  overflow:hidden;
}
#palq{
  width:100%;font-family:var(--sans);font-size:var(--t-l);
  padding:var(--s3);
  background:none;border:0;border-bottom:1px solid var(--hair);color:var(--body);
}
#pallist{max-height:44vh;overflow-y:auto;}
.pitem{padding:var(--s2) var(--s3);cursor:pointer;display:flex;gap:var(--s2);align-items:baseline;}
.pitem[aria-selected="true"]{background:var(--accent-wash);}
.pitem .pk{font-family:var(--mono);font-size:var(--t-xs);color:var(--faint);}
.pitem .pt{font-size:var(--t-m);color:var(--body);}
.pitem .pd{margin-left:auto;font-size:var(--t-xs);color:var(--faint);}
#palhint{display:flex;gap:var(--s3);padding:var(--s2) var(--s3);border-top:1px solid var(--hair-soft);font-size:var(--t-xs);color:var(--faint);}

#toast{
  position:fixed;left:50%;bottom:var(--s4);transform:translateX(-50%);
  display:none;padding:var(--s2) var(--s4);
  background:var(--strong);color:var(--panel);
  border-radius:var(--r-ctl);font-size:var(--t-s);
}
#toast[data-open="1"]{display:block;}

/* A three-column console does not fold into a phone. It says so rather than
   collapsing into something nobody can work in. */
#small{display:none;padding:var(--s4);}
#small h2{font-size:var(--t-l);color:var(--strong);margin:0 0 var(--s2);}
#small p{font-size:var(--t-s);color:var(--mute);}
@media (max-width:900px){
  #app{display:none;}
  #small{display:block;}
}
