/* ---------------------------------------------------------------------------
   The portal.

   Same tokens as docs/data-flow.html, because they describe the same system.
   The complete light palette lives on bare :root; the dark blocks redefine only
   those values, so no colour is ever defined solely behind a media query.

   Nothing here is set from JavaScript as an inline style: the page's CSP has no
   'unsafe-inline', and a stylesheet that can be enforced is worth the small
   discipline of saying everything in classes.
   --------------------------------------------------------------------------- */

:root{
  --ground:#EDF0EE;
  --paper:#F8FAF9;
  --raised:#FFFFFF;
  --ink:#121A17;
  --ink-2:#39443F;
  --muted:#6B7872;
  --line:#D3DAD6;
  --line-strong:#B4BFB9;
  --accent:#2C6A5D;
  --accent-ink:#22564B;
  --accent-soft:#DEEAE5;
  --oxide:#A2472A;
  --oxide-soft:#F1E1D9;
  /* The one hue that is neither the accent nor the alarm: a source switched off
     on purpose. It has to read as "somebody did this" at a glance, and the
     greens and the oxide are both already spoken for. */
  --held:#4A5A78;
  --held-soft:#E2E7EF;
  --shadow:0 1px 2px rgba(18,26,23,.05), 0 6px 18px -12px rgba(18,26,23,.22);
  --radius:3px;
  --topbar-h:3.6rem;
  color-scheme:light;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ground:#0F1513;
    --paper:#161E1B;
    --raised:#1C2523;
    --ink:#E0E7E3;
    --ink-2:#B0BCB6;
    --muted:#7C8A84;
    --line:#28332F;
    --line-strong:#3B4A45;
    --accent:#6FC0AA;
    --accent-ink:#8ED2BE;
    --accent-soft:#1A2D28;
    --oxide:#DE8E6A;
    --oxide-soft:#33211A;
    --held:#93A7C8;
    --held-soft:#1B2231;
    --shadow:0 1px 2px rgba(0,0,0,.35), 0 8px 22px -14px rgba(0,0,0,.7);
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --ground:#0F1513;
  --paper:#161E1B;
  --raised:#1C2523;
  --ink:#E0E7E3;
  --ink-2:#B0BCB6;
  --muted:#7C8A84;
  --line:#28332F;
  --line-strong:#3B4A45;
  --accent:#6FC0AA;
  --accent-ink:#8ED2BE;
  --accent-soft:#1A2D28;
  --oxide:#DE8E6A;
  --oxide-soft:#33211A;
  --held:#93A7C8;
  --held-soft:#1B2231;
  --shadow:0 1px 2px rgba(0,0,0,.35), 0 8px 22px -14px rgba(0,0,0,.7);
  color-scheme:dark;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font-family:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  font-size:15px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4{font-family:Spectral,Georgia,"Times New Roman",serif;font-weight:600;margin:0;line-height:1.2;text-wrap:balance}
p{margin:0}
a{color:var(--accent-ink);text-underline-offset:3px;text-decoration-thickness:1px}
a:hover{color:var(--ink)}
code,.mono{font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace}
code{font-size:.86em;background:var(--accent-soft);color:var(--accent-ink);padding:.08em .34em;border-radius:2px;word-break:break-word}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;background:var(--accent);color:var(--raised);padding:.6rem 1rem;z-index:60}
.skip:focus{left:.5rem;top:.5rem}

.eyebrow{
  font-family:"IBM Plex Mono",ui-monospace,monospace;
  font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
}

kbd{
  font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:.72rem;
  border:1px solid var(--line-strong);border-bottom-width:2px;border-radius:3px;
  padding:.05em .35em;color:var(--ink-2);background:var(--raised);
}

/* --- top bar -------------------------------------------------------------- */
.topbar{
  position:sticky;top:0;z-index:40;
  height:var(--topbar-h);
  display:flex;align-items:center;gap:1rem;
  padding:0 clamp(.8rem,2vw,1.4rem);
  background:var(--paper);
  border-bottom:1px solid var(--line);
}
.brand{display:flex;align-items:center;gap:.55rem;flex:0 0 auto}
.brand-mark{
  width:.7rem;height:.7rem;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);
}
.brand-name{font-family:Spectral,Georgia,serif;font-size:1.06rem;font-weight:600;letter-spacing:-.01em}

.searchbox{position:relative;flex:1 1 auto;max-width:640px}
.searchbox input{
  width:100%;
  font:inherit;font-size:.95rem;
  padding:.5rem 2.2rem .5rem .8rem;
  color:var(--ink);background:var(--raised);
  border:1px solid var(--line-strong);border-radius:var(--radius);
}
.searchbox input::placeholder{color:var(--muted)}
.searchbox input:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px var(--accent-soft)}
.searchbox .hint{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);pointer-events:none}
.searchbox input:focus + .hint{opacity:0}

.topbar-right{display:flex;align-items:center;gap:.5rem;flex:0 0 auto;margin-left:auto}
select,.ghost{
  font:inherit;font-size:.85rem;
  color:var(--ink-2);background:var(--raised);
  border:1px solid var(--line-strong);border-radius:var(--radius);
  padding:.4rem .6rem;cursor:pointer;
}
select:hover,.ghost:hover{border-color:var(--accent);color:var(--ink)}
.ghost.icon{padding:.4rem .5rem;line-height:1}
.theme-glyph{display:block;width:.95rem;height:.95rem;border-radius:50%;border:1.5px solid currentColor;background:linear-gradient(90deg,currentColor 50%,transparent 50%)}
#filters-toggle{display:none}

/* --- shell ---------------------------------------------------------------- */
.shell{
  display:grid;
  grid-template-columns:250px minmax(340px,.95fr) minmax(0,1.15fr);
  align-items:start;
  height:calc(100vh - var(--topbar-h) - 2.2rem);
}
/* display:grid outranks the UA rule behind the hidden attribute, so a shell
   that is hidden must be told so here or both views show at once. */
.shell[hidden]{display:none}
.filters,.results,.reader{height:100%;overflow-y:auto;overscroll-behavior:contain}

/* --- filters -------------------------------------------------------------- */
.filters{background:var(--paper);border-right:1px solid var(--line)}
.filters-inner{padding:1.1rem clamp(.8rem,1.4vw,1.1rem) 3rem}
.facet + .facet,#facets .facet:first-child{margin-top:1.5rem}
.facet-title{
  font-family:"IBM Plex Mono",ui-monospace,monospace;
  font-size:.68rem;font-weight:500;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);margin-bottom:.55rem;
}
.facet-note{font-size:.76rem;color:var(--muted);line-height:1.5;margin-top:.5rem;text-wrap:pretty}

/* The ⓘ, and the row it shares with the title it belongs to. Sized off the
   title rather than off a finger: this is the smallest control on the screen
   because it is the least urgent one, and a column of them should read as
   punctuation down the margin, not as a second row of buttons competing with
   the chips. The note it opens grows a rule down its left edge — it appears
   below the chips, a few lines from the button that asked for it, and the rule
   is what says the two belong together. */
.facet-head{display:flex;align-items:center;gap:.4rem;margin-bottom:.55rem}
.facet-head .facet-title{margin-bottom:0}
.facet-info{
  flex:0 0 auto;display:grid;place-items:center;
  width:1.05rem;height:1.05rem;padding:0;
  font-family:"IBM Plex Mono",ui-monospace,monospace;
  font-size:.64rem;line-height:1;
  color:var(--muted);background:none;
  border:1px solid var(--line);border-radius:50%;cursor:pointer;
}
.facet-info:hover{color:var(--accent-ink);border-color:var(--accent)}
.facet-info[aria-expanded="true"]{
  color:var(--raised);background:var(--accent);border-color:var(--accent);
}
.facet-note.foldable{border-left:2px solid var(--line);padding-left:.55rem}

.chips{display:flex;flex-wrap:wrap;gap:.3rem}
.chip{
  font:inherit;font-size:.78rem;
  padding:.2rem .5rem;cursor:pointer;
  color:var(--ink-2);background:var(--raised);
  border:1px solid var(--line);border-radius:999px;
}
.chip:hover{border-color:var(--accent)}
.chip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--raised)}

/* The two pay floors. A number box rather than a chip, because a threshold has
   no list of values to offer — and it is styled off the search field above so
   the one other place in this page that takes typing looks like this one. */
.pay{display:grid;gap:.4rem}
.pay-field{display:grid;gap:.2rem}
.pay-label{font-size:.78rem;color:var(--ink-2)}
.pay-entry{display:flex;align-items:center;gap:.4rem}
.pay-entry input{
  font:inherit;font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.8rem;font-variant-numeric:tabular-nums;
  flex:1 1 auto;min-width:0;width:100%;
  padding:.28rem .45rem;
  color:var(--ink);background:var(--raised);
  border:1px solid var(--line);border-radius:2px;
}
.pay-entry input::placeholder{color:var(--muted)}
.pay-entry input:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px var(--accent-soft)}
.pay-unit{flex:0 0 auto;font-size:.74rem;color:var(--muted);white-space:nowrap}

.facet-list{list-style:none;margin:0;padding:0}
.facet-list li + li{margin-top:1px}
.facet-opt{
  display:flex;align-items:baseline;gap:.5rem;width:100%;
  font:inherit;font-size:.83rem;text-align:left;
  padding:.22rem .4rem;cursor:pointer;
  color:var(--ink-2);background:none;border:0;border-radius:var(--radius);
}
.facet-opt:hover{background:var(--accent-soft);color:var(--accent-ink)}
.facet-opt[aria-pressed="true"]{background:var(--accent-soft);color:var(--accent-ink);font-weight:500}
.facet-opt[aria-pressed="true"] .facet-label::before{content:"× ";font-family:"IBM Plex Mono",monospace}
.facet-label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.facet-count{
  flex:0 0 auto;font-family:"IBM Plex Mono",monospace;font-size:.72rem;
  color:var(--muted);font-variant-numeric:tabular-nums;
}
.facet-more{
  font:inherit;font-size:.75rem;color:var(--accent-ink);background:none;border:0;
  padding:.25rem .4rem;cursor:pointer;text-decoration:underline;text-underline-offset:2px;
}

#coverage-panel{
  margin-top:1.9rem;padding-top:1.3rem;
  border-top:1px solid var(--line);
}
.coverage{list-style:none;margin:.55rem 0 0;padding:0;font-size:.78rem}
.coverage li{display:flex;align-items:center;gap:.5rem;padding:.12rem 0;color:var(--ink-2)}
.coverage .cov-label{flex:1 1 auto}
.coverage .cov-share{font-family:"IBM Plex Mono",monospace;font-size:.72rem;color:var(--muted);font-variant-numeric:tabular-nums}
.coverage progress{flex:0 0 3.2rem;height:.3rem;appearance:none;border:0;background:var(--line);border-radius:2px;overflow:hidden}
.coverage progress::-webkit-progress-bar{background:var(--line)}
.coverage progress::-webkit-progress-value{background:var(--accent)}
.coverage progress::-moz-progress-bar{background:var(--accent)}
.coverage li.empty .cov-label{color:var(--muted)}
.coverage li.empty .cov-share{color:var(--oxide)}

/* --- results -------------------------------------------------------------- */
.results{border-right:1px solid var(--line);background:var(--ground)}
.results-head{
  position:sticky;top:0;z-index:10;
  background:var(--ground);border-bottom:1px solid var(--line);
  padding:.7rem clamp(.8rem,1.4vw,1.1rem) .6rem;
  /* A head that is stuck to the top is a head the list can never scroll out of
     the way, so it is not allowed to grow without limit: past this it scrolls
     inside itself and the postings keep their half of the column. */
  max-height:50vh;overflow-y:auto;overscroll-behavior:contain;
}
.count{font-size:.8rem;color:var(--muted);font-variant-numeric:tabular-nums}
.count b{color:var(--ink);font-weight:600}
.applied{display:flex;flex-wrap:wrap;gap:.3rem;margin-top:.5rem}
.applied:empty{display:none}
.applied .chip{background:var(--accent-soft);border-color:var(--accent-soft);color:var(--accent-ink)}
.applied .chip::after{content:" ×";font-family:"IBM Plex Mono",monospace}
.applied .chip.clear{background:none;border-color:var(--line-strong);color:var(--muted)}
.applied .chip.clear::after{content:""}

/* --- where a mission came from ------------------------------------------
   One rule, where there were twenty-two.
   .perimeter-band and its headline, eyebrow, criteria chip, hidden count,
   picker and refusal line existed to confess what a filter had removed. The
   per-verdict box in the reader, its four border colours, its test list and the
   two row badges existed to argue a verdict test by test. Nothing is removed
   and nothing is judged now: a perimeter is where a mission came from, it is
   chosen in the sidebar like a country, and the row says which one found it. */
.tag.origin{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-soft)}

/* Where the mission came from, in the reader: the perimeters that brought it in
   and the question each one asked. One neutral border and no colour scale,
   because there is nothing here to rank — a provenance is not a grade. */
.origin-box{
  margin:1rem 0;padding:.7rem .8rem;
  border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:var(--radius);background:var(--paper);
}
.origin-title{
  font-family:"IBM Plex Mono",monospace;font-size:.68rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);
}
.origin-list{list-style:none;margin-top:.55rem;display:grid;gap:.15rem}
.origin-row{
  display:flex;justify-content:space-between;gap:1rem;
  font-size:.76rem;padding:.15rem 0;border-bottom:1px dotted var(--line);
}
.origin-name{color:var(--ink-2)}
.origin-question{font-family:"IBM Plex Mono",monospace;color:var(--muted);text-align:right}

/* While a search is in flight. Enough to read as "working", not enough to
   make the list unreadable — the previous results stay legible underneath. */
.results.busy .list{opacity:.4;transition:opacity .12s ease-out}
.results.busy .count::after{
  content:" · searching…";color:var(--accent-ink);
}

.list{list-style:none;margin:0;padding:0}
.row{
  display:block;width:100%;text-align:left;
  font:inherit;color:inherit;background:var(--paper);
  border:0;border-bottom:1px solid var(--line);border-left:2px solid transparent;
  padding:.7rem clamp(.8rem,1.4vw,1.1rem);cursor:pointer;
}
.row:hover{background:var(--raised)}
.row[aria-current="true"]{background:var(--raised);border-left-color:var(--accent)}
.row.cursor{box-shadow:inset 0 0 0 1px var(--accent-soft)}
.row-title{
  font-family:Spectral,Georgia,serif;font-size:1.02rem;font-weight:600;
  line-height:1.25;color:var(--ink);margin-bottom:.18rem;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.row-company{font-size:.83rem;color:var(--ink-2)}
.row-company .sep{color:var(--line-strong);padding:0 .35rem}
.row-meta{
  display:flex;flex-wrap:wrap;align-items:center;gap:.45rem;margin-top:.4rem;
  font-family:"IBM Plex Mono",monospace;font-size:.7rem;color:var(--muted);
}
.tag{border:1px solid var(--line);border-radius:2px;padding:.02em .3em}
.tag.remote{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-soft)}
/* A stated absence, not a value. Same weight as the row's other facts so it is
   read, no border so it never competes with a figure that is actually there. */
.tag.unstated{border-color:transparent;color:var(--muted);font-style:italic;padding-left:0}
.age{display:inline-flex;align-items:center;gap:.3rem}
.age::before{content:"";width:.4rem;height:.4rem;border-radius:50%;background:var(--line-strong)}
.age.new::before{background:var(--accent)}
.age.week::before{background:var(--accent);opacity:.55}
.age.old::before{background:var(--oxide);opacity:.5}

.list-foot{padding:1.2rem;text-align:center}
.more{
  font:inherit;font-size:.85rem;padding:.45rem 1.1rem;cursor:pointer;
  color:var(--accent-ink);background:var(--raised);
  border:1px solid var(--line-strong);border-radius:var(--radius);
}
.more:hover{border-color:var(--accent)}
/* A button with nothing to do says so, rather than answering a press with
   silence. Used by Save the reason, which is disabled exactly when what is in
   the field is what the record already holds. */
.more:disabled{cursor:default;color:var(--muted);border-color:var(--line)}
.more:disabled:hover{border-color:var(--line)}
.end{font-size:.75rem;color:var(--muted)}

.blank{padding:3rem 1.5rem;text-align:center;color:var(--muted)}
.blank h2{font-size:1.15rem;color:var(--ink);margin-bottom:.4rem}
.blank p{font-size:.85rem;max-width:34ch;margin:0 auto;text-wrap:pretty}

/* --- reader --------------------------------------------------------------- */
.reader{background:var(--raised)}
.reader-empty{padding:clamp(2rem,6vh,4rem) clamp(1.2rem,3vw,2.4rem);max-width:44ch}
.reader-empty-lede{font-family:Spectral,Georgia,serif;font-size:1.3rem;color:var(--ink-2);margin:.5rem 0 1.6rem}
.keys{display:grid;grid-template-columns:auto 1fr;gap:.5rem .9rem;font-size:.83rem;color:var(--muted);margin:0}
.keys dt{text-align:right}
.keys dd{margin:0}

.reader-head{
  position:sticky;top:0;z-index:10;
  background:var(--raised);border-bottom:1px solid var(--line);
  padding:1.1rem clamp(1.2rem,2.4vw,2rem) .9rem;
}
.reader-head h1{font-size:clamp(1.3rem,1.05rem + .7vw,1.75rem);letter-spacing:-.01em}
.reader-sub{margin-top:.35rem;font-size:.92rem;color:var(--ink-2)}
.reader-sub b{font-weight:600;color:var(--ink)}
.reader-actions{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.9rem}
.apply{
  font:inherit;font-size:.85rem;font-weight:500;text-decoration:none;
  padding:.42rem .95rem;border-radius:var(--radius);
  color:var(--raised);background:var(--accent);border:1px solid var(--accent);
}
.apply:hover{background:var(--accent-ink);border-color:var(--accent-ink);color:var(--raised)}
.linkish{
  font:inherit;font-size:.85rem;text-decoration:none;
  padding:.42rem .8rem;border-radius:var(--radius);
  color:var(--ink-2);background:var(--paper);border:1px solid var(--line-strong);
}
.linkish:hover{border-color:var(--accent);color:var(--accent-ink)}
.reader-close{display:none}

/* --- marks: what I did with a posting, and what I made of it ---------------
   The thumbs sit under the apply link, in the sticky head, because they are the
   same kind of act and a long advert would otherwise bury two of the three.
   The oxide is the alarm hue everywhere else in this file and it is right here
   too: a thumb down is not an error, but it is the one that says "no". */
.marks{margin-top:.75rem;display:flex;flex-direction:column;gap:.5rem}
.thumbs{display:flex;gap:.4rem}
.thumb{
  font:inherit;font-size:.8rem;cursor:pointer;display:inline-flex;align-items:center;gap:.4rem;
  padding:.34rem .7rem;border-radius:var(--radius);
  color:var(--ink-2);background:var(--paper);border:1px solid var(--line-strong);
}
.thumb:hover{border-color:var(--accent);color:var(--accent-ink)}
.thumb-glyph{font-family:"IBM Plex Mono",monospace;font-size:.72rem;line-height:1}
.thumb-up[aria-pressed="true"]{
  background:var(--accent-soft);border-color:var(--accent);color:var(--accent-ink);
}
.thumb-down:hover{border-color:var(--oxide);color:var(--oxide)}
.thumb-down[aria-pressed="true"]{
  background:var(--oxide-soft);border-color:var(--oxide);color:var(--oxide);
}
.reason{display:flex;flex-wrap:wrap;gap:.4rem;align-items:flex-start}
/* Same trap as .shell above: display:flex outranks the UA rule behind hidden. */
.reason[hidden]{display:none}
.reason-field{
  flex:1 1 18rem;font:inherit;font-size:.83rem;line-height:1.45;resize:vertical;
  padding:.4rem .55rem;border-radius:var(--radius);
  color:var(--ink);background:var(--raised);border:1px solid var(--line-strong);
}
.reason-field:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px var(--accent-soft)}
.mark-state{font-size:.74rem;color:var(--muted);line-height:1.5;text-wrap:pretty}
.mark-state:empty{display:none}
.mark-failed{color:var(--oxide)}

/* The badge on the list row. A marked row is dimmed rather than removed: the
   filter is what removes it, and it does so at the next search. */
.row.marked .row-title{color:var(--ink-2)}
.row-marks{display:inline-flex;gap:.3rem}
.mark{border:1px solid var(--line);border-radius:2px;padding:.02em .3em}
.mark-visited{border-color:var(--held);color:var(--held);background:var(--held-soft)}
.mark-up{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-soft)}
.mark-down{border-color:var(--oxide);color:var(--oxide);background:var(--oxide-soft)}

.reader-scroll{padding:1.2rem clamp(1.2rem,2.4vw,2rem) 4rem}

.spec{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:.1rem 1.4rem;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:.9rem 0;margin-bottom:1.6rem;
}
.spec div{padding:.2rem 0}
.spec dt{font-family:"IBM Plex Mono",monospace;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.spec dd{margin:.1rem 0 0;font-size:.88rem;color:var(--ink)}
.spec dd.unstated{color:var(--muted);font-style:italic}

.spec + .facet-note{margin:-.9rem 0 1.7rem;padding-bottom:.1rem}

.advert{max-width:70ch;font-size:.95rem;line-height:1.68;color:var(--ink-2)}
.advert h3,.advert h4,.advert h5,.advert h6{
  font-family:Spectral,Georgia,serif;color:var(--ink);
  margin:1.7rem 0 .5rem;font-size:1.08rem;
}
.advert p{margin:0 0 .95rem}
.advert ul,.advert ol{margin:0 0 1.05rem;padding-left:1.3rem}
.advert li{margin:.25rem 0}
.advert strong{color:var(--ink);font-weight:600}
.advert blockquote{
  margin:0 0 1rem;padding:.2rem 0 .2rem 1rem;
  border-left:2px solid var(--line-strong);color:var(--muted);font-style:italic;
}
.advert hr{border:0;border-top:1px solid var(--line);margin:1.6rem 0}
.advert a{word-break:break-word}

.provenance{
  margin-top:2.5rem;padding-top:1rem;border-top:1px solid var(--line);
  font-family:"IBM Plex Mono",monospace;font-size:.72rem;color:var(--muted);
  display:grid;grid-template-columns:auto 1fr;gap:.25rem .9rem;
}
.provenance dt{color:var(--line-strong)}
.provenance dd{margin:0;word-break:break-all}

/* --- footer --------------------------------------------------------------- */
.footer{
  height:2.2rem;display:flex;align-items:center;
  padding:0 clamp(.8rem,2vw,1.4rem);
  border-top:1px solid var(--line);background:var(--paper);
  font-family:"IBM Plex Mono",monospace;font-size:.7rem;color:var(--muted);
  white-space:nowrap;overflow-x:auto;overflow-y:hidden;
}
.footer code{font-size:.95em;background:none;color:var(--muted);padding:0}

/* --- narrow --------------------------------------------------------------- */
@media (max-width:1080px){
  .shell{grid-template-columns:220px minmax(0,1fr);height:auto}
  .filters,.results{height:calc(100vh - var(--topbar-h) - 2.2rem)}
  .reader{
    position:fixed;inset:var(--topbar-h) 0 0;z-index:50;
    height:auto;border-left:1px solid var(--line);
  }
  .reader[hidden]{display:none}
  .reader-empty{display:none}
  .reader-close{display:inline-block}
}

@media (max-width:760px){
  /* The search box is the point of the page; it gets its own row rather than
     the sliver left over between the sort control and the filters button. */
  :root{--topbar-h:6.1rem}
  .topbar{
    height:var(--topbar-h);
    flex-wrap:wrap;align-content:center;gap:.5rem .6rem;
  }
  .searchbox{order:3;flex:1 1 100%;max-width:none}
  .brand-name{display:none}
  #filters-toggle{display:inline-block}

  .shell{grid-template-columns:1fr}
  .filters{
    position:fixed;inset:var(--topbar-h) 0 0;z-index:45;
    border-right:0;height:auto;
  }
  .filters[hidden]{display:none}
  .results{height:calc(100vh - var(--topbar-h) - 2.2rem)}
  .reader{inset:var(--topbar-h) 0 0}
  select{max-width:9.5rem}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none !important;transition:none !important;scroll-behavior:auto !important}
}

/* ---------------------------------------------------------------------------
   Criteria — M-01. The one screen that writes.
   --------------------------------------------------------------------------- */

.views{display:flex;gap:.15rem;flex:0 0 auto;padding:.15rem;background:var(--ground);border:1px solid var(--line);border-radius:var(--radius)}
.view-tab{
  font:inherit;font-size:.82rem;
  padding:.28rem .7rem;cursor:pointer;
  color:var(--muted);background:none;border:0;border-radius:2px;
}
.view-tab:hover{color:var(--ink)}
.view-tab[aria-current="true"]{background:var(--raised);color:var(--ink);font-weight:500;box-shadow:var(--shadow)}

/* On the criteria screen the search box and the sort control have nothing to
   act on, so they step aside rather than sitting there inert. */
/* The search box and the sort act on the postings and nothing else, so they
   step aside elsewhere. The nav sits beside the brand rather than after the
   search box, so hiding it cannot make the tabs jump sideways. */
body:not([data-view="postings"]) .searchbox,
body:not([data-view="postings"]) #sort,
body:not([data-view="postings"]) #filters-toggle{display:none}

.shell-criteria{grid-template-columns:290px minmax(0,1fr)}
.shell-criteria[hidden]{display:none}

.crit-index{height:100%;overflow-y:auto;background:var(--paper);border-right:1px solid var(--line);padding:1.1rem 1rem 3rem}
.crit-index-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.7rem}
.crit-index-head .facet-title{margin:0}
.crit-index-head .more{padding:.25rem .6rem;font-size:.78rem}

.crit-list{list-style:none;margin:0;padding:0}
.crit-list li + li{margin-top:2px}
.crit-item{
  display:flex;flex-direction:column;gap:.15rem;width:100%;text-align:left;
  font:inherit;padding:.5rem .6rem;cursor:pointer;
  color:var(--ink-2);background:var(--raised);
  border:1px solid var(--line);border-left:2px solid transparent;border-radius:var(--radius);
}
.crit-item:hover{border-color:var(--line-strong)}
.crit-item[aria-current="true"]{border-left-color:var(--accent);background:var(--accent-soft);color:var(--accent-ink)}
.crit-item-label{font-family:"IBM Plex Mono",monospace;font-size:.82rem;color:var(--ink);display:flex;align-items:center;gap:.4rem}
.crit-item[aria-current="true"] .crit-item-label{color:var(--accent-ink)}
.crit-off{font-size:.66rem;letter-spacing:.08em;text-transform:uppercase;color:var(--oxide);border:1px solid var(--oxide);border-radius:2px;padding:0 .25em}
.crit-item-meta{font-size:.72rem;color:var(--muted)}

.crit-editor{height:100%;overflow-y:auto;background:var(--raised);padding:1.4rem clamp(1.2rem,2.4vw,2.2rem) 4rem}
.crit-form{max-width:60ch;display:flex;flex-direction:column;gap:1.5rem}
.crit-field{display:flex;flex-direction:column;gap:.3rem}
.crit-label{
  font-family:"IBM Plex Mono",monospace;font-size:.68rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
}
.crit-field .facet-note{margin-top:0}

.crit-input{
  font:inherit;font-size:.9rem;
  padding:.42rem .6rem;
  color:var(--ink);background:var(--paper);
  border:1px solid var(--line-strong);border-radius:var(--radius);
  width:100%;
}
.crit-input:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px var(--accent-soft)}
.crit-input:disabled{opacity:.6;cursor:not-allowed}
.crit-notes{resize:vertical;line-height:1.55;font-size:.86rem}

.crit-check{display:flex;align-items:center;gap:.45rem;font-size:.88rem;color:var(--ink)}
.crit-check input{accent-color:var(--accent);width:1rem;height:1rem}

.tags{
  display:flex;flex-wrap:wrap;align-items:center;gap:.3rem;
  padding:.32rem .4rem;min-height:2.2rem;
  background:var(--paper);border:1px solid var(--line-strong);border-radius:var(--radius);
}
.tags:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.tag-chip{
  display:inline-flex;align-items:center;gap:.25rem;
  font-family:"IBM Plex Mono",monospace;font-size:.75rem;
  padding:.1rem .2rem .1rem .42rem;
  color:var(--accent-ink);background:var(--accent-soft);
  border:1px solid transparent;border-radius:2px;
}
.tag-x{
  font:inherit;font-size:.9rem;line-height:1;
  padding:0 .2rem;cursor:pointer;
  color:var(--accent-ink);background:none;border:0;opacity:.6;
}
.tag-x:hover{opacity:1;color:var(--oxide)}
.tag-input{
  flex:1 1 7rem;min-width:6rem;
  font:inherit;font-size:.82rem;
  padding:.12rem .2rem;
  color:var(--ink);background:none;border:0;
}
.tag-input:focus{outline:none}
.tag-input::placeholder{color:var(--muted)}

.crit-errors{
  list-style:none;margin:1.4rem 0 0;padding:.8rem 1rem;max-width:60ch;
  background:var(--oxide-soft);border-left:2px solid var(--oxide);border-radius:var(--radius);
  font-size:.84rem;color:var(--ink);
}
.crit-errors li + li{margin-top:.4rem}
.crit-errors[hidden]{display:none}

.crit-actions{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.8rem;max-width:60ch}
.crit-actions .apply:disabled{opacity:.45;cursor:not-allowed}
.crit-delete{color:var(--oxide);border-color:var(--oxide)}
.crit-delete:hover{background:var(--oxide-soft);color:var(--oxide);border-color:var(--oxide)}

@media (max-width:760px){
  .shell-criteria{grid-template-columns:1fr}
  .crit-index{height:auto;max-height:40vh;border-right:0;border-bottom:1px solid var(--line)}
  .crit-editor{height:auto}
  .shell-criteria{height:calc(100vh - var(--topbar-h) - 2.2rem);grid-template-rows:auto 1fr}
}


/* ---------------------------------------------------------------------------
   Sources — read-only. A rank is earned, never typed in.
   --------------------------------------------------------------------------- */

/* The index carries three chip rows and a slug, a name and three figures per
   row. At a fixed 300px every one of those wraps, so half the panel is spent on
   filters and five of forty sources are visible at once — on a wide screen it
   reads as a sliver beside a detail pane with room to spare. So the column takes
   a share of the window instead: never narrower than it was, never so wide that
   the source it is describing loses its own space. */
.shell-sources{
  grid-template-columns:clamp(300px,26vw,420px) minmax(0,1fr);
  grid-template-rows:auto auto minmax(0,1fr);
}

/* ---------------------------------------------------------------------------
   The monitor's header. Spans both columns because the tally is about the whole
   list, not about the pane beside it.
   --------------------------------------------------------------------------- */
.src-monitor{
  grid-column:1 / -1;
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.6rem 1.2rem;
  padding:.55rem 1rem;
  background:var(--paper);border-bottom:1px solid var(--line-strong);
}
.src-tally{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem .5rem}
.src-tally-item{
  display:inline-flex;align-items:baseline;gap:.32rem;
  padding:.12em .5em;border-radius:2px;border:1px solid var(--line-strong);
  font:inherit;font-size:.72rem;color:var(--ink-2);background:none;
  cursor:pointer;
}
.src-tally-item b{font-family:"IBM Plex Mono",monospace;font-size:.82rem;color:var(--ink)}
.src-tally-item:hover{border-color:currentColor}
/* The ring is drawn in the chip's own tone rather than in the accent, because
   the tone is already saying which condition this is and a second colour laid
   over it would be a third thing to read. The weight carries it for anyone who
   sees no ring at all, and aria-pressed carries it for anyone who sees none of
   this. */
.src-tally-item[aria-pressed="true"]{
  outline:2px solid currentColor;outline-offset:1px;font-weight:600;
}
.src-tally-all{color:var(--muted)}
.src-tally-all[aria-pressed="true"]{color:var(--ink-2)}
.src-asof{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;
  font-family:"IBM Plex Mono",monospace;font-size:.72rem;color:var(--muted);
}
.src-asof-clock{color:var(--ink-2)}
.src-asof-note{color:var(--muted)}
/* A reading that is two polls old is not "now", and the screen has to say so
   rather than let a frozen snapshot pass for the present. */
.src-asof.stale{color:var(--oxide)}
.src-asof.stale .src-asof-clock{color:var(--oxide);font-weight:600}

/* The six tones. Every one of them is carried by a WORD as well, because a
   colour alone is not a reason and cannot be read aloud. */
.tone-on{color:var(--accent-ink);border-color:var(--accent);background:var(--accent-soft)}
.tone-alarm{color:var(--oxide);border-color:var(--oxide);background:var(--oxide-soft)}
.tone-held{color:var(--held);border-color:var(--held);background:var(--held-soft)}
.tone-wait{color:var(--ink-2);border-color:var(--line-strong);background:var(--ground)}
.tone-off{color:var(--muted);border-color:var(--line-strong);background:var(--ground)}
.tone-none{color:var(--muted);border-color:var(--line)}

.src-index{height:100%;overflow-y:auto;background:var(--paper);border-right:1px solid var(--line)}
/* Across the window, not down the column. Both groups sit on one line at any
   width that gives the index its full 420px, and wrap to a second before they
   ever push the list down. */
.src-filters{
  grid-column:1 / -1;
  display:flex;flex-wrap:wrap;align-items:center;gap:.4rem 1.5rem;
  background:var(--paper);border-bottom:1px solid var(--line);
  padding:.5rem 1rem;
}
.src-filter{display:flex;flex-wrap:wrap;align-items:center;gap:.3rem .6rem}
.src-filter .facet-title{margin-bottom:0}

.src-list{list-style:none;margin:0;padding:.5rem .6rem 3rem}
.src-list li + li{margin-top:2px}
.src-item{
  display:flex;flex-direction:column;gap:.2rem;width:100%;text-align:left;
  font:inherit;padding:.5rem .6rem;cursor:pointer;
  color:var(--ink-2);background:var(--raised);
  border:1px solid var(--line);border-left:2px solid transparent;border-radius:var(--radius);
}
.src-item:hover{border-color:var(--line-strong)}
.src-item[aria-current="true"]{border-left-color:var(--accent);background:var(--accent-soft);color:var(--accent-ink)}
.src-item-head{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.src-slug{font-family:"IBM Plex Mono",monospace;font-size:.82rem;color:var(--ink)}
.src-item[aria-current="true"] .src-slug{color:var(--accent-ink)}
.src-item-name{font-size:.8rem;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.src-item-meta{
  display:flex;align-items:center;justify-content:space-between;gap:.5rem;
  font-family:"IBM Plex Mono",monospace;font-size:.7rem;color:var(--muted);
}
.src-count{color:var(--accent-ink)}

.src-state{
  flex:0 0 auto;
  font-family:"IBM Plex Mono",monospace;font-size:.63rem;letter-spacing:.08em;text-transform:uppercase;
  padding:.05em .35em;border-radius:2px;border:1px solid var(--line-strong);color:var(--muted);
}
.src-state.on{color:var(--accent-ink);border-color:var(--accent);background:var(--accent-soft)}
.src-state.pending{color:var(--muted)}
.src-state.off{color:var(--oxide);border-color:var(--oxide);background:var(--oxide-soft)}

/* The state column, demoted to the meta line: it is what the SOURCE chain
   wrote down, and the badge above it is whether anything is arriving. */
.src-item-state{text-transform:none;letter-spacing:0}
.src-item-state.on{color:var(--accent-ink)}
.src-item-state.off{color:var(--oxide)}

/* ---------------------------------------------------------------------------
   The condition, and the screens under it. The reason is prose and is given
   the width prose needs: this is the text the screen exists to show.
   --------------------------------------------------------------------------- */
.src-condition{
  max-width:74ch;padding:.85rem 1rem;border-radius:var(--radius);
  border:1px solid var(--line);border-left:3px solid var(--line-strong);background:var(--paper);
}
/* The tone classes above set colour and background for the small chips; the
   banner keeps the paper ground so a long sentence stays readable, and takes
   the tone on its edge instead. Stated per tone rather than left to the
   shorthand, which would otherwise win and leave every banner the same grey. */
.src-condition.tone-on{border-left-color:var(--accent)}
.src-condition.tone-alarm{border-left-color:var(--oxide)}
.src-condition.tone-held{border-left-color:var(--held)}
.src-condition.tone-wait{border-left-color:var(--line-strong)}
.src-condition.tone-off{border-left-color:var(--line-strong)}
.src-condition.tone-none{border-left-color:var(--line)}
.src-condition-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.6rem}
.src-condition-label{
  font-family:"IBM Plex Mono",monospace;font-size:.9rem;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:inherit;
}
.src-condition-group{
  font-family:"IBM Plex Mono",monospace;font-size:.68rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);
}
.src-condition-why{
  margin:.5rem 0 0;font-size:.9rem;line-height:1.6;color:var(--ink);text-wrap:pretty;
}
.src-condition-note{
  margin:.6rem 0 0;font-size:.78rem;line-height:1.55;color:var(--ink-2);
  padding-top:.55rem;border-top:1px dashed var(--line-strong);text-wrap:pretty;
}

.src-screen{
  max-width:74ch;margin-top:.8rem;padding:.8rem 1rem;
  background:var(--paper);border:1px solid var(--line);
  border-left:3px solid var(--line-strong);border-radius:var(--radius);
}
.src-screen.tone-on{border-left-color:var(--accent)}
.src-screen.tone-alarm{border-left-color:var(--oxide)}
.src-screen.tone-held{border-left-color:var(--held)}
.src-screen.tone-off{border-left-color:var(--oxide)}
.src-screen-head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.55rem}
.src-screen-name{
  font-family:"IBM Plex Mono",monospace;font-size:.86rem;font-weight:600;color:var(--ink);
}
.src-screen-mode{
  font-family:"IBM Plex Mono",monospace;font-size:.68rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line-strong);border-radius:2px;padding:.05em .35em;
}
.src-screen-verdict{
  margin-left:auto;font-family:"IBM Plex Mono",monospace;font-size:.7rem;
  letter-spacing:.06em;color:inherit;
}
.src-screen-why{margin:.45rem 0 0;font-size:.84rem;line-height:1.55;color:var(--ink);text-wrap:pretty}
.src-screen-sub{
  font-family:"IBM Plex Mono",monospace;font-size:.64rem;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
  margin:1rem 0 .2rem;
}
.src-screen .spec{margin-top:.7rem;margin-bottom:0}

/* L2's mandatory field, printed whole. It is never truncated and never reduced
   to a badge: the difference between a refusal on principle and a transport
   nobody has worked out yet is these sentences and nothing else. */
.src-reason,.src-notes{
  max-width:74ch;margin:.3rem 0 0;
  padding:.7rem .9rem;
  background:var(--raised);border:1px solid var(--line);border-radius:var(--radius);
  font-size:.85rem;line-height:1.6;color:var(--ink-2);text-wrap:pretty;
  white-space:pre-line;
}
.src-notes{border-left:2px solid var(--oxide)}
.spec .alarming{color:var(--oxide);font-weight:600}

.src-detail{height:100%;overflow-y:auto;background:var(--raised)}
.src-section{
  font-family:"IBM Plex Mono",monospace;font-size:.68rem;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
  margin:2rem 0 .3rem;
}
.src-detail .reader-scroll > .src-section:first-child{margin-top:0}
.src-detail .spec{margin-bottom:0}

.src-unranked{
  margin-top:1rem;padding:.7rem .9rem;max-width:70ch;
  background:var(--oxide-soft);border-left:2px solid var(--oxide);border-radius:var(--radius);
  font-size:.85rem;color:var(--ink);
}
.src-unranked strong{color:var(--oxide)}

/* §8 — written before the first request, and the reason the source may be read
   at all. It gets the room that importance deserves. */
.src-tos{
  max-width:70ch;margin-top:.6rem;
  padding:.9rem 1.1rem;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);
  font-size:.88rem;line-height:1.62;color:var(--ink-2);text-wrap:pretty;
}

@media (max-width:760px){
  .shell-sources{grid-template-columns:1fr;grid-template-rows:auto auto auto 1fr;height:calc(100vh - var(--topbar-h) - 2.2rem)}
  .src-index{height:auto;max-height:42vh;border-right:0;border-bottom:1px solid var(--line)}
  .src-detail{height:auto}
}

/* The score breakdown is a table, so it is one. Wide content scrolls inside
   its own box rather than pushing the page sideways. */
.src-table-scroll{max-width:100%;overflow-x:auto;margin-top:.6rem}
.src-table{border-collapse:collapse;font-size:.8rem;min-width:44rem;width:100%}
.src-table th,.src-table td{
  text-align:left;padding:.4rem .7rem .4rem 0;
  border-bottom:1px solid var(--line);vertical-align:baseline;
}
.src-table thead th{
  font-family:"IBM Plex Mono",monospace;font-size:.66rem;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);
  border-bottom-color:var(--line-strong);
}
.src-table tbody th{font-weight:500;color:var(--ink);white-space:nowrap}
.src-table td{color:var(--ink-2)}
.src-table .num{font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;white-space:nowrap}
.src-table .num.strong{color:var(--ink);font-weight:500}
.src-table .scale{font-family:"IBM Plex Mono",monospace;font-size:.74rem;color:var(--muted);white-space:nowrap}
.src-table tr.na th{color:var(--muted);font-weight:400}
.src-table .src-na{color:var(--muted);font-style:italic}
.src-table-scroll .spec{margin-top:1rem;border-bottom:0}

/* The one control on the sources page (D-27). It sits with the source's own
   link rather than anywhere prominent: this page is a monitor, and the switch
   is the single thing on it that changes anything. */
.src-switch-wrap{display:inline-flex;flex-direction:column;gap:.25rem}
.src-switch{
  font:inherit;font-size:.78rem;padding:.25rem .7rem;cursor:pointer;
  color:var(--oxide);background:var(--oxide-soft);
  border:1px solid var(--oxide);border-radius:var(--radius);
}
/* Switching one back ON is not an alarm, so it does not wear the alarm colour. */
.src-switch.on{color:var(--accent-ink);background:var(--accent-soft);border-color:var(--accent)}
.src-switch-error{margin:0;font-size:.75rem;color:var(--oxide)}
