*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%;overflow:hidden;font-family:var(--font);background:var(--navy-dark);color:var(--text);transition:background-color .35s ease,color .35s ease}
*{scrollbar-width:thin;scrollbar-color:var(--divider) transparent}
*::-webkit-scrollbar{width:6px;height:6px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--divider);border-radius:var(--r-xs)}
*::-webkit-scrollbar-thumb:hover{background:var(--text-faint)}
#app{display:flex;flex-direction:column;height:100vh}
/* topbar */
#topbar{height:80px;flex-shrink:0;background:var(--navy-dark);border-bottom:2px solid transparent;border-image:var(--brand-grad) 1;display:flex;align-items:center;padding:0 22px;gap:14px;z-index:100;position:relative;box-shadow:var(--e3);transition:background-color .35s ease}
.logo-mark{width:30px;height:30px;background:var(--brand-grad);border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.logo-mark svg{width:16px;height:16px;fill:white}
.eco-mark-grad{position:absolute;inset:0;background:var(--brand-grad);mix-blend-mode:color;pointer-events:none;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center}
.app-title{font-size:var(--t-lg);font-weight:600;line-height:1.15}
.app-tag{font-size:var(--t-base);font-weight:600;color:var(--teal);letter-spacing:.03em;line-height:1.15;background:var(--brand-grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.study-chip{font-size:var(--t-sm);color:var(--text-muted);background:var(--surface-tint);border:1px solid var(--divider);border-radius:var(--radius);padding:4px 9px;display:flex;align-items:center;gap:6px;white-space:nowrap;transition:background .2s ease,border-color .2s ease,color .2s ease}
.study-chip.empty{color:var(--text-faint)}
.study-chip:not(.empty){background:var(--teal-dim);border-color:var(--teal-border);color:var(--text)}
.study-chip .sc-ico{color:var(--teal);font-size:var(--t-sm)}
.study-chip.empty .sc-ico{color:var(--text-faint)}
/* ── Topbar search ────────────────────────────────────────────────────────────
   Centred between the brand block and the actions. margin:auto on both sides is what
   centres it in the flex row; .topbar-actions keeps its own margin-left:auto so it stays
   hard right regardless of how wide the brand block renders. */
#topbar-search{position:relative;flex:1 1 240px;max-width:420px;min-width:0;margin:0 auto;
  display:flex;align-items:center;
  gap:var(--s2);padding:0 var(--s4);height:34px;background:var(--navy);
  border:1px solid var(--divider);border-radius:var(--r-pill);transition:border-color .15s,box-shadow .15s}
#topbar-search:focus-within{border-color:var(--teal);box-shadow:0 0 0 3px rgba(45,212,170,.12)}
.tbs-ic{flex-shrink:0;width:14px;height:14px;color:var(--text-faint);display:flex}
.tbs-ic svg{width:100%;height:100%}
#topbar-search-input{flex:1;min-width:0;background:none;border:none;outline:none;
  color:var(--text);font-size:var(--t-base);font-family:inherit}
#topbar-search-input::placeholder{color:var(--text-faint)}
#topbar-search-status{flex-shrink:0;font-size:var(--t-2xs);color:var(--text-faint);white-space:nowrap}
/* Suggestions drop below the field. Rows are .lot-result-item, shared with the other two
   search boxes, so they need no styling of their own here. */
#topbar-search-results{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:120;
  background:var(--navy);border:1px solid var(--divider);border-radius:var(--r-md);
  box-shadow:var(--e4);max-height:280px;overflow-y:auto}
#topbar-search-results:empty{display:none}

.topbar-actions{margin-left:auto;display:flex;gap:8px;align-items:center}
/* Icon-only secondary action — square, so the one labelled button reads as the primary. */
.tbtn-ic{width:32px;height:32px;padding:0;display:inline-flex;align-items:center;
  justify-content:center;font-size:var(--t-lg);line-height:1}

/* Responsive topbar rules live at the END of this file — see the block after the last
   component. Placed here they lost to .tb-by's own display:flex declared further down. */
/* topbar status — one grouped, bordered chip instead of separate coloured pills */
.tb-seg-group{display:flex;align-items:center;background:var(--surface-tint);border:1px solid var(--divider);border-radius:var(--r-lg);overflow:hidden;flex-shrink:0;min-width:0}
.tb-seg{font-size:var(--t-xs);color:var(--text-muted);padding:5px 9px;white-space:nowrap;display:flex;align-items:center;min-width:0}
.tb-seg+.tb-seg{border-left:1px solid var(--divider)}
/* Queensland -> states/territories dropdown — QLD is the only live state today; the rest are
   shown greyed-out with a "Coming soon" tag so the roadmap is visible without overclaiming. */
.tb-state-btn{position:relative;cursor:pointer;gap:4px;transition:color .15s ease}
.tb-state-btn:hover{color:var(--text)}
.tb-state-chev{font-size:var(--t-3xs);color:var(--text-faint);transition:transform .15s ease}
.tb-state-btn.open .tb-state-chev{transform:rotate(180deg)}
#state-menu{display:none;position:fixed;width:230px;background:var(--glass-bg);backdrop-filter:blur(10px) saturate(140%);-webkit-backdrop-filter:blur(10px) saturate(140%);border:1px solid var(--divider);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--e4);z-index:2000;cursor:default}
.tb-state-btn.open #state-menu{display:block;animation:fIn .18s cubic-bezier(.2,.8,.2,1) both}
.state-row{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:var(--t-base);color:var(--text-dim)}
.state-row.active{color:var(--text);font-weight:600}
.state-row+.state-row{border-top:1px solid var(--divider)}
.state-dot{width:6px;height:6px;border-radius:50%;background:var(--brand-grad);flex-shrink:0;box-shadow:0 0 6px rgba(29,158,117,.65)}
.state-tag{margin-left:auto;font-size:var(--t-2xs);font-weight:600;text-transform:uppercase;letter-spacing:.03em;padding:2px 6px;border-radius:var(--r-xs);flex-shrink:0}
.state-tag.live{background:var(--teal-dim);color:var(--teal)}
.state-tag.soon{background:var(--navy-mid);color:var(--text-faint)}
/* Account dropdown (subscription management + help/feedback, combined) — lives inside
   .tb-seg-group, which has overflow:hidden for its pill-shaped rounded corners, so — same
   gotcha as the Queensland dropdown — #account-menu must be position:fixed with its
   top/left computed from the button's real screen rect (see toggleAccountMenu), not
   position:absolute, or it gets silently clipped invisible. */
/* Initials avatar — the account surface. Replaces the old email chip plus separate "Account ▾"
   button; both facts now live inside its menu, which is how the bar reaches four icons. */
.tb-avatar{position:relative;width:32px;height:32px;flex-shrink:0;padding:0;border:none;
  border-radius:50%;background:var(--brand-grad);color:#fff;font-family:inherit;
  font-size:var(--t-xs);font-weight:700;letter-spacing:.02em;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 1px var(--divider);transition:box-shadow .15s}
.tb-avatar:hover,.tb-avatar.open{box-shadow:0 0 0 2px var(--teal)}
/* Signed out (local/staging bypass only — production never reveals the app without a session).
   Muted and hollow so it reads as "nobody", not as a logged-in user with odd initials. */
.tb-avatar.anon{background:none;background-color:var(--surface-tint);color:var(--text-faint);
  box-shadow:0 0 0 1px var(--divider)}
.tb-avatar:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
#avatar-initials{pointer-events:none;line-height:1}
/* Both dropdowns are position:fixed and placed from the button's screen rect by topbar.js —
   they hang off right-edge buttons, so that code anchors them by `right`, not `left`. */
#account-menu,#help-menu{display:none;position:fixed;width:280px;background:var(--glass-bg);backdrop-filter:blur(10px) saturate(140%);-webkit-backdrop-filter:blur(10px) saturate(140%);border:1px solid var(--divider);border-radius:var(--r-xl);overflow:hidden;box-shadow:var(--e4);z-index:2000;cursor:default;text-align:left}
.tb-avatar.open #account-menu,#help-menu-btn.open #help-menu{display:block;animation:fIn .18s cubic-bezier(.2,.8,.2,1) both}
#help-menu-btn{position:relative}
.hm-row{display:flex;flex-direction:column;gap:1px;padding:9px 14px;font-size:var(--t-base);color:var(--text-dim);cursor:pointer;transition:background .12s,color .12s}
.hm-row:hover{background:var(--navy-light);color:var(--text)}
.hm-sub{font-size:var(--t-2xs);color:var(--text-faint)}
.acct-id{padding:12px 14px 10px;display:flex;flex-direction:column;gap:2px;font-size:var(--t-base);color:var(--text);word-break:break-all}
.acct-id-l{font-size:var(--t-2xs);text-transform:uppercase;letter-spacing:.07em;color:var(--text-faint)}
.acct-foot{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);padding:10px 14px 12px;font-size:var(--t-xs);color:var(--text-faint)}
.acct-row{padding:9px 14px;font-size:var(--t-base);color:var(--text-dim);cursor:pointer;transition:background .12s,color .12s}
.acct-row:hover{background:var(--navy-light);color:var(--text)}
.help-sec{font-size:var(--t-xs);font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--text-faint);padding:12px 14px 6px}
.help-email-row{display:flex;align-items:center;gap:9px;padding:2px 14px 12px;font-size:var(--t-base);color:var(--text-dim);text-decoration:none;transition:color .12s}
.help-email-row:hover{color:var(--teal)}
.help-divider{border-top:1px solid var(--divider);margin:0}
.tb-by{font-size:var(--t-xs);color:var(--text-faint);white-space:nowrap;display:flex;align-items:center;gap:5px;flex-shrink:0}
.tb-by img{height:22px;width:auto;opacity:.85;vertical-align:middle;display:block}
/* Inside the account menu the credit is a footnote, not a masthead. */
.acct-foot .tb-by img{height:15px}
.tbtn{font-size:var(--t-xs);padding:5px 11px;border:1px solid var(--divider);border-radius:var(--radius);background:var(--navy-dark);color:var(--text-muted);cursor:pointer;transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease,color .15s ease,background .15s ease;box-shadow:0 2px 8px rgba(0,0,0,.25)}
.tbtn:hover{border-color:var(--teal);color:var(--teal);transform:translateY(-1px);box-shadow:0 4px 14px rgba(0,0,0,.3)}
.tbtn:active{transform:translateY(0)}
.tbtn.primary{background:var(--brand-grad);border-color:transparent;color:#fff;box-shadow:0 4px 16px rgba(29,158,117,.35)}
.tbtn.primary:hover{filter:brightness(1.08);box-shadow:0 6px 20px rgba(29,158,117,.45);transform:translateY(-1px)}
#theme-toggle{padding:6px 9px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.theme-ic{width:15px;height:15px;display:block}
.theme-ic-moon{display:none}
html[data-theme="light"] .theme-ic-sun{display:none}
html[data-theme="light"] .theme-ic-moon{display:block}
/* body */
#body{display:flex;flex:1;overflow:hidden;position:relative}
/* sidebar */
#sidebar{width:var(--sw);flex-shrink:0;background:var(--navy);border-right:1px solid var(--divider);display:flex;flex-direction:column;transition:width .25s ease,background-color .35s ease,border-color .35s ease;overflow:hidden;z-index:10;box-shadow:6px 0 20px rgba(0,0,0,.22)}
/* border-right-width is the only real change here: under the global border-box reset a
   0-width box still paints its 1px border, so the collapsed panel measured 1px and left
   a hairline hanging off the rail.
   min-width:0 is belt-and-braces, NOT the fix — width:0 collapses this on its own. A flex
   item's automatic minimum size is capped by its own definite width (CSS Flexbox §4.5), so
   min-width:auto already resolves to 0 here, not to the content minimum. The usual
   "min-width:auto stops a flex item shrinking" trap needs a flex-basis/flex-shrink item
   with no definite width; this one has width:0, so it was never affected. Keeping the
   declaration only guards a future switch to flex-basis sizing.
   Content clipping during the .25s transition is already handled — #sidebar carries
   overflow:hidden above. */
#sidebar.collapsed{width:0;min-width:0;border-right-width:0;box-shadow:none}
/* ── Mode: Explore ⇄ Assess ───────────────────────────────────────────────────
   One map, two intents. The switch drives which nav shows (spine vs Explore lenses),
   via body[data-mode] below. */
#mode-tabs{display:flex;gap:var(--s1);flex-shrink:0;padding:var(--s3) var(--s3) var(--s2);background:var(--navy-dark)}
/* Height and type live HERE, not in a later override — see the #mode-tabs note further down.
   44px/13px is measured off the concept, where the two modes are the heaviest control in the
   sidebar. The old 34px/11.5px base plus a 42px/12px override further down was two generations
   of the same decision, and only the second one ever applied. */
.mode-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--s2);height:44px;border-radius:var(--r-lg);border:1px solid var(--divider);background:var(--navy-mid);color:var(--text-dim);font-size:var(--t-lg);font-weight:600;font-family:inherit;cursor:pointer;transition:color .15s,border-color .15s,background .15s}
.mode-btn:hover{color:var(--text);border-color:var(--teal-border)}
.mode-btn.active{background:var(--teal-dim);border-color:var(--teal);color:var(--teal)}

/* ── Workflow spine (vertical) ────────────────────────────────────────────────
   The four steps of the assessment. Vertical so each step carries its OWN live state
   line — area/buffer, layers queried, constraints found — instead of one shared caption.
   Replaced a 7-peer-tab row PLUS a separate dot tracker PLUS a 6-step how-to list:
   three competing answers to "what do I do next?". Now there is one. */
#tab-nav{display:flex;flex-direction:column;gap:2px;flex-shrink:0;padding:var(--s2) var(--s3) var(--s3);border-bottom:1px solid var(--divider);background:var(--navy-dark);position:relative}
.spine-hdr{display:flex;align-items:baseline;justify-content:space-between;padding:0 var(--s2) var(--s2)}
.spine-lbl{font-size:var(--t-2xs);text-transform:uppercase;letter-spacing:.1em;font-weight:700;color:var(--text-faint)}
.spine-pct{font-size:var(--t-xs);color:var(--text-dim);font-weight:600}
.tab-btn{display:flex;align-items:center;gap:var(--s4);width:100%;text-align:left;padding:8px var(--s3);border-radius:var(--r-lg);border:1px solid transparent;background:none;color:var(--text-dim);font-family:inherit;cursor:pointer;transition:background .15s,border-color .15s}
.tab-btn:hover{background:var(--surface-tint)}
.tab-btn.active{background:var(--teal-dim);border-color:var(--teal-border)}
/* Step chip: outlined while pending, brand-filled once that step is complete. */
.tb-num{width:22px;height:22px;flex:0 0 auto;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--t-xs);font-weight:700;border:1.5px solid var(--divider);color:var(--text-faint);background:var(--navy-dark);transition:background .15s,border-color .15s,color .15s}
.tab-btn.active .tb-num{border-color:var(--teal);color:var(--teal)}
/* Completed steps: green fill, WHITE tick — was a dark teal (#04342c) tick on the gradient,
   which read as a hole rather than a completed marker. */
/* Flat green, not --brand-grad. That gradient runs #1e57b8 -> #1D9E75, so a completed step's
   circle was half BLUE and only became green at its right edge — which is why it never read as
   the concept's solid green disc. The concept uses a flat --accent (#1D9E75, the same value as
   --teal) with white on top. Reserve the gradient for the primary CTA, where a 40px-wide button
   has room for a gradient to be legible; a 19px disc does not. */
.tab-btn.done .tb-num{background:var(--teal);border-color:var(--teal);color:#fff}
/* Current step: green ring + a soft halo, as in the concept (box-shadow:0 0 0 3px accent-soft).
   Costs no layout — the halo draws outside the border box, so the four rows still fit. */
.tab-btn.active .tb-num{box-shadow:0 0 0 3px var(--teal-dim)}
/* Label and its live sub-label share ONE line (they used to stack, which made each of the
   four spine rows twice as tall and pushed the panel content below the fold). The sub-label
   shrinks and ellipsises; the label never does. */
.tb-txt{flex:1;min-width:0;display:flex;align-items:baseline;gap:var(--s2)}
.tb-lbl{flex:0 0 auto;font-size:var(--t-md);font-weight:600;line-height:1.3;color:var(--text-muted)}
.tab-btn.active .tb-lbl{color:var(--text)}
.tb-sub{flex:0 1 auto;min-width:0;font-size:var(--t-xs);color:var(--text-faint);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tab-btn.active .tb-sub{color:var(--text-dim)}
.tb-go{flex:0 0 auto;color:var(--text-faint);font-size:var(--t-lg);opacity:0;transform:translateX(-3px);transition:opacity .15s,transform .15s}
.tab-btn:hover .tb-go,.tab-btn.active .tb-go{opacity:1;transform:none}
#tab-indicator{display:none} /* the vertical spine marks the active step directly */

/* Explore's lenses. Find/Compare ship disabled — an honest placeholder beats hiding
   the shape of where this is going. */
#explore-nav{display:flex;gap:var(--s1);flex-shrink:0;margin:var(--s2) var(--s5) var(--s5);padding:var(--s1);border-radius:var(--r-lg);border:1px solid var(--divider);background:var(--navy-dark)}
.subm-btn{flex:1;height:28px;border:none;background:transparent;border-radius:var(--radius);color:var(--text-dim);font-size:var(--t-xs);font-weight:700;font-family:inherit;cursor:pointer;transition:color .15s,background .15s}
.subm-btn:hover:not(:disabled){color:var(--text)}
.subm-btn.active{background:var(--navy-mid);color:var(--teal);box-shadow:var(--e1)}
.subm-btn:disabled{color:var(--text-faint);opacity:.5;cursor:not-allowed}

/* Utilities — reachable, but deliberately quieter than the spine so they read as
   "elsewhere", not "next". */
#util-nav{display:flex;flex-shrink:0;gap:var(--s1);padding:var(--s2) var(--s4);border-bottom:1px solid var(--divider);background:var(--navy-dark)}
.util-btn{flex:1;padding:5px var(--s1);font-size:var(--t-xs);font-weight:500;color:var(--text-faint);background:none;border:1px solid transparent;border-radius:var(--r-sm);cursor:pointer;transition:color .15s,background .15s,border-color .15s;white-space:nowrap;font-family:inherit}
.util-btn:hover{color:var(--text-muted);background:var(--surface-tint)}
.util-btn.active{color:var(--teal);border-color:var(--teal-border);background:var(--teal-dim)}

/* ── Shared form/control components ───────────────────────────────────────────
   Extracted from repeated inline style="" blobs in index.html during the Phase-C
   consistency sweep. Each reproduces its original appearance exactly, now via tokens,
   so one edit here changes every instance instead of 4 scattered copies. */
.eco-input{padding:7px 9px;background:var(--navy);border:1px solid var(--divider);border-radius:var(--r-md);color:var(--text);font-size:var(--t-base);font-family:inherit}
.eco-field{width:100%;padding:8px var(--s4);margin-bottom:var(--s3);background:var(--navy-dark);border:1px solid var(--divider);border-radius:var(--r-md);color:var(--text);font-size:var(--t-base);font-family:inherit}
.eco-field-inline{flex:1;padding:8px var(--s4);background:var(--navy-dark);border:1px solid var(--divider);border-radius:var(--r-md);color:var(--text);font-size:var(--t-base);font-family:inherit}
/* .eco-minibtn removed with the Explore bulk row it styled — All on / All off / Expand /
   Collapse became the icon tool row (.lt-btn, css/layers.css) and nothing else used it. */
.eco-segbtn{border:none;padding:3px var(--s5);font-size:var(--t-sm);cursor:pointer;background:transparent;color:var(--text-muted);font-family:inherit}
.eco-input:focus,.eco-field:focus,.eco-field-inline:focus{outline:none;border-color:var(--teal)}

/* Mode gating — one attribute on <body> decides which nav is in play. */
body[data-mode="explore"] #tab-nav{display:none}
body[data-mode="assess"] #explore-nav{display:none}


.tab-panel{display:none;flex:1;overflow-y:auto;flex-direction:column}
.tab-panel.active{display:flex}
.tab-panel::-webkit-scrollbar{width:4px}
.tab-panel::-webkit-scrollbar-thumb{background:var(--divider);border-radius:2px}
/* toggle */
#sidebar-toggle{position:absolute;left:var(--sw);top:50%;transform:translateY(-50%);width:20px;height:48px;background:var(--navy-mid);border:1px solid var(--divider);border-left:none;border-radius:0 4px 4px 0;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:20;transition:left .25s ease;color:var(--text-dim)}
#sidebar-toggle:hover{background:var(--navy-light);color:var(--teal)}
#sidebar-toggle svg{width:12px;height:12px;transition:transform .25s}
#sidebar.collapsed~#sidebar-toggle{left:0}
#sidebar.collapsed~#sidebar-toggle svg{transform:rotate(180deg)}
/* drag-to-resize handle: pinned to the sidebar's right edge, drives --sw */
#sidebar-resize{position:absolute;left:calc(var(--sw) - 8px);top:0;bottom:0;width:8px;cursor:col-resize;z-index:19;transition:left .25s ease}
#sidebar-resize::before{content:"";position:absolute;top:50%;left:2px;transform:translateY(-50%);width:3px;height:34px;border-radius:2px;background:transparent;transition:background .15s}
#sidebar-resize:hover::before,#sidebar-resize.dragging::before{background:var(--brand-grad)}
#sidebar.collapsed~#sidebar-resize{display:none}
#sidebar.sb-no-anim{transition:none}
#sidebar-resize.dragging{transition:none}
body.sb-resizing{cursor:col-resize;user-select:none}
/* section label */
.slabel{font-size:var(--t-xs);font-weight:600;color:var(--text-dim);letter-spacing:.07em;text-transform:uppercase;padding:12px 14px 6px}
/* info */
#panel-info{padding:16px 14px;gap:12px}
.info-header{display:flex;align-items:center;gap:10px;padding-bottom:14px;border-bottom:1px solid var(--divider)}
.info-logo{width:36px;height:36px;background:var(--brand-grad);border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.info-logo svg{width:18px;height:18px;fill:white}
.info-title{font-size:var(--t-lg);font-weight:600}
.info-sub{font-size:var(--t-sm);color:var(--text-dim);margin-top:2px}
.info-badge{margin-left:auto;font-size:var(--t-xs);font-weight:600;padding:2px 10px;border-radius:var(--r-xl);background:var(--teal-dim);color:var(--teal);border:1px solid var(--teal-border);flex-shrink:0}
.info-desc{font-size:var(--t-base);color:var(--text-muted);line-height:1.65}
.info-purpose{background:rgba(29,158,117,.08);border-left:3px solid var(--teal);border-radius:0 6px 6px 0;padding:11px 13px}
.info-purpose-text{font-size:var(--t-base);color:var(--text-muted);line-height:1.65}
.info-covers-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.info-cover-card{background:var(--navy-mid);border:1px solid var(--divider);border-radius:var(--radius);padding:8px 10px;display:flex;align-items:flex-start;gap:8px;box-shadow:var(--e1)}
.info-cover-icon{font-size:var(--t-xl);flex-shrink:0;margin-top:1px}
.info-cover-label{font-size:var(--t-base);font-weight:600;color:var(--text);line-height:1.3}
.info-cover-sub{font-size:var(--t-xs);color:var(--text-muted);margin-top:2px;line-height:1.3}
.steps{display:flex;flex-direction:column;gap:8px}
.step{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;background:var(--navy-mid);border-radius:var(--radius);border:1px solid var(--divider);box-shadow:var(--e1)}
.step-num{width:22px;height:22px;background:var(--brand-grad);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--t-sm);font-weight:700;color:#fff;flex-shrink:0;margin-top:1px}
.step-title{font-size:var(--t-base);font-weight:600;margin-bottom:2px}
.step-desc{font-size:var(--t-sm);color:var(--text-muted);line-height:1.5}
.step-tab{display:inline-block;font-size:var(--t-xs);font-weight:600;padding:1px 6px;border-radius:var(--r-xs);background:var(--teal-dim);color:var(--teal);border:1px solid var(--teal-border);margin-left:3px;vertical-align:middle;cursor:pointer;transition:background .15s ease}
.step-tab:hover{background:var(--teal-border)}
.trigger-callout{background:var(--red-bg);border:1px solid var(--red-border);border-radius:var(--radius);padding:10px 12px;display:flex;gap:10px}
.trigger-callout-text{font-size:var(--t-sm);color:var(--red);line-height:1.55}
.trigger-callout-text strong{color:var(--red);display:block;margin-bottom:3px}
.src-badges{display:flex;flex-wrap:wrap;gap:5px}
.src-badge{font-size:var(--t-xs);padding:3px 8px;border-radius:var(--r-sm);background:var(--navy-mid);color:var(--text-muted);border:1px solid var(--divider)}
.disc-box{background:var(--navy-dark);border-radius:var(--radius);padding:12px 14px;border:1px solid var(--divider)}
.disc-title{font-size:var(--t-xs);font-weight:600;color:var(--text-dim);letter-spacing:.06em;text-transform:uppercase;margin-bottom:6px}
.disc-text{font-size:var(--t-xs);color:var(--text-dim);line-height:1.6}
.disc-cur{margin-top:8px;font-size:var(--t-xs);color:var(--text-faint);display:flex;align-items:center;gap:5px}
.disc-cur::before{content:'●';color:var(--teal);font-size:var(--t-3xs)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:5px 12px;border-radius:var(--radius);font-size:var(--t-sm);font-weight:500;cursor:pointer;transition:all .15s;border:none;width:100%}
.btn-p{background:var(--brand-grad);color:#fff}
.btn-p:hover{filter:brightness(1.08)}
.btn-s{background:transparent;color:var(--text-muted);border:1px solid var(--divider)}
.btn-s:hover{border-color:var(--teal);color:var(--teal)}
.btn-d{background:transparent;color:var(--red);border:1px solid var(--red-border)}
.btn-d:hover{background:var(--red-dim)}
.btn-row{display:flex;gap:6px}
.btn-row .btn{flex:1}
.upload-drop{border:2px dashed var(--divider);border-radius:var(--radius);padding:16px;text-align:center;cursor:pointer;transition:all .15s;margin-bottom:8px}
.upload-drop:hover{border-color:var(--teal);background:var(--teal-dim)}
.upload-drop.drag-over{border-color:var(--teal);background:var(--teal-dim)}
.upload-drop p{font-size:var(--t-sm);color:var(--text-dim);margin-top:4px}
#file-input{display:none}
/* external */
#panel-external{padding:12px;gap:6px}
.ext-sec{font-size:var(--t-xs);font-weight:600;color:var(--text-dim);letter-spacing:.06em;text-transform:uppercase;padding:8px 0 4px}
.ext-btn{display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--divider);border-radius:var(--radius);background:var(--navy-mid);cursor:pointer;transition:all .15s;text-decoration:none;color:var(--text)}
.ext-btn:hover{border-color:var(--teal);background:rgba(29,158,117,.06)}
.ext-icon{width:28px;height:28px;border-radius:var(--r-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:var(--t-lg)}
.ext-name{font-size:var(--t-base);font-weight:500}
.ext-sub{font-size:var(--t-xs);color:var(--text-dim);margin-top:1px}
.ext-arr{margin-left:auto;color:var(--text-faint);font-size:var(--t-base)}
/* The on-map status pill was removed — it sat over the basemap chips and only repeated
   what the step tracker, scanning animation and results banner already say. setStatus()
   in core/utils.js is now null-safe, so re-adding an element with id="statusbar"
   anywhere would bring all 15 of its messages back with no code change. */

/* loading */
#loading{position:fixed;inset:0;overflow:hidden;display:flex;align-items:center;justify-content:center;z-index:1000;transition:opacity .6s ease, transform .6s ease;
  background:
    radial-gradient(circle at 18% 20%, rgba(29,158,117,0.14), transparent 42%),
    radial-gradient(circle at 82% 78%, rgba(46,79,110,0.42), transparent 46%),
    linear-gradient(160deg, var(--navy-dark) 0%, #0c1826 55%, #070d15 100%);
}
#loading.loading-exit{opacity:0;transform:scale(1.045);pointer-events:none}

/* intro sequence — plays once when #loading gets the .play class (see unlockApp) */
#loading .contours{position:absolute;inset:0;width:100%;height:100%}
#loading .contours path{fill:none;stroke:var(--teal);stroke-width:1;opacity:.26;stroke-dasharray:1400;stroke-dashoffset:1400}
#loading.play .contours path{animation:drawLine 1.6s cubic-bezier(.3,.7,.3,1) forwards}
#loading.play .contours path:nth-child(1){animation-delay:.05s}
#loading.play .contours path:nth-child(2){animation-delay:.18s;opacity:.19}
#loading.play .contours path:nth-child(3){animation-delay:.30s;opacity:.15}
#loading.play .contours path:nth-child(4){animation-delay:.12s;opacity:.21}
@keyframes drawLine{to{stroke-dashoffset:0}}

#loading .scan{position:absolute;top:0;bottom:0;width:26%;
  background:linear-gradient(90deg, transparent, rgba(29,158,117,.16) 45%, rgba(29,158,117,.30) 50%, rgba(29,158,117,.16) 55%, transparent);
  transform:translateX(-120%);pointer-events:none}
#loading.play .scan{animation:scanSweep 1.15s cubic-bezier(.5,0,.3,1) forwards;animation-delay:.15s}
@keyframes scanSweep{to{transform:translateX(220%)}}

#loading .intro-content{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;text-align:center}
#loading .eco-mark{width:72px;height:72px;display:block;opacity:0}
#loading.play .eco-mark{animation:logoIn .7s .35s cubic-bezier(.2,.8,.2,1) forwards, logoGlow 2.2s 1.05s ease-in-out infinite}
#loading .eco-mark-grad{opacity:0}
#loading.play .eco-mark-grad{animation:logoIn .7s .35s cubic-bezier(.2,.8,.2,1) forwards}
@keyframes logoIn{0%{opacity:0;transform:scale(.55) rotate(-10deg)}65%{opacity:1;transform:scale(1.08) rotate(2deg)}100%{opacity:1;transform:scale(1) rotate(0)}}
@keyframes logoGlow{0%,100%{filter:drop-shadow(0 0 2px rgba(29,158,117,.25))}50%{filter:drop-shadow(0 0 20px rgba(29,158,117,.65))}}

#loading .wordmark{display:flex;margin-top:18px;font-size:var(--t-3xl);font-weight:700;letter-spacing:.3px;color:var(--text)}
#loading .wordmark span{opacity:0;display:inline-block}
#loading.play .wordmark span{animation:letterIn .45s cubic-bezier(.2,.8,.2,1) forwards}
@keyframes letterIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
#loading .tagline{margin-top:6px;font-size:var(--t-base);color:var(--text-muted);opacity:0}
#loading.play .tagline{animation:fadeUp .5s 1.35s cubic-bezier(.2,.8,.2,1) forwards}
@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}

#loading .acronym{margin-top:14px;font-size:16px;color:var(--text-muted);line-height:1.7;max-width:400px}
#loading .acronym .acr-word{opacity:0;display:inline-block;transform:translateY(4px)}
#loading .acronym .acr-word strong{color:var(--teal);font-weight:700;font-size:1.15em}
#loading.play .acronym .acr-word{animation:fadeUp .4s cubic-bezier(.2,.8,.2,1) forwards}

#loading .status{margin-top:28px;height:14px;position:relative;font-size:var(--t-sm);color:var(--text-faint);font-family:ui-monospace,'SF Mono',Consolas,'Liberation Mono',monospace;letter-spacing:.2px;min-width:220px}
#loading .status span{position:absolute;left:50%;top:0;transform:translateX(-50%);white-space:nowrap;opacity:0}
#loading.play .status span:nth-child(1){animation:statusStepOut .55s ease forwards;animation-delay:1.6s}
#loading.play .status span:nth-child(2){animation:statusStepOut .55s ease forwards;animation-delay:2.3s}
#loading.play .status span:nth-child(3){animation:statusStep .55s ease forwards;animation-delay:3.3s}
@keyframes statusStep{from{opacity:0;transform:translateX(-50%) translateY(4px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}
@keyframes statusStepOut{0%{opacity:0;transform:translateX(-50%) translateY(4px)}20%{opacity:1;transform:translateX(-50%) translateY(0)}75%{opacity:1;transform:translateX(-50%) translateY(0)}100%{opacity:0;transform:translateX(-50%) translateY(-4px)}}

#loading .load-bar{margin-top:11px;width:200px;height:2px;border-radius:2px;background:var(--divider);overflow:hidden;position:relative}
#loading .load-bar-fill{position:absolute;left:0;top:0;bottom:0;width:0;background:var(--brand-grad);border-radius:2px}
#loading.play .load-bar-fill{animation:trackFill 5.3s cubic-bezier(.4,0,.2,1) forwards;animation-delay:.5s}
@keyframes trackFill{0%{width:0}70%{width:96%}100%{width:100%}}

@media (prefers-reduced-motion: reduce){
  #loading.play .eco-mark, #loading.play .wordmark span, #loading.play .tagline, #loading.play .acronym .acr-word, #loading.play .status span, #loading.play .load-bar-fill, #loading.play .contours path, #loading.play .scan{
    animation-duration:.01s !important; animation-delay:0s !important;
  }
}
#app{transition:opacity .6s ease .05s}
#app.app-hidden{opacity:0}
/* toast */
/* Above every modal. At z-index 500 this sat BEHIND the wizard overlay (15300),
   so a toast raised from inside a modal — including the only feedback the intake
   gave when Next was blocked — was invisible. A notification layer that can be
   covered by the thing raising it is not a notification layer. */
#toast-c{position:fixed;bottom:20px;right:20px;display:flex;flex-direction:column;gap:8px;z-index:16000}
.toast{padding:10px 16px;border-radius:var(--radius);font-size:var(--t-base);max-width:280px;animation:fIn .2s ease;pointer-events:none}
.toast-info{background:var(--navy-mid);border:1px solid var(--divider);color:var(--text-muted)}
.toast-success{background:var(--green-bg);border:1px solid rgba(29,158,117,.4);color:var(--green)}
.toast-error{background:var(--red-bg);border:1px solid var(--red-border);color:var(--red)}
@keyframes fIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes fInUp{from{opacity:0;transform:translateX(-50%) translateY(14px)}to{opacity:1;transform:translateX(-50%) translateY(0)}}
@keyframes fInCenter{from{opacity:0;transform:translate(-50%,-50%) scale(.97)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
@keyframes fadeBg{from{opacity:0}to{opacity:1}}
@keyframes fInModal{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}

/* ── Step-panel header ────────────────────────────────────────────────────────
   Every one of the four workflow steps opens the same way: eyebrow naming the step,
   a plain-English title saying what this panel is for, then a one-line orientation.
   .panel-hdr is the standalone variant (Define, Screen); Review and Report wrap the
   same three elements in their existing .res-hdr. */
/* Define and Screen scroll the WHOLE panel (#panel-tools / #panel-layers are the scroll
   containers themselves), whereas Review and Report pin .res-hdr above an inner scroller.
   Sticky keeps the heading visible in all four, so the step you're on never scrolls out. */
.panel-hdr{position:sticky;top:0;z-index:2;padding:12px 14px;border-bottom:1px solid var(--divider);background:var(--navy-dark);flex-shrink:0}
.res-eyebrow{font-size:var(--t-2xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--teal);font-weight:700;margin-bottom:2px}
.res-title{font-size:var(--t-xl);font-weight:600;color:var(--text);letter-spacing:-.01em;
  line-height:1.2;margin-bottom:var(--s1)}
.res-summary{font-size:var(--t-base);color:var(--text-muted)}

/* Shared sub-label hint — one class for the small muted explainer under a field or button.
   Was duplicated as inline "font-size:10px;color:var(--text-faint);margin-top:8px" in Define
   and as .rd-hint in report.css. */
.form-hint{font-size:var(--t-xs);color:var(--text-faint);margin-top:var(--s2);line-height:1.45}

/* ── Responsive topbar ────────────────────────────────────────────────────────
   Must be the LAST rules in this file: .tb-by declares its own display:flex above,
   so an earlier media query at equal specificity loses the cascade and silently
   does nothing. The logo, version/state segs and actions can't shrink, so the search
   is what gets squeezed — shed the non-essential brand chrome first, then below
   ~980px drop the search entirely. The map's own Search launcher covers that case
   and runs the identical pipeline, so nothing becomes unreachable. */
/* Scoped to #topbar: the same class now also appears inside #account-menu, which is a
   fixed-position dropdown and must keep its credit at every width. */
@media (max-width:1280px){ #topbar>.tb-by{display:none} .app-tag{display:none} }
@media (max-width:980px){ #topbar-search{display:none} }

/* ── Density pass to match the concept ────────────────────────────────────────
   The concept fits all of Define without scrolling; ours overflowed by 220px at the
   same width. These are the measured contributors, tightened in place. Last in the
   file so they win over the earlier component declarations. */
#topbar{height:68px;padding:0 16px;gap:12px}
/* Icon buttons were rendering smaller than intended: .tbtn's own font-size:var(--t-xs) (10px)
   comes later in this file than .tbtn-ic's font-size:var(--t-lg) (13px) declaration above, so
   at equal specificity it silently won the cascade — the glyphs (emoji + the SVG icons, which
   scale off this same font-size) were never actually reaching their intended 13px. Sized up
   further from there, not just restored, since even the intended 13px read as hard to
   distinguish at a glance. +6px on the topbar (above) gives the taller buttons the same
   breathing room they had at 32px/62px. */
.tbtn-ic{width:38px;height:38px;font-size:16px}
/* Topbar logo only. This was briefly a bare ".eco-mark ... !important", which also hit the
   welcome overlay, the splash and the auth gate — none of which set their own width, so they
   squashed. Scoped, and the !important is gone because the inline height it was overriding
   has been moved here too (rule 6b). */
#topbar .eco-mark{height:40px;width:auto;display:block}
/* Spine rows: 42px -> 34px across four rows. */
.tab-btn{padding:5px var(--s3);gap:var(--s3)}
.tb-num{width:19px;height:19px;font-size:var(--t-2xs)}
.tb-lbl{font-size:var(--t-base)}
/* util-nav's three destinations now live as topbar icons, as in the concept. */
#util-nav{display:none}
/* Panel header: trim the block without losing the eyebrow/title/description hierarchy. */
.panel-hdr,.res-hdr{padding:10px 14px}
.res-title{font-size:var(--t-lg);margin-bottom:2px}
.res-summary{font-size:var(--t-sm);line-height:1.4}
/* Final density trim: the concept fits Define without scrolling, so the chrome above the
   panel has to give up its share too, not just the panel contents. */
/* Explore / Assess a site are the app's two top-level modes — the biggest decision on the
   panel. They were rendering 43px tall at 11.5px type, flush against the topbar with a 6px
   gap below: read as a minor segmented control rather than the primary split. Sized and
   spaced to match the concept. This is the ONLY place #mode-tabs padding is set; an override
   added below will silently win. The button's own height/type sizing lives with the .mode-btn
   base rule above — do not re-declare it here, that is exactly the duplication just removed. */
#mode-tabs{padding:var(--s5);gap:var(--s3)}
#tab-nav{padding:var(--s1) var(--s3) var(--s2)}
.tab-btn{padding:3px var(--s3)}
.spine-hdr{padding:var(--s1) var(--s2)}

/* ── Uniform surface ──────────────────────────────────────────────────────────
   The concept uses ONE navy across every surface; only two things break out of it —
   editable fields (darker, so they read as wells you can type into) and buttons (accent).
   Before this, the sidebar stacked three shades — #111e2e on the headers and nav, #1a2e44
   on the sidebar, #243B55 on the tiles — which is what read as patchwork rather than one
   calm surface. */
#sidebar,#mode-tabs,#tab-nav,.panel-hdr,.res-hdr{background:var(--navy)}
/* Sections separate by rule, not by a change of fill. */
#mode-tabs,#tab-nav{border-bottom:1px solid var(--divider)}

/* Primary CTAs (Define's "Choose what to screen", Review's "Set up your report") were the
   heaviest elements on screen. Thinner, in line with the smaller type scale — still the one
   accented action per panel, just less shouty. */
.define-cta,.res-report-cta{padding:5px 12px;font-size:var(--t-sm);gap:var(--s2)}
#run-btn{padding:5px 12px;font-size:var(--t-sm)}
.dc-arr,.rrc-arr{font-size:var(--t-base)}
/* Completed step: white tick on the green fill. Specificity raised deliberately — the
   .active rule sets the same property at equal weight, and a step that is both current and
   complete (the normal case when you revisit Define) was landing on whichever won. */
.tab-btn.done .tb-num,.tab-btn.active.done .tb-num{color:#fff}
/* Group headings inside the How-to-use map-tools list, matching the menu's own View / Measure /
   Overlays sections so the documentation and the control share one structure. */
.mt-help-grp{list-style:none;margin-left:-18px;margin-top:6px;font-size:var(--t-2xs);
  letter-spacing:.07em;text-transform:uppercase;color:var(--text-faint)}
.mt-help-grp strong{font-weight:700}

/* ── A disabled control must look disabled ──────────────────────────────────
   App-wide, not per-button. Three bugs were reported in two days as "the app is
   broken" when the real answer was a control that was off and gave no sign of
   it — "Run the screen" with no study area, the buffer Apply, the intake's Next.
   Each rendered at full opacity with a pointer cursor, so a disabled control was
   pixel-identical to a working one and the natural response was to press again.

   Scoped to what the user can press. :disabled only matches form controls, which
   is exactly right — a div with aria-disabled is styled by its own component. */
button:disabled, input:disabled, select:disabled, textarea:disabled {
  opacity: .5;
  cursor: not-allowed;
  filter: saturate(.35);
}
button:disabled:hover, input:disabled:hover { opacity: .5; }

/* ── Stale-build guard banner ──────────────────────────────────────────────────
   Shown only when the loaded modules disagree with the version the HTML asked for
   (see js/core/build-check.js). Amber, not red: nothing is broken yet and the fix
   is one click, so this is a warning about the build rather than an error in it.
   Fixed to the bottom so it cannot cover the topbar or the panel the user is
   working in, and above the toast layer so a toast cannot bury it. */
#stale-build-bar{position:fixed;left:50%;bottom:14px;transform:translateX(-50%);
  z-index:16100;display:flex;align-items:center;gap:12px;max-width:min(720px,94vw);
  padding:10px 12px 10px 16px;border-radius:var(--r-lg);
  background:var(--amber-dim);border:1px solid var(--amber-border);
  color:var(--text);box-shadow:var(--e3);font-size:var(--t-md);line-height:1.45}
#stale-build-bar .sbb-txt{flex:1 1 auto;min-width:0}
#stale-build-bar strong{color:var(--amber)}
#stale-build-bar .sbb-go{flex:0 0 auto;padding:6px 14px;border-radius:var(--r-md);
  border:1px solid var(--amber-border);background:var(--amber);color:#2a1c00;
  font:inherit;font-weight:700;cursor:pointer}
#stale-build-bar .sbb-go:hover{filter:brightness(1.08)}
#stale-build-bar .sbb-x{flex:0 0 auto;width:26px;height:26px;border:0;border-radius:var(--r-sm);
  background:transparent;color:var(--text-dim);font-size:16px;line-height:1;cursor:pointer}
#stale-build-bar .sbb-x:hover{background:var(--surface-tint);color:var(--text)}
@media (max-width:620px){ #stale-build-bar{flex-wrap:wrap} #stale-build-bar .sbb-txt{flex-basis:100%} }
#stale-build-bar kbd{display:inline-block;padding:0 4px;border:1px solid var(--amber-border);
  border-radius:var(--r-xs);background:var(--surface-tint);font-family:ui-monospace,Consolas,monospace;
  font-size:var(--t-sm);line-height:1.5}
