/* ue.css — one stylesheet for the whole Utility Edition shell.

   The type and spacing scales below are the intake console's, deliberately:
   the two apps are read by the same people on the same day, and a second set
   of sizes would make them look like products from different companies for no
   gain. What is NOT carried over is the intake console's density — intake is
   an operator's working surface with nine chips on a row, and this is a
   reviewer's reading surface, where the job is to make one design legible and
   one decision obvious. Same vocabulary, quieter sentences.

   ONE type scale, ONE spacing scale, and nothing outside this file sets a
   font-size, a margin or a colour. */

:root {
  --t-xs: 11.5px;      /* chips, monospace ids, captions            */
  --t-sm: 12.5px;      /* secondary prose, detail panels            */
  --t-md: 14px;        /* body                                      */
  --t-lg: 16px;        /* an address, a card heading                */
  --t-xl: 20px;        /* the page title                            */
  --t-num: 26px;       /* the one number that matters               */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px;
  --radius: 8px;
  --radius-pill: 99px;
  --ok:#1a7f37; --bad:#b3261e; --warn:#8a6d1f; --hot:#a4381f;
  --line:#d6d8dc; --muted:#5f6368; --ink:#1a1a1a; --paper:#fff; --bg:#fafafa;
  --accent:#174ea6; --accent-bg:#e8f0fe; --accent-line:#c6dafc;
  --mono: ui-monospace, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
body { margin:0; background:var(--bg); color:var(--ink);
       font:var(--t-md)/1.55 -apple-system,Segoe UI,Roboto,sans-serif; }
button, input, select, textarea { font:inherit; }
a { color:var(--accent); }

.wrap { max-width:1180px; margin:0 auto; padding:var(--s-4) var(--s-5) 80px; }
.wrap.narrow { max-width:640px; }

h1 { font-size:var(--t-xl); margin:0 0 var(--s-1); }
h2 { font-size:var(--t-lg); margin:0 0 var(--s-3); }
h3 { font-size:var(--t-sm); text-transform:uppercase; letter-spacing:.06em;
     color:var(--muted); margin:var(--s-5) 0 var(--s-2); }
p  { margin:0 0 var(--s-3); }
.sub { color:var(--muted); margin:0 0 var(--s-4); }
.mono { font-family:var(--mono); }
.muted { color:var(--muted); }
.card { background:var(--paper); border:1px solid var(--line);
        border-radius:var(--radius); padding:var(--s-4);
        margin:0 0 var(--s-4); }
.hint { color:var(--muted); font-size:var(--t-sm); margin:var(--s-2) 0 0;
        max-width:80ch; }

/* --------------------------------------------------------------- chrome */
.bar { background:var(--paper); border-bottom:1px solid var(--line); }
.bar .in { max-width:1180px; margin:0 auto; padding:var(--s-3) var(--s-5);
           display:flex; align-items:baseline; gap:var(--s-4); flex-wrap:wrap; }
.bar .brand { font-weight:700; font-size:var(--t-md); color:var(--ink);
              text-decoration:none; }
.bar .tenant { font-size:var(--t-sm); color:var(--muted); }
.bar nav { margin-left:auto; display:flex; gap:var(--s-4); align-items:baseline;
           font-size:var(--t-sm); }
.bar nav .who { color:var(--muted); }
.bar nav form { margin:0; }
.bar nav button.link { border:none; background:none; padding:0; cursor:pointer;
                       color:var(--accent); font-size:var(--t-sm);
                       text-decoration:underline; }

/* ----------------------------------------------------------------- forms */
label { display:block; font-size:var(--t-xs); text-transform:uppercase;
        letter-spacing:.06em; color:var(--muted);
        margin:var(--s-3) 0 var(--s-1); }
input[type=text], input[type=password], select, textarea {
  padding:var(--s-2) var(--s-3); border:1px solid var(--line);
  border-radius:6px; background:var(--paper); width:100%; }
textarea { min-height:72px; }
.grid2 { display:grid; grid-template-columns:1fr 1fr; gap:0 var(--s-3); }
.actions { display:flex; gap:var(--s-3); align-items:center;
           margin-top:var(--s-4); flex-wrap:wrap; }
button.primary { background:var(--ink); color:#fff; border:1px solid var(--ink);
                 border-radius:var(--radius-pill); padding:9px 22px;
                 cursor:pointer; font-weight:600; }
button.primary[disabled] { opacity:.45; cursor:default; }
button.approve { background:var(--ok); border-color:var(--ok); }
button.reject  { background:var(--bad); border-color:var(--bad); }
a.quiet, button.quiet { border:1px solid var(--line); background:var(--paper);
                        border-radius:var(--radius-pill); padding:6px 16px;
                        cursor:pointer; font-size:var(--t-sm); color:var(--ink);
                        text-decoration:none; display:inline-block; }
a.quiet:hover, button.quiet:hover { border-color:#9aa0a6; }

.err { border:2px solid var(--bad); background:#fdf1f0; border-radius:6px;
       padding:var(--s-3); margin:0 0 var(--s-4); color:var(--bad);
       font-weight:600; }
.notice { border:1px solid var(--accent-line); background:var(--accent-bg);
          border-radius:6px; padding:var(--s-3); margin:0 0 var(--s-4);
          font-size:var(--t-sm); }
.caveat { border-left:4px solid var(--warn); background:#fef7e0;
          border-radius:0 6px 6px 0; padding:var(--s-2) var(--s-3);
          margin:var(--s-2) 0; font-size:var(--t-sm); max-width:90ch; }

/* --------------------------------------------------------------- listing */
.plist { list-style:none; padding:0; margin:0; }
.plist > li { border-bottom:1px solid #eceef0; padding:var(--s-3) 0; }
.plist > li:last-child { border-bottom:none; }
.plist .addr { font-size:var(--t-lg); font-weight:600; text-decoration:none;
               color:var(--ink); }
.plist .addr:hover { text-decoration:underline; }
.plist .meta { font-size:var(--t-sm); color:var(--muted); margin:var(--s-1) 0 0; }
.empty { color:var(--muted); padding:var(--s-5) 0; }

.status { font-size:var(--t-xs); border-radius:var(--radius-pill);
          padding:2px 10px; white-space:nowrap; font-family:var(--mono);
          border:1px solid var(--line); background:#f2f4f6; color:var(--muted); }
.status.in_review { background:var(--accent-bg); border-color:var(--accent-line);
                    color:var(--accent); }
.status.approved  { background:#f2f8f3; border-color:#b7ddc0; color:#12602a; }
.status.rejected  { background:#fdf1f0; border-color:#f0c3ad; color:var(--bad); }
.status.draft     { background:#fef7e0; border-color:#f0d493; color:#7a5c0f; }

/* ---------------------------------------------------------------- tables */
table { border-collapse:collapse; width:100%; font-size:var(--t-sm); }
th { text-align:left; font-size:var(--t-xs); text-transform:uppercase;
     letter-spacing:.06em; color:var(--muted); font-weight:600;
     padding:var(--s-2) var(--s-3) var(--s-2) 0; border-bottom:1px solid var(--line); }
td { padding:var(--s-2) var(--s-3) var(--s-2) 0; border-bottom:1px solid #eceef0;
     vertical-align:top; }
tr.sel td { background:#f6faf7; }
td.num, th.num { text-align:right; font-family:var(--mono); padding-right:var(--s-4); }
.scroll { overflow-x:auto; }

/* ------------------------------------------------------------- the design */
.tally { display:flex; flex-wrap:wrap; gap:var(--s-5); margin:0 0 var(--s-3); }
.tally div { min-width:130px; }
.tally b { display:block; font-size:var(--t-num); font-weight:600; line-height:1.15; }
.tally span { color:var(--muted); font-size:var(--t-xs); }
.chosen { border:2px solid var(--ok); background:#f6faf7;
          border-radius:var(--radius); padding:var(--s-3) var(--s-4);
          margin:0 0 var(--s-4); }
.chosen .id { font-family:var(--mono); font-size:var(--t-lg); font-weight:700; }
.chosen .why { color:var(--muted); font-size:var(--t-sm); margin-top:var(--s-1); }
ul.plain { list-style:none; padding:0; margin:0; }
ul.plain li { font-size:var(--t-sm); padding:var(--s-1) 0;
              border-bottom:1px solid #eceef0; }
ul.plain li:last-child { border-bottom:none; }
.chips { display:flex; flex-wrap:wrap; gap:var(--s-1); margin:var(--s-1) 0; }
.chip { font-size:var(--t-xs); border-radius:var(--radius-pill);
        padding:2px 9px; white-space:nowrap; font-family:var(--mono);
        border:1px solid var(--line); background:#f2f4f6; color:var(--muted); }
.chip.sel { background:#f2f8f3; border-color:#b7ddc0; color:#12602a;
            font-weight:700; }
details.more { margin:var(--s-3) 0 0; }
details.more > summary { cursor:pointer; color:var(--muted);
                         font-size:var(--t-sm); }
details.more .box { border-left:2px solid var(--line); margin:var(--s-2) 0 0;
                    padding:var(--s-1) 0 var(--s-1) var(--s-3); }

.versions li { display:flex; gap:var(--s-3); align-items:baseline;
               flex-wrap:wrap; }
.versions .seq { font-family:var(--mono); font-weight:700; min-width:3.5em; }
.versions .kind { font-size:var(--t-xs); }

.decision { border:1px solid var(--line); border-radius:var(--radius);
            padding:var(--s-3) var(--s-4); background:var(--paper); }
.decision.blocked { background:#fafafa; }
.audit td.detail { font-family:var(--mono); font-size:var(--t-xs);
                   color:var(--muted); word-break:break-word; max-width:52ch; }
.audit td.when { font-family:var(--mono); white-space:nowrap; }
.filters { display:flex; gap:var(--s-2); flex-wrap:wrap; align-items:baseline;
           margin:0 0 var(--s-3); font-size:var(--t-sm); }
.filters a { text-decoration:none; }
.filters a.on { font-weight:700; color:var(--ink); }

/* --------------------------------------------------------------- login */
.login { max-width:420px; margin:var(--s-7) auto; }
.login .card { padding:var(--s-5); }
.login .foot { font-size:var(--t-sm); color:var(--muted); margin-top:var(--s-4); }

/* The two marks. The wordmark replaces the word "DistroDesigner" and nothing
   else: it is still the h1, so the page still announces one heading, and
   "Utility Edition" stays the muted qualifier it always was — set beneath the
   wordmark rather than beside it, because 280px of wordmark plus the
   qualifier does not fit on one line in a 420px column. The AMPOWER lockup
   sits outside the card, below it, small and centred: whose product this is,
   not what the page is for. Both are sized by width alone, with the intrinsic
   size on the element so the column does not jump while they load. */
.login .mark { margin:0 0 var(--s-5); }
.login .mark img { display:block; width:280px; max-width:100%; height:auto; }
.login .mark .muted { display:block; font-size:var(--t-sm);
                      font-weight:400; margin-top:var(--s-1); }
.login .by { margin:var(--s-5) 0 0; text-align:center; }
.login .by img { width:170px; max-width:100%; height:auto;
                 /* The lockup as supplied is an OPAQUE white canvas, not the
                    transparent one it looks like — so on this page's --bg it
                    drew a white card behind itself. `multiply` against a
                    near-white surface takes the white to the background
                    exactly (255 x 250/255 = 250) and leaves the crimson
                    crimson. The alternative was re-encoding the owner's file,
                    which is a worse default than one line of CSS. The dead
                    padding around the pill IS trimmed in the committed file,
                    so 170px is 170px of lockup. If a genuinely transparent
                    export ever lands, delete this line, nothing else. */
                 mix-blend-mode:multiply; }

/* ======================================================== UE2: the viewer

   The design canvas, its inspector and the panels under it. Same type and
   spacing scale as everything above — nothing here introduces a size.

   The one thing worth knowing about the colours: the plan's inks are NOT
   chosen here. `--ink-existing` and `--ink-proposed` are the engine's own
   state colours (`designer.symbols.STATE_STROKE`, repeated in
   `designer.report` as OVERLAY_EXISTING / OVERLAY_NEW), so a reviewer who
   reads the operator report and then opens this viewer is reading one
   drawing convention and not two. `ue_core.viewmodel.PALETTE` carries the
   same values to any consumer that is not this stylesheet. */

:root {
  --ink-existing:#8e24aa;   /* engine: STATE_STROKE[existing]  */
  --ink-proposed:#d50000;   /* engine: STATE_STROKE[proposed]  */
  --ink-ghost:#616161;      /* engine: STATE_STROKE[ghost]     */
  --ink-conflict:#e8710a;
  --ink-demand:#8a6d1f;
  --ink-street:#d7d3cb;
  --ink-parcel:#c2bcab;
  --ink-pole:#00695c;
  --ink-room:#8a1c11;
  --panel-w: 380px;
}

.wrap.wide { max-width:1500px; }

.dv-head { display:flex; align-items:flex-start; gap:var(--s-4);
           justify-content:space-between; flex-wrap:wrap; }
.dv-stamp { font-family:var(--mono); font-size:var(--t-xs); color:var(--bad);
            border:1px solid var(--bad); border-radius:4px; padding:3px 9px;
            letter-spacing:.04em; white-space:nowrap; }

.dv { border:1px solid var(--line); border-radius:var(--radius);
      background:var(--paper); overflow:hidden; margin:0 0 var(--s-4); }
.dv-bar { display:flex; gap:var(--s-4); align-items:center; flex-wrap:wrap;
          padding:var(--s-2) var(--s-3); border-bottom:1px solid var(--line);
          background:#fcfcfc; }
.dv-bar label.dv-opt { margin:0; }
.dv-bar select { width:auto; max-width:340px; padding:4px var(--s-2);
                 border:1px solid var(--line); border-radius:6px; }
.dv-layers { display:flex; gap:var(--s-3); flex-wrap:wrap; }
.dv-layer { display:inline-flex; align-items:center; gap:5px; margin:0;
            text-transform:none; letter-spacing:0; font-size:var(--t-sm);
            color:var(--ink); cursor:pointer; }
.dv-layer input { margin:0; }
.dv-layer .sw { width:14px; height:10px; border-radius:2px; display:inline-block;
                border:1px solid rgba(0,0,0,.25); }
.sw-context     { background:var(--ink-street); }
.sw-existing_ug { background:var(--ink-existing); }
.sw-overhead    { background:var(--ink-pole); }
.sw-proposed    { background:var(--ink-proposed); }
.sw-conflicts   { background:var(--ink-conflict); }
.sw-demands     { background:var(--ink-demand); }
.dv-zoom { margin-left:auto; display:flex; gap:var(--s-1); }
.dv-zoom button { padding:3px 12px; }

.dv-body { display:flex; align-items:stretch; }
.dv-canvas { position:relative; flex:1 1 auto; min-width:0; height:620px;
             background:#fdfdfb; }
.dv-canvas svg { width:100%; height:100%; display:block; cursor:grab;
                 touch-action:none; }
.dv-canvas svg.dragging { cursor:grabbing; }
.dv-loading { position:absolute; inset:auto 0 50% 0; text-align:center;
              color:var(--muted); font-size:var(--t-sm); }
.dv-loading.err { color:var(--bad); font-weight:600; }
.dv-scale { position:absolute; left:12px; bottom:10px; display:flex;
            align-items:center; gap:var(--s-2); font-size:var(--t-xs);
            color:var(--ink); background:rgba(253,253,251,.86);
            border:1px solid var(--line); border-radius:4px; padding:3px 8px; }
.dv-scale-bar { height:5px; border:1px solid var(--ink); border-top:none;
                min-width:40px; }
.dv-north { font-family:var(--mono); border-left:1px solid var(--line);
            padding-left:var(--s-2); }

.dv-panel { position:relative; width:var(--panel-w); flex:0 0 var(--panel-w);
            border-left:1px solid var(--line); background:var(--paper);
            overflow-y:auto; height:620px; padding:var(--s-3) var(--s-4) 40px; }
.dv-close { position:absolute; top:6px; right:8px; border:none; background:none;
            font-size:20px; line-height:1; cursor:pointer; color:var(--muted); }
.dv-panel h3.dv-title { font-size:var(--t-lg); text-transform:none;
                        letter-spacing:0; color:var(--ink); margin:0; }
.dv-panel p.dv-sub { margin:0 0 var(--s-2); font-size:var(--t-xs);
                     color:var(--muted); }
.dv-panel h4 { font-size:var(--t-xs); text-transform:uppercase;
               letter-spacing:.06em; color:var(--muted); font-weight:600;
               margin:var(--s-4) 0 var(--s-1);
               border-top:1px solid #eceef0; padding-top:var(--s-2); }
.dv-panel .sec { font-size:var(--t-sm); }
.dv-foot { padding:var(--s-2) var(--s-4) var(--s-3); margin:0;
           border-top:1px solid var(--line); max-width:none; }

dl.kv { display:grid; grid-template-columns:auto 1fr; gap:1px var(--s-2);
        margin:var(--s-1) 0; font-size:var(--t-xs); }
dl.kv dt { color:var(--muted); font-family:var(--mono); white-space:nowrap; }
dl.kv dd { margin:0; word-break:break-word; }

/* -------------------------------------------------------- honesty styling
   Unknowns and refusals are styled UP, not down: they are the parts of a
   machine-made design a person is being asked to look at. */
.unsettled { border-left:3px solid var(--warn); background:#fef7e0;
             padding:var(--s-2) var(--s-3); margin:var(--s-2) 0;
             font-size:var(--t-xs); border-radius:0 4px 4px 0; }
.refusal { border-left:3px solid var(--hot); background:#fdf3f0;
           padding:var(--s-2) var(--s-3); margin:var(--s-2) 0;
           font-size:var(--t-sm); border-radius:0 4px 4px 0; }
.refusal .stage { font-size:var(--t-xs); color:var(--hot); }
.demand { border-left:3px solid var(--accent); background:var(--accent-bg);
          padding:var(--s-2) var(--s-3); margin:var(--s-2) 0;
          font-size:var(--t-sm); border-radius:0 4px 4px 0; }
.demand-asks { font-weight:600; }
ul.plain.refusals li { padding:var(--s-2) 0; }
ul.plain.unplaced li { padding:var(--s-2) 0; }
ul.plain.unplaced .chip.bad, .chip.bad { background:#fdf1f0;
                                         border-color:#f0c3ad;
                                         color:var(--bad); font-weight:600; }

.claim { border:1px solid var(--line); border-radius:6px;
         padding:var(--s-2) var(--s-3); margin:var(--s-2) 0; }
.claim-head { display:flex; gap:var(--s-2); align-items:baseline; }
.claim-name { font-family:var(--mono); font-size:var(--t-xs);
              color:var(--muted); }
.conf { font-size:var(--t-xs); color:var(--muted); }
.conf.unconfirmed { color:var(--hot); font-weight:600; }
.ev-head { font-size:var(--t-xs); text-transform:uppercase; color:var(--muted);
           letter-spacing:.06em; margin-top:var(--s-2); }
ul.ev li { font-size:var(--t-xs); padding:var(--s-1) 0; }

.check { border:1px solid var(--line); border-left-width:3px;
         border-radius:0 6px 6px 0; padding:var(--s-2) var(--s-3);
         margin:var(--s-2) 0; font-size:var(--t-sm); }
.check.v-pass    { border-left-color:var(--ok); }
.check.v-fail    { border-left-color:var(--bad); background:#fdf1f0; }
.check.v-unknown { border-left-color:var(--warn); background:#fef7e0; }
.check-head { display:flex; gap:var(--s-2); align-items:baseline;
              flex-wrap:wrap; }
.check-note { margin-top:var(--s-1); }
.cite { font-size:var(--t-xs); margin-top:var(--s-1); }
span.v { font-size:var(--t-xs); font-weight:700; text-transform:uppercase;
         letter-spacing:.05em; }
span.v.pass { color:var(--ok); }
span.v.fail { color:var(--bad); }
span.v.unknown { color:var(--warn); }
td .v { margin-right:6px; }
.nowrap { white-space:nowrap; }

.rule { border:1px dashed var(--line); border-radius:6px;
        padding:var(--s-2) var(--s-3); margin:var(--s-2) 0; background:#fafafa; }
.rule-head { display:flex; gap:var(--s-2); align-items:baseline;
             flex-wrap:wrap; }
.rule-id { font-weight:700; font-size:var(--t-xs); }
.rule-what { font-size:var(--t-sm); margin-top:var(--s-1); }
blockquote.quote { margin:var(--s-2) 0; padding:var(--s-1) var(--s-3);
                   border-left:3px solid var(--accent-line);
                   font-size:var(--t-xs); color:var(--ink);
                   font-style:italic; }
.prov { font-size:var(--t-xs); }
.chip.conf-cited    { background:#f2f8f3; border-color:#b7ddc0; color:#12602a; }
.chip.conf-operator { background:#fef7e0; border-color:#f0d493; color:#7a5c0f; }
.chip.conf-derived  { background:var(--accent-bg);
                      border-color:var(--accent-line); color:var(--accent); }

.dv-tabs { display:flex; gap:var(--s-2); align-items:center; flex-wrap:wrap;
           border-bottom:1px solid var(--line); margin:0 0 var(--s-3); }
.dv-tabs button { border:none; background:none; cursor:pointer;
                  font-size:var(--t-sm); color:var(--accent);
                  padding:var(--s-2) var(--s-2); border-bottom:2px solid transparent; }
.dv-tabs button.on { color:var(--ink); font-weight:700;
                     border-bottom-color:var(--ink); }
.dv-tabs a.quiet { margin-left:auto; }
.dv-tabbody { font-size:var(--t-sm); }
.dv-report { width:100%; height:640px; border:1px solid var(--line);
             border-radius:6px; background:#fff; }
table.dv-scores th { vertical-align:bottom; }

/* ------------------------------------------------------------ the canvas
   Every stroke is non-scaling: a 1.6 px run stays 1.6 px at any zoom, which
   is what makes a plan readable at both ends of the range. */
#dv-svg path, #dv-svg circle, #dv-svg rect { vector-effect:non-scaling-stroke; }
#dv-svg .line, #dv-svg .ring, #dv-svg .route { fill:none; stroke-linejoin:round;
                                               stroke-linecap:round; }
#dv-svg .hit { fill:none; stroke:transparent; stroke-width:11;
               vector-effect:non-scaling-stroke; cursor:pointer; }

#dv-svg .L-context .k-street { stroke:var(--ink-street); stroke-width:2.6; }
#dv-svg .L-context .k-parcel { stroke:var(--ink-parcel); stroke-width:.7;
                               fill:#f7f5f0; }
#dv-svg .k-development_boundary { stroke:#3c4043; stroke-width:1.6;
                                  stroke-dasharray:7 4; fill:#fff8e1;
                                  fill-opacity:.55; }
#dv-svg .k-electrical_room rect { fill:var(--ink-room); stroke:#4a0e08;
                                  stroke-width:1; }

#dv-svg .L-existing_ug .line { stroke:var(--ink-existing); stroke-width:1.7; }
#dv-svg .L-existing_ug .st-sheet_proposed { stroke:var(--ink-proposed);
                                            stroke-dasharray:5 3; }
#dv-svg .L-existing_ug .st-unknown_state { stroke:var(--ink-ghost);
                                           stroke-dasharray:2 3; }
/* A candidate's routed corridor: real geometry, and there are 26 of them all
   radiating from the same site. Drawn faintly so the plant stays readable, and
   brought up to full weight when its candidate is selected. */
#dv-svg .route { stroke:var(--ink-existing); stroke-width:1;
                 stroke-dasharray:1 4; opacity:.28; }
#dv-svg .route.on { opacity:1; stroke-width:2.2; stroke:var(--accent);
                    stroke-dasharray:4 3; }
#dv-svg .mk circle, #dv-svg .mk rect, #dv-svg .mk path { fill:#fff;
  stroke:var(--ink-existing); stroke-width:1.4; }
#dv-svg .mk .tick { fill:none; }
#dv-svg .L-existing_ug .st-sheet_proposed circle,
#dv-svg .L-existing_ug .st-sheet_proposed rect,
#dv-svg .L-existing_ug .st-sheet_proposed path { stroke:var(--ink-proposed); }
#dv-svg .L-existing_ug .st-unknown_state circle,
#dv-svg .L-existing_ug .st-unknown_state rect,
#dv-svg .L-existing_ug .st-unknown_state path { stroke:var(--ink-ghost);
  stroke-dasharray:2 2; }
#dv-svg .L-overhead .mk circle, #dv-svg .L-overhead .mk path {
  stroke:var(--ink-pole); }
#dv-svg .L-demands .mk path { fill:#fff8e1; stroke:var(--ink-demand);
                              stroke-width:1.6; }
#dv-svg .L-proposed .line { stroke:var(--ink-proposed); stroke-width:2.4; }
#dv-svg .L-proposed .line.ghost { stroke-dasharray:6 4; opacity:.85; }
#dv-svg .L-proposed .mk circle, #dv-svg .L-proposed .mk rect {
  fill:#ffd6d6; stroke:var(--ink-proposed); stroke-width:1.8; }
#dv-svg .L-conflicts .halo { fill:none; stroke:var(--ink-conflict);
                             stroke-width:9; opacity:.32;
                             stroke-linecap:round; }
#dv-svg text.lbl { font:10px ui-monospace,Menlo,Consolas,monospace;
                   fill:#3c4043; paint-order:stroke; stroke:#fdfdfb;
                   stroke-width:3px; pointer-events:none; }
#dv-svg .on { filter:drop-shadow(0 0 3px #174ea6); }
#dv-svg .mk.on circle, #dv-svg .mk.on rect, #dv-svg .mk.on path {
  stroke:var(--accent); stroke-width:2.4; }
#dv-svg .line.on, #dv-svg .ring.on { stroke:var(--accent); stroke-width:3.4; }
dl.kv.nested { margin:0; padding-left:var(--s-2);
               border-left:1px solid #eceef0; }
ul.plain.nested { margin:0; }
ul.plain.nested > li { border-bottom:none; padding:var(--s-1) 0 var(--s-1) var(--s-2);
                       border-left:1px solid #eceef0; }

/* ======================================================= UE3: the workspace

   The editable canvas, the pending-edit tray, the concerns panel and the
   version tree. Same type and spacing scale as everything above; nothing here
   introduces a size.

   **The plan's inks are still the engine's.** Human-changed work is not a new
   colour — it is the engine's proposed red with a marker over it: a dashed
   trace beside a corridor, a ring around a symbol. A reviewer who reads the
   operator report, opens the viewer and then opens the workspace is reading
   one drawing convention throughout, and "somebody changed this" is a
   different question from "what state is this plant in". */

:root {
  --ws-human:#174ea6;        /* the marker only, never the element's own ink */
  --ws-handle:#174ea6;
  --tree-w: 232px;
}

.ws-head { display:flex; gap:var(--s-4); align-items:center;
           justify-content:space-between; flex-wrap:wrap;
           padding:var(--s-3) var(--s-4); }
.ws-version { display:flex; gap:var(--s-2); align-items:baseline;
              flex-wrap:wrap; font-size:var(--t-sm); }
.ws-version .seq { font-family:var(--mono); font-weight:700;
                   font-size:var(--t-lg); }
.ws-actions { display:flex; gap:var(--s-2); align-items:center; }

.chip.st-clean    { background:#f2f8f3; border-color:#b7ddc0; color:#12602a;
                    font-weight:700; }
.chip.st-concerns { background:#fef7e0; border-color:#f0d493; color:#7a5c0f;
                    font-weight:700; }
.chip.st-blocked  { background:#fdf1f0; border-color:#f0c3ad; color:var(--bad);
                    font-weight:700; }

/* ---------------------------------------------------------- the side tree */
.ws-side { width:var(--tree-w); flex:0 0 var(--tree-w); height:620px;
           overflow-y:auto; border-right:1px solid var(--line);
           background:#fcfcfc; padding:var(--s-2) var(--s-3); }
.ws-side h4 { font-size:var(--t-xs); text-transform:uppercase;
              letter-spacing:.06em; color:var(--muted); margin:0 0 var(--s-2); }
.ws-tree li { border-bottom:1px solid #eceef0; padding:var(--s-1) 0;
              display:flex; align-items:center; gap:var(--s-1); }
.ws-tree li.on { background:var(--accent-bg); }
.ws-v-open { flex:1 1 auto; text-align:left; border:none; background:none;
             cursor:pointer; font-size:var(--t-xs); padding:var(--s-1);
             display:flex; flex-wrap:wrap; gap:4px; align-items:baseline; }
.ws-v-open .seq { font-family:var(--mono); font-weight:700; }
.ws-v-open .who { color:var(--ink); }
.ws-restore { padding:1px 8px; font-size:var(--t-xs); }

/* -------------------------------------------------------------- the canvas */
.ws .dv-canvas { cursor:default; }
.ws.ws-picking .dv-canvas svg { cursor:crosshair; }
.ws.ws-busy { opacity:.72; pointer-events:none; }
#dv-svg .ws-handles circle { fill:#fff; stroke:var(--ws-handle);
                             stroke-width:2; cursor:grab; }
#dv-svg .ws-h.on circle { fill:var(--ws-handle); }
#dv-svg .human-trace { fill:none; stroke:var(--ws-human); stroke-width:6;
                       opacity:.20; stroke-linecap:round;
                       stroke-linejoin:round; }
#dv-svg .L-proposed .line.human { stroke-dasharray:9 4; }
#dv-svg .mk .human-ring { fill:none; stroke:var(--ws-human); stroke-width:1.6;
                          stroke-dasharray:3 2; }
.ws.ws-dirty .dv-canvas { box-shadow:inset 0 0 0 2px var(--warn); }
.ws-legend { position:absolute; right:12px; bottom:10px; display:flex;
             gap:var(--s-3); font-size:var(--t-xs); color:var(--ink);
             background:rgba(253,253,251,.86); border:1px solid var(--line);
             border-radius:4px; padding:3px 8px; }
.ws-legend i { display:inline-block; width:16px; height:3px;
               vertical-align:middle; margin-right:4px; }
.ws-legend i.sw-engine { background:var(--ink-proposed); }
.ws-legend i.sw-human { background:var(--ws-human); }

/* ------------------------------------------------------- tray and changes */
.ws-cols { display:grid; grid-template-columns:1fr 1fr; gap:var(--s-4);
           align-items:start; }
@media (max-width: 1100px) { .ws-cols { grid-template-columns:1fr; } }
.ws-tray-list li { display:flex; gap:var(--s-2); align-items:baseline;
                   padding:var(--s-2) 0; }
.ws-tray-list li span:nth-child(2) { flex:1 1 auto; }
.ws-undo { padding:1px 10px; font-size:var(--t-xs); }
.ws-add-wrap { margin-top:var(--s-3); }
.ws-field { margin:var(--s-2) 0; }
.ws-field input, .ws-field select { max-width:340px; }
.ws-note { min-height:56px; margin:var(--s-2) 0; }
.ws-danger { border-color:#f0c3ad; color:var(--bad); }
.ws-replace { margin-top:var(--s-2); max-width:340px; }

.ws-tally { display:flex; flex-wrap:wrap; gap:var(--s-5); margin:0 0 var(--s-3); }
.ws-stat { min-width:120px; }
.ws-stat b { display:block; font-size:var(--t-num); font-weight:600;
             line-height:1.15; }
.ws-stat span { display:block; color:var(--muted); font-size:var(--t-xs); }
.ws-changed li { padding:var(--s-2) 0; }
.ws-verdict, .ws-change { font-size:var(--t-xs); font-family:var(--mono);
                          padding:1px 0; }
.ws-verdict.v-fail, .ws-change.v-fail { color:var(--bad); }
.ws-verdict.v-unknown, .ws-change.v-unknown { color:var(--warn); }
.ws-verdict.v-pass, .ws-change.v-pass { color:var(--ok); }
.ws-verdict.v-waived, .ws-change.v-waived { color:var(--accent); }
td.d-up { color:var(--hot); }
td.d-down { color:var(--ok); }
table.ws-takeoff td.mono { font-family:var(--mono); }

/* ------------------------------------------------------------- concerns */
.ws-concerns li { border-bottom:1px solid #eceef0; padding:var(--s-3) 0; }
.ws-concern-head { display:flex; gap:var(--s-2); align-items:baseline;
                   flex-wrap:wrap; }
.ws-concern-title { margin-top:var(--s-1); }
.ws-concern.v-fail { border-left:3px solid var(--bad); padding-left:var(--s-3);
                     background:#fdf1f0; }
.ws-concern.v-unknown { border-left:3px solid var(--warn);
                        padding-left:var(--s-3); }
.ws-concern.v-waived { border-left:3px solid var(--accent);
                       padding-left:var(--s-3); }
.ws-goto { padding:1px 10px; font-size:var(--t-xs); }
.ws-waive { margin-top:var(--s-2); }
.ws-waive-form { border:1px solid var(--line); border-radius:6px;
                 padding:var(--s-2) var(--s-3); margin-top:var(--s-2);
                 max-width:60ch; }
.ws-waive-form textarea { min-height:56px; }
.ws-waive-form textarea.bad { border-color:var(--bad); }

/* A design carrying unchecked edits says so, on the canvas and on the shapes.
   `box-shadow: inset` would be clipped by `.dv`'s own `overflow:hidden`, so
   the frame is an inset outline. */
.ws.ws-dirty .dv-canvas { outline:2px solid var(--warn); outline-offset:-2px; }
#dv-svg .L-proposed .pending { stroke-dasharray:5 3; opacity:.95; }
#dv-svg .mk.pending circle, #dv-svg .mk.pending rect { stroke-dasharray:3 2; }

/* ==========================================================  UE5-import  ===
   The new-work-order form, the site sketch, and the findings page.

   No new tokens and no new type scale: everything below is built out of the
   same spacing, colour and radius variables the rest of this file uses, for
   the same reason the viewer's palette is the engine's — a page a reviewer
   arrives at from the work-order queue must not look like a different
   application. */

input[type=file] { display:block; margin:0 0 var(--s-3); font-size:var(--t-sm); }
input:not([type]), input[type=number] {
  display:block; width:100%; padding:var(--s-2) var(--s-3);
  border:1px solid var(--line); border-radius:var(--radius);
  background:#fff; margin:0 0 var(--s-3); }

.btn { display:inline-block; border:1px solid var(--line); background:#fff;
  color:var(--ink); border-radius:var(--radius); padding:var(--s-2) var(--s-4);
  text-decoration:none; font-size:var(--t-sm); cursor:pointer; }
.btn.primary { background:var(--ink); color:#fff; border-color:var(--ink); }
form.inline { display:inline; }

/* the three ways to give a site: draw it, paste it, upload it */
.tabs { display:flex; gap:var(--s-1); margin:var(--s-3) 0 var(--s-3); }
.tab { border:1px solid var(--line); border-radius:var(--radius-pill);
  background:#fff; padding:var(--s-1) var(--s-4); cursor:pointer;
  font-size:var(--t-sm); }
.tab.on { background:var(--ink); color:#fff; border-color:var(--ink); }
.pane { margin:0 0 var(--s-3); }
.drawwrap { display:flex; gap:var(--s-4); align-items:flex-start;
  flex-wrap:wrap; }
.drawwrap svg { border:1px solid var(--line); border-radius:var(--radius);
  background:#fff; width:640px; max-width:100%; height:auto; cursor:crosshair; }
.drawside { min-width:200px; flex:1; }

/* findings: the kind, the subject, what it means, and what would settle it —
   in that order, because that is the order a reader needs them in. A finding
   that changes what the engine would answer is marked, and it is the same red
   the engine uses for proposed work rather than a fourth colour. */
ul.findings { list-style:none; padding:0; margin:0; }
ul.findings > li { border-bottom:1px solid #eceef0; padding:var(--s-3) 0; }
ul.findings > li:last-child { border-bottom:none; }
ul.findings > li.design { border-left:3px solid var(--bad);
  padding-left:var(--s-3); }
.findings .kind { display:inline-block; font-size:var(--t-xs);
  text-transform:uppercase; letter-spacing:.06em; color:var(--muted);
  margin-right:var(--s-2); }
.findings .tag { font-size:var(--t-xs); border:1px solid var(--bad);
  color:var(--bad); border-radius:var(--radius-pill);
  padding:0 var(--s-2); margin-left:var(--s-2); }
.findings .meta { color:var(--muted); font-size:var(--t-sm);
  margin:var(--s-1) 0 0; }
.findings .settles { font-size:var(--t-sm); margin:var(--s-1) 0 0;
  max-width:100ch; }
.findings .small, .small { font-size:var(--t-xs); }

table.grid td, table.grid th { padding:var(--s-1) var(--s-3); }
table.grid td.n, table.grid th.n { text-align:right;
  font-family:var(--mono); }
table.grid td.n.bad { color:var(--bad); font-weight:700; }
.card.run { background:var(--accent-bg); border-color:var(--accent-line); }

/* ===================================================== UE4: packs and costs */

/* The pack a version was checked under, in the workspace head. `bad` when the
   pack in force has moved on since — which is a fact about the version, not a
   fault in it, so it is a marked chip rather than a warning banner. */
.chip.pack { font-family:var(--mono); font-size:var(--t-xs); }
.chip.pack.bad { border-color:var(--warn); color:var(--warn); }

/* The estimate's own row: a total that is only a total when nothing refused. */
table.ws-takeoff tr.ws-total td { border-top:2px solid var(--line);
  font-weight:600; }
table.ws-takeoff td.small, table.ws-takeoff th.small { font-size:var(--t-xs); }

/* An option a person picks, as opposed to `.check`, which is a fired rule.
   `label` is upper-cased site-wide (it is a field caption everywhere else);
   these are sentences a person reads and choose between, so they are not. */
label.opt, label.rv-cand { display:block; margin:var(--s-1) 0;
  font-weight:400; text-transform:none; letter-spacing:0;
  font-size:var(--t-sm); color:var(--ink); }
label.opt input, label.rv-cand input { margin-right:var(--s-2); }

/* `hidden` has to win over the button shapes above it, which set `display`. */
[hidden] { display:none !important; }

/* ------------------------------------------------------- the review page */
.rv-groups { display:flex; flex-wrap:wrap; gap:var(--s-2); margin:0; }
.rv-groups .chip { text-decoration:none; }
.rv-groups .chip.sel { border-color:var(--accent); color:var(--accent); }
.rv-rule h3 .chip { margin-left:var(--s-2); }
.rv-value { background:var(--accent-bg); border:1px solid var(--accent-line);
  border-radius:6px; padding:var(--s-2) var(--s-3); overflow-x:auto;
  font-size:var(--t-xs); margin:0 0 var(--s-2); }
.rv-quote { margin:var(--s-1) 0 0; padding-left:var(--s-3);
  border-left:3px solid var(--line); color:var(--ink);
  font-size:var(--t-sm); max-width:100ch; }
.rv-cands { max-height:340px; overflow-y:auto; }
.rv-cands > li { border-bottom:1px solid #eceef0; padding:var(--s-2) 0; }
.rv-cand { display:block; cursor:pointer; }
.rv-decide { border-top:1px solid var(--line); margin-top:var(--s-3);
  padding-top:var(--s-3); }
.rv-json { font-family:var(--mono); font-size:var(--t-xs); min-height:52px;
  max-width:60ch; }
.rv-needs { max-width:80ch; }

/* A link that reads as a button — the "Review the rules" affordance. It takes
   `.quiet`'s shape rather than defining a third one. */
a.button { display:inline-block; text-decoration:none; color:var(--ink);
  border:1px solid var(--line); background:var(--paper);
  border-radius:var(--radius-pill); padding:6px 16px; font-size:var(--t-sm); }
a.button:hover { border-color:#9aa0a6; }
