/* CurveNumber interface.
   A tool, scanned and operated rather than read top to bottom, so the craft
   goes into information design: the delta is the hero, the method badge and
   provenance are always visible rather than buried, and the defaults that
   matter are ranked rather than listed. */

:root {
  --ground: #f5f4f0;
  --surface: #ffffff;
  --sunk: #efeee8;
  --line: #dfdcd3;
  --line-strong: #c6c2b6;
  --ink: #1e2320;
  --ink-mid: #5a5f58;
  --ink-soft: #82867d;
  --accent: #26696c;
  --accent-soft: #e2edec;
  --accent-line: #9dc2c1;
  --ochre: #9c5f2b;
  --ochre-soft: #f3e7db;
  --ochre-line: #d6ac83;
  --red: #9b3226;
  --red-soft: #f7e4e1;
  --shadow: 0 1px 2px rgba(30,35,32,.05), 0 4px 14px rgba(30,35,32,.05);
  /* MapLibre ships black control glyphs as background images, so the only way
     to make them legible on a dark surface is to invert them. */
  --mlfilter: none;
  /* The diagonal hatch stripes. They are one of the four channels that keeps
     retention, filtration and detention apart, so they have their own tokens
     rather than borrowing --ochre-soft: that token is a fill meant to sit
     under text and is nearly invisible as a stripe on the dark surface.
     There are two because there are now three destinations to tell apart:
     filtration takes the first at 45 degrees and detention takes the second
     at minus 45, and two hatches at opposite diagonals read as two different
     textures where two shades of one colour would not. */
  --hatch: #f0dfd0;
  --hatch2: #f4dcd7;
  /* The fourth destination. Water somebody drew out and used is neither
     runoff nor recharge, so it needed a fourth value on every channel rather
     than a legend: its own colour here, its own rule and its own fill below.
     A stipple rather than a third diagonal, because two hatches at opposite
     diagonals and a third at some other angle read as one texture family,
     and dots do not. */
  --use: #3d5a99;
  --use-soft: #e6eaf4;
  --use-line: #9fb0d4;
  --stipple: #cfd8ea;
  --sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --serif: "Source Serif 4", Georgia, serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #151917; --surface: #1d2220; --sunk: #262b28;
    --line: #333935; --line-strong: #4a514c;
    --ink: #e9e7e0; --ink-mid: #a8ada4; --ink-soft: #848a80;
    --accent: #5fafb0; --accent-soft: #1e3234; --accent-line: #356f71;
    --ochre: #d3924f; --ochre-soft: #33261a; --ochre-line: #7a5730;
    --red: #d98276; --red-soft: #331e1b;
    --hatch: rgba(211,146,79,.22);
    --hatch2: rgba(217,130,118,.22);
    --use: #8ba6e0; --use-soft: #1c2436; --use-line: #41548a;
    --stipple: rgba(139,166,224,.30);
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 14px rgba(0,0,0,.25);
    --mlfilter: invert(1) brightness(.92);
  }
}
:root[data-theme="dark"] {
  --ground: #151917; --surface: #1d2220; --sunk: #262b28;
  --line: #333935; --line-strong: #4a514c;
  --ink: #e9e7e0; --ink-mid: #a8ada4; --ink-soft: #848a80;
  --accent: #5fafb0; --accent-soft: #1e3234; --accent-line: #356f71;
  --ochre: #d3924f; --ochre-soft: #33261a; --ochre-line: #7a5730;
  --red: #d98276; --red-soft: #331e1b;
  --hatch: rgba(211,146,79,.22);
  --hatch2: rgba(217,130,118,.22);
  --use: #8ba6e0; --use-soft: #1c2436; --use-line: #41548a;
  --stipple: rgba(139,166,224,.30);
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 4px 14px rgba(0,0,0,.25);
  --mlfilter: invert(1) brightness(.92);
}

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--ground); color: var(--ink);
  font-family: var(--sans); font-size: 14px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
[hidden] { display: none !important; }

/* ---------- shell ----------

   A grid item's automatic minimum size is its content, so `min-width: 0` on
   both rows is what stops one wide thing anywhere inside the tool setting a
   floor under the whole page. Without it the header's eight nav buttons set a
   505 px floor that `body` inherited, and the entire tool scrolled sideways
   at phone width with the left half of every line off screen -- on a product
   whose marketing site is exact at 400 px and whose first button says "Open
   the tool". */
.app { display: grid; grid-template-rows: auto 1fr; height: 100vh; }
.app > * { min-width: 0; }
header {
  display: flex; align-items: center; gap: 1.25rem;
  padding: .7rem 1.25rem; background: var(--surface);
  border-bottom: 1px solid var(--line);
  /* Wrap unconditionally rather than only under the breakpoint below. The
     breakpoint moves the layout deliberately; this is the guarantee that no
     future nav entry, no translation and no wider font can push the page
     sideways again between breakpoints. */
  flex-wrap: wrap;
}
.brand { font-family: var(--serif); font-weight: 700; font-size: 1.15rem; letter-spacing: -.01em; }
.brand span { color: var(--accent); }
nav { display: flex; flex-wrap: wrap; gap: .25rem; margin-left: auto; min-width: 0; }
nav button {
  font-family: var(--sans); font-size: 13px; color: var(--ink-mid);
  background: none; border: 1px solid transparent; padding: .35rem .7rem;
  border-radius: 2px; cursor: pointer;
}
nav button:hover { background: var(--sunk); color: var(--ink); }
nav button[aria-current="true"] { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.acct { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }

/* Below the width at which the brand, eight tabs, the theme toggle and the
   account chip fit on one line, the tabs take a line of their own. They are
   not collapsed behind a button: every one of them is a place a user may be
   mid-task in, and a tool whose navigation is hidden on the device somebody
   is standing in a field with is a tool they close. */
@media (max-width: 900px) {
  header { gap: .35rem .6rem; padding: .55rem .75rem; }
  .brand { margin-right: auto; }
  nav { order: 4; width: 100%; margin-left: 0; gap: .2rem; }
  nav button { padding: .3rem .55rem; font-size: 12.5px; }
}

/* `overflow: auto` and NOT `overflow-x: hidden`. Hiding the overflow would
   make this measurement read clean while clipping the right hand end off
   every wide table in the tool, which is a worse defect than the scroll bar
   and an invisible one. Anything genuinely wider than the screen gets its own
   scrolling container instead; see .scrollx below. */
main { overflow: auto; padding: 1.25rem; min-width: 0; scroll-padding-top: 1rem; }
.wrap { max-width: 1280px; margin: 0 auto; min-width: 0; }

/* `main` is the scroll container and the header sits above it, so a
   `scrollIntoView({block: "start"})` -- which estimates.js, practice.js,
   greenroof.js and admin.js all use to raise the thing they just opened --
   lands the element flush against the header's underside with no breathing
   room, and its first row reads as cut in half. `scroll-padding-top` on the
   container fixes every one of those at once, including the ones nobody has
   written yet; `scroll-margin-top` on the panels covers an element scrolled
   by a container other than `main`. This is placement, not decoration: the
   first row of the assistant panel is the allowance, which is the number that
   tells a user what a question is about to cost them. */
.panel, section[id^='view-'] { scroll-margin-top: 1rem; }
@media (max-width: 640px) {
  main { padding: .75rem; }
}

/* ---------- panels ---------- */
.panel { background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow); margin-bottom: 1rem; }
.panel > h2 {
  font-family: var(--serif); font-size: 1.05rem; font-weight: 600; margin: 0;
  padding: .75rem 1rem; border-bottom: 1px solid var(--line);
}
.panel > .body { padding: 1rem; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.grid3 { display: grid; grid-template-columns: 2fr 1fr; gap: 1rem; align-items: start; }
@media (max-width: 900px) { .grid2, .grid3 { grid-template-columns: 1fr; } }

/* ---------- the delta, which is the hero ---------- */
.delta {
  background: var(--surface); border: 1px solid var(--line);
  border-top: 3px solid var(--accent); box-shadow: var(--shadow); padding: 1.25rem;
}
.delta-row { display: flex; align-items: baseline; gap: 1.5rem; flex-wrap: wrap; }
.delta-big {
  font-family: var(--mono); font-size: 2.6rem; font-weight: 600; line-height: 1;
  letter-spacing: -.03em; color: var(--accent); font-variant-numeric: tabular-nums;
}
.delta-unit { font-size: 1rem; font-weight: 400; color: var(--ink-soft); }
.delta-label { font-size: 12px; color: var(--ink-mid); margin-top: .3rem; }
.prepost { display: flex; gap: 2rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.prepost div { flex: 1; }
.prepost .n { font-family: var(--mono); font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.prepost .l { font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-soft); }

/* ---------- method badge ---------- */
.badge {
  font-family: var(--mono); font-size: 11.5px; line-height: 1.5;
  border: 1px solid var(--accent-line); background: var(--accent-soft); color: var(--accent);
  padding: .5rem .7rem; border-radius: 2px; margin-bottom: .75rem;
}
.badge.warn { border-color: var(--ochre-line); background: var(--ochre-soft); color: var(--ochre); }
.badge strong { font-weight: 600; }

/* ---------- tables ---------- */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th {
  text-align: left; font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
  padding: .4rem .5rem; border-bottom: 1px solid var(--line-strong);
}
td { padding: .45rem .5rem; border-bottom: 1px solid var(--line); vertical-align: top; }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
tr:last-child td { border-bottom: 0; }
.scroll { overflow-x: auto; }

/* ---------- origin chips: the three states, kept visually distinct ---------- */
.origin {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em;
  text-transform: uppercase; padding: 1px 5px; border-radius: 2px; border: 1px solid;
  white-space: nowrap;
}
.origin.derived   { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.origin.defaulted { color: var(--ink-soft); border-color: var(--line-strong); background: transparent; }
.origin.overridden{ color: var(--ochre); border-color: var(--ochre-line); background: var(--ochre-soft); }
.origin.computed  { color: var(--ink-mid); border-color: var(--line); background: transparent; }
.flagged { color: var(--red); font-weight: 600; }

/* ---------- forms ---------- */
label { display: block; font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
        text-transform: uppercase; color: var(--ink-soft); margin-bottom: .25rem; }
input, select, textarea {
  width: 100%; font-family: var(--sans); font-size: 13.5px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
  padding: .4rem .5rem; border-radius: 2px;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.field { margin-bottom: .75rem; }
.row { display: flex; gap: .6rem; align-items: flex-end; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 90px; }
button.primary, button.ghost {
  font-family: var(--sans); font-size: 13px; padding: .45rem .9rem;
  border-radius: 2px; cursor: pointer; white-space: nowrap;
}
button.primary { background: var(--accent); color: var(--surface); border: 1px solid var(--accent); font-weight: 500; }
button.primary:hover { filter: brightness(1.1); }
button.ghost { background: transparent; color: var(--ink-mid); border: 1px solid var(--line-strong); }
button.ghost:hover { border-color: var(--accent); color: var(--accent); }
button.small { font-size: 11px; padding: .2rem .5rem; }
button:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- what matters ---------- */
.matters { display: flex; flex-direction: column; gap: .6rem; }
.matter { border-left: 3px solid var(--ochre); padding-left: .7rem; }
.matter .q { font-weight: 500; font-size: 13.5px; }
.matter .w { font-size: 12px; color: var(--ink-mid); margin-top: .15rem; }
.matter .d { font-size: 11.5px; color: var(--ink-soft); margin-top: .15rem; font-style: italic; }

/* ---------- misc ---------- */
.note { font-size: 12px; color: var(--ink-mid); line-height: 1.55; }
.warnbox { border-left: 3px solid var(--ochre); background: var(--ochre-soft);
           padding: .6rem .75rem; font-size: 12.5px; margin-bottom: .75rem; }
.errbox  { border-left: 3px solid var(--red); background: var(--red-soft);
           padding: .6rem .75rem; font-size: 12.5px; margin-bottom: .75rem; }
.mono { font-family: var(--mono); font-size: 12px; }
.muted { color: var(--ink-soft); }
.disclaimer { font-size: 11.5px; color: var(--ink-soft); border-top: 1px solid var(--line);
              margin-top: 1rem; padding-top: .75rem; line-height: 1.6; }
.list { display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.item { background: var(--surface); padding: .6rem .75rem; cursor: pointer; display: flex;
        justify-content: space-between; align-items: center; gap: 1rem; }
.item:hover { background: var(--sunk); }
.item .n { font-weight: 500; }
.item .m { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }
.empty { padding: 2rem; text-align: center; color: var(--ink-soft); font-size: 13px; }

/* =====================================================================
   The drawing surface.

   The map is full bleed inside its panel and every control floats over it,
   because a boundary is drawn by looking at the ground, not at a toolbar
   stacked above it. The floating surfaces are the same warm neutral as the
   panels, translucent over whatever basemap is underneath, so the interface
   stays one material rather than becoming a map plus some chrome.
   ===================================================================== */

.canvas {
  display: grid; grid-template-columns: minmax(0, 1.62fr) minmax(330px, .85fr);
  gap: 1rem; align-items: start; margin-bottom: 1rem;
}
/* The derived data is a document and grows; the drawing surface is a fixed
   instrument. Rather than letting the column stretch the map to the height of
   whatever the soil survey returned, the derived panel scrolls inside itself,
   so the polygon stays on screen next to the rows that describe it. */
.panel.derive-panel { max-height: calc(100vh - 7rem); }
@media (max-width: 1080px) { .canvas { grid-template-columns: 1fr; } }

.panel.map-panel, .panel.derive-panel { margin-bottom: 0; display: flex; flex-direction: column; min-height: 0; }
h2.with-action { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
                 flex-wrap: wrap; }
.panel-sub { font-family: var(--sans); font-size: 11.5px; font-weight: 400; color: var(--ink-soft); }
/* `white-space: nowrap` keeps a pair of buttons from breaking across lines,
   and it was also applied to the explanatory sub-line some panels put in this
   slot, which is a sentence and must be allowed to wrap. A sentence that
   cannot wrap is the widest thing on the page. */
.head-actions { display: flex; align-items: center; gap: .6rem; flex: 0 1 auto;
                flex-wrap: wrap; white-space: nowrap; min-width: 0; }
.head-actions .panel-sub { white-space: normal; }
@media (max-width: 640px) {
  h2.with-action { gap: .25rem .6rem; }
  .head-actions { width: 100%; }
}
#derive-sub { font-family: var(--mono); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.derive-panel > .body { overflow: auto; min-height: 0; flex: 1; }

.mapwrap { position: relative; flex: 1; min-height: 620px; overflow: hidden; }
#map { position: absolute; inset: 0; background: var(--sunk); }
#map canvas { outline: none; }

/* one material for everything that floats */
.map-search, .map-tools, .map-basemap, .map-readout, .map-legend, .map-alert, .citepop {
  background: color-mix(in srgb, var(--surface) 91%, transparent);
  border: 1px solid var(--line);
  box-shadow: 0 1px 3px rgba(16,20,18,.18), 0 8px 24px rgba(16,20,18,.14);
  border-radius: 3px;
  -webkit-backdrop-filter: blur(14px) saturate(1.08);
  backdrop-filter: blur(14px) saturate(1.08);
}

/* ---------- the left rail: search above tools, in normal flow ---------- */
.map-rail { position: absolute; top: .7rem; left: .7rem; width: 300px; z-index: 6;
            display: flex; flex-direction: column; gap: .4rem; }
.map-search { padding: .4rem; }
.geo-in { display: flex; gap: .35rem; }
.geo-in input { background: var(--sunk); border-color: var(--line); font-size: 13px; }
.geo-btn {
  font-family: var(--sans); font-size: 12px; padding: .35rem .65rem; cursor: pointer;
  background: var(--accent); color: var(--surface); border: 1px solid var(--accent); border-radius: 2px;
}
.geo-btn:hover { filter: brightness(1.1); }
.geo-results { margin-top: .35rem; border-top: 1px solid var(--line); max-height: 230px; overflow: auto; }
.geo-row {
  display: block; width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  padding: .4rem .35rem; font-family: var(--sans); font-size: 12.5px; color: var(--ink);
  border-bottom: 1px solid var(--line); line-height: 1.45;
}
.geo-row:hover { background: var(--sunk); }
.geo-row.muted { color: var(--ink-mid); cursor: default; }
.geo-addr { display: block; }
.geo-xy { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft);
          font-variant-numeric: tabular-nums; }
.geo-note { margin-top: .4rem; padding-top: .4rem; border-top: 1px solid var(--line);
            font-size: 11.5px; color: var(--ink-mid); line-height: 1.5; }
.geo-clear { background: none; border: 0; padding: 0; margin-left: .25rem; cursor: pointer;
             font-family: var(--mono); font-size: 10.5px; color: var(--accent); text-decoration: underline; }
.geo-pin {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid #3ad0c8; background: rgba(58,208,200,.25);
  box-shadow: 0 0 0 1.5px rgba(16,20,18,.55), 0 0 0 6px rgba(58,208,200,.16);
}

/* ---------- drawing tools ---------- */
.map-tools { padding: .45rem; }
.toolgroup { display: flex; gap: .3rem; }
.toolgroup + .toolgroup { margin-top: .3rem; }
.tool {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: .32rem;
  font-family: var(--sans); font-size: 11.5px; line-height: 1; white-space: nowrap;
  color: var(--ink-mid); background: var(--sunk); border: 1px solid var(--line);
  padding: .42rem .3rem; border-radius: 2px; cursor: pointer;
}
.tool:hover:not(:disabled) { color: var(--ink); border-color: var(--line-strong); }
.tool[aria-pressed="true"] {
  background: var(--accent); color: var(--surface); border-color: var(--accent); font-weight: 500;
}
.tool.minor { font-size: 11px; padding: .3rem; }
.tool:disabled { opacity: .42; cursor: not-allowed; }
.tool-ic { display: inline-flex; }
.map-hint {
  margin-top: .4rem; padding-top: .4rem; border-top: 1px solid var(--line);
  font-size: 11px; line-height: 1.45; color: var(--ink-soft);
}

/* ---------- basemap switch ---------- */
/* Under the zoom control rather than beside it: the top strip belongs to the
   refusals, which have to be readable at full width when they appear. */
.map-basemap { position: absolute; top: 5.3rem; right: .7rem; z-index: 5; display: flex; padding: 2px; }
.map-basemap button {
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-mid); background: none; border: 0; padding: .35rem .6rem; cursor: pointer;
  border-radius: 2px;
}
.map-basemap button:hover { color: var(--ink); }
.map-basemap button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }
.map-overzoom {
  position: absolute; top: 7.7rem; right: .7rem; z-index: 5;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ochre); background: color-mix(in srgb, var(--ochre-soft) 88%, transparent);
  border: 1px solid var(--ochre-line); border-radius: 2px; padding: .2rem .45rem;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}

/* ---------- refusals, where the drawing happens ---------- */
.map-alert {
  position: absolute; top: .7rem; left: calc(.7rem + 314px); right: 3.4rem; z-index: 7;
  display: flex; align-items: flex-start; gap: .5rem; padding: .55rem .65rem;
  font-size: 12.5px; line-height: 1.5;
}
.map-alert.err { border-left: 3px solid var(--red); }
.map-alert.err .map-alert-text { color: var(--red); }
.map-alert.warn { border-left: 3px solid var(--ochre); }
.map-alert.warn .map-alert-text { color: var(--ochre); }
.map-alert-text { flex: 1; }
.map-alert-x { background: none; border: 0; color: var(--ink-soft); cursor: pointer;
               font-size: 15px; line-height: 1; padding: 0 .1rem; }

/* ---------- the area readout, which is the hero of this panel ---------- */
.map-bl { position: absolute; left: .7rem; bottom: .7rem; z-index: 5; width: 258px;
          display: flex; flex-direction: column; gap: .45rem; }
.map-readout { padding: .6rem .75rem; border-top: 3px solid var(--accent); }
.map-readout.live { border-top-color: var(--ochre); }
.ro-fig { display: flex; align-items: baseline; gap: .35rem; }
.ro-num {
  font-family: var(--mono); font-size: 2.05rem; font-weight: 600; line-height: 1;
  letter-spacing: -.035em; color: var(--accent); font-variant-numeric: tabular-nums;
}
.map-readout.live .ro-num { color: var(--ochre); }
.ro-unit { font-size: .85rem; color: var(--ink-soft); }
.ro-sub { display: flex; justify-content: space-between; align-items: baseline;
          gap: .5rem; margin-top: .3rem; }
.ro-sqft { font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums;
           color: var(--ink-mid); }
.ro-label { font-size: 10px; text-transform: uppercase; letter-spacing: .09em; color: var(--ink-soft); }

/* ---------- the map furniture at phone width ----------

   Every floating piece of this panel is positioned for a wide screen: a 300 px
   rail down the left, a basemap switch on the right, an alert strip in the gap
   between them, and a 258 px readout in the bottom corner. At 400 px those
   four overlap each other and the library's own zoom control, and
   `.map-alert`'s `left: calc(.7rem + 314px); right: 3.4rem` computes to a
   21 px wide box, which is a refusal notice nobody can read.

   So they stack. The rail across the top, clear of the zoom control; the
   readout and the legend across the bottom; the basemap switch and the
   overzoom badge on the last line. The alert keeps the top slot and sits over
   the rail when it appears, which is right: it is raised while the user is
   drawing, and what it has to say outranks the search box underneath it. */
@media (max-width: 640px) {
  .mapwrap { min-height: 440px; }
  .map-rail { width: auto; left: .5rem; right: 2.9rem; top: .5rem; }
  .map-alert { left: .5rem; right: .5rem; top: .5rem; }
  .map-bl { left: .5rem; right: .5rem; width: auto; bottom: 2.9rem; }
  .map-basemap { top: auto; bottom: .5rem; left: .5rem; right: auto; }
  .map-overzoom { top: auto; bottom: .5rem; right: .5rem; left: auto; max-width: 45%; }
}

/* ---------- the areas legend ---------- */
.map-legend { padding: .35rem .45rem .45rem; font-size: 12px; }
.lg-head {
  display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
  padding: .15rem .15rem .3rem; border-bottom: 1px solid var(--line);
}
.lg-row {
  display: grid; grid-template-columns: 10px 1fr auto 16px; align-items: center; gap: .45rem;
  padding: .3rem .15rem; cursor: pointer; border-bottom: 1px solid var(--line);
}
.lg-row:last-child { border-bottom: 0; }
.lg-row:hover { background: var(--sunk); }
.lg-row.sel .lg-name { font-weight: 600; }
.lg-dot { width: 10px; height: 10px; border-radius: 2px; }
.lg-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lg-ac { font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.lg-holes { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em;
             text-transform: uppercase; color: var(--ink-soft); }
.lg-x { grid-column: 4; background: none; border: 0; color: var(--ink-soft); cursor: pointer;
        font-size: 14px; line-height: 1; padding: 0; }
.lg-x:hover { color: var(--red); }
.lg-note { font-size: 10.5px; color: var(--ink-soft); line-height: 1.45; padding: .35rem .15rem 0;
           border-top: 1px solid var(--line); margin-top: .2rem; }

/* MapLibre's own controls, brought into the palette rather than left default */
.maplibregl-ctrl-group {
  background: color-mix(in srgb, var(--surface) 91%, transparent) !important;
  border: 1px solid var(--line); box-shadow: 0 1px 3px rgba(16,20,18,.18) !important;
  border-radius: 3px !important;
}
.maplibregl-ctrl-group button { background: transparent !important; }
.maplibregl-ctrl-group button:hover { background: var(--sunk) !important; }
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--line); }
.maplibregl-ctrl-group button span { filter: var(--mlfilter, none); }
.maplibregl-ctrl-scale {
  background: color-mix(in srgb, var(--surface) 88%, transparent) !important;
  border-color: var(--line-strong) !important; color: var(--ink-mid) !important;
  font-family: var(--mono) !important; font-size: 10px !important; border-radius: 0 0 2px 2px;
}
.maplibregl-ctrl-attrib {
  background: color-mix(in srgb, var(--surface) 88%, transparent) !important;
  font-size: 10px !important;
}
.maplibregl-ctrl-attrib a { color: var(--ink-mid) !important; }

/* =====================================================================
   The derived-data panel: a ranked list of what matters, not a data dump.
   ===================================================================== */

.dv-empty { padding: 2.2rem 1rem; text-align: center; color: var(--ink-mid); font-size: 13px;
            border: 1px dashed var(--line-strong); }
.dv-empty span { display: block; margin-top: .4rem; font-size: 11.5px; color: var(--ink-soft); }

.dv-questions { margin-bottom: 1.1rem; }
.dv-qhead {
  display: flex; justify-content: space-between; align-items: baseline; gap: .5rem;
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ochre); border-bottom: 1px solid var(--ochre-line); padding-bottom: .3rem;
  margin-bottom: .6rem;
}
.dv-qhead span { color: var(--ink-soft); letter-spacing: .04em; text-transform: none;
                 font-family: var(--sans); font-size: 11px; }
.dv-q + .dv-q { margin-top: .6rem; }

.dv-sec { margin-bottom: 1.15rem; }
.dv-sec h3 {
  font-family: var(--serif); font-size: .95rem; font-weight: 600; margin: 0 0 .45rem;
  display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
  border-bottom: 1px solid var(--line); padding-bottom: .3rem;
}
.dv-sec h3 span { font-family: var(--sans); font-size: 11px; font-weight: 400; color: var(--ink-soft);
                  text-align: right; }
.dv-table td { vertical-align: middle; }
.dv-edition { font-size: 10px; color: var(--ink-soft); margin-top: .4rem; line-height: 1.45; }
.dv-foot { margin-top: .5rem; }
.dv-caveats { margin: .5rem 0 0; padding-left: 1rem; font-size: 11.5px; color: var(--ink-mid); line-height: 1.5; }

.mu-name { font-size: 12.5px; }
.mu-key { font-size: 10px; margin-top: .1rem; }
.hsg-cell { white-space: nowrap; }
.hsg {
  font-family: var(--mono); font-size: 12px; font-weight: 600; letter-spacing: .02em;
  border: 1px solid var(--line-strong); padding: 1px 6px; border-radius: 2px; color: var(--ink);
}
.hsg.dual { color: var(--ochre); border-color: var(--ochre-line); background: var(--ochre-soft); }
.hsg.none { color: var(--red); border-color: var(--red); background: var(--red-soft);
            font-weight: 500; font-size: 10.5px; letter-spacing: .04em; }
.hsg-note { font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
            color: var(--ink-soft); margin-left: .3rem; }
.dv-assumed td { border-bottom: 1px solid var(--line); background: var(--sunk); font-size: 11.5px;
                 color: var(--ink-mid); padding-top: .3rem; padding-bottom: .3rem; }
.dv-assumed.open td { color: var(--red); }
.dv-arrow { font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
            color: var(--ink-soft); margin-right: .35rem; }
.dv-assumed.open .dv-arrow { color: var(--red); }

.dv-hero { display: flex; align-items: baseline; gap: .5rem; }
.dv-hero .fig-n { font-size: 2rem; letter-spacing: -.03em; color: var(--accent); }
.dv-pair { display: flex; gap: 1.75rem; }
.dv-k { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
        color: var(--ink-soft); margin-bottom: .15rem; }

.fig { display: inline-flex; align-items: baseline; gap: .3rem; }
.fig-n { font-family: var(--mono); font-size: 1.05rem; font-variant-numeric: tabular-nums;
         line-height: 1.1; }
.fig-u { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }

.lclist { display: flex; flex-direction: column; gap: .3rem; }
.lcrow { display: grid; grid-template-columns: 1fr 78px 44px; align-items: center; gap: .5rem;
         font-size: 12px; }
.lc-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lc-bar { height: 6px; background: var(--sunk); border: 1px solid var(--line); }
.lc-bar i { display: block; height: 100%; background: var(--accent); opacity: .8; }
.lc-pct { font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums;
          text-align: right; color: var(--ink-mid); white-space: nowrap; }
.lc-pct .fig-u { font-size: 9.5px; margin-left: 1px; }

/* the citation, one hover or click from every figure */
button.cite-chip { cursor: pointer; font-family: var(--mono); }
button.cite-chip:hover { filter: brightness(1.06); }
.citepop {
  position: fixed; z-index: 60; max-width: 380px; padding: .6rem .7rem; font-size: 12px;
  line-height: 1.55; pointer-events: none;
}
.cp-head { display: flex; align-items: center; gap: .4rem; margin-bottom: .35rem; }
.cp-label { font-size: 11px; color: var(--ink-mid); }
.cp-cite { font-family: var(--mono); font-size: 11px; color: var(--ink); word-break: break-word; }
.cp-explain { margin-top: .35rem; font-size: 11.5px; color: var(--ink-mid); }

/* ---------- theme toggle ---------- */
.theme-toggle {
  font-family: var(--mono); font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-soft); background: none; border: 1px solid var(--line); border-radius: 2px;
  padding: .3rem .55rem; cursor: pointer;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--line-strong); }

/* =====================================================================
   The open question, and its answer.

   The control sits in the panel beside the map rather than in a dialog over
   it, because the evidence a user can attest to is usually the ground behind
   the dialog. It is built to make a considered answer cheap and an empty one
   awkward: the choice states what it is worth before it is made, the demand
   for a reason grows with that figure, and the line under it names the
   account the sentence will be filed against.
   ===================================================================== */

.dv-refusal { border-left: 3px solid var(--red); background: var(--red-soft);
              padding: .6rem .75rem; margin-bottom: .7rem; }
.dv-rhead { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            text-transform: uppercase; color: var(--red); margin-bottom: .25rem; }
.dv-refusal p { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--ink-mid); }

.cn-open { margin-top: .5rem; }

.cn-answer { margin-top: .6rem; border: 1px solid var(--line-strong); background: var(--sunk);
             padding: .6rem; border-radius: 2px; }
.cn-row { display: flex; gap: .35rem; flex-wrap: wrap; }
.cn-letter {
  flex: 1 1 0; min-width: 64px; display: flex; flex-direction: column; align-items: center;
  gap: .1rem; padding: .4rem .3rem; cursor: pointer; border-radius: 2px;
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink);
  font-family: var(--sans);
}
.cn-letter:hover { border-color: var(--accent); }
.cn-letter .l { font-family: var(--mono); font-size: 1.05rem; font-weight: 600; line-height: 1; }
.cn-letter .cap { font-size: 10px; color: var(--ink-soft); line-height: 1.2; text-align: center; }
.cn-letter .cn { font-family: var(--mono); font-size: 9.5px; color: var(--ink-soft); }
.cn-letter.on { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.cn-letter.on .cap, .cn-letter.on .cn { color: var(--surface); opacity: .85; }

.cn-worth { margin-top: .5rem; font-size: 12px; line-height: 1.5; color: var(--ochre);
            border-left: 3px solid var(--ochre-line); padding-left: .5rem; }
.cn-worth.flat { color: var(--ink-mid); border-left-color: var(--line-strong); }
.cn-illus { display: block; font-size: 10.5px; color: var(--ink-soft); margin-top: .15rem; }

.cn-demand { margin-top: .5rem; font-size: 12px; line-height: 1.5; color: var(--ink-mid); }
.cn-kinds { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .45rem; }
.cn-kind {
  font-family: var(--sans); font-size: 11px; padding: .2rem .45rem; cursor: pointer;
  border-radius: 2px; background: var(--surface); border: 1px solid var(--line-strong);
  color: var(--ink-mid);
}
.cn-kind:hover { border-color: var(--accent); color: var(--accent); }
.cn-kind.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent);
              font-weight: 500; }

.cn-reason { margin-top: .45rem; font-size: 12.5px; line-height: 1.5; resize: vertical; }
.cn-foot { display: flex; align-items: center; justify-content: space-between; gap: .6rem;
           margin-top: .45rem; flex-wrap: wrap; }
.cn-gate { font-family: var(--mono); font-size: 10.5px; color: var(--ochre); line-height: 1.4; }
.cn-gate.ok { color: var(--accent); }
.cn-actions { display: flex; gap: .35rem; flex: 0 0 auto; }
.cn-attrib { margin-top: .45rem; padding-top: .4rem; border-top: 1px solid var(--line);
             font-size: 10.5px; line-height: 1.5; color: var(--ink-soft); }

/* ---------- an answered question, which is not a resolved one ---------- */
/* Both halves stay: what the survey published, and what a person attested.
   The arrow between them is the whole record. */
.dv-answered { margin-top: .8rem; }
.dv-ahead {
  display: flex; justify-content: space-between; align-items: baseline; gap: .5rem;
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ochre); border-bottom: 1px solid var(--ochre-line); padding-bottom: .3rem;
  margin-bottom: .6rem;
}
.dv-ahead span { color: var(--ink-soft); letter-spacing: .04em; text-transform: none;
                 font-family: var(--sans); font-size: 11px; }
.dv-a { border-left: 3px solid var(--ochre); padding-left: .7rem; }
.dv-a + .dv-a { margin-top: .7rem; }
.dv-a .q { font-weight: 500; font-size: 13.5px; display: flex; align-items: center; gap: .4rem;
           flex-wrap: wrap; }
.dv-apair { display: flex; align-items: center; gap: .6rem; margin-top: .35rem; flex-wrap: wrap; }
.dv-apair .k { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .09em;
               text-transform: uppercase; color: var(--ink-soft); margin-bottom: .15rem; }
.dv-aarrow { color: var(--ink-soft); font-size: 14px; padding-top: .6rem; }
.dv-ashare { margin-left: auto; font-family: var(--mono); font-size: 11.5px; color: var(--ink-mid);
             font-variant-numeric: tabular-nums; }
.hsg.att { color: var(--ochre); border-color: var(--ochre-line); background: var(--ochre-soft); }
.dv-awho { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft); margin-top: .3rem; }
.dv-areason { font-size: 12px; line-height: 1.55; color: var(--ink-mid); margin-top: .25rem;
              border-left: 2px solid var(--line-strong); padding-left: .5rem; }
.dv-areason.small { font-size: 11px; margin-top: .2rem; }
.dv-aacts { display: flex; gap: .35rem; margin-top: .45rem; flex-wrap: wrap; }
.dv-assumed.attested td { background: var(--ochre-soft); color: var(--ink); }
.dv-assumed.quiet td { color: var(--ink-soft); }

/* =====================================================================
   Per service state.

   Four states and three remedies. "Unreachable" is worth trying again in
   five minutes; "no coverage" will say the same thing tomorrow and needs a
   different dataset or a different site; "not started" needs one more pass
   now that the cache is warm. Collapsing any of them into one grey
   "unavailable" hands two thirds of the users the wrong remedy, so they do
   not share a colour.
   ===================================================================== */

.svc-chip {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase;
  padding: 1px 5px; border-radius: 2px; border: 1px solid; white-space: nowrap;
}
.svc-chip.svc-ok { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.svc-chip.svc-unavailable { color: var(--red); border-color: var(--red); background: var(--red-soft); }
.svc-chip.svc-no_coverage { color: var(--ochre); border-color: var(--ochre-line); background: var(--ochre-soft); }
.svc-chip.svc-skipped { color: var(--ink-soft); border-color: var(--line-strong); background: transparent; }

.svc-name { font-size: 12.5px; }
.svc-detail { margin-top: .25rem; font-size: 10.5px; line-height: 1.45; color: var(--ink-soft);
              word-break: break-word; }
.svc-table td { vertical-align: top; }
.svc-table td .fig-u { display: block; font-size: 9.5px; }

.dv-missing { border: 1px dashed var(--line-strong); padding: .6rem .7rem; }
.dv-missing.svc-unavailable { border-color: var(--red); background: var(--red-soft); }
.dv-missing.svc-no_coverage { border-color: var(--ochre-line); background: var(--ochre-soft); }
.dv-mhead { display: flex; align-items: center; gap: .4rem; font-size: 12.5px; font-weight: 500; }
.dv-mwhy { margin-top: .3rem; font-size: 12px; line-height: 1.55; color: var(--ink-mid); }

/* =====================================================================
   The practice.

   Two panels side by side at width: the section on the left and what the
   practice does on the right. The split is the widest thing on the page
   because it is the part a reviewer reads.
   ===================================================================== */

.prac-zone {
  display: grid; grid-template-columns: minmax(420px, 1fr) minmax(460px, 1.05fr);
  gap: 1rem; align-items: start; margin-top: 1rem;
}
@media (max-width: 1080px) { .prac-zone { grid-template-columns: 1fr; } }

.pr-sec { margin-bottom: 1.35rem; }
.pr-sec h3 {
  font-family: var(--serif); font-size: .95rem; font-weight: 600; margin: 0 0 .55rem;
  padding-bottom: .3rem; border-bottom: 1px solid var(--line);
  display: flex; align-items: baseline; justify-content: space-between; gap: .6rem;
}
.pr-sec h3 span { font-family: var(--sans); font-size: 11px; font-weight: 400;
                  color: var(--ink-soft); text-align: right; }
.pr-note { font-size: 12px; color: var(--ink-mid); line-height: 1.55; margin-top: .5rem; }
.pr-hint { font-size: 11px; color: var(--ink-soft); line-height: 1.5; margin-top: .25rem; }
.pr-prov { font-size: 10px; color: var(--ink-soft); line-height: 1.45; margin-top: .4rem;
           word-break: break-word; }
.pr-path { font-size: 12px; color: var(--ink-mid); line-height: 1.55;
           border-left: 3px solid var(--accent-line); padding: .35rem .6rem;
           background: var(--sunk); margin-bottom: .6rem; }
.pr-frommap { margin: 0 0 .5rem; }
.linkish { background: none; border: 0; padding: 0; font: inherit; color: var(--accent);
           text-decoration: underline; cursor: pointer; }

/* ---------- the condition switch ---------- */
.pr-condrow { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
              margin-bottom: .85rem; }
.pr-condl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
            text-transform: uppercase; color: var(--ink-soft); }
.pr-cond {
  font-family: var(--sans); font-size: 12px; padding: .22rem .6rem; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink-mid);
}
.pr-cond.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.pr-condnote { font-size: 11px; color: var(--ink-soft); flex: 1 1 220px; line-height: 1.45; }

/* ---------- choices ---------- */
.pr-picks { display: flex; gap: .35rem; flex-wrap: wrap; }
.pr-picks.wrap { display: grid; grid-template-columns: 1fr 1fr; gap: .35rem; }
.pr-pick {
  font-family: var(--sans); font-size: 12.5px; padding: .4rem .6rem; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink);
  text-align: left; display: flex; flex-direction: column; gap: .15rem;
}
.pr-pick:hover { border-color: var(--accent); }
.pr-pick.on { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.pr-pick .pr-x { font-size: 10px; color: var(--ink-soft); line-height: 1.35; }
.pr-pick.on .pr-x { color: var(--surface); opacity: .85; }
.pr-pick.tall { min-height: 3.4rem; }
/* ---------- the kind picker, in three groups ----------
   The groups are not cosmetic. A wet kind cannot be saved without a permanent
   pool and a refused kind cannot be saved at all, so a user choosing from one
   flat list of twenty one names would meet both facts as a 422. */
.pr-kgroup { margin-bottom: .7rem; }
.pr-kgroup:last-of-type { margin-bottom: 0; }
.pr-kglabel { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
              text-transform: uppercase; color: var(--ink-soft); margin-bottom: .3rem;
              display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.pr-kglabel span { font-family: var(--sans); font-size: 11px; letter-spacing: 0;
                   text-transform: none; color: var(--ink-soft); }
.pr-pick.wet { border-color: var(--accent-line); }
.pr-pick.small { padding: .25rem .5rem; font-size: 11px; }
/* The kinds the engine refuses. Marked rather than hidden, so a user
   looking for a green roof is told why it is not here. */
.pr-pick.unmodelled { border-style: dashed; color: var(--ink-soft); }
.pr-pick.unmodelled.on { background: var(--ochre-soft); border-color: var(--ochre);
                         color: var(--ochre); }
.pr-pick.unmodelled.on .pr-x { color: var(--ochre); }

/* A kind the engine names and refuses. Its own reason, in full, on the face
   of the control: a user who came looking for a green roof is told what a
   green roof needs and this product has no source for, which is a longer and
   more useful answer than a short list they cannot find it in. */
.pr-refused-kind { border: 3px double var(--red); border-left-width: 6px;
                   background: var(--red-soft); padding: .6rem .75rem; margin-top: .6rem; }
.prk-l { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; font-weight: 700;
         text-transform: uppercase; color: var(--red); }
.pr-refused-kind p { margin: .35rem 0 0; font-size: 12px; line-height: 1.55;
                     color: var(--ink-mid); }

/* A kind that has no honest form without a permanent pool. */
.pr-poolreq { border-left: 4px solid var(--accent); background: var(--accent-soft);
              padding: .5rem .65rem; margin-top: .6rem; }
.prp-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; font-weight: 700;
         color: var(--accent); }
.pr-poolreq p { margin: .3rem 0 0; font-size: 12px; line-height: 1.55; color: var(--ink-mid); }

/* ---------- the outlet structure builder ----------
   One card per stage, in the order the plan draws them. The engine sorts by
   elevation when it builds the structure and both orders are worth having, so
   this shows the given order and the stored result below it shows the
   engine's. */
.pr-stage { border: 1px solid var(--line-strong); border-left: 4px dashed var(--red);
            padding: .55rem .7rem; margin-top: .6rem; }
/* An orifice is the only control that empties the facility in finite time,
   which is the property the whole drawdown turns on, so it is marked. */
.pr-stage.empties { border-left-style: solid; border-left-color: var(--accent); }
.pr-stage-h { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.pr-stage-n { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
              text-transform: uppercase; font-weight: 700; color: var(--ink-mid); }
.pr-stage-h .pr-picks { flex: 1 1 auto; }
.pr-stage-h > button:last-child { margin-left: auto; }
.pr-stage-note { font-size: 11px; color: var(--ink-soft); line-height: 1.5; margin-top: .35rem; }
.pr-stage-add { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: .6rem; }

/* A figure the engine computed and did not check. Not a pass and not a
   failure: the check that would have applied does not apply to this kind of
   facility, and no meter is drawn against a ceiling that was not used. */
.pr-unchecked { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
                text-transform: uppercase; font-weight: 700; color: var(--ochre);
                border: 1px dashed var(--ochre); padding: 1px 4px; margin-left: .5rem;
                white-space: nowrap; vertical-align: middle; }

/* ---------- fields ---------- */
.pr-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .55rem .7rem; margin-top: .6rem; }
.pr-field.wide { grid-column: 1 / -1; }
.pr-field label { display: flex; align-items: baseline; gap: .35rem; flex-wrap: wrap;
                  font-size: 11px; color: var(--ink-mid); margin-bottom: .2rem; }
.pr-unit { font-family: var(--mono); font-size: 10px; color: var(--ink-soft); }
.pr-chip { margin-left: auto; }
.pr-field input { width: 100%; }
/* A field the template is filling. Legible, not greyed out of readability:
   the value has to be readable because it is the value being inherited. */
.pr-field.dim input { background: var(--sunk); border-style: dashed; }

/* ---------- what follows from the section ---------- */
.pr-derived { margin-top: .8rem; border: 1px solid var(--line); padding: .5rem .6rem; }
.pr-dhead { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
            text-transform: uppercase; color: var(--ink-soft); margin-bottom: .2rem; }

/* ---------- the infiltration rate, which does not look like the others ----
   It is given the weight of a departure because that is its weight: every
   retention figure rests on it, and the difference between a boring and a
   texture class default is the difference between a facility that works and
   one that ponds for a week. */
.rate-sec { border: 1px solid var(--line-strong); border-left: 5px solid var(--accent);
            padding: .8rem .85rem; background: var(--sunk); }
.rate-sec h3 { border-bottom-color: var(--line-strong); }
.rate-picks { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
@media (max-width: 620px) { .rate-picks, .pr-grid, .pr-picks.wrap { grid-template-columns: 1fr; } }
.rate-pick {
  font-family: var(--sans); text-align: left; cursor: pointer; padding: .55rem .65rem;
  background: var(--surface); border: 2px solid var(--line-strong); color: var(--ink);
  display: flex; flex-direction: column; gap: .25rem;
}
.rate-pick:hover { border-color: var(--accent); }
.rate-pick .rp-l { font-size: 13px; font-weight: 600; }
.rate-pick .rp-d { font-size: 11px; color: var(--ink-mid); line-height: 1.45; }
.rate-pick.on { border-color: var(--accent); background: var(--accent-soft); }
.rate-pick.on .rp-l { color: var(--accent); }
.rate-pick.untested { border-style: double; border-width: 3px; }
.rate-pick.untested.on { border-color: var(--red); background: var(--red-soft); }
.rate-pick.untested.on .rp-l { color: var(--red); }

.rate-consequence {
  margin-top: .6rem; border: 3px double var(--red); border-left-width: 5px;
  padding: .6rem .7rem; background: var(--surface);
  background-image: repeating-linear-gradient(45deg, var(--hatch) 0 5px, transparent 5px 10px);
}
.rate-consequence .rc-head { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 700; color: var(--red); }
.rate-consequence p { margin: .35rem 0 0; font-size: 12px; line-height: 1.55; }

.rate-stored { margin-top: .7rem; border-left: 4px solid var(--accent);
               padding: .5rem .65rem; background: var(--surface); }
.rate-stored .rs-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 700; color: var(--accent); }
.rate-stored p { margin: .3rem 0 0; font-size: 12px; line-height: 1.55; color: var(--ink-mid); }
.rate-stored .rs-pair { margin-top: .35rem; font-size: 11px; color: var(--ink-soft); }
.rate-stored.untested { border: 3px double var(--red); border-left-width: 6px;
  background-image: repeating-linear-gradient(45deg, var(--hatch) 0 5px, transparent 5px 10px); }
.rate-stored.untested .rs-l { color: var(--red); }

/* ---------- the save gate ---------- */
.pr-foot { display: flex; align-items: flex-start; justify-content: space-between; gap: .7rem;
           margin-top: 1rem; padding-top: .7rem; border-top: 1px solid var(--line-strong);
           flex-wrap: wrap; }
.pr-gate { font-family: var(--mono); font-size: 10.5px; color: var(--ochre); line-height: 1.5;
           min-width: 0; }
/* The save gate's buttons wrap rather than being pinned to one line: at 360 px
   the pair ran a fraction of a pixel past the panel, and a fraction of a pixel
   is a horizontal scroll bar across the whole tool. */
.pr-actions { display: flex; gap: .35rem; flex: 0 0 auto; flex-wrap: wrap; }

/* =====================================================================
   The volume split, with THREE destinations rather than two.

   Retention, filtration and detention are three different claims and the
   single worst thing this panel could do is let any two of them read as one
   number. They are separated on the same four channels report.py uses in
   print, in the same order of reliability:
     1. the words. Each group is headed with where the water went, spelled
        out, and carries the credit it is claimed under as its own word:
        RETENTION, FILTRATION or DETENTION. A band between each adjacent pair
        says in capitals that those two are not added and what the difference
        between them is. This survives everything, including a screenshot
        pasted into a document with the styles gone.
     2. the border. Solid on retention, double on filtration, dashed on
        detention, and a thin dotted rule on the two groups that are nobody's
        credit, which are the untreated overflow and what is still standing in
        the practice.
     3. the fill. Plain, a hatch running one way, a hatch running the other.
        Two hatches at opposite diagonals read as two textures where two
        shades of one colour would not, which is why --hatch2 exists.
     4. the colour, which is the weakest channel and is last.
   Either of the first two alone is enough to read it correctly. Each channel
   gained a third value when detention arrived rather than a legend being
   introduced to carry the difference: a legend is a fifth thing to read and
   it is the thing nobody reads. There is no stacked bar: every channel has
   its own meter in its own track, so nothing is ever laid end to end with
   anything else.
   ===================================================================== */

.split { border: 1px solid var(--line-strong); margin-top: .3rem; }
.split-cap { font-size: 12px; color: var(--ink-mid); line-height: 1.55; padding: .65rem .75rem; }
.split .grp { padding: .6rem .75rem .7rem; }
/* Three credited destinations, so each channel gained a third value rather
   than a legend being introduced to carry the difference: a legend is a fifth
   thing to read and it is the thing nobody reads. Border: solid, double,
   dashed. Fill: plain, a hatch one way, a hatch the other way. Colour last. */
.split .grp.keep { border-left: 6px solid var(--accent); }
.split .grp.filter { border-left: 6px double var(--ochre);
  background-image: repeating-linear-gradient(45deg, var(--hatch) 0 5px, transparent 5px 10px); }
.split .grp.detain { border-left: 6px dashed var(--red);
  background-image: repeating-linear-gradient(-45deg, var(--hatch2) 0 5px, transparent 5px 10px); }
/* Neither of these is a credit, so neither gets a credit block's weight. */
.split .grp.spill, .split .grp.hold { border-left: 3px dotted var(--ink-soft);
  background: var(--sunk); }
.split .grp-h { font-family: var(--mono); font-size: 10px; letter-spacing: .14em;
                font-weight: 700; color: var(--ink); margin-bottom: .45rem; }
.split .grp.keep .grp-h { color: var(--accent); }
.split .grp.filter .grp-h { color: var(--ochre); }
.split .grp.detain .grp-h { color: var(--red); }
.split .grp.spill .grp-h, .split .grp.hold .grp-h { color: var(--ink-soft); }

/* The credit each destination is claimed under, as its own word beside the
   label. It is the token a reviewer matches against their own manual. */
.ch-l .credit { font-family: var(--mono); font-size: 9px; letter-spacing: .12em;
                text-transform: uppercase; font-weight: 700; border: 1px solid currentColor;
                padding: 1px 4px; margin-left: .4rem; white-space: nowrap; }
.ch.keep .credit { color: var(--accent); }
.ch.filter .credit { color: var(--ochre); }
.ch.detain .credit { color: var(--red); }
.ch.spill .credit, .ch.hold .credit { color: var(--ink-soft); }

.ch + .ch { margin-top: .7rem; padding-top: .6rem; border-top: 1px dotted var(--line-strong); }
.ch-l { font-size: 12px; font-weight: 600; line-height: 1.4; }
.ch-n { font-family: var(--mono); font-size: 1.45rem; font-weight: 600; line-height: 1.15;
        margin-top: .15rem; }
.ch-n .u { font-family: var(--sans); font-size: .78rem; font-weight: 400; color: var(--ink-soft); }
.ch-share { font-size: 10.5px; color: var(--ink-soft); margin-top: .2rem; }
.ch-s { font-size: 11.5px; color: var(--ink-mid); line-height: 1.5; margin-top: .3rem; }

.nosum { border-top: 3px double var(--ink); border-bottom: 3px double var(--ink);
         padding: .55rem .75rem; background: var(--sunk); }
.nosum b { font-family: var(--mono); font-size: 10px; letter-spacing: .07em; font-weight: 700;
           line-height: 1.55; display: block; }
.nosum-why { font-size: 11px; color: var(--ink-mid); line-height: 1.5; margin-top: .35rem; }
.split-foot { padding: .55rem .75rem; border-top: 1px solid var(--line);
              font-size: 11.5px; color: var(--ink-mid); line-height: 1.55; }

/* The small drawdown split. Even here the three are not one bar: a rule and
   the words "not added" sit between each adjacent pair. */
.sp-pair, .sp-triple { display: grid; gap: .6rem; align-items: center; margin-top: .6rem; }
.sp-pair { grid-template-columns: 1fr auto 1fr; }
.sp-triple { grid-template-columns: 1fr auto 1fr auto 1fr; }
.sp { padding: .4rem .55rem; }
.sp.keep { border-left: 4px solid var(--accent); }
.sp.filter { border-left: 4px double var(--ochre);
  background-image: repeating-linear-gradient(45deg, var(--hatch) 0 4px, transparent 4px 8px); }
.sp.detain { border-left: 4px dashed var(--red);
  background-image: repeating-linear-gradient(-45deg, var(--hatch2) 0 4px, transparent 4px 8px); }
.sp-l { font-size: 11px; color: var(--ink-mid); line-height: 1.4; }
.sp-n { font-family: var(--mono); font-size: 1.05rem; font-variant-numeric: tabular-nums;
        margin-top: .15rem; }
.sp-n .u { font-family: var(--sans); font-size: .68rem; color: var(--ink-soft); }
.sp-nosum { font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
            color: var(--ink-soft); writing-mode: vertical-rl; text-align: center;
            border-left: 1px solid var(--line-strong); border-right: 1px solid var(--line-strong);
            padding: .2rem; }
@media (max-width: 900px) { .sp-triple { grid-template-columns: 1fr; } }
@media (max-width: 620px) { .sp-pair { grid-template-columns: 1fr; } }
@media (max-width: 900px) { .sp-triple .sp-nosum { writing-mode: horizontal-tb; border: 0;
                                        border-top: 3px double var(--ink); padding: .3rem 0; } }
@media (max-width: 620px) { .sp-pair .sp-nosum { writing-mode: horizontal-tb; border: 0;
                                        border-top: 3px double var(--ink); padding: .3rem 0; } }

/* ---------- meters: one ratio against one limit, never a stacked bar ------
   The track is the limit and the fill is the value, so the reading is how
   close to the line rather than how big. */
.meter { position: relative; height: 7px; margin-top: .35rem; background: var(--sunk);
         border: 1px solid var(--line); }
.meter .fill { display: block; height: 100%; background: var(--ink-soft); }
.meter.keep .fill, .meter.good .fill { background: var(--accent); }
.meter.filter .fill { background: var(--ochre); }
.meter.detain .fill { background: var(--red); }
.meter.spill .fill, .meter.hold .fill { background: var(--ink-soft); }
.meter.warn .fill { background: var(--ochre); }
.meter.bad .fill { background: var(--red); }
.meter.unknown .fill { background: repeating-linear-gradient(45deg,
  var(--line-strong) 0 3px, transparent 3px 6px); }
.meter .mk { position: absolute; top: -3px; bottom: -3px; width: 1px; background: var(--ink-soft); }
.meter .mk.hard { width: 2px; background: var(--ink); }

.pr-stat { margin-top: .8rem; }
.pr-stat:first-child { margin-top: 0; }
.ps-l { font-size: 11.5px; color: var(--ink-mid); line-height: 1.4; }
.ps-n { font-family: var(--mono); font-size: 1.25rem; font-weight: 600; margin-top: .1rem; }
.ps-n .u { font-family: var(--sans); font-size: .72rem; font-weight: 400; color: var(--ink-soft); }
.ps-s { font-size: 11px; color: var(--ink-soft); line-height: 1.5; margin-top: .3rem; }
.pr-func { font-family: var(--mono); font-size: 11.5px; color: var(--accent);
           border: 1px solid var(--accent-line); background: var(--accent-soft);
           padding: .4rem .55rem; margin-bottom: .6rem; }
.pr-split-small { margin-top: .9rem; }

/* ---------- refusals, in two states that mean different things ---------- */
.refuse { border-left: 5px double var(--red); padding: .5rem .7rem; margin-top: .7rem;
          background: var(--red-soft); }
.refuse.partial { border-left-style: solid; border-left-color: var(--ochre);
                  background: var(--ochre-soft); }
.rf-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; font-weight: 700;
        color: var(--red); display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.refuse.partial .rf-l { color: var(--ochre); }
.rf-k { font-weight: 400; letter-spacing: .04em; text-transform: none; color: var(--ink-mid); }
.rf-r { font-size: 12px; line-height: 1.55; color: var(--ink-mid); margin-top: .3rem; }
.rf-s { font-size: 12px; line-height: 1.55; color: var(--ink); margin-top: .35rem; }
.rf-s span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
             text-transform: uppercase; color: var(--ink-soft); display: block; }
.pr-voided { border: 3px double var(--red); padding: .5rem .7rem; font-size: 12px;
             line-height: 1.55; color: var(--ink); margin-bottom: .6rem; }

/* A withheld figure, as words where a number would have been. Never a blank:
   a blank in a numeric slot is read as a zero. */
.pr-withheld { border: 2px dashed var(--red); padding: .45rem .6rem; margin-top: .25rem; }
.pw-l { font-family: var(--mono); font-size: 11px; letter-spacing: .06em; font-weight: 700;
        color: var(--red); line-height: 1.35; }
.pw-r { font-size: 11.5px; color: var(--ink-mid); line-height: 1.5; margin-top: .3rem; }

/* ---------- a design finding, which an overflow is ---------- */
.finding { border: 1px solid var(--line-strong); border-left: 4px solid var(--ochre);
           padding: .5rem .7rem; margin-top: .7rem; }
.finding.clear { border-left-color: var(--accent-line); }
.fd-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; font-weight: 700;
        color: var(--ochre); }
.finding.clear .fd-l { color: var(--accent); }
.finding p { margin: .3rem 0 0; font-size: 12px; line-height: 1.55; color: var(--ink-mid); }

.pr-caveat { border: 1px dashed var(--line-strong); padding: .5rem .65rem; margin-top: .7rem;
             font-size: 11.5px; color: var(--ink-mid); line-height: 1.55; }
.pr-caveat b { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em;
               text-transform: uppercase; color: var(--ochre); margin-bottom: .25rem; }
.pr-await { border: 1px dashed var(--line-strong); padding: .7rem .8rem; font-size: 12px;
            color: var(--ink-mid); line-height: 1.55; margin-bottom: 1rem; }
.pr-assume { margin-top: .7rem; display: flex; flex-wrap: wrap; gap: .3rem; align-items: baseline; }
.pr-assume > span:first-child { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-soft); }
.pr-akey { font-size: 10px; color: var(--ink-soft); border: 1px dashed var(--line-strong);
           padding: 1px 4px; }

/* =====================================================================
   The acknowledge and reason control, shared by the boundary and the
   practice. The acknowledgement is a separate act from the reason: the
   reason says why the change is right, the acknowledgement says the user
   has understood what it supersedes.
   ===================================================================== */

.ack { border: 3px double var(--ochre); padding: .7rem .8rem; margin-bottom: .9rem;
       background: var(--sunk); }
.ack-head { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            text-transform: uppercase; font-weight: 700; color: var(--ochre); }
.ack-why { font-size: 12px; line-height: 1.55; color: var(--ink-mid); margin-top: .35rem; }
.ack-check { display: flex; align-items: flex-start; gap: .5rem; margin-top: .6rem; }
.ack-box { font-family: var(--mono); font-size: 10px; letter-spacing: .07em;
           text-transform: uppercase; padding: .3rem .55rem; cursor: pointer;
           background: var(--surface); border: 2px solid var(--line-strong);
           color: var(--ink-mid); flex: 0 0 auto; }
.ack-box:hover { border-color: var(--ochre); color: var(--ochre); }
.ack-box.on { background: var(--ochre); border-color: var(--ochre); color: var(--surface); }
.ack-ctext { font-size: 11.5px; color: var(--ink-mid); line-height: 1.5; }
.ack-reason { margin-top: .55rem; font-size: 12.5px; line-height: 1.5; resize: vertical;
              width: 100%; }
.ack-foot { display: flex; align-items: center; justify-content: space-between; gap: .6rem;
            margin-top: .45rem; flex-wrap: wrap; }
.ack-gate { font-family: var(--mono); font-size: 10.5px; color: var(--ochre); line-height: 1.4; }
.ack-gate.ok { color: var(--accent); }
.ack-actions { display: flex; gap: .35rem; flex: 0 0 auto; }
.ack-attrib { margin-top: .45rem; padding-top: .4rem; border-top: 1px solid var(--line);
              font-size: 11px; color: var(--ink-soft); line-height: 1.5; }

/* =====================================================================
   The site's record level actions: the report, and the boundary after
   the site has been created.
   ===================================================================== */

.site-act { margin-top: 1rem; }
.site-act-block { border-top: 1px solid var(--line); padding-top: .75rem; }
.sa-head { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
           text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem;
           display: flex; justify-content: space-between; gap: .6rem; align-items: baseline; }
.sa-id { font-size: 10px; color: var(--ink-soft); letter-spacing: 0; text-transform: none; }
.sa-meta { font-size: 10.5px; color: var(--ink-soft); margin-bottom: .5rem; line-height: 1.5; }
.sa-row { display: flex; gap: .4rem; flex-wrap: wrap; }
.sa-note { margin-top: .45rem; }
.sa-msg { margin-top: .55rem; margin-bottom: 0; }
.okbox { border-left: 3px solid var(--accent); background: var(--accent-soft);
         padding: .6rem .75rem; font-size: 12.5px; margin-bottom: .75rem; }

/* ---------- the practice on the map ---------- */
.pr-map-label {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .02em; white-space: nowrap;
  color: #fff; background: rgba(16,20,18,.72); padding: 2px 6px;
  border: 1px solid rgba(255,79,163,.85); pointer-events: none;
}
.map-readout.practice { border-top-color: #ff4fa3; }
.map-readout.practice .ro-num { color: #ff4fa3; }
.lg-head-practice { margin-top: .35rem; border-top: 1px solid var(--line); padding-top: .3rem; }
.lg-row.practice .lg-dot { border-radius: 0; transform: rotate(45deg); }

/* A placeholder that says what a blank field will be filled with has to be
   distinguishable from a value that is actually there. Without this a number
   input showing "the top width" reads as a value nobody typed. */
input::placeholder, textarea::placeholder { color: var(--ink-soft); font-style: italic; opacity: 1; }

/* A run that came back with no practice section on it. Distinct from the
   state before any run, because the remedy is different and a user shown
   "not routed yet" presses Compute again and gets the same nothing. */
.pr-notrouted { border: 3px double var(--ochre); padding: .6rem .75rem; margin-bottom: 1rem; }
.pr-notrouted .nr-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
  font-weight: 700; color: var(--ochre); }
.pr-notrouted p { margin: .35rem 0 0; font-size: 12px; line-height: 1.55; color: var(--ink-mid); }

/* The brief form of a withheld figure: the headline and where the reason is,
   for the secondary slots the same refusal touches. Without it the engine's
   paragraph is printed four times on one page and stops being read. */
.pr-withheld.brief { border-style: dotted; padding: .35rem .5rem; }
.pr-withheld.brief .pw-l { font-size: 10px; }
.pr-withheld.brief .pw-r { font-size: 11px; margin-top: .2rem; }

/* A refused figure in a table cell. The word, not an em dash: a dash in a
   numeric column is read as a zero or as a missing input, and this is
   neither. */
.pr-refnum { font-family: var(--mono); font-size: 10.5px; letter-spacing: .05em;
             text-transform: uppercase; color: var(--red); border-bottom: 1px dotted var(--red);
             cursor: help; }

/* The brand is now a link back to the public site. It must not pick up the
   default link colour, because the wordmark's two-tone treatment is the
   identity and a blue underline would read as a mistake. */
a.brand { text-decoration: none; color: inherit; }
a.brand:hover span { text-decoration: underline; }
a.brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* =====================================================================
   THE CHANGE LOG

   Fourteen commit kinds and three colours. What a reviewer separates at a
   glance is a reading of the site from a change to it, and a change a person
   put their name behind from a change to the model, so three channels carry
   that and the verb itself stays where it already is, in the engine's own
   subject line.

   The claim family is drawn in the ochre this interface already uses for an
   overridden value and for a departure, so the colour means the same thing
   here as it does on the derived-data panel rather than being a fourth
   vocabulary a user has to learn.
   ===================================================================== */

.hs-controls { margin-bottom: .9rem; }
.hs-chips { display: flex; gap: .3rem; flex-wrap: wrap; }
.hs-chip {
  font-family: var(--sans); font-size: 12px; padding: .25rem .55rem; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--ink-mid);
  display: inline-flex; align-items: baseline; gap: .35rem; border-radius: 2px;
}
.hs-chip:hover { border-color: var(--accent); color: var(--accent); }
.hs-chip.on { background: var(--accent-soft); border-color: var(--accent-line);
              color: var(--accent); font-weight: 500; }
.hs-chip.alt.on { background: var(--ochre-soft); border-color: var(--ochre-line);
                  color: var(--ochre); }
.hs-n { font-family: var(--mono); font-size: 10px; color: var(--ink-soft);
        font-variant-numeric: tabular-nums; }
.hs-chip.on .hs-n { color: inherit; opacity: .8; }

/* Three lines, printed rather than hidden behind a legend key. Three is a
   legend somebody reads once; fourteen is one nobody reads at all. */
.hs-legend { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: .55rem;
             padding-top: .5rem; border-top: 1px solid var(--line); }
.hs-leg { font-size: 11px; color: var(--ink-soft); line-height: 1.45;
          flex: 1 1 200px; border-left: 3px solid var(--line-strong); padding-left: .5rem; }
.hs-leg b { display: block; font-family: var(--mono); font-size: 9.5px;
            letter-spacing: .1em; font-weight: 700; margin-bottom: .1rem;
            color: var(--ink-mid); }
.hs-leg-reading { border-left-color: var(--accent); }
.hs-leg-reading b { color: var(--accent); }
.hs-leg-claim { border-left-color: var(--ochre); }
.hs-leg-claim b { color: var(--ochre); }

.hs-diffbar {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: .6rem;
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  padding: .4rem .6rem;
}
.hs-dl, .hs-darr { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
                   text-transform: uppercase; color: var(--accent); }
.hs-dc { font-size: 12px; color: var(--ink); }
.hs-diffbar button { margin-left: auto; }
.hs-more { text-align: center; margin-top: .8rem; }

/* ---------- one commit ---------- */
.cm {
  border: 1px solid var(--line); border-left: 3px solid var(--line-strong);
  background: var(--surface); padding: .6rem .8rem; margin-bottom: .55rem;
}
.cm-claim { border-left-color: var(--ochre); }
/* A run is a reading of the site and not an edit, so it is the one family with
   a fill as well as a rail: the runs have to be findable by eye in a column of
   forty commits without reading any of them. */
.cm-reading { border-left-width: 6px; border-left-color: var(--accent);
              background: var(--accent-soft); }
.cm-gone { opacity: .62; }
.cm-gone:hover { opacity: 1; }
.cm-sel { outline: 2px solid var(--accent); outline-offset: 1px; }

.cm-top { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.cm-seq { font-family: var(--mono); font-size: 11px; font-weight: 600;
          color: var(--ink-soft); font-variant-numeric: tabular-nums;
          min-width: 1.6rem; }
.cm-fam { font-family: var(--mono); font-size: 9px; letter-spacing: .11em;
          font-weight: 700; color: var(--ink-mid); border: 1px solid var(--line-strong);
          padding: 0 4px; }
.cm-reading .cm-fam { color: var(--accent); border-color: var(--accent-line);
                      background: var(--surface); }
.cm-claim .cm-fam { color: var(--ochre); border-color: var(--ochre-line); }
.cm-kind { font-size: 10.5px; color: var(--ink-soft); }
.cm-storm { font-family: var(--mono); font-size: 11px; color: var(--accent);
            font-variant-numeric: tabular-nums; }
.cm-meta { margin-left: auto; font-family: var(--mono); font-size: 10px;
           color: var(--ink-soft); white-space: nowrap; }
.cm-selm { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
           text-transform: uppercase; color: var(--surface); background: var(--accent);
           padding: 1px 5px; }
.cm-subject { font-size: 14px; line-height: 1.45; margin-top: .3rem; }

/* ---------- the six pricing states ----------
   The rail says whether an evaluation happened at all. Solid means the engine
   ran on both sides and the storm it ran at is named on the line; dashed means
   nothing was evaluated, which is the same grammar the derived-data panel uses
   for a service that did not answer. Telling a change that MOVED NOTHING from
   a change NOBODY PRICED is the distinction this whole block exists for. */
.cm-price { margin-top: .45rem; padding: .35rem .6rem; border-left: 3px solid var(--line);
            background: var(--sunk); }
.cm-price.unevaluated { border-left-style: dashed; background: transparent; }
.cm-pl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         font-weight: 700; color: var(--ink-mid); display: flex; gap: .5rem;
         flex-wrap: wrap; align-items: baseline; }
.cm-pb { font-size: 12.5px; line-height: 1.55; color: var(--ink); margin-top: .25rem; }
.cm-pnow { font-family: var(--sans); font-size: 10px; font-weight: 400;
           letter-spacing: 0; color: var(--accent); }
.cm-phint { font-size: 11px; line-height: 1.5; color: var(--ink-soft); margin-top: .3rem; }
.cm-pact { margin-top: .4rem; display: flex; gap: .5rem; align-items: flex-start;
           flex-wrap: wrap; }
.cm-pact .cm-phint { flex: 1 1 240px; margin-top: 0; }

.p-priced { border-left-color: var(--accent); }
.p-priced .cm-pl { color: var(--accent); }
/* Evaluated, and nothing moved. A real answer, so it keeps the solid rail and
   names its storm; it is only the colour that says no figure changed. */
.p-flat { border-left-color: var(--line-strong); }
.p-flat .cm-pl { color: var(--ink-mid); }
.p-none .cm-pl { color: var(--ink-soft); }
.p-defer { border-left-color: var(--ochre); }
.p-defer .cm-pl { color: var(--ochre); }
.p-declined { border-left-color: var(--red); }
.p-declined .cm-pl { color: var(--red); }

.cm-super { margin-top: .45rem; border-left: 3px solid var(--line-strong);
            padding: .3rem .6rem; font-family: var(--mono); font-size: 9.5px;
            letter-spacing: .09em; font-weight: 700; color: var(--ink-soft);
            background: var(--sunk); }
.cm-super span { display: block; font-family: var(--sans); font-size: 11px;
                 font-weight: 400; letter-spacing: 0; color: var(--ink-soft);
                 margin-top: .2rem; line-height: 1.5; }
.cm-super button { font-size: 11px; margin-top: .25rem; }

.cm-acts { display: flex; gap: .9rem; margin-top: .45rem; }
.cm-acts .linkish { font-size: 11.5px; }

/* ---------- the detail ---------- */
.cm-detail { margin-top: .6rem; padding-top: .55rem; border-top: 1px solid var(--line); }
.cm-sub { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
          text-transform: uppercase; color: var(--ink-soft); margin: .6rem 0 .3rem; }
.cm-sub:first-child { margin-top: 0; }
.cm-figs { font-size: 12px; }
.cm-figs td { vertical-align: top; }
.cm-fk { display: block; font-size: 9.5px; color: var(--ink-soft); }
.cm-word { font-family: var(--mono); font-size: 10px; letter-spacing: .05em;
           text-transform: uppercase; color: var(--ink-soft); }
tr.dir-appeared .cm-word, tr.dir-withheld .cm-word { color: var(--red); }
.cm-d { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.cm-d.up { color: var(--ochre); }
.cm-d.down { color: var(--accent); }
.cm-pct { font-size: 10.5px; color: var(--ink-soft); }
.cm-fnote td { font-size: 11px; color: var(--ink-soft); line-height: 1.5;
               padding-top: 0; }
.cm-pay td { font-size: 12px; }
.cm-pay td:first-child { width: 30%; color: var(--ink-soft); }
.cm-segs { font-size: 12px; }
.cm-snapc { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
            text-transform: uppercase; color: var(--ink-mid); margin: .5rem 0 .2rem; }
.cm-snapline { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
               margin-top: .25rem; }
.cm-meta2 { margin-top: .6rem; padding-top: .4rem; border-top: 1px solid var(--line);
            font-size: 10px; line-height: 1.55; color: var(--ink-soft);
            word-break: break-word; }

/* ---------- the diff ---------- */
.hd-heads { display: grid; grid-template-columns: 1fr auto 1fr; gap: .9rem;
            align-items: stretch; margin-bottom: .9rem; }
@media (max-width: 760px) { .hd-heads { grid-template-columns: 1fr; } }
.hd-stub { border: 1px solid var(--line); border-top: 3px solid var(--line-strong);
           padding: .5rem .65rem; background: var(--sunk); }
.hd-sl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
         text-transform: uppercase; color: var(--ink-soft); }
.hd-ss { font-size: 13px; font-weight: 500; display: flex; gap: .5rem;
         align-items: baseline; }
.hd-ss .mono { font-size: 10.5px; font-weight: 400; color: var(--ink-soft); }
.hd-sub { font-size: 12.5px; line-height: 1.5; margin-top: .2rem; }
.hd-sm { font-family: var(--mono); font-size: 10px; color: var(--ink-soft);
         margin-top: .25rem; }
.hd-arrow { display: flex; align-items: center; justify-content: center;
            font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
            text-transform: uppercase; color: var(--ink-soft); text-align: center;
            max-width: 7rem; line-height: 1.4; }
.hd-note { font-size: 11.5px; line-height: 1.55; color: var(--ink-soft);
           margin-top: .55rem; }
.hd-groups { margin-top: 1rem; }
.hd-group { margin-bottom: .9rem; }
.hd-gh { font-family: var(--serif); font-size: .92rem; font-weight: 600;
         padding-bottom: .25rem; border-bottom: 1px solid var(--line);
         margin-bottom: .4rem; }
.hd-gh span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
              text-transform: uppercase; color: var(--ochre); margin-left: .4rem; }
.hd-gl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         text-transform: uppercase; color: var(--ink-soft); margin: .4rem 0 .15rem; }
.hd-row { display: flex; gap: .6rem; flex-wrap: wrap; font-size: 12.5px;
          line-height: 1.55; padding: .15rem 0; }
.hd-n { font-weight: 500; min-width: 8rem; }
.hd-v { color: var(--ink-mid); flex: 1 1 12rem; }
.hd-f { font-family: var(--mono); font-size: 11px; color: var(--ink); }

/* =====================================================================
   REFUSALS AND WAIVERS

   Four states on one refusal, and they are not four severities. A standing
   refusal is a refusal. An overruled one is a refusal a named person released,
   and it stays exactly where it was. A refusal carrying a waiver that did not
   clear is a refusal that stands with a failed attempt attached, which is a
   real third state and is the one an interface usually draws as a success. A
   structural refusal has no number behind it and offers nothing at all.
   ===================================================================== */

.wv-list > .refuse:first-child { margin-top: 0; }
.refuse.rf-standing { border-left-color: var(--red); }
/* An overruled refusal is not red. Red is the engine withholding a figure, and
   here it is not withholding one any more: a named person released it and the
   whole record of that is under the refusal. Ochre is the colour this interface
   already gives to a value a person overrode, which is the same act one layer
   down. */
.refuse.rf-overruled { border-left: 5px double var(--ochre); background: var(--ochre-soft); }
.refuse.rf-overruled .rf-l { color: var(--ochre); }
.refuse.rf-failed { border-left: 5px double var(--red); }
.refuse.rf-structural { border-left: 5px double var(--red); }
.rf-l { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.rf-tax { margin-left: auto; display: flex; gap: .35rem; align-items: baseline;
          font-weight: 400; letter-spacing: 0; text-transform: none; }
.rf-tax .mono { font-size: 10.5px; color: var(--ink-mid); }
.rf-w { font-size: 12px; line-height: 1.55; color: var(--ink-mid); margin-top: .35rem; }
.rf-w span, .rf-s span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
                         text-transform: uppercase; color: var(--ink-soft);
                         display: block; }

.wv-cls { font-family: var(--mono); font-size: 9px; letter-spacing: .08em;
          text-transform: uppercase; padding: 1px 5px; border: 1px solid;
          border-radius: 2px; cursor: help; }
.wv-policy { color: var(--ochre); border-color: var(--ochre-line); background: var(--ochre-soft); }
.wv-evidence { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.wv-structural { color: var(--red); border-color: var(--red); background: var(--red-soft); }

.wv-slot { margin-top: .5rem; }
.wv-note { font-size: 11.5px; line-height: 1.55; color: var(--ink-soft); }

/* The waiver already on a refusal. It sits under the refusal and never in
   place of it: the refusal fired, and a named person overruled it, and a
   report has to show both. */
.wv-stamp { border-left: 3px solid var(--ochre); background: var(--ochre-soft);
            padding: .4rem .6rem; margin-top: .5rem; }
.wv-stamp.failed { border-left-color: var(--red); background: var(--red-soft); }
.wv-sl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
         font-weight: 700; color: var(--ochre); }
.wv-stamp.failed .wv-sl { color: var(--red); }
.wv-sr { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid); margin-top: .2rem; }
.wv-sq { font-size: 12px; line-height: 1.55; color: var(--ink); margin-top: .3rem;
         border-left: 2px solid var(--line-strong); padding-left: .5rem; }

/* A structural refusal. The engine's two sentences, quoted and not softened. */
.wv-struct { border: 3px double var(--red); background: var(--red-soft);
             padding: .55rem .7rem; }
.wv-sh { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         font-weight: 700; color: var(--red); margin-bottom: .15rem; }
.wv-struct p { margin: 0 0 .5rem; font-size: 12.5px; line-height: 1.6; color: var(--ink); }
.wv-sfoot { font-size: 11px; line-height: 1.55; color: var(--ink-soft);
            border-top: 1px solid var(--red); padding-top: .35rem; }

/* ---------- the waiver control ---------- */
.wv-form { border: 1px solid var(--line-strong); background: var(--sunk);
           padding: .7rem .8rem; }
.wv-fh { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
         font-weight: 700; color: var(--ink-mid); display: flex; gap: .45rem;
         align-items: baseline; margin-bottom: .4rem; }
.wv-demand { font-size: 12px; line-height: 1.55; color: var(--ink-mid);
             margin-bottom: .45rem; }
.wv-kinds { display: flex; flex-wrap: wrap; gap: .25rem; margin-bottom: .5rem; }
.wv-lab { display: block; font-family: var(--mono); font-size: 9.5px;
          letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
          margin-bottom: .2rem; }
.wv-val { width: 100%; }
.wv-hint { font-size: 11px; line-height: 1.5; color: var(--ink-soft); margin-top: .25rem; }

/* The demand and the progress toward it, shown rather than enforced. The
   button below is never disabled for a short reason: filing below the bar is a
   real outcome and the button says which outcome pressing it produces. */
.wv-meter { margin: .35rem 0 .55rem; }
.wv-mbar, .wl-bar { height: 4px; background: var(--line); overflow: hidden; }
.wv-mbar i, .wl-bar i { display: block; height: 100%; background: var(--ochre); }
.wv-meter.ok .wv-mbar i, .wl-bar.ok i { background: var(--accent); }
.wv-ml, .wl-barl { font-family: var(--mono); font-size: 10px; color: var(--ochre);
                   margin-top: .2rem; }
.wv-meter.ok .wv-ml, .wl-bar.ok + .wl-barl { color: var(--accent); }

.wv-foot { display: flex; align-items: flex-start; justify-content: space-between;
           gap: .7rem; margin-top: .4rem; flex-wrap: wrap; }
.wv-gate { font-size: 11.5px; line-height: 1.55; color: var(--ochre); flex: 1 1 16rem; }
.wv-gate.ok { color: var(--accent); }
.wv-gate.bad { color: var(--red); }
.wv-acts { display: flex; gap: .35rem; flex: 0 0 auto; align-items: flex-start; }
.wv-attrib { margin-top: .5rem; padding-top: .4rem; border-top: 1px solid var(--line);
             font-size: 10.5px; line-height: 1.5; color: var(--ink-soft); }
.wv-busy { font-family: var(--mono); font-size: 10px; color: var(--ink-soft);
           margin-top: .3rem; }

/* ---------- what filing actually produced ----------
   Three outcomes and three treatments. The middle one is deliberately not
   green and deliberately not quiet: a 201 that released nothing must not look
   like a 201 that released a figure. */
.wv-out { border: 3px double var(--accent); background: var(--accent-soft);
          padding: .55rem .7rem; }
.wv-out.failed { border-color: var(--ochre); background: var(--ochre-soft); }
.wv-out.refused { border-color: var(--red); background: var(--red-soft); }
.wv-ol { font-family: var(--mono); font-size: 10px; letter-spacing: .09em;
         font-weight: 700; color: var(--accent); line-height: 1.4; }
.wv-out.failed .wv-ol { color: var(--ochre); }
.wv-out.refused .wv-ol { color: var(--red); }
.wv-or { font-size: 12.5px; line-height: 1.55; color: var(--ink); margin-top: .3rem; }
.wv-of { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid); margin-top: .3rem; }
.wv-out button { margin-top: .45rem; }

/* ---------- the waiver ledger ---------- */
.wl { border: 1px solid var(--line); border-left: 4px solid var(--ochre);
      padding: .6rem .7rem; margin-bottom: .6rem; background: var(--surface); }
.wl-cleared { border-left-color: var(--ochre); }
.wl-failed { border-left-color: var(--red); }
.wl-gone { border-left-color: var(--line-strong); opacity: .72; }
.wl-gone:hover { opacity: 1; }
.wl-h { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
        font-weight: 700; color: var(--ochre); display: flex; gap: .4rem;
        align-items: baseline; flex-wrap: wrap; }
.wl-failed .wl-h { color: var(--red); }
.wl-gone .wl-h { color: var(--ink-soft); }
.wl-id { font-size: 10.5px; font-weight: 400; letter-spacing: 0; color: var(--ink-mid); }
.wl-refuses { font-size: 12.5px; line-height: 1.5; margin-top: .3rem; }
.wl-who { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft);
          margin-top: .25rem; }
.wl-num { font-size: 11.5px; line-height: 1.5; color: var(--ink-mid); margin-top: .25rem; }
.wl-bar { margin-top: .4rem; }
.wl-att { font-size: 11.5px; line-height: 1.5; color: var(--ink-mid); margin-top: .3rem; }
.wl-att span:first-child { display: block; font-family: var(--mono); font-size: 9px;
                           letter-spacing: .09em; text-transform: uppercase;
                           color: var(--ink-soft); }
.wl-reason { font-size: 12px; line-height: 1.55; color: var(--ink); margin-top: .35rem;
             border-left: 2px solid var(--line-strong); padding-left: .5rem; }
.wl-note { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid); margin-top: .35rem; }
.wl-res { font-size: 11.5px; line-height: 1.55; color: var(--ink-soft); margin-top: .35rem; }
.wl-res span { display: block; font-family: var(--mono); font-size: 9px;
               letter-spacing: .09em; text-transform: uppercase; }
.wl-line { margin-top: .4rem; }
.wl-line summary { font-family: var(--mono); font-size: 10px; letter-spacing: .06em;
                   color: var(--ink-soft); cursor: pointer; }
.wl-line p { font-size: 11px; line-height: 1.6; color: var(--ink-mid);
             margin: .3rem 0 0; border-left: 2px solid var(--line); padding-left: .5rem; }
.wl-wd { border: 1px solid var(--line-strong); background: var(--sunk);
         padding: .5rem .6rem; margin-top: .5rem; }
.wl-wdh { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
          font-weight: 700; color: var(--ink-mid); }
.wl-wdw { font-size: 11px; line-height: 1.5; color: var(--ink-soft); margin-top: .25rem; }
.wl-wdacts { display: flex; gap: .35rem; justify-content: flex-end; margin-top: .4rem; }

/* The local list of sites this browser has opened. Named for what it is: the
   API publishes no route that lists a project's sites, so this is a
   convenience held in one browser and not a record of anything. */
#recent-sites { margin-top: .9rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.rs-head { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
           text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem; }

/* What the refusal is costing right now, under the state line rather than
   beside it. Beside it, the two run together in a narrow column and the state
   word stops being the first thing read. */
.rf-eff { font-size: 11.5px; line-height: 1.5; color: var(--ink-mid); margin-top: .2rem; }

/* The optional value field's hint runs straight into the next label without
   this, and two blocks of small grey type with no gap read as one paragraph. */
.wv-hint { margin-bottom: .55rem; }

/* A long commit message, folded after its opening. Nothing is summarised and
   nothing is dropped: a derivation that refused a headline carries the whole
   refusal, and a log with twelve lines of it in the middle is one a reader
   scrolls past instead of reading. */
.cm-more { margin-top: .3rem; }
.cm-more summary { font-family: var(--mono); font-size: 10px; letter-spacing: .06em;
                   color: var(--ink-soft); cursor: pointer; }
.cm-more summary:hover { color: var(--accent); }
.cm-more p { margin: .3rem 0 0; font-size: 12.5px; line-height: 1.55;
             color: var(--ink-mid); }

/* The figure table is the same element in a narrow commit and in the full
   width diff panel. Left to itself it stretches to 1,400 px there, which puts
   a metre of empty rule between the name of a figure and its two numbers. */
.cm-figs { max-width: 1050px; }

/* =====================================================================
   THE FOURTH DESTINATION.

   Water drawn out of a practice for a use left the site as neither runoff
   nor recharge. It is the fifth term in the volume balance and the fourth
   credited destination, and it needed a fourth value on every one of the
   four channels rather than a legend to carry the difference. Border: a
   segmented heavy rule, against solid, double and dashed. Fill: a stipple,
   against plain and the two opposed hatches. Colour last, as always.
   ===================================================================== */

.split .grp.use {
  border-left: 6px solid var(--use);
  border-image: repeating-linear-gradient(to bottom, var(--use) 0 6px,
                transparent 6px 10px) 6;
  background-image: radial-gradient(var(--stipple) 1px, transparent 1.3px);
  background-size: 7px 7px;
}
.split .grp.use .grp-h { color: var(--use); }
.ch.use .credit { color: var(--use); }
.meter.use .fill { background: var(--use); }

/* The antecedent term is on the INFLOW side of the balance and it is not a
   destination at all, so it is drawn before the credited blocks and outside
   the grammar they use: a thin bracket rather than a rule, and no fill. */
.split .grp.before { border-left: 3px solid var(--line-strong);
                     border-top: 1px solid var(--line);
                     border-bottom: 1px solid var(--line); }
.split .grp.before .grp-h { color: var(--ink-soft); }
.ch.before .credit { color: var(--ink-soft); }
.meter.before .fill { background: var(--ink-soft); }

.split-terms { margin-top: .4rem; padding-top: .4rem;
               border-top: 1px solid var(--line); font-size: 11px;
               color: var(--ink-soft); line-height: 1.5; }

/* =====================================================================
   A RESOLUTION, WHICH IS NOT A WAIVER.

   Marked so the two cannot be confused at a glance, on the same channels
   the printed report uses and in the same order of reliability. The word
   first: every block is headed RESOLVED REFUSAL and carries NOT A WAIVER as
   its own boxed token. Then the rule: a single SOLID left rule against the
   waiver's heavy DOUBLE one. Then the fill: plain, against the waiver's
   hatch. Then colour, which is last because it is the weakest and the first
   thing a photocopy loses.

   They are also in a different SECTION with a different heading, and that is
   the channel that actually carries it: a reader who sees "Refusals a
   supplied input resolved" above one block and "Refusals a person overruled"
   above the other has been told the difference in words before reading
   either.
   ===================================================================== */

.rsl-list { margin-top: .3rem; }
.rsl-head { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            text-transform: uppercase; font-weight: 700; color: var(--accent);
            margin-bottom: .45rem; }
.rsl-head span { display: block; font-family: var(--sans); font-size: 11.5px;
                 letter-spacing: 0; text-transform: none; font-weight: 400;
                 color: var(--ink-mid); line-height: 1.55; margin-top: .25rem; }
.rsl { border-left: 6px solid var(--accent); background: var(--sunk);
       padding: .6rem .75rem; margin-bottom: .55rem; }
.rsl.weak { border-left-color: var(--ochre); }
.rsl-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         text-transform: uppercase; font-weight: 700; color: var(--accent);
         display: flex; gap: .45rem; align-items: center; flex-wrap: wrap; }
.rsl.weak .rsl-l { color: var(--ochre); }
.rsl-not { font-family: var(--mono); font-size: 8.5px; letter-spacing: .14em;
           border: 1px solid currentColor; padding: 1px 5px; white-space: nowrap; }
.rsl-what { font-size: 12px; line-height: 1.55; color: var(--ink); margin-top: .4rem; }
.rsl-what span, .rsl-before span {
  display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-soft); }
.rsl-before { font-size: 12px; line-height: 1.55; color: var(--ink-mid);
              margin-top: .45rem; padding: .45rem .55rem;
              border: 1px dashed var(--line-strong); }
.rsl-h { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
         text-transform: uppercase; color: var(--ink-soft); margin-top: .5rem; }
.rsl-in { margin: .2rem 0 0 1.1rem; padding: 0; font-size: 11.5px;
          color: var(--ink-mid); line-height: 1.6; }
.rsl-who { font-size: 11px; color: var(--ink-soft); line-height: 1.5;
           margin-top: .45rem; }
/* The designer's own assumption is the weakest of the three provenances and
   is never allowed to look like the other two. */
.rsl-weak, .gr-weak, .pr-weakest {
  font-size: 11.5px; line-height: 1.55; color: var(--ink); margin-top: .5rem;
  border: 2px dashed var(--ochre); background: var(--ochre-soft);
  padding: .45rem .6rem; }
.rsl-weak::first-line, .gr-weak::first-line, .pr-weakest::first-line {
  font-family: var(--mono); font-weight: 700; }
.rsl-margin { font-size: 12px; line-height: 1.55; color: var(--ink);
              margin-top: .45rem; }
.rsl-note { font-size: 11.5px; color: var(--ink-mid); line-height: 1.5;
            margin-top: .35rem; }
.rsl-line { margin-top: .45rem; font-size: 11px; color: var(--ink-soft); }
.rsl-line summary { cursor: pointer; font-family: var(--mono); font-size: 10px;
                    letter-spacing: .06em; }
.rsl-line p { font-size: 11.5px; line-height: 1.6; color: var(--ink-mid);
              margin: .35rem 0 0; }
.rsl-scope { font-size: 10px; color: var(--ink-soft); margin-top: .35rem; }

/* The offer under a refusal that named an input. It is an offer to SUPPLY and
   never an offer to overrule, so it carries the same NOT A WAIVER token a
   resolution does and the same solid accent rule. */
.rsv-offer, .pr-resolvable {
  border: 1px solid var(--accent-line); border-left: 6px solid var(--accent);
  background: var(--accent-soft); padding: .6rem .75rem; margin-top: .6rem; }
.rsv-oh, .prr-l { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
                  text-transform: uppercase; font-weight: 700; color: var(--accent);
                  display: flex; gap: .45rem; align-items: center; flex-wrap: wrap; }
.rsv-offer p, .pr-resolvable p { font-size: 12px; line-height: 1.55;
                                 color: var(--ink-mid); margin: .4rem 0 0; }
.rsv-needs { font-size: 12px; line-height: 1.55; margin-top: .4rem; }
.rsv-needs span, .rsv-becomes span { display: block; font-family: var(--mono);
  font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-soft); }
.rsv-becomes { font-size: 12px; line-height: 1.55; margin-top: .4rem; }
.rsv-list, .prr-list { margin: .3rem 0 0 1.1rem; padding: 0; font-size: 11.5px;
                       color: var(--ink); line-height: 1.6; }
.rsv-act, .prr-act { display: flex; gap: .5rem; align-items: center;
                     flex-wrap: wrap; margin-top: .6rem; }
.rsv-route { font-size: 10px; color: var(--ink-soft); }
.rsv-foot, .prr-foot { font-size: 11px; color: var(--ink-mid); line-height: 1.5;
                       margin-top: .5rem; padding-top: .4rem;
                       border-top: 1px solid var(--accent-line); }

/* =====================================================================
   THE SUPPLIED INPUTS ON THE PRACTICE FORM: two tables and a schedule.
   ===================================================================== */

.pr-curvekind { border: 1px solid var(--accent-line); border-left: 6px solid var(--accent);
                background: var(--accent-soft); padding: .6rem .75rem; margin: .6rem 0; }
.pr-curvekind p { font-size: 12px; line-height: 1.55; color: var(--ink-mid);
                  margin: .4rem 0 0; }
.pr-curves { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem;
             margin-top: .6rem; }
@media (max-width: 1100px) { .pr-curves { grid-template-columns: 1fr; } }
.pr-curve { border: 1px solid var(--line); padding: .5rem .6rem; }
.pc-h { font-size: 12px; font-weight: 600; display: flex; justify-content: space-between;
        gap: .5rem; flex-wrap: wrap; align-items: baseline; }
.pc-u { font-family: var(--mono); font-size: 10px; color: var(--ink-soft); }
.pc-grid { display: grid; grid-template-columns: 1fr 1fr auto; gap: .25rem;
           margin-top: .45rem; align-items: center; }
.pc-hd { font-family: var(--mono); font-size: 9.5px; letter-spacing: .07em;
         text-transform: uppercase; color: var(--ink-soft); }
.pc-cell input { width: 100%; font-family: var(--mono);
                 font-variant-numeric: tabular-nums; }
.pc-cell.bad input { border-color: var(--red); background: var(--red-soft); }
.pc-x { display: flex; align-items: center; gap: .35rem; }
.pc-fixed { font-size: 10px; color: var(--ink-soft); }
.pc-bad { font-size: 10px; color: var(--red); line-height: 1.35; }
.pc-acts { display: flex; gap: .35rem; margin-top: .45rem; }
.pr-curvetop { margin-top: .6rem; font-size: 11.5px; color: var(--ink);
               border-left: 3px solid var(--accent); background: var(--accent-soft);
               padding: .45rem .6rem; line-height: 1.55; }
.pr-declares { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem;
               margin-top: .7rem; }
@media (max-width: 820px) { .pr-declares { grid-template-columns: 1fr; } }
.pr-pick.weakest { border-style: dashed; }
.pr-pick.weakest.on { background: var(--ochre); border-color: var(--ochre);
                      color: var(--surface); }
.pr-pick.resolvable { border-color: var(--accent-line); }
.pr-pick.curved { border-style: dotted; }

/* The twelve month demand schedule. Twelve boxes and twelve bars, because the
   seasonal failure is the whole point of asking for twelve: an interface that
   took an annual average would credit a tank in the month it does nothing. */
.pr-months { display: grid; grid-template-columns: repeat(12, 1fr); gap: .3rem;
             margin-top: .6rem; }
@media (max-width: 1000px) { .pr-months { grid-template-columns: repeat(6, 1fr); } }
@media (max-width: 560px) { .pr-months { grid-template-columns: repeat(3, 1fr); } }
.pr-month { border: 1px solid var(--line); padding: .3rem .25rem; }
.pr-month.storm { border-color: var(--accent); background: var(--accent-soft); }
.pm-name { display: block; width: 100%; font-family: var(--mono); font-size: 10px;
           letter-spacing: .06em; text-transform: uppercase; background: none;
           border: 0; border-bottom: 1px solid transparent; color: var(--ink-soft);
           cursor: pointer; padding: 0 0 .15rem; }
.pm-name:hover { color: var(--accent); border-bottom-color: var(--accent-line); }
.pr-month.storm .pm-name { color: var(--accent); font-weight: 700; }
/* The spinner arrows on a number input eat a third of a box this narrow and
   clip the value, and a schedule that shows 2 where 20 was typed is worse than
   no schedule at all. */
.pr-month input { width: 100%; font-family: var(--mono); font-size: 11px;
                  padding: .15rem .25rem; font-variant-numeric: tabular-nums;
                  -moz-appearance: textfield; appearance: textfield; }
.pr-month input::-webkit-outer-spin-button,
.pr-month input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pm-bar { height: 34px; margin-top: .25rem; background: var(--sunk);
          display: flex; align-items: flex-end; }
.pm-bar i { display: block; width: 100%; background: var(--accent-line);
            min-height: 1px; }
.pr-month.storm .pm-bar i { background: var(--accent); }
.pm-storm { font-size: 9px; color: var(--accent); line-height: 1.25; margin-top: .2rem; }

/* The span of antecedent states. The engine refuses to pick a point on it, so
   the interface draws the whole of it and marks where the stated state falls,
   with the requirement on the same axis. */
.pr-span { border: 1px solid var(--line-strong); padding: .6rem .75rem; }
.ps-track { position: relative; height: 16px; background: var(--sunk);
            border: 1px solid var(--line); }
.ps-fill { display: block; height: 100%; background: var(--accent-soft);
           border-right: 2px solid var(--accent); }
.ps-at { position: absolute; top: -4px; bottom: -4px; width: 2px;
         background: var(--accent); }
.ps-req { position: absolute; top: -4px; bottom: -4px; width: 2px;
          background: var(--ochre); }
.ps-ends { display: flex; justify-content: space-between; font-family: var(--mono);
           font-size: 10px; color: var(--ink-soft); margin-top: .25rem; }
.ps-marks { margin-top: .5rem; display: grid; gap: .3rem; }
.ps-mark { font-size: 11.5px; color: var(--ink-mid); line-height: 1.5;
           border-left: 3px solid var(--accent); padding-left: .5rem; }
.ps-mark.req { border-left-color: var(--ochre); }
.ps-mark b { display: block; font-family: var(--mono); color: var(--ink); }
.ps-note { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
           margin-top: .55rem; padding-top: .45rem; border-top: 1px solid var(--line); }

/* The supplied curve drawn against the stage the storm reached. The region
   past the top of the table is shaded because it is the region the device is
   not rated for, and the whole point of the guard is that the engine will not
   compute in it. */
.pr-curveview { border: 1px solid var(--line-strong); padding: .6rem .75rem; }
.cv { width: 100%; height: auto; display: block; }
.cv-off { fill: var(--red-soft); }
.cv-ax { stroke: var(--line-strong); stroke-width: 1; }
.cv-line { fill: none; stroke: var(--accent); stroke-width: 2; }
.cv-pt { fill: var(--accent); }
.cv-top { stroke: var(--red); stroke-width: 1.5; stroke-dasharray: 3 3; }
.cv-reached { stroke: var(--ink); stroke-width: 1.5; }
.cv-tl { fill: var(--red); font-family: var(--mono); font-size: 9px; }
.cv-rl { fill: var(--ink); font-family: var(--mono); font-size: 9px; }
.cv-lab { fill: var(--ink-soft); font-family: var(--mono); font-size: 9px; }
.cv-read { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: .5rem;
           font-size: 11.5px; color: var(--ink-mid); line-height: 1.5; }
.cv-read b { font-family: var(--mono); color: var(--ink); }

/* =====================================================================
   THE GREEN ROOF, WHICH IS NOT A PRACTICE.

   The margin is the headline and the boolean is the word above it, because a
   roof that captures the storm with an hour to spare and one that captures it
   with a week are the same boolean and different designs.
   ===================================================================== */

.gr-margin { border: 1px solid var(--line-strong); border-left: 6px solid var(--accent);
             padding: .7rem .8rem; margin-bottom: .9rem; }
.gr-margin.short { border-left-color: var(--red); }
.gr-ml { font-family: var(--mono); font-size: 10px; letter-spacing: .11em;
         font-weight: 700; color: var(--accent); }
.gr-margin.short .gr-ml { color: var(--red); }
.gr-mn { font-family: var(--mono); font-size: 2.1rem; font-weight: 600; line-height: 1.1;
         letter-spacing: -.02em; margin-top: .2rem;
         font-variant-numeric: tabular-nums; color: var(--accent); }
.gr-margin.short .gr-mn { color: var(--red); }
.gr-mn .u { font-family: var(--sans); font-size: .78rem; font-weight: 400;
            color: var(--ink-soft); letter-spacing: 0; }
.gr-bars { display: grid; gap: .5rem; margin-top: .7rem; }
.gr-bl { font-size: 11px; color: var(--ink-mid); }
.gr-track { height: 10px; background: var(--sunk); border: 1px solid var(--line);
            margin-top: .2rem; }
.gr-track i { display: block; height: 100%; background: var(--ink-soft); }
.gr-track.given i { background: var(--accent); }
.gr-bv { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft);
         margin-top: .15rem; }
.gr-mnote { font-size: 12px; color: var(--ink); line-height: 1.55; margin-top: .6rem; }
.gr-mwhy { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
           margin-top: .4rem; padding-top: .4rem; border-top: 1px solid var(--line); }
.gr-refusal { border: 2px dashed var(--red); padding: .55rem .7rem; margin: .6rem 0; }
.gr-rl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         font-weight: 700; color: var(--red); }
.gr-refusal p { font-size: 12px; line-height: 1.55; color: var(--ink-mid);
                margin: .35rem 0 0; }
.gr-supplied { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
               border-left: 3px solid var(--accent-line); padding-left: .6rem;
               margin-bottom: .6rem; }
.gr-notrouted { border: 3px double var(--ink); padding: .6rem .75rem; margin-top: .8rem; }
.gr-nrl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
          font-weight: 700; color: var(--ink); }
.gr-notrouted p { font-size: 12px; line-height: 1.55; color: var(--ink-mid);
                  margin: .35rem 0 0; }
.gr-acts { display: flex; gap: .4rem; margin-top: .9rem; flex-wrap: wrap; }

/* =====================================================================
   THE JURISDICTION: the manual, its rules, the credits and the verdict.
   ===================================================================== */

.ju-none { border: 1px dashed var(--line-strong); padding: .9rem 1rem; }
.ju-nonel { font-family: var(--mono); font-size: 10px; letter-spacing: .11em;
            font-weight: 700; color: var(--ink-mid); }
.ju-none p { font-size: 12.5px; line-height: 1.6; color: var(--ink-mid);
             margin: .45rem 0; }
.ju-adopt { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: .7rem; }
.ju-adoptl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
             text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem; }
.ju-adoptrow { display: flex; align-items: center; justify-content: space-between;
               gap: .7rem; border: 1px solid var(--line); padding: .45rem .6rem;
               margin-bottom: .35rem; }
.ju-adoptrow .n { font-size: 12.5px; font-weight: 600; }
.ju-adoptrow .m { font-size: 11px; color: var(--ink-soft); }

.ju-card { border: 1px solid var(--line-strong); padding: .7rem .85rem;
           margin-bottom: 1rem; }
.ju-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
        font-weight: 700; color: var(--ink); display: flex; gap: .5rem;
        flex-wrap: wrap; align-items: center; }
.ju-sup { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
          border: 1px solid var(--ochre); color: var(--ochre); padding: 1px 5px; }
.ju-cite-line { font-family: var(--serif); font-size: 14px; line-height: 1.6;
                font-weight: 600; margin-top: .4rem; }
.ju-acts { display: flex; gap: .4rem; margin-top: .7rem; flex-wrap: wrap; }
.ju-basis { border: 1px solid var(--accent-line); background: var(--accent-soft);
            padding: .55rem .7rem; }
.ju-basisl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
             font-weight: 700; color: var(--accent); }
.ju-basis p { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
              margin: .35rem 0 0; }
.ju-cite { margin-top: .7rem; }
.ju-cite label { display: block; font-size: 11.5px; color: var(--ink-mid);
                 margin-bottom: .25rem; }
.ju-cite textarea { width: 100%; font-size: 12.5px; line-height: 1.5;
                    resize: vertical; }
.ju-meter { margin-top: .35rem; }
.ju-mbar { height: 5px; background: var(--sunk); border: 1px solid var(--line); }
.ju-mbar i { display: block; height: 100%; background: var(--ochre); }
.ju-meter.ok .ju-mbar i { background: var(--accent); }
.ju-ml { font-size: 10.5px; color: var(--ink-soft); line-height: 1.45;
         margin-top: .2rem; }
.ju-noed { display: flex; gap: .6rem; align-items: flex-start; margin-top: .6rem;
           flex-wrap: wrap; }
.ju-noed span { flex: 1 1 18rem; font-size: 11px; color: var(--ink-soft);
                line-height: 1.5; }

.ju-figrow { display: grid; grid-template-columns: 2fr 1fr 1fr 1.4fr auto;
             gap: .35rem; align-items: start; border: 1px solid var(--line);
             padding: .45rem .5rem; margin-bottom: .45rem; }
@media (max-width: 1000px) { .ju-figrow { grid-template-columns: 1fr 1fr; } }
.ju-figrow input, .ju-figrow select { width: 100%; }
.ju-fignote { grid-column: 1 / -1; font-size: 10.5px; color: var(--ink-soft);
              line-height: 1.5; }
.ju-pm p { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
           margin: .45rem 0 0; }
.ju-unapplied { margin: .3rem 0 0 1.1rem; padding: 0; font-size: 12px;
                color: var(--ink-mid); line-height: 1.6; }
.ju-args { display: flex; gap: .5rem; flex-wrap: wrap; }
.ju-arg { font-family: var(--mono); font-size: 11px; border: 1px solid var(--line-strong);
          padding: .2rem .45rem; }
.ju-arg b { display: block; font-size: 9.5px; letter-spacing: .06em;
            color: var(--ink-soft); font-weight: 400; }

/* A row of the provenance table that is OURS reads differently from a row
   that was transcribed. Two marks, two rules and two words, because a table
   that rendered a county's requirement and a judgement of ours alike is the
   one thing this table exists to prevent. A row the manual does not state and
   this product does not default carries neither mark, because it is neither. */
.ju-ours { font-family: var(--mono); font-size: 8.5px; letter-spacing: .09em;
           font-weight: 700; border: 1px dashed var(--ink-soft); padding: 0 4px;
           margin-left: .3rem; white-space: nowrap; color: var(--ink-soft); }
.ju-transcribed { font-family: var(--mono); font-size: 8.5px; letter-spacing: .09em;
                  font-weight: 700; border: 1px solid var(--ochre); padding: 0 4px;
                  margin-left: .3rem; white-space: nowrap; color: var(--ochre); }
tr.ju-ourrow td:first-child { border-left: 4px dashed var(--ink-soft); }
tr.ju-usrrow td:first-child { border-left: 4px solid var(--ochre); }

.ju-form { margin-top: .2rem; }
.ju-sub { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
          text-transform: uppercase; color: var(--ink-soft); margin: .9rem 0 .3rem; }

.ju-rule { border-left: 4px solid var(--line-strong); padding: .5rem .7rem;
           margin-bottom: .6rem; background: var(--surface);
           border-top: 1px solid var(--line); border-right: 1px solid var(--line);
           border-bottom: 1px solid var(--line); }
.ju-rl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         text-transform: uppercase; font-weight: 700; color: var(--ink-mid);
         display: flex; justify-content: space-between; gap: .5rem;
         align-items: center; }
.ju-rd { font-size: 13px; line-height: 1.5; margin-top: .3rem; font-weight: 600; }
.ju-rc { font-size: 11.5px; color: var(--ink-mid); margin-top: .25rem; }
.ju-rh { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
         text-transform: uppercase; color: var(--ink-soft); margin-top: .5rem; }
.ju-conds { margin: .25rem 0 0 1.1rem; padding: 0; font-size: 12px;
            line-height: 1.6; }
.ju-conds li { margin-bottom: .25rem; }
.ju-guards { display: block; font-size: 11px; color: var(--ink-soft);
             line-height: 1.5; }
.ju-nocond { font-size: 11.5px; line-height: 1.55; color: var(--ink);
             border: 2px dashed var(--ochre); background: var(--ochre-soft);
             padding: .45rem .6rem; margin-top: .3rem; }
.ju-reads { margin-top: .5rem; display: flex; gap: .3rem; flex-wrap: wrap;
            align-items: baseline; }
.ju-reads > span:first-child { font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-soft); }
.ju-readk { font-family: var(--mono); font-size: 10px; border: 1px solid var(--accent-line);
            color: var(--accent); padding: 0 4px; }
.ju-rn { font-size: 11.5px; color: var(--ink-mid); margin-top: .4rem; }
.ju-addrow { display: flex; gap: .7rem; align-items: center; flex-wrap: wrap;
             margin-top: .8rem; }
.ju-chapter { font-size: 11px; color: var(--ink-soft); }

.ju-cond { border: 1px solid var(--line); padding: .5rem .6rem; margin-bottom: .5rem; }
.ju-condh { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
            text-transform: uppercase; color: var(--ink-soft); display: flex;
            justify-content: space-between; align-items: center; gap: .5rem; }
.ju-condgrid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem .7rem;
               margin-top: .45rem; }
@media (max-width: 820px) { .ju-condgrid { grid-template-columns: 1fr; } }
.ju-condgrid select { width: 100%; }
.ju-again { display: flex; gap: .6rem; align-items: flex-start; flex-wrap: wrap;
            margin-bottom: .6rem; }
.ju-again span { flex: 1 1 18rem; font-size: 11px; color: var(--ink-soft);
                 line-height: 1.5; }

/* The declaration that the manual imposes no condition. Two deliberate
   gestures with a statement between them, because a checkbox beside a Save
   button is a thing people click past on the way to the button, and what
   would be clicked past here is the substance of the rule. */
.ju-declare-offer { border: 1px dashed var(--ochre); padding: .55rem .7rem;
                    margin-top: .6rem; }
.ju-declare-offer p { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
                      margin: 0 0 .5rem; }
.ju-declare { border: 3px double var(--ochre); background: var(--sunk);
              padding: .7rem .8rem; margin-top: .6rem; }
.ju-declare.made { border-color: var(--accent); }
.ju-declh { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            font-weight: 700; color: var(--ochre); }
.ju-declare.made .ju-declh { color: var(--accent); }
.ju-declare p { font-size: 11.5px; line-height: 1.6; color: var(--ink-mid);
                margin: .45rem 0 0; }
.ju-declare .linkish { margin-top: .55rem; display: inline-block; }

.ju-chosen { border-left: 4px solid var(--accent); background: var(--accent-soft);
             padding: .5rem .65rem; margin-top: .6rem; font-size: 12.5px;
             line-height: 1.55; }
.ju-chosenl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
              font-weight: 700; color: var(--accent); margin-bottom: .3rem; }

/* A measurement box the chosen rule reads, against one no rule reads. The
   difference is drawn in the form, before the result exists, because a blank
   where a rule conditions on it produces a standing refusal rather than a
   credit and never a zero. */
.pr-field.ju-read { border-left: 3px solid var(--accent); padding-left: .5rem; }
.ju-readmark { font-family: var(--mono); font-size: 8.5px; letter-spacing: .09em;
               font-weight: 700; color: var(--accent); border: 1px solid var(--accent-line);
               padding: 0 4px; margin-left: .35rem; }
.ju-unreadmark { font-family: var(--mono); font-size: 8.5px; letter-spacing: .07em;
                 color: var(--ink-soft); margin-left: .35rem; }
.ju-reader { font-size: 10.5px; color: var(--accent); line-height: 1.45;
             margin-top: .2rem; }
.ju-blankwarn { font-size: 11px; line-height: 1.5; color: var(--ink);
                border: 2px dashed var(--red); background: var(--red-soft);
                padding: .35rem .5rem; margin-top: .3rem; }

/* One credit, in the three states the engine distinguishes. A DENIED credit is
   the manual's own answer and a computed zero; a REFUSED one was never
   computed at all. They are given different rules, different words and
   different fills so that a reader cannot take the second for the first. */
.ju-cr { border: 1px solid var(--line); border-left: 6px solid var(--accent);
         padding: .65rem .8rem; margin-bottom: .7rem; }
/* The hatch is a channel and not a texture for its own sake, so it is drawn
   light enough that the figure sitting on it stays a figure. A denied credit
   is a computed zero and the zero has to be legible. */
.ju-cr.denied { border-left: 6px dashed var(--ochre); background: var(--surface);
  background-image: repeating-linear-gradient(45deg, var(--hatch) 0 1.5px,
                    transparent 1.5px 13px); }
.ju-cr.refused { border-left: 6px double var(--red); background: var(--red-soft); }
.ju-crl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
          font-weight: 700; color: var(--accent); display: flex;
          justify-content: space-between; gap: .5rem; align-items: center; }
.ju-cr.denied .ju-crl { color: var(--ochre); }
.ju-cr.refused .ju-crl { color: var(--red); }
.ju-crname { font-size: 13px; font-weight: 600; margin-top: .3rem; }
.ju-crn { font-family: var(--mono); font-size: 1.8rem; font-weight: 600;
          line-height: 1.15; margin-top: .25rem; font-variant-numeric: tabular-nums; }
.ju-crn .u { font-family: var(--sans); font-size: .72rem; font-weight: 400;
             color: var(--ink-soft); }
/* Words where the number would be. A blank in a numeric slot is read as a zero
   by anyone skimming, and zero is the one thing a refused credit is not. */
.ju-crnull { border: 2px dashed var(--red); padding: .45rem .6rem; margin-top: .3rem; }
.ju-crnulll { font-family: var(--mono); font-size: 11px; letter-spacing: .06em;
              font-weight: 700; color: var(--red); }
.ju-crnullr { font-size: 11.5px; color: var(--ink-mid); line-height: 1.5;
              margin-top: .25rem; }
.ju-crshare { font-size: 11.5px; color: var(--ink-soft); margin-top: .2rem; }
.ju-crwhat { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
             margin-top: .45rem; }
.ju-crrule { font-size: 12px; margin-top: .45rem; }
.ju-crh { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
          text-transform: uppercase; color: var(--ink-soft); margin-top: .55rem; }
.ju-checks { margin: .25rem 0 0 1.1rem; padding: 0; font-size: 12px; line-height: 1.6; }
.ju-checks li { margin-bottom: .3rem; }
.ju-cw { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
         font-weight: 700; border: 1px solid currentColor; padding: 0 4px;
         margin-right: .4rem; white-space: nowrap; }
.ju-checks li.pass { color: var(--ink-mid); }
.ju-checks li.pass .ju-cw { color: var(--accent); }
.ju-checks li.fail { color: var(--ink); font-weight: 600; }
.ju-checks li.fail .ju-cw { color: var(--ochre); }
.ju-checks li.unchecked { color: var(--ink); font-weight: 600; font-style: italic; }
.ju-checks li.unchecked .ju-cw { color: var(--red); font-style: normal; }
.ju-blanks { border: 2px dashed var(--red); padding: .5rem .65rem; margin-top: .6rem; }
.ju-blanksl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
              font-weight: 700; color: var(--red); }
.ju-blank { font-size: 12px; margin-top: .4rem; }
.ju-blankc { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
             margin-top: .2rem; }
.ju-crnote { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
             margin-top: .45rem; }
.ju-crres { margin-top: .7rem; }
.ju-crref { margin-top: .7rem; }
.ju-explain { margin-top: .6rem; font-size: 11px; color: var(--ink-soft); }
.ju-explain summary { cursor: pointer; font-family: var(--mono); font-size: 10px; }
.ju-explain pre { white-space: pre-wrap; font-family: var(--mono); font-size: 11px;
                  line-height: 1.55; color: var(--ink-mid); margin: .4rem 0 0; }
.ju-nofig { font-family: var(--mono); font-size: 10px; color: var(--red); }
/* A value column that wraps "125 cu ft" onto two lines reads as two numbers.
   These tables are two and three columns wide and have the room. */
.gr-result .dv-table td.num, .ju-cmp .dv-table td.num { white-space: nowrap; }
tr.ju-st-refused td { color: var(--red); }

/* The compliance verdict. The verdict paragraph is set at the size of the
   figures above it and is never truncated: it is the finding AND the four
   things it does not claim, and a first sentence lifted out as a badge would
   turn an arithmetic check into an approval. The badge beside it is built from
   `meets`, which has three states and not two. */
.ju-cmp { border: 3px double var(--ink); padding: .8rem .9rem; }
.ju-cmp.withheld { border-style: dashed; }
.ju-cmpl { font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
           font-weight: 700; }
.ju-cmp.ok .ju-cmpl { color: var(--accent); }
.ju-cmp.short .ju-cmpl { color: var(--red); }
.ju-cmp.withheld .ju-cmpl { color: var(--ochre); }
.ju-withheld { border: 1px solid var(--ochre-line); background: var(--ochre-soft);
               padding: .55rem .7rem; margin-top: .6rem; }
.ju-withheldl { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
                font-weight: 700; color: var(--ochre); }
.ju-withheld p { font-size: 12px; line-height: 1.6; color: var(--ink); margin: .35rem 0 0; }
.ju-cmpnote { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
              margin-top: .5rem; }
.ju-verdict { font-size: 13.5px; line-height: 1.7; margin-top: .8rem;
              padding-top: .6rem; border-top: 1px solid var(--line-strong); }
.ju-verdictnote { font-size: 11px; color: var(--ink-soft); line-height: 1.55;
                  margin-top: .6rem; }

/* The fourth family in the change log. A resolution is not a claim: nobody
   overruled anything, so it does not take the ochre a departure and a waiver
   share. It takes the accent a resolution carries everywhere else. */
.cm-supply { border-left-color: var(--accent); }
.cm-supply .cm-fam { color: var(--accent); border-color: var(--accent-line); }
.hs-leg-supply { border-left-color: var(--accent); }
.hs-leg-supply b { color: var(--accent); }

/* A gate that is ready and says the result will be a refusal is not the same
   as a gate that is ready and says the rule will run. It is not an error
   either: it is the third state, and it is drawn as the third state. */
.pr-gate.warn { color: var(--ochre); }

/* The axis of the antecedent span, named. A track with two marks on it and no
   statement of what the axis is is a picture rather than a reading. */
.ps-axis { font-size: 11px; color: var(--ink-soft); margin-bottom: .3rem; }

/* Which sizing figures came from the entered manual rather than from our
   registry. Without it the panel prints a required volume computed from a
   county's number with nothing on the screen saying whose number it was. */
.pr-jur { border: 1px solid var(--ochre-line); border-left: 4px solid var(--ochre);
          background: var(--ochre-soft); padding: .55rem .7rem; margin-bottom: .7rem; }
.prj-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
         font-weight: 700; color: var(--ochre); }
.prj-cite { font-size: 11.5px; line-height: 1.55; margin-top: .3rem; }
.prj-key { font-family: var(--mono); font-size: 10px; border: 1px solid var(--ochre-line);
           padding: 1px 4px; color: var(--ochre); }
.prj-note { font-size: 11px; color: var(--ink-mid); line-height: 1.5; margin-top: .35rem; }

/* =====================================================================
   THE ESTIMATES.

   The whole design problem here is that eight filled boxes read alike, and a
   user shown eight confident numbers checks none of them. So the ranking is
   the layout rather than a sort order: the three the engine names as the ones
   that move the answer are set full size with what they rest on, what they are
   worth and what would displace them, and the other five are one line behind a
   control that says what they are worth before it is opened.

   The origin chips are the same ones the derived data panel uses, on purpose.
   A figure off gridMET and a figure off the soil survey are the same kind of
   claim and have to read the same way; an estimate with a prettier treatment
   would be the product dressing a guess up as a measurement.
   ===================================================================== */

.es-headline {
  font-family: var(--serif); font-size: 15px; line-height: 1.55; color: var(--ink);
  border-left: 3px solid var(--accent); padding: .1rem 0 .1rem .7rem;
  margin-bottom: 1rem;
}

.es-row { border-left: 3px solid var(--accent-line); padding: .55rem 0 .55rem .7rem;
          margin-bottom: .8rem; }
.es-row.rest { border-left-width: 2px; border-left-color: var(--line-strong);
               padding-top: .35rem; padding-bottom: .35rem; margin-bottom: .4rem; }
.es-row.edited { border-left-color: var(--ochre); }

.es-top { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.es-rank { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
           text-transform: uppercase; color: var(--ink-soft);
           border: 1px solid var(--line); padding: 0 .3rem; white-space: nowrap; }
.es-title { font-weight: 500; font-size: 13.5px; }
.es-moves { font-family: var(--mono); font-size: 10.5px; color: var(--ochre);
            margin-left: auto; font-variant-numeric: tabular-nums; }
.es-row.rest .es-title { font-size: 12.5px; font-weight: 400; }

.es-val { margin: .3rem 0 .35rem; }
.es-row.rest .es-val .fig-n { font-size: .95rem; }

.es-rests, .es-worth, .es-disp, .es-judge {
  font-size: 12px; line-height: 1.55; color: var(--ink-mid); margin-top: .3rem;
}
.es-rests .k, .es-worth .k, .es-disp .k, .es-judge .k, .es-edited .k {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: .1rem;
}
.es-worth { color: var(--ochre); }
.es-j { font-size: 11.5px; color: var(--ink-soft); margin-top: .15rem;
        display: flex; align-items: baseline; gap: .35rem; flex-wrap: wrap; }

.es-edited { margin-top: .45rem; border-left: 2px solid var(--ochre-line);
             padding-left: .5rem; font-family: var(--mono); font-size: 12px;
             color: var(--ink); }
.es-who { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft);
          margin-top: .2rem; }
.es-reason { font-family: var(--sans); font-size: 12px; line-height: 1.55;
             color: var(--ink-mid); margin-top: .2rem; }
.es-acts { display: flex; gap: .35rem; margin-top: .45rem; flex-wrap: wrap;
           align-items: baseline; }
.es-noedit { font-size: 11px; color: var(--ink-soft); line-height: 1.5; }

.es-more {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font-family: var(--sans); font-size: 11.5px; color: var(--ink-mid);
  background: var(--sunk); border: 1px solid var(--line); border-radius: 2px;
  padding: .4rem .6rem; margin: .2rem 0 .6rem;
}
.es-more:hover { border-color: var(--accent-line); color: var(--accent); }

/* ---------- the edit control ---------- */
/* Deliberately the same shape as the attestation control in the derived data
   panel: the same reason box, the same gate line, the same statement at the
   bottom about what is recorded. A user who has learned what this box wants in
   one place should not have to learn it again here. */
.es-edit { margin-top: .6rem; border: 1px solid var(--line-strong);
           background: var(--sunk); padding: .6rem; border-radius: 2px; }
.es-ehead { font-family: var(--mono); font-size: 10px; letter-spacing: .09em;
            text-transform: uppercase; color: var(--ink-soft); margin-bottom: .3rem; }
.es-about { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
            margin-bottom: .45rem; }
.es-num { display: flex; align-items: baseline; gap: .45rem; flex-wrap: wrap; }
.es-input { width: 9rem; font-family: var(--mono); }
.es-prior { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft); }
.es-demand { margin-top: .5rem; font-size: 12px; line-height: 1.5;
             color: var(--ink-mid); }
.es-picks { display: flex; flex-wrap: wrap; gap: .3rem; }
.es-pick {
  font-family: var(--sans); font-size: 11.5px; padding: .3rem .5rem; cursor: pointer;
  border-radius: 2px; background: var(--surface); border: 1px solid var(--line-strong);
  color: var(--ink-mid); display: flex; flex-direction: column; gap: .1rem;
  text-align: left;
}
.es-pick:hover { border-color: var(--accent); color: var(--accent); }
.es-pick.on { background: var(--accent-soft); border-color: var(--accent-line);
              color: var(--accent); font-weight: 500; }
.es-x { font-family: var(--mono); font-size: 9.5px; color: var(--ink-soft); }
.es-pick.on .es-x { color: var(--accent); opacity: .8; }

/* ---------- refusals ---------- */
/* Four different treatments, because they are four different things with four
   different remedies. A regulatory choice has an answer and gets a chooser. A
   figure in no dataset has none and gets a sentence. A measurement left blank
   on purpose says so and offers no control at all, because a control there
   would be the product filling a box it has just explained it must not. A
   figure below a method's applicability floor says the method does not apply,
   and nothing rounds it up. */
.es-ref { border-left: 4px double var(--line-strong); padding: .55rem .7rem;
          margin: .8rem 0; background: var(--sunk); border-radius: 2px; }
.es-ref.reg { border-left-color: var(--accent); }
.es-ref.floor { border-left-color: var(--red); background: var(--red-soft); }
.es-ref.blank { border-left-color: var(--ink-soft); }
.es-ref.svc { border-left-color: var(--ochre); background: var(--ochre-soft); }
.es-rhead { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
            font-weight: 500; font-size: 13px; }
.es-rtag { font-family: var(--mono); font-size: 9px; letter-spacing: .09em;
           text-transform: uppercase; color: var(--ink-soft); margin-left: auto; }
.es-ref.floor .es-rtag { color: var(--red); }
.es-rlead { font-size: 12px; line-height: 1.55; color: var(--ink); margin-top: .3rem; }
.es-rmsg { font-size: 11.5px; line-height: 1.6; color: var(--ink-mid);
           margin-top: .35rem; }
.es-remedy { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
             margin-top: .4rem; border-top: 1px solid var(--line);
             padding-top: .35rem; }

/* ---------- the design storm chooser ---------- */
/* Ten tabulated return periods with their ninety percent intervals and nothing
   preselected. The span between the ends is printed under it, because the size
   of the choice has to be visible before it is made: a factor of five on the
   depth is more than every other estimate in this panel put together. */
.es-storm { margin-top: .6rem; }
.es-shead { font-family: var(--mono); font-size: 10px; letter-spacing: .06em;
            color: var(--ink-soft); margin-bottom: .35rem; }
.es-sgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
            gap: .3rem; }
.es-storm-pick {
  display: flex; flex-direction: column; gap: .1rem; align-items: flex-start;
  padding: .35rem .45rem; cursor: pointer; border-radius: 2px;
  background: var(--surface); border: 1px solid var(--line-strong);
  color: var(--ink); font-family: var(--sans);
}
.es-storm-pick:hover { border-color: var(--accent); }
.es-storm-pick .yr { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); }
.es-storm-pick .dep { font-family: var(--mono); font-size: 14px; font-weight: 600;
                      font-variant-numeric: tabular-nums; }
.es-storm-pick .ci { font-family: var(--mono); font-size: 9.5px; color: var(--ink-soft); }
.es-storm-pick.on { background: var(--accent); border-color: var(--accent);
                    color: var(--surface); }
.es-storm-pick.on .yr, .es-storm-pick.on .ci { color: var(--surface); opacity: .85; }
.es-sspan { font-size: 11.5px; line-height: 1.55; color: var(--ochre); margin-top: .35rem; }

/* ---------- what the estimator was asked ---------- */
.es-inputs { margin-top: 1.1rem; border-top: 1px solid var(--line); padding-top: .7rem; }
.es-ihead { display: flex; justify-content: space-between; align-items: baseline;
            gap: .5rem; flex-wrap: wrap;
            font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            text-transform: uppercase; color: var(--ink-soft); margin-bottom: .6rem; }
.es-ihead span { font-family: var(--sans); font-size: 11px; letter-spacing: .02em;
                 text-transform: none; color: var(--ink-soft); }
.es-input-row { border-left: 2px solid var(--line-strong); padding-left: .7rem;
                margin-bottom: .7rem; }
.es-itop { display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap; }
.es-ititle { font-weight: 500; font-size: 12.5px; }
.es-ival { font-family: var(--mono); font-size: 12px; color: var(--ink); margin-top: .2rem; }
.es-iabout { font-size: 11.5px; line-height: 1.55; color: var(--ink-soft); margin-top: .2rem; }

/* ---------- what an edit changed ---------- */
/* The panel says this because an edit is handed to the estimator and the whole
   chain is rerun, so more than the edited figure can move. A user shown only
   the number they typed would have no way to see the rest, which is exactly
   the failure that makes patching a stored value dangerous. */
.es-changed { border: 1px solid var(--ochre-line); background: var(--ochre-soft);
              padding: .6rem .7rem; margin-bottom: .9rem; border-radius: 2px; }
.es-chead { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            text-transform: uppercase; color: var(--ochre); margin-bottom: .3rem; }
.es-cline { font-family: var(--mono); font-size: 13px; margin-bottom: .25rem; }
.es-crest { font-size: 11.5px; line-height: 1.55; color: var(--ink-mid);
            margin-bottom: .4rem; }
.es-cr { font-family: var(--mono); font-size: 11.5px; color: var(--ink-mid);
         display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap;
         padding: .12rem 0; }
.es-cr.sub { color: var(--ink); font-weight: 600; }

/* ---------- the marker other panels put beside a prefilled field ---------- */
/* One edit control in the product, not one per panel. The marker says what the
   figure is and what it is worth, and its control opens the estimates panel's
   own form, so the gate and the wording live in one place. */
.es-mark { display: inline-flex; align-items: baseline; gap: .35rem;
           flex-wrap: wrap; margin-left: .35rem; }
.es-mtag { font-family: var(--mono); font-size: 9.5px; color: var(--ink-soft); }
.linky { background: none; border: 0; padding: 0; cursor: pointer;
         font-family: var(--sans); font-size: 11px; color: var(--accent);
         text-decoration: underline; text-underline-offset: 2px; }
.linky:hover { color: var(--ochre); }

.es-prefill { border-left: 3px solid var(--accent-line); background: var(--accent-soft);
              padding: .45rem .6rem; margin: .5rem 0; border-radius: 2px;
              font-size: 11.5px; line-height: 1.55; color: var(--ink-mid); }
.es-prefill b { color: var(--ink); }
.es-blank { border-left: 3px solid var(--ink-soft); padding: .45rem .6rem;
            margin: .5rem 0; background: var(--sunk); border-radius: 2px;
            font-size: 11.5px; line-height: 1.6; color: var(--ink-mid); }
.es-blank .h { font-family: var(--mono); font-size: 9.5px; letter-spacing: .09em;
               text-transform: uppercase; color: var(--ink-soft); }

/* =====================================================================
   The account and billing screens.

   They reuse the panel, table, field and origin-chip vocabulary rather than
   inventing a second one, because they are the same product. What is new here
   is only what those screens have and no other screen does: the key shown
   once, the three stages of an order, and the signed out card.
   ===================================================================== */

/* ---------- signed out ---------- */
.panel.authpanel { max-width: 34rem; }
.authtabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line);
            margin: 0 0 1rem; }
.authtab { font-family: var(--sans); font-size: 13px; color: var(--ink-mid);
           background: none; border: 0; border-bottom: 2px solid transparent;
           padding: .4rem .7rem; cursor: pointer; }
.authtab:hover { color: var(--ink); }
.authtab[aria-current="true"] { color: var(--accent); border-bottom-color: var(--accent); }
.authalt { margin-top: 1.1rem; border-top: 1px solid var(--line); padding-top: .7rem; }
.authalt summary { font-size: 12px; color: var(--ink-soft); cursor: pointer; }
.authalt summary:hover { color: var(--accent); }

/* ---------- the key shown once ----------
   Double ruled and ochre, the same treatment the acknowledge control carries,
   because it is the same kind of moment: something is about to become
   irreversible and the interface is asking the person to notice. The key
   itself is set at a size that can be read off a screen and copied by hand,
   with word breaking on, because a key that wraps mid-character into an
   ellipsis is a key somebody transcribes wrongly. */
.panel.keyonce { border: 3px double var(--ochre); max-width: 44rem; }
.panel.keyonce > h2 { color: var(--ochre); border-bottom-color: var(--ochre-line); }
.keyval { background: var(--sunk); border: 1px solid var(--line-strong);
          padding: .7rem .8rem; margin-top: .3rem; }
.keyval code { font-family: var(--mono); font-size: 13.5px; line-height: 1.7;
               word-break: break-all; user-select: all; }

/* ---------- an order, and the three states it moves through ---------- */
.reqcard { border: 1px solid var(--line); border-left: 3px solid var(--line-strong);
           padding: .7rem .85rem; margin-bottom: .7rem; background: var(--surface); }
.reqcard:last-child { margin-bottom: 0; }
.reqhead { display: flex; justify-content: space-between; align-items: flex-start;
           gap: 1rem; margin-bottom: .5rem; }
.reqhead .m { font-family: var(--mono); font-size: 10.5px; color: var(--ink-soft);
              margin-top: .2rem; }
.reqstate { font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em;
            text-transform: uppercase; padding: 2px 6px; border-radius: 2px;
            border: 1px solid var(--line-strong); color: var(--ink-soft);
            white-space: nowrap; flex: 0 0 auto; }
.reqstate.invoiced { color: var(--ochre); border-color: var(--ochre-line);
                     background: var(--ochre-soft); }
.reqstate.credited { color: var(--accent); border-color: var(--accent-line);
                     background: var(--accent-soft); }
.reqstate.cancelled { color: var(--red); border-color: var(--red); background: var(--red-soft); }

/* Three states drawn as three, with the one it is at marked and the ones
   behind it spent. A two state control would make "nobody has invoiced this"
   and "nobody has paid it" the same waiting, which is exactly the distinction
   the invoiced_at column was added to hold. */
.stages { display: flex; gap: 0; margin: .1rem 0 .55rem; flex-wrap: wrap; }
.stage { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em;
         text-transform: uppercase; color: var(--ink-soft);
         border: 1px solid var(--line); border-right: 0; padding: .2rem .55rem;
         background: var(--surface); }
.stage:last-child { border-right: 1px solid var(--line); }
.stage.done { color: var(--accent); border-color: var(--accent-line);
              background: var(--accent-soft); }
.stage.now { color: var(--surface); background: var(--accent); border-color: var(--accent);
             font-weight: 600; }
.stage.off { color: var(--red); border-color: var(--red); background: var(--red-soft); }

.billfigs { gap: 2.2rem; }
.billfigs .delta-big { font-size: 2rem; }
.subhead { font-family: var(--serif); font-size: .95rem; font-weight: 600;
           margin: 1.2rem 0 .5rem; padding-top: .8rem; border-top: 1px solid var(--line); }

/* An outcome that went well. The warning box was doing double duty for "your
   address is confirmed" and "this order was cancelled", which taught a reader
   that the ochre rule means nothing in particular. Three boxes, three
   meanings: accent for something that worked, ochre for something to be
   careful about, red for a refusal. */
.okbox { border-left: 3px solid var(--accent); background: var(--accent-soft);
         padding: .6rem .75rem; font-size: 12.5px; margin-bottom: .75rem; }

/* A queued message opened for an operator to send by hand. Monospace and
   preformatted, because what is being read is the message exactly as it would
   go out and a reflowed copy of it is not that. */
.msgbody { border-left: 3px solid var(--ochre); padding: .6rem .75rem;
           background: var(--sunk); }
.msgbody pre { font-family: var(--mono); font-size: 11.5px; line-height: 1.6;
               white-space: pre-wrap; word-break: break-word; margin: .5rem 0; }

/* =====================================================================
   THE ASSISTANT LAYER
   =====================================================================

   Three things are drawn here and they are deliberately not drawn alike.

   THE PROACTIVE TRAY is the product speaking without being asked, and it
   borrows the refusal's visual language -- a heavy left rail, a small
   uppercase state word, quantities with their provenance chips -- because it
   is the same kind of statement: the engine saying what it found, with no
   model involved. It sits above the map and it is the one part of this layer
   that renders with the assistant switched off.

   THE CONVERSATION is the only place in this product where a paragraph of
   generated prose appears, and it is set in the reading face rather than the
   interface face. That is the channel that separates what a model wrote from
   what the product says about it: everything in the serif is the answer, and
   everything in the sans around it -- the guard line, the class tags, the
   disclaimer chrome -- is the product's own voice. A reader never has to
   wonder which they are looking at.

   THE CITATION is a chip and it has four states, not two. Resolved, resolved
   to unverified corpus, unresolved, and a label that is not a source at all.
   The unresolved one is drawn loudly because it is the state that must never
   be mistaken for the others, and the unverified one carries its label in the
   text beside it so that a reader who never hovers still sees it.
   ===================================================================== */

/* ---------- the proactive tray ---------- */

.pa-panel > h2 { border-bottom-color: var(--line-strong); }
.pa-quiet { font-size: 12.5px; color: var(--ink-mid); line-height: 1.6; }
.pa-foot { font-size: 11px; color: var(--ink-soft); line-height: 1.55;
           margin-top: .8rem; padding-top: .6rem; border-top: 1px solid var(--line); }

.pa-item { border-left: 5px solid var(--ochre); background: var(--sunk);
           padding: .6rem .8rem; margin-bottom: .55rem; }
.pa-item:last-child { margin-bottom: 0; }
.pa-item.pa-high { border-left-color: var(--red); }
.pa-item.pa-blocking { border-left: 5px double var(--red); background: var(--red-soft); }
.pa-item.pa-gone { opacity: .62; background: transparent;
                   border-left-style: dotted; }

.pa-l { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.pa-sev { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
          font-weight: 700; color: var(--ochre); }
.pa-high .pa-sev, .pa-blocking .pa-sev { color: var(--red); }
.pa-trig { margin-left: auto; font-size: 10.5px; color: var(--ink-soft); }
.pa-dis { font-family: var(--mono); font-size: 9px; letter-spacing: .08em;
          text-transform: uppercase; color: var(--ink-soft);
          border: 1px solid var(--line-strong); padding: 0 4px; border-radius: 2px; }

.pa-blockline { font-size: 11.5px; line-height: 1.55; color: var(--red);
                margin-top: .3rem; }
.pa-blockline b { font-weight: 600; }
.pa-t { font-size: 12.5px; line-height: 1.6; color: var(--ink); margin-top: .35rem; }

.pa-qs { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .55rem; }
.pa-q { display: inline-flex; align-items: baseline; gap: .35rem; cursor: help;
        border: 1px solid var(--line); background: var(--surface);
        padding: .2rem .45rem; border-radius: 2px; }
.pa-ql { font-size: 11px; color: var(--ink-mid); }
.pa-qv { font-size: 11.5px; color: var(--ink); font-variant-numeric: tabular-nums; }

.pa-act { display: flex; align-items: center; gap: .55rem; margin-top: .55rem;
          flex-wrap: wrap; }
.pa-note { font-size: 11px; color: var(--ink-soft); }
.pa-fail { border-left: 3px solid var(--red); background: var(--red-soft);
           padding: .45rem .6rem; font-size: 11.5px; line-height: 1.55;
           margin-top: .5rem; }
.pa-more { margin-top: .7rem; }
.pa-gone-list { margin-top: .55rem; padding-top: .55rem;
                border-top: 1px dashed var(--line-strong); }

/* The knock: a blocked control was pressed and the tray says which card is
   the reason. Two short pulses, not a wobble, because this is a statement and
   not a decoration. */
@keyframes pa-knock {
  0%, 100% { box-shadow: 0 0 0 0 rgba(155,50,38,0); }
  25%, 75% { box-shadow: 0 0 0 4px rgba(155,50,38,.28); }
}
.pa-knock { animation: pa-knock .5s ease-in-out 2; }
@media (prefers-reduced-motion: reduce) { .pa-knock { animation: none;
  outline: 2px solid var(--red); outline-offset: 2px; } }

/* The control a blocking signal names, wherever in the product it lives. */
.pa-blocked { opacity: .45; cursor: not-allowed; filter: grayscale(1); }
.pa-block-bar { border-left: 5px double var(--red); background: var(--red-soft);
                padding: .5rem .7rem; margin: 0 0 .8rem; font-size: 12px;
                line-height: 1.6; color: var(--ink); }
.pa-block-w { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
              font-weight: 700; color: var(--red); margin-right: .45rem; }

/* ---------- citations: layer 1 ---------- */

.cn-prose { font-family: var(--serif); font-size: 15px; line-height: 1.72;
            color: var(--ink); white-space: pre-wrap; }

.cn-m { font-family: var(--mono); font-size: 10.5px; line-height: 1.3;
        padding: 1px 4px; border-radius: 2px; border: 1px solid;
        cursor: pointer; white-space: nowrap; vertical-align: .08em;
        margin: 0 1px; background: var(--surface); }
.cn-m-static { cursor: default; }
.cn-m-ok { color: var(--accent); border-color: var(--accent-line);
           background: var(--accent-soft); }
.cn-m-unverified { color: var(--ochre); border-color: var(--ochre-line);
                   background: var(--ochre-soft); }
.cn-m-label { color: var(--ink-mid); border-color: var(--line-strong);
              background: transparent; letter-spacing: .02em; }
/* Doc 05 Section 5.3 rule 3. An unresolved marker is a citation from memory,
   and it is drawn so that it cannot be read as one of the others: red, a
   broken border, and the word beside it. */
.cn-m-bad { color: var(--red); border: 1px dashed var(--red);
            background: var(--red-soft); text-decoration: line-through; }
.cn-m:hover, .cn-m:focus-visible { filter: brightness(1.07); }

.cn-unv-tag, .cn-bad-tag {
  font-family: var(--mono); font-size: 9px; letter-spacing: .06em;
  text-transform: uppercase; padding: 1px 4px; border-radius: 2px;
  margin-left: 2px; white-space: nowrap; vertical-align: .1em;
}
.cn-unv-tag { color: var(--ochre); border: 1px solid var(--ochre-line);
              background: var(--ochre-soft); }
.cn-bad-tag { color: var(--surface); background: var(--red);
              border: 1px solid var(--red); }

/* ---------- claim classes ---------- */

.cn-cl { display: inline; }
.cn-cc-set { white-space: nowrap; }
.cn-cc { font-family: var(--mono); font-size: 8.5px; letter-spacing: .07em;
         color: var(--ink-soft); border: 1px solid var(--line);
         padding: 0 3px; border-radius: 2px; margin-left: 2px;
         opacity: .42; transition: opacity .12s; vertical-align: .3em;
         cursor: help; }
.cn-cl:hover .cn-cc { opacity: 1; }
.cn-cc-C3 { color: var(--ochre); border-color: var(--ochre-line); }
.cn-cc-C5 { color: var(--accent); border-color: var(--accent-line); }
.cn-cc-none { color: var(--red); border-color: var(--red); opacity: .85; }

/* Doc 05 Section 5.3 rule 2: a C5 inference is visually distinguishable from
   a C1 to C4 claim. A rule down its left edge, a tint behind it, and the word
   Interpretation in front of it. Three channels, because one of them is
   colour and colour alone is not a distinction. */
.cn-cl-c5 { display: inline; background: var(--accent-soft);
            box-shadow: -.45rem 0 0 0 var(--accent-soft),
                         .25rem 0 0 0 var(--accent-soft);
            border-left: 2px solid var(--accent-line); padding-left: .3rem; }
.cn-interp { font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
             text-transform: uppercase; font-weight: 600; color: var(--accent);
             border: 1px solid var(--accent-line); background: var(--surface);
             padding: 1px 5px; border-radius: 2px; margin-right: .35rem;
             vertical-align: .12em; white-space: nowrap; }
.cn-cl-uncited { text-decoration: underline wavy var(--red); text-underline-offset: 4px; }

/* ---------- citations: layer 2 ---------- */

.cn-pop {
  position: fixed; z-index: 70; max-width: 420px; padding: .7rem .8rem;
  background: var(--surface); border: 1px solid var(--line-strong);
  box-shadow: var(--shadow); font-size: 12px; line-height: 1.6;
  pointer-events: none;
  /* Layer 2 now carries the passage, and a passage is up to 1500 characters.
     The panel is bounded by the window rather than by the text, and the
     quotation inside it scrolls. */
  max-height: 78vh; overflow-y: auto;
}
/* Hover cannot take the pointer without losing its own mouseout. Tap can, and
   has to: dragging a scrollbar is how a long passage is read. */
.cn-pop-pinned { pointer-events: auto; }
.cn-pop-h { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
            font-weight: 700; color: var(--accent); }
.cn-pop-h.cn-pop-unverified { color: var(--ochre); }
.cn-pop-h.cn-pop-bad { color: var(--red); }
.cn-pop-h.cn-pop-label { color: var(--ink-soft); }
.cn-pop-m { margin-top: .25rem; color: var(--ink); word-break: break-word; }
.cn-pop-t { font-family: var(--serif); font-size: 14px; font-weight: 600;
            margin-top: .4rem; }
.cn-pop-e { font-size: 11.5px; color: var(--ink-mid); margin-top: .1rem; }
.cn-pop-r { margin-top: .45rem; font-size: 11.5px; color: var(--ink); }
.cn-pop-k { display: block; font-family: var(--mono); font-size: 9px;
            letter-spacing: .09em; text-transform: uppercase;
            color: var(--ink-soft); }
.cn-pop-src { font-size: 11px; color: var(--ink-mid); margin-top: .2rem; }
.cn-pop-why { font-size: 11px; color: var(--ink-soft); margin-top: .4rem;
              font-style: italic; }
.cn-pop-gap { font-size: 11px; color: var(--ink-soft); margin-top: .35rem; }

/* Doc 05 Section 5.2 layer 2: the exact retrieved passage. Three blocks and
   the boundary between them is the design. The heading and the note are ours
   and read as ours: mono, small caps, our ink. The quotation is somebody
   else's document and is set apart from both of them, indented behind a rule,
   in the reading face, with its own line breaks kept. Nothing of ours is ever
   drawn inside it. */
/* One flowing line rather than a flex row: the heading can be two lines wide
   at this width, and a flex row puts the unverified tag beside the first of
   them with the second hanging underneath it. */
.cn-pop-q-h { margin-top: .55rem; }
.cn-pop-q-h .cn-pop-k { display: inline; margin-right: .35rem; }
.cn-pop-q {
  margin: .25rem 0 0; padding: .4rem 0 .4rem .6rem;
  border-left: 3px solid var(--line-strong);
  font-family: var(--serif); font-size: 12px; line-height: 1.65;
  color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 16rem; overflow-y: auto;
}
/* An upload's passage is unverified where the passage is, not only where the
   marker is: a reader scrolled into 1500 characters cannot see the chip that
   opened this. */
.cn-pop-q-unv { border-left-color: var(--ochre); background: var(--ochre-soft); }
.cn-pop-q-n { margin-top: .4rem; font-size: 11px; line-height: 1.55;
              color: var(--ink-mid); }
.cn-pop-unv { border-left: 3px solid var(--ochre); background: var(--ochre-soft);
              padding: .4rem .55rem; font-size: 11.5px; margin-top: .5rem; }
.cn-pop-bad { border-left: 3px solid var(--red); background: var(--red-soft);
              padding: .4rem .55rem; font-size: 11.5px; margin-top: .5rem; }

/* ---------- citations: layer 3, the register ---------- */

table.cn-reg td:first-child { white-space: nowrap; }

/* ---------- the assistant panel ---------- */

/* Doc 05 Section 7.3, last row. Homeowner mode carries this and there is no
   control on it: it is not inside a details element, it has no close button,
   and it is the first block in the view. */
.asst-chrome { border: 1px solid var(--ochre-line); border-left: 5px solid var(--ochre);
               background: var(--ochre-soft); padding: .8rem 1rem;
               margin-bottom: 1rem; box-shadow: var(--shadow); }
.asst-chrome-w { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
                 font-weight: 700; color: var(--ochre); margin-bottom: .4rem; }
.asst-chrome p { margin: 0 0 .4rem; font-size: 12.5px; line-height: 1.6; }
.asst-chrome p:last-child { margin-bottom: 0; }

.asst-allow { display: flex; align-items: flex-end; gap: 2rem; flex-wrap: wrap;
              padding-bottom: .85rem; margin-bottom: .85rem;
              border-bottom: 1px solid var(--line); }
.asst-an { font-family: var(--mono); font-size: 1.85rem; font-weight: 600;
           line-height: 1; letter-spacing: -.03em; color: var(--accent);
           font-variant-numeric: tabular-nums; }
.asst-ao { font-size: .85rem; font-weight: 400; color: var(--ink-soft);
           letter-spacing: 0; }
.asst-al { font-size: 11.5px; color: var(--ink-mid); margin-top: .3rem; }
.asst-ameta { margin-left: auto; text-align: right; font-family: var(--mono);
              font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
              color: var(--ink-soft); }
.asst-degr { color: var(--ochre); }
.asst-micro { font-family: var(--sans); font-size: 11px; letter-spacing: 0;
              text-transform: none; color: var(--ink-mid); margin-top: .3rem; }

.asst-standing { border-left: 3px solid var(--red); background: var(--red-soft);
                 padding: .5rem .7rem; font-size: 12px; line-height: 1.55;
                 margin-bottom: .85rem; }
.asst-standing-block { border-left: 5px double var(--red); }

.asst-ask { }
.asst-selects { display: flex; gap: .8rem; flex-wrap: wrap; margin-bottom: .7rem;
                align-items: flex-start; }
.asst-selects > div { flex: 1; min-width: 170px; }
.asst-teach label { display: flex; align-items: center; gap: .4rem;
                    font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
                    text-transform: uppercase; color: var(--ink-soft);
                    margin-bottom: .25rem; }
.asst-teach input { width: auto; }
.asst-hint { font-size: 11px; line-height: 1.5; color: var(--ink-soft); }
.asst-actions { display: flex; align-items: center; gap: .6rem; margin-top: .6rem;
                flex-wrap: wrap; }

.asst-deep { border: 1px solid var(--accent-line); background: var(--accent-soft);
             padding: .7rem .85rem; margin-top: .7rem; }
.asst-deep-w { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
               font-weight: 700; color: var(--accent); margin-bottom: .35rem; }
.asst-deep p { margin: 0 0 .45rem; font-size: 12.5px; line-height: 1.6; }
.asst-deep-act { display: flex; gap: .5rem; flex-wrap: wrap; }

.asst-log { display: flex; flex-direction: column; gap: 1.1rem; }
.asst-msg { }
.asst-who { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
            text-transform: uppercase; color: var(--ink-soft);
            display: flex; gap: .5rem; align-items: baseline;
            margin-bottom: .35rem; }
.asst-stamp { margin-left: auto; font-size: 10px; }
.asst-user .asst-text { font-family: var(--sans); font-size: 13.5px;
                        line-height: 1.6; color: var(--ink);
                        border-left: 3px solid var(--line-strong);
                        padding: .1rem 0 .1rem .7rem; white-space: pre-wrap; }
.asst-bot { border-left: 3px solid var(--accent-line); padding-left: .9rem; }
.asst-bot.asst-refused { border-left-color: var(--red); }
.asst-bot .asst-text { font-family: var(--serif); font-size: 15px;
                       line-height: 1.72; white-space: pre-wrap; }

.asst-disc { padding: .6rem .75rem; margin-bottom: .7rem; }
.asst-disc-w { font-family: var(--mono); font-size: 9px; letter-spacing: .11em;
               font-weight: 700; margin-bottom: .35rem; }
.asst-disc p { margin: 0 0 .4rem; font-size: 11.5px; line-height: 1.6; }
.asst-disc p:last-child { margin-bottom: 0; }
.asst-disc-full { border: 1px solid var(--line-strong); background: var(--sunk); }
.asst-disc-full .asst-disc-w { color: var(--ink-mid); }
.asst-disc-short { border-left: 3px solid var(--ochre); background: var(--ochre-soft); }
.asst-disc-short .asst-disc-w { color: var(--ochre); }

.asst-refusal { }
.asst-ref-h { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
              font-weight: 700; color: var(--red); margin-bottom: .4rem; }
.asst-ref-t { font-family: var(--sans); font-size: 12.5px; line-height: 1.65;
              color: var(--ink-mid); white-space: pre-wrap; margin-bottom: .5rem; }

.asst-instr { border: 1px solid var(--ochre-line); border-left: 5px solid var(--ochre);
              background: var(--ochre-soft); padding: .6rem .75rem; margin-top: .7rem; }
.asst-instr-w { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
                font-weight: 700; color: var(--ochre); margin-bottom: .35rem; }
.asst-instr p { margin: 0 0 .45rem; font-size: 12px; line-height: 1.6; }
.asst-instr ul { margin: 0; padding-left: 1rem; font-size: 11.5px; }
.asst-instr-q { font-family: var(--mono); font-size: 11px; color: var(--ink-mid);
                border-left: 2px solid var(--ochre-line); padding-left: .5rem;
                margin: .2rem 0; }

.asst-notes { margin-top: .7rem; }
.asst-notes p { margin: 0 0 .35rem; font-size: 11.5px; line-height: 1.6;
                color: var(--ink-mid); }

.asst-guard { margin-top: .7rem; padding-top: .5rem; border-top: 1px dashed var(--line-strong);
              font-size: 11px; line-height: 1.6; color: var(--ink-soft); }
.asst-gw { font-family: var(--mono); font-size: 9px; letter-spacing: .11em;
           font-weight: 700; color: var(--accent); margin-right: .4rem; }
.asst-guard-bad .asst-gw { color: var(--red); }
.asst-viol { margin: .35rem 0 0; padding-left: 1rem; }
.asst-viol li { margin-bottom: .2rem; }
.asst-vsev { font-family: var(--mono); font-size: 8.5px; letter-spacing: .07em;
             text-transform: uppercase; border: 1px solid var(--line-strong);
             padding: 0 3px; border-radius: 2px; }
.asst-vsev-blocking { color: var(--red); border-color: var(--red); }

.asst-forget { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
               margin-top: 1rem; padding-top: .8rem; border-top: 1px solid var(--line); }
.asst-forgot { border-left: 3px solid var(--accent); background: var(--accent-soft);
               padding: .6rem .75rem; margin-top: 1rem; }
.asst-forgot-w { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
                 font-weight: 700; color: var(--accent); margin-bottom: .3rem; }
.asst-forgot p { margin: 0 0 .4rem; font-size: 12px; line-height: 1.6; }

.asst-up { border: 1px solid var(--line); background: var(--sunk);
           padding: .6rem .75rem; margin-bottom: .55rem; }
.asst-up-h { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.asst-up-h b { font-size: 13.5px; }
.asst-up-unv { font-family: var(--mono); font-size: 9px; letter-spacing: .08em;
               color: var(--ochre); border: 1px solid var(--ochre-line);
               background: var(--ochre-soft); padding: 1px 5px; border-radius: 2px; }
.asst-up-h button { margin-left: auto; }
.asst-up-m { font-size: 10.5px; color: var(--ink-soft); margin-top: .25rem; }
.asst-up-n { font-size: 11.5px; color: var(--ink-mid); line-height: 1.55;
             margin-top: .3rem; }
.asst-up-i { font-size: 11.5px; color: var(--ochre); line-height: 1.55;
             margin-top: .3rem; }
.asst-upform { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.asst-upform label { margin-top: .5rem; }

/* The model's own `[Interpretation]` marker, wearing the label's clothes.
   One word, drawn once: a quiet marker beside a loud chip saying the same
   thing reads as a rendering fault, and the marker is the one that has to
   survive being copied out of the panel. */
.cn-m.cn-m-interp {
  font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 600; color: var(--accent); border-color: var(--accent-line);
  background: var(--surface); margin-right: .3rem;
}
.asst-vdetail { font-size: 12px; line-height: 1.55; color: var(--ink);
                margin-top: .35rem; }
.asst-vdetail span { font-family: var(--mono); font-size: 9.5px;
                     letter-spacing: .09em; text-transform: uppercase;
                     color: var(--red); display: block; }
.asst-disc-in { color: var(--ink-soft); font-style: italic; }
