/* LoadLens — light, professional engineering-tool theme.
   No external fonts or images: system font stack only. */

:root {
  --bg: #f2f5f8;
  --card: #ffffff;
  --ink: #1b2430;
  --ink-soft: #5b6774;
  --line: #d3dbe4;
  --line-soft: #e6ebf1;
  --accent: #1b5e9c;
  --accent-dark: #14456f;
  --accent-soft: #e8f1fa;
  --ok: #1d7a4b;
  --ok-soft: #e7f5ee;
  --warn: #8a5a00;
  --warn-soft: #fdf6e3;
  --danger: #b3261e;
  --danger-soft: #fdecea;
  --radius: 8px;
  --shadow: 0 1px 2px rgba(20, 40, 70, .06), 0 1px 8px rgba(20, 40, 70, .05);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

.wrap { width: 100%; max-width: 1400px; margin: 0 auto; padding: 0 16px; }

h1 { font-size: 20px; margin: 0 0 4px; letter-spacing: .2px; }
h2 { font-size: 16px; margin: 0; color: var(--accent-dark); }
h3 { font-size: 14px; margin: 0; }
p { margin: 0 0 8px; }

.hidden { display: none !important; }
.muted { color: var(--ink-soft); }
.small { font-size: 12px; }

/* ---------- header ---------- */
.app-header {
  background: linear-gradient(180deg, #ffffff, #f6f9fc);
  border-bottom: 1px solid var(--line);
  padding: 14px 0 12px;
}
.header-inner { display: flex; gap: 16px; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; }
.tagline { color: var(--ink-soft); margin: 0; max-width: 900px; }
.header-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- cards ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px 16px;
  margin: 16px 0;
}
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.sub-head { margin: 16px 0 6px; color: var(--accent-dark); }
.hint { color: var(--ink-soft); font-size: 13px; margin: 4px 0 12px; }
.hint em { font-style: normal; font-weight: 600; }

/* ---------- form fields ---------- */
.grid { display: grid; gap: 10px 14px; }
.grid-project { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.field { display: flex; flex-direction: column; gap: 3px; margin: 0; min-width: 0; }
.field > span { font-size: 12px; color: var(--ink-soft); font-weight: 600; }
.field-inline { min-width: 150px; }

input[type="text"], input[type="number"], input[type="search"], select {
  font: inherit;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 6px 8px;
  width: 100%;
  min-width: 0;
}
input:focus, select:focus, button:focus-visible, .dropzone:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
input::placeholder { color: #9aa6b2; }
input[readonly] { background: #f5f7fa; color: var(--ink-soft); }

details.adv { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 10px; }
details.adv > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--accent-dark);
  margin-bottom: 10px;
  list-style: none;
}
details.adv > summary::marker { content: ""; }
details.adv > summary::before { content: "\25B8 "; }
details.adv[open] > summary::before { content: "\25BE "; }

/* ---------- buttons ---------- */
.btn {
  font: inherit;
  font-weight: 600;
  background: var(--accent);
  color: #fff;
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 7px 13px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
.btn-ghost { background: #fff; color: var(--accent-dark); border-color: var(--line); }
.btn-ghost:hover { background: var(--accent-soft); border-color: var(--accent); }
.btn-danger-ghost { background: #fff; color: var(--danger); border-color: #e7bdb9; }
.btn-danger-ghost:hover { background: var(--danger-soft); border-color: var(--danger); }
.btn-small { padding: 4px 9px; font-size: 13px; font-weight: 500; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.row { display: flex; gap: 8px; }
.wrap-row { flex-wrap: wrap; }

/* ---------- dropzone ---------- */
.dropzone {
  border: 2px dashed #b9c6d4;
  border-radius: var(--radius);
  background: #fafcfe;
  padding: 22px 16px;
  text-align: center;
  cursor: pointer;
  transition: background .12s, border-color .12s;
  margin-bottom: 12px;
}
.dropzone:hover { border-color: var(--accent); background: var(--accent-soft); }
.dropzone.over { border-color: var(--accent); background: var(--accent-soft); }
.dropzone.busy { opacity: .6; pointer-events: none; }
.dz-icon {
  display: inline-block;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 1px;
  color: var(--accent-dark);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 3px 8px;
  margin-bottom: 6px;
}
.dz-main { font-weight: 600; margin: 4px 0 2px; }
.dz-sub { color: var(--ink-soft); margin: 0; }
.linkish { color: var(--accent); text-decoration: underline; }

/* ---------- OCR option (upload panel) ---------- */
.check-line {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 12px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fafcfe;
  font-size: 13px;
  cursor: pointer;
}
.check-line:hover { border-color: var(--accent); background: var(--accent-soft); }
.check-line input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 1px 0 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.check-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.check-note { color: var(--ink-soft); font-size: 12px; }

/* ---------- progress / status ---------- */
.progress-box {
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 10px;
  background: #fafcfe;
}
.progress-line { font-size: 13px; margin-bottom: 6px; color: var(--accent-dark); font-weight: 600; }
.progress-bar { height: 6px; background: var(--line-soft); border-radius: 3px; overflow: hidden; }
#progressFill { height: 100%; width: 0; background: var(--accent); transition: width .2s; }

.status {
  margin-top: 12px;
  border-radius: 6px;
  padding: 8px 11px;
  font-size: 13px;
  border: 1px solid var(--line);
  background: #f7f9fc;
}
.status.ok { background: var(--ok-soft); border-color: #b7ddc6; color: #135c39; }
.status.warn { background: var(--warn-soft); border-color: #e8d7a6; color: var(--warn); }
.status.err { background: var(--danger-soft); border-color: #eec4c0; color: var(--danger); }

details.warn {
  margin-top: 12px;
  border: 1px solid #e8d7a6;
  background: var(--warn-soft);
  border-radius: 6px;
  padding: 8px 11px;
  font-size: 13px;
}
details.warn > summary { cursor: pointer; font-weight: 600; color: var(--warn); }
details.warn ul { margin: 8px 0 0 18px; padding: 0; }
details.warn li { margin-bottom: 3px; }

/* ---------- summary cards ---------- */
.cards { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.scard {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fbfdff;
  padding: 10px 12px;
}
.scard .k { font-size: 12px; color: var(--ink-soft); font-weight: 600; }
.scard .v { font-size: 22px; font-weight: 700; color: var(--accent-dark); line-height: 1.25; }
.scard .v small { font-size: 12px; font-weight: 600; color: var(--ink-soft); }
.scard.hero { background: var(--accent-soft); border-color: #bcd7ef; }
.scard.hero .v { font-size: 26px; }

/* ---------- tables ---------- */
.table-scroll {
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  -webkit-overflow-scrolling: touch;
}
.table-rooms { max-height: 70vh; }

table.data-table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13px; }
.data-table th, .data-table td {
  border-bottom: 1px solid var(--line-soft);
  border-right: 1px solid var(--line-soft);
  padding: 4px 6px;
  text-align: right;
  vertical-align: middle;
  white-space: nowrap;
}
.data-table th { background: #eef3f8; color: var(--accent-dark); font-weight: 600; text-align: center; font-size: 12px; }
.data-table th.l, .data-table td.l { text-align: left; }
.data-table thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  border-bottom: 1px solid var(--line);
}
.data-table thead tr:first-child th { top: 0; }
.data-table th[data-sort] { cursor: pointer; user-select: none; }
.data-table th[data-sort]:hover { background: #e2ebf4; }
.data-table th.sort-asc::after { content: " \25B2"; font-size: 9px; }
.data-table th.sort-desc::after { content: " \25BC"; font-size: 9px; }
.data-table tbody tr:hover { background: #f7fafd; }
.data-table tbody tr.excluded { opacity: .45; }
.data-table tbody tr.selected { background: #e8f1fa; }
.data-table tbody tr.clickable { cursor: pointer; }
.data-table tfoot td, .data-table tr.total-row td {
  font-weight: 700;
  background: #f1f6fb;
  border-top: 1px solid var(--line);
}

/* inline editing inputs inside the room table */
.rooms-table td { padding: 2px 3px; }
.rooms-table input[type="text"], .rooms-table input[type="number"], .rooms-table select {
  padding: 3px 5px;
  border-radius: 4px;
  border-color: transparent;
  background: transparent;
  font-size: 13px;
}
.rooms-table input:hover, .rooms-table select:hover { border-color: var(--line); background: #fff; }
.rooms-table input:focus, .rooms-table select:focus { border-color: var(--accent); background: #fff; }
.rooms-table td.c-name input { min-width: 170px; }
.rooms-table td.c-num input { min-width: 62px; }
.rooms-table td.c-num { text-align: right; }
.rooms-table td.l input { min-width: 110px; }
.rooms-table td.c-type select { min-width: 135px; }
/* The space type is the one table control whose text can be longer than its column ("Conference/
   Meeting", "Reception/Lobby"). A native select with appearance:auto paints its selected text OUTSIDE
   its own box when it is squeezed, and the cell's overflow is visible, so the label spilled into the
   neighbouring column. Drawing the control ourselves lets it ellipsize instead of spilling, at any
   column width, window size or browser zoom. */
.rooms-table td.c-type,
.rooms-table td select[data-field="orient"] { overflow: hidden; }
.rooms-table td.c-type select,
.rooms-table td select[data-field="orient"] {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  padding: 3px 22px 3px 8px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  /* Drawing the control ourselves also removes the background Windows used to paint for it, so the
     pill that told the user "this is a dropdown" has to be put back here. */
  background-color: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23808b99' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 7px center;
}
.rooms-table th.c-type, .rooms-table td.c-type { min-width: 175px; }
.rooms-table th.th-include, .rooms-table td.c-include { width: 34px; text-align: center; }
.rooms-table th.th-del, .rooms-table td.c-del { width: 34px; text-align: center; border-right: none; }
.rooms-table th.th-src, .rooms-table td.c-src {
  width: 76px;
  text-align: center;
  color: var(--ink-soft);
  font-size: 11px;
}
.rooms-table .res { font-variant-numeric: tabular-nums; color: #23405c; }
.rooms-table .res.hi { font-weight: 700; color: var(--accent-dark); }
.rooms-table input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

.btn-del {
  border: none;
  background: transparent;
  color: #9aa6b2;
  font-size: 15px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 4px;
  cursor: pointer;
}
.btn-del:hover { background: var(--danger-soft); color: var(--danger); }

.empty {
  margin: 12px 0 0;
  padding: 16px;
  text-align: center;
  color: var(--ink-soft);
  background: #fafcfe;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}

/* ---------- toolbar / bulk ---------- */
.toolbar {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.toolbar-buttons { display: flex; gap: 6px; }
.bulk {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
  background: #f7fafd;
  border: 1px solid var(--line-soft);
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 12px;
}
.bulk-label { font-size: 13px; font-weight: 600; color: var(--accent-dark); padding-bottom: 6px; }

/* ---------- detail panel ---------- */
.bd-head { display: flex; gap: 16px; flex-wrap: wrap; align-items: baseline; margin-bottom: 10px; }
.bd-head .bd-title { font-size: 16px; font-weight: 700; }
.bd-head .bd-meta { color: var(--ink-soft); font-size: 13px; }
.bd-total { display: flex; gap: 18px; flex-wrap: wrap; margin: 0 0 12px; }
.bd-total div { background: var(--accent-soft); border: 1px solid #bcd7ef; border-radius: 6px; padding: 6px 12px; }
.bd-total .k { font-size: 12px; color: var(--ink-soft); font-weight: 600; }
.bd-total .v { font-size: 18px; font-weight: 700; color: var(--accent-dark); }

.bd-group { margin-top: 14px; }
.bd-group h3 { color: var(--accent-dark); margin-bottom: 6px; }
.bd-row {
  display: grid;
  grid-template-columns: minmax(190px, 260px) 90px 1fr 56px;
  gap: 8px;
  align-items: center;
  padding: 2px 0;
  border-bottom: 1px solid var(--line-soft);
}
.bd-row .w { text-align: right; font-variant-numeric: tabular-nums; }
.bd-row .pct { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-soft); font-size: 12px; }
.bd-bar { height: 10px; background: #eef3f8; border-radius: 5px; overflow: hidden; }
.bd-bar > div { height: 100%; border-radius: 5px; }
.bd-bar > div.s-Sensible { background: #2c7fb8; }
.bd-bar > div.s-Latent { background: #41ab5d; }
.bd-bar > div.s-Freshair { background: #d9911c; }
.bd-bar > div.s-Safety { background: #8c6bb1; }
.bd-total-row { font-weight: 700; border-top: 1px solid var(--line); padding-top: 5px; margin-top: 5px; }
.bd-note { font-size: 12px; color: var(--ink-soft); margin-top: 10px; }

/* ---------- footer ---------- */
.app-footer { border-top: 1px solid var(--line); background: #fff; padding: 12px 0 22px; margin-top: 10px; }
.app-footer p { margin: 0 0 4px; color: var(--ink-soft); font-size: 13px; }
.app-footer strong { color: var(--accent-dark); }

/* ---------- responsive ---------- */
@media (max-width: 860px) {
  .header-inner { flex-direction: column; }
  .header-actions { width: 100%; }
  .header-actions .btn { flex: 1 1 auto; text-align: center; }
  .grid-project { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .bd-row { grid-template-columns: minmax(120px, 1fr) 80px 1fr 48px; }
  .table-rooms { max-height: none; }
  .scard .v { font-size: 19px; }
}

/* keep the room table usable on print of the app page (report is separate) */
@media print {
  .app-header .header-actions, .toolbar, .bulk, .dropzone, .check-line, .row, .progress-box, .card-head .btn { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; break-inside: avoid; }
  .table-scroll { overflow: visible; border: none; }
  table.data-table { font-size: 11px; }
  .data-table thead th { position: static; }
}
/* --------------------------- shared top navigation (all pages, identical look)
   The calculator page reuses the marketing header's styling: same white sticky bar, same
   SVG brand mark, same link order and colours, so the header does not change between pages.
   .app-nav* is kept as the class prefix so js/nav.js finds it. */
.app-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  line-height: 1.6;          /* same as the marketing pages, so the header height matches */
  background: linear-gradient(180deg, #ffffff, #f6f9fc);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 3px rgba(20, 40, 70, .05);
}
.app-nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 56px;
  flex-wrap: wrap;
  padding-top: 8px;
  padding-bottom: 8px;
}
.app-nav-brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  color: var(--accent-dark);
  text-decoration: none;
}
.app-nav-brand .brand-mark { color: var(--accent); flex: 0 0 auto; }
.app-nav-brand .brand-text { font-size: 17px; letter-spacing: .2px; white-space: nowrap; }
.app-nav-brand .brand-sub { display: block; font-size: 11px; font-weight: 600; color: var(--ink-soft); letter-spacing: .4px; }
/* The brand is a link home, so it must LOOK like one on this page too: the marketing pages give it
   a hover colour and a focus ring, and without the same rules here it read as plain text — a link
   with no feedback is indistinguishable from a label. Keep these two blocks in step. */
a.app-nav-brand { text-decoration: none; }
a.app-nav-brand:hover .brand-text { color: var(--accent); }
a.app-nav-brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 8px; }
.app-nav-links { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.app-nav-links a {
  display: inline-block;
  padding: 7px 11px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent-dark);
  text-decoration: none;
}
.app-nav-links a:hover { background: var(--accent-soft); color: var(--accent-dark); }
.app-nav-links a[aria-current="page"] { background: var(--accent-soft); text-decoration: underline; }

/* hamburger, styled like the marketing pages' one */
.nav-burger {
  display: none;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  padding: 7px 11px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent-dark);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 7px;
  cursor: pointer;
}
.nav-burger:hover { background: var(--accent-soft); }
.nav-burger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nav-burger-bars { display: inline-flex; flex-direction: column; gap: 3px; }
.nav-burger-bars span { display: block; width: 16px; height: 2px; background: currentColor; border-radius: 2px; }

@media (max-width: 700px) {
  nav.app-nav.js-nav .app-nav-inner { flex-wrap: wrap; }
  nav.app-nav.js-nav .app-nav-brand { order: 1; }
  nav.app-nav.js-nav .nav-burger { display: inline-flex; order: 2; }
  nav.app-nav.js-nav .app-nav-links { display: none; order: 3; }
  nav.app-nav.js-nav.nav-open .app-nav-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    margin: 4px 0 6px;
    gap: 2px;
  }
  nav.app-nav.js-nav.nav-open .app-nav-links a { padding: 11px 12px; font-size: 15px; }
}
@media print { .app-nav { display: none; } }

/* ------------------------------------------- hamburger menu on narrow screens */
.nav-burger {
  display: none;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  padding: 7px 11px;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: 7px;
  cursor: pointer;
}
.nav-burger:hover { background: rgba(255, 255, 255, .22); }
.nav-burger:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.nav-burger-bars { display: inline-flex; flex-direction: column; gap: 3px; }
.nav-burger-bars span { display: block; width: 16px; height: 2px; background: currentColor; border-radius: 2px; }
.nav-burger-text { font-size: 13px; }

@media (max-width: 700px) {
  nav.app-nav.js-nav .app-nav-inner { flex-wrap: wrap; }
  nav.app-nav.js-nav .app-nav-brand { order: 1; }
  nav.app-nav.js-nav .nav-burger { display: inline-flex; order: 2; }
  nav.app-nav.js-nav .app-nav-links { display: none; order: 3; }
  nav.app-nav.js-nav.nav-open .app-nav-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    margin: 2px 0 6px;
    gap: 2px;
  }
  nav.app-nav.js-nav.nav-open .app-nav-links a { padding: 10px 12px; font-size: 15px; }
}

/* ---------------- plan view: draw rooms on the drawing ----------------
   js/viewer.js owns the canvas inside .viewer-wrap; js/overlay.js owns the SVG. Both live in
   #planView, which is BOTH the positioning context and the scroll box: the SVG is an absolutely
   positioned child of the scroller, so it moves with the canvas when the drawing is scrolled.
   The room-box class names below are exactly the ones js/overlay.js documents at the top of that
   file (it adds no stylesheet of its own), styled here in the app's own palette. Presentation
   attributes the overlay sets itself — text-anchor, dominant-baseline, label font-size — are
   deliberately NOT repeated here: a CSS rule would override them. */
.plan-intro { margin: 4px 0 12px; max-width: 80ch; }
.plan-toolbar {
  display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center;
  padding: 8px 10px; margin-bottom: 10px;
  background: var(--accent-soft); border: 1px solid var(--line-soft); border-radius: var(--radius);
}
.plan-group { display: flex; align-items: center; gap: 6px; }
.plan-group > label { font-size: 13px; color: var(--ink-soft); white-space: nowrap; }
.plan-pos { min-width: 78px; text-align: center; }
.plan-mode { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; cursor: pointer; }
.plan-mode input { margin: 0; }
/* "Place all rooms on the plan" / "Remove placed rooms" — a two-button group that stays together
   when the toolbar wraps on a narrow window. The boxes they create reuse the .plan-room-box
   contract below: a placed box is an ordinary locator box, so it needs no style of its own. */
.plan-place-actions { flex-wrap: wrap; gap: 6px; }
.plan-place-actions .btn { white-space: nowrap; }
#planScale {
  padding: 4px 6px; font-size: 13px; color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px; background: #fff;
}
.plan-view {
  position: relative; overflow: auto; max-height: 72vh;
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
}
.viewer-wrap { position: relative; line-height: 0; }
#planCanvas { display: block; max-width: none; }
/* --- the overlay (js/overlay.js) ---
   Anchored to the CONTENT origin and sized by the width/height attributes the overlay sets from the
   canvas box. It must NOT be stretched to the container (inset: 0): .plan-view is the scroll box, so
   that would size the layer to the visible window, and everything further down the sheet would have
   no overlay covering it — no pointer events, no drawing (the "above 70% I cannot draw" bug).
   overflow-anchor:none is deliberate: the overlay REPLACES its room groups on every render, and while
   the sheet is scrolled Chrome's scroll anchoring then re-anchors and silently shifts scrollTop —
   dragging a room made the whole plan jump by tens of pixels at zoom. Excluding this subtree from
   anchoring keeps the scroll box still. */
.plan-overlay {
  position: absolute; left: 0; top: 0; touch-action: none; overflow: visible; overflow-anchor: none;
}
.plan-overlay.is-draw { cursor: crosshair; }
.plan-overlay.is-select { cursor: default; }
.plan-room { cursor: pointer; }
/* Only rooms that HAVE geometry are drawn, i.e. the ones placed on the plan: parsed and scheduled
   rooms have no position on the sheet, so they appear in the table but never here. */
.plan-room-box { fill: var(--accent); fill-opacity: .26; stroke: var(--accent); stroke-width: 2; }
.plan-room.is-excluded .plan-room-box { fill: #8b95a1; fill-opacity: .18; stroke: #6b7480; }
.plan-room.is-selected .plan-room-box { stroke: var(--danger); stroke-width: 2.5; }
/* Stage 2 — a room being moved or resized, the four corner grips of the SELECTED room, and the
   overlay while panning. Grips are presentational (pointer-events:none): the overlay's grab test is
   geometric (handleAtPoint on PDF points), so the grip under the pointer is never a DOM hit. */
.plan-room.is-dragging { cursor: grabbing; }
.plan-room.is-dragging .plan-room-box { stroke-width: 3; }
/* TRACED OUTLINE (room.poly, from js/trace.js): drawn as a polygon path instead of a rectangle. A
   thinner stroke and a lighter fill than a rectangle so the plan's own linework stays readable
   underneath — this is a real traced boundary, not a box. Selected / excluded / dragging states stay
   obvious. Only outlines carry data-shape="poly"; rectangles carry data-shape="rect". */
.plan-room[data-shape="poly"] .plan-room-box {
  fill: var(--accent); fill-opacity: .14; stroke: var(--accent); stroke-width: 1.5;
}
.plan-room.is-excluded[data-shape="poly"] .plan-room-box {
  fill: #8b95a1; fill-opacity: .12; stroke: #6b7480;
}
.plan-room.is-selected[data-shape="poly"] .plan-room-box { stroke: var(--danger); stroke-width: 2.5; }
.plan-room.is-dragging[data-shape="poly"] .plan-room-box { stroke-width: 3; }
.plan-room-handle {
  fill: #fff; stroke: var(--danger); stroke-width: 1.5; pointer-events: none;
}
.plan-overlay.is-pan { cursor: grabbing; }
.plan-room-label {
  font-size: 11px; fill: var(--ink); pointer-events: none;
  paint-order: stroke; stroke: rgba(255, 255, 255, .88); stroke-width: 3px;
}
.plan-draft-box { fill: var(--accent); fill-opacity: .2; stroke: var(--accent); stroke-width: 2; stroke-dasharray: 6 4; }
.plan-overlay-readout {
  font-size: 12px; fill: var(--ink); pointer-events: none;
  paint-order: stroke; stroke: #fff; stroke-width: 3px;
}
.plan-hint { margin: 8px 0 0; }
@media (max-width: 700px) {
  .plan-toolbar { gap: 6px 10px; padding: 7px 8px; }
  .plan-view { max-height: 58vh; }
  .plan-pos { min-width: 0; }
  .plan-room-label { font-size: 13px; }
}

/* --- the loading report, shown in the page instead of a pop-up window ----------------------------
   Fixed over the app so it reads like a document. body.reporting hides everything else from the
   printer, so Ctrl+P prints the report rather than the calculator behind it. */
.report-view {
  position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column;
  background: #fff; padding: 0;
}
.report-view.hidden { display: none; }
.report-bar {
  display: flex; align-items: center; gap: 10px; padding: 8px 14px;
  border-bottom: 1px solid var(--line); background: var(--card);
}
.report-bar-title { font-weight: 600; margin-right: auto; }
.report-frame { flex: 1 1 auto; width: 100%; border: 0; background: #fff; }
@media print {
  body.reporting > *:not(.report-view) { display: none !important; }
  body.reporting .report-bar { display: none !important; }
  body.reporting .report-view { position: static; }
}
