/* ---------------------------------------------------------------------------
   SolarDesk - self contained stylesheet.

   No build step and no CDN: the application is often run on a laptop in a site
   office with poor connectivity, and a proposal has to render the same way
   whether or not the network is up.
   --------------------------------------------------------------------------- */

:root {
  /* --------------------------------------------------------------------
     Power & Sun brand palette, sampled from the logo artwork.
       amber  #FAAE43  the sun
       orange #F05A2D  the wordmark and the bolt
       blue   #134C97  the strapline and the rule
     The chart colours are deliberately the same three: solar is the amber
     of the sun, storage the orange of the bolt, the grid the blue. A reader
     who has seen the logo already knows what each colour means.
     -------------------------------------------------------------------- */
  --bg: #f5f7f9;
  --surface: #ffffff;
  --surface-2: #fafbfc;
  --border: #e2e6ec;
  --border-strong: #c7d0dc;
  --text: #14212e;
  --muted: #5f6e7f;
  --faint: #8a97a6;

  --brand: #134C97;
  --brand-dark: #0e3a73;
  --brand-light: #e8eef8;

  --sun: #FAAE43;
  --sun-light: #fef3e2;
  --grid: #134C97;
  --grid-light: #e8eef8;
  --battery: #F05A2D;
  --battery-light: #fdeee8;
  --load: #5a6b7c;

  --ok: #15803d;
  --ok-light: #e8f5ec;
  --warn: #9a5b00;
  --warn-light: #fdf1de;
  --bad: #b3261e;
  --bad-light: #fbeae8;

  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(16,24,32,.05), 0 1px 3px rgba(16,24,32,.04);
  --shadow-lg: 0 4px 16px rgba(16,24,32,.08);
  /* The sticky topbar's height, so anything else that sticks can clear it
     instead of sliding underneath. */
  --topbar-h: 52px;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

/* The `hidden` attribute has to win.
   It is implemented as a user-agent rule of ordinary weight, so any author
   rule that sets `display` - an inline style especially - silently overrides
   it, and an element marked hidden stays on screen. That is how a storage
   field survived being hidden on a grid design: it carried an inline
   display:flex. Scripts here toggle `el.hidden`, so this makes that mean what
   it says. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { margin: 0 0 .5rem; font-weight: 600; line-height: 1.25; letter-spacing: -.01em; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.125rem; }
h3 { font-size: .95rem; }
h4 { font-size: .85rem; }
p { margin: 0 0 .75rem; }
small { font-size: .8125rem; }

/* ---- Layout ------------------------------------------------------------ */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 232px; flex: 0 0 232px;
  background: #0d2e56; color: #cfdaea;
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.sidebar-brand {
  /* No side padding: the logo band runs the full width of the sidebar. */
  padding: 0 0 .9rem;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.sidebar-logo {
  display: block;
  background: #fff;
  padding: .7rem .5rem;
  margin-bottom: .55rem;
}
.sidebar-logo img { display: block; width: 100%; height: auto; }
.sidebar-brand strong { color: #fff; font-size: 1.05rem; display: block; letter-spacing: -.02em; padding: 1.1rem 1.15rem 0; }
.sidebar-brand span { font-size: .75rem; color: #8fa8c6; padding: 0 1.15rem; display: block; }
.sidebar nav { padding: .75rem .6rem; flex: 1; }
.sidebar nav .group { font-size: .7rem; text-transform: uppercase; letter-spacing: .07em; color: #7d97b8; padding: .9rem .55rem .3rem; }
.sidebar nav a {
  display: flex; align-items: center; gap: .55rem;
  padding: .48rem .55rem; border-radius: var(--radius-sm);
  color: #cfdaea; font-size: .875rem; text-decoration: none;
}
.sidebar nav a:hover { background: rgba(255,255,255,.06); color: #fff; }
.sidebar nav a.active { background: var(--sun); color: #14212e; font-weight: 600; }
.sidebar nav a .ico { width: 16px; text-align: center; opacity: .85; font-size: .9rem; }
.sidebar-foot { padding: .85rem 1.15rem; border-top: 1px solid rgba(255,255,255,.08); font-size: .8rem; }
.sidebar-foot .who { color: #fff; }
.sidebar-foot .role { color: #8fa8c6; font-size: .75rem; text-transform: capitalize; }
.sidebar-foot button {
  margin-top: .5rem; background: none; border: 1px solid rgba(255,255,255,.16);
  color: #cfdaea; padding: .3rem .6rem; border-radius: var(--radius-sm);
  font-size: .78rem; cursor: pointer;
}
.sidebar-foot button:hover { background: rgba(255,255,255,.08); }
.locale-picker { margin-top: .55rem; }
.locale-picker label { color: #8fa8c6; margin-bottom: .2rem; }
.locale-picker select {
  padding: .25rem .4rem; font-size: .78rem;
  background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.16); color: #e6eef8;
}
.locale-picker select option { color: var(--text); background: #fff; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  background: var(--surface); border-bottom: 1px solid var(--border);
  padding: .85rem 1.5rem; display: flex; align-items: center; gap: 1rem;
  position: sticky; top: 0; z-index: 20;
}
.topbar .crumbs { font-size: .8rem; color: var(--muted); }
.topbar .crumbs a { color: var(--muted); }
.topbar h1 { margin: 0; font-size: 1.15rem; }
.topbar .spacer { flex: 1; }
/* Centred, so whatever a wide screen has spare is shared either side rather
   than left as one dead gutter on the right. The cap is generous because the
   pages that matter here are dense tables and side-by-side charts, which are
   easier to read wide than tall. */
.content { padding: 1.5rem; max-width: 1760px; width: 100%; margin-inline: auto; }
@media (max-width: 700px) { .content { padding: 1rem .85rem; } }

/* ---- Cards ------------------------------------------------------------- */

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  margin-bottom: 1.25rem;
}
.card-head {
  padding: .85rem 1.1rem; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
}
.card-head h2, .card-head h3 { margin: 0; }
.card-head .spacer { flex: 1; }
.card-head .hint { font-size: .8rem; color: var(--muted); font-weight: 400; }
.card-body { padding: 1.1rem; }
.card-body.tight { padding: .75rem 1.1rem; }
.card-foot { padding: .75rem 1.1rem; border-top: 1px solid var(--border); background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius); }

.grid { display: grid; gap: 1.25rem; }
.grid.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.c4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid.side { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
@media (max-width: 1240px) { .grid.side { grid-template-columns: 1fr; } }
@media (max-width: 1100px) { .grid.c3, .grid.c4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 860px)  { .grid.c2 { grid-template-columns: 1fr; } }
@media (max-width: 720px)  { .grid.c2, .grid.c3, .grid.c4, .grid.side { grid-template-columns: 1fr; } }

/* ---- The sidebar as a drawer ------------------------------------------- */

/* Wide enough for both, the sidebar is a column and the toggle is not needed.
   Below that the column would take a quarter of the screen from the work, so
   it slides out over the page instead and gives all the width back. */
.nav-toggle { display: none; }

@media (max-width: 960px) {
  .nav-toggle {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 4px;
    width: 34px; height: 34px; padding: 0 7px; flex: 0 0 auto;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius-sm); cursor: pointer;
  }
  .nav-toggle span { display: block; height: 2px; background: var(--text); border-radius: 2px; }
  .nav-toggle:hover { background: var(--surface-2); }

  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; height: 100%;
    z-index: 60; transform: translateX(-100%);
    transition: transform .18s ease-out;
    box-shadow: var(--shadow-lg);
  }
  .shell.nav-open .sidebar { transform: none; }

  .nav-backdrop {
    position: fixed; inset: 0; z-index: 50;
    background: rgba(16, 33, 46, .45);
  }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
}

/* ---- Stats ------------------------------------------------------------- */

.stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: .9rem 1rem; box-shadow: var(--shadow); }
.stat .label { font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; color: var(--faint); }
.stat .value { font-size: 1.5rem; font-weight: 650; letter-spacing: -.02em; margin-top: .15rem; }
.stat .value small { font-size: .9rem; font-weight: 500; color: var(--muted); }
.stat .sub { font-size: .8rem; color: var(--muted); margin-top: .1rem; }
.stat.accent-sun { border-left: 3px solid var(--sun); }
.stat.accent-grid { border-left: 3px solid var(--grid); }
.stat.accent-battery { border-left: 3px solid var(--battery); }
.stat.accent-brand { border-left: 3px solid var(--brand); }

/* ---- Tables ------------------------------------------------------------ */

table { width: 100%; border-collapse: collapse; font-size: .875rem; }
thead th {
  text-align: left; font-weight: 600; font-size: .75rem; text-transform: uppercase;
  letter-spacing: .04em; color: var(--faint); padding: .5rem .7rem;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
tbody td { padding: .55rem .7rem; border-bottom: 1px solid var(--border); vertical-align: top; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-2); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.mono { font-family: var(--mono); font-size: .82rem; }
table.compact tbody td, table.compact thead th { padding: .35rem .55rem; }

/* Dense numeric tables: rows striped so a figure can be tracked across a wide
   row without losing which line it belongs to. */
table.data tbody tr:nth-child(even) { background: var(--surface-2); }
table.data tbody tr:hover { background: var(--brand-light); }
table.data thead th { border-bottom: 1px solid var(--border-strong); }

/* A sub-line under the head it belongs to, in a cost or BOQ breakdown. The
   compact selector has to be named too, or its own padding wins on specificity
   and the indent never shows. */
tbody td.indent, table.compact tbody td.indent { padding-left: 1.7rem; color: var(--muted); }

/* The line a breakdown adds up to. */
tr.total td { font-weight: 650; border-top: 1px solid var(--border-strong); background: var(--surface-2); }
tr.total:hover td { background: var(--surface-2); }

/* The size a value curve settles on, marked in the row rather than in a legend
   away from it. */
tr.row-best td { background: var(--sun-light); box-shadow: inset 3px 0 0 var(--sun); }
tr.row-best:hover td { background: var(--sun-light); }

/* A figure that leads its own small block, where a full .stat card would be
   more furniture than the number is worth. */
.value-sm { font-size: 1.05rem; font-weight: 650; letter-spacing: -.01em; margin-top: .1rem; }

/* Words carrying a state on their own, outside a badge or an alert. */
.warn { color: var(--warn); }
.ok { color: var(--ok); }
.bad { color: var(--bad); }
strong.warn, strong.ok, strong.bad { font-weight: 650; }

/* A filter over rows already on the page. */
.table-filter { display: flex; align-items: center; gap: .75rem; margin-bottom: .9rem; }
.table-filter input[type="search"] { flex: 1 1 260px; max-width: 420px; margin: 0; }

/* A glossary entry: term, then what it means. */
.glossary-term { padding: .6rem 0; border-bottom: 1px solid var(--border); }
.glossary-term:last-child { border-bottom: none; }
.glossary-term > strong { font-size: .9rem; }
.glossary-term > div { margin-top: .15rem; line-height: 1.6; }

/* A tornado: each driver swung either side of the base case, longest first. */
.tornado { display: flex; flex-direction: column; gap: .5rem; }
.tornado-row { display: grid; grid-template-columns: minmax(140px, 1.1fr) minmax(0, 2fr) minmax(150px, 1.2fr); gap: .85rem; align-items: center; }
.tornado-label strong { display: block; font-size: .82rem; font-weight: 600; }
.tornado-label span { display: block; }
.tornado-track { position: relative; height: 20px; background: var(--surface-2); border-radius: var(--radius-sm); }
.tornado-axis { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px; background: var(--border-strong); }
.tornado-bar { position: absolute; top: 3px; bottom: 3px; border-radius: 2px; min-width: 1px; }
/* The low end of the swing and the high end, not good and bad: which one is
   welcome depends on the metric, and the figures beside the bar say which. */
.tornado-bar.low { background: var(--grid); }
.tornado-bar.high { background: var(--sun); }
.tornado-figures { display: flex; gap: .35rem; flex-wrap: wrap; align-items: baseline; }
@media (max-width: 860px) {
  .tornado-row { grid-template-columns: 1fr; gap: .25rem; }
  .tornado-track { height: 14px; }
}

/* Back and next along the project workflow, at the foot of a step. */
.workflow-nav {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  margin: 1.25rem 0 .5rem; padding-top: 1rem;
  border-top: 1px solid var(--border);
}
.workflow-nav > div:first-child { margin-right: auto; }
.workflow-nav > div:last-child { margin-left: auto; }

/* An area marked out on a map. */
.boundary-map { margin-top: 1rem; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .7rem .85rem; }
.boundary-map > summary { cursor: pointer; font-size: .85rem; font-weight: 600; display: flex; align-items: center; gap: .5rem; }
.boundary-map[open] > summary { margin-bottom: .85rem; }
.boundary-canvas {
  height: 380px; width: 100%;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.boundary-readout { border-top: 1px solid var(--border); padding-top: .85rem; }
/* Leaflet puts its panes at a high z-index by default, which would otherwise
   lift the map over this application's own sticky header and drawer. */
.boundary-canvas .leaflet-pane,
.boundary-canvas .leaflet-top,
.boundary-canvas .leaflet-bottom { z-index: 1; }
@media (max-width: 700px) { .boundary-canvas { height: 280px; } }

/* Shadows falling across a surface, drawn axonometrically and to scale. */
.shadow-view { margin-top: .5rem; }
.shadow-controls { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin-bottom: .6rem; }
.shadow-controls select { width: auto; padding: .25rem .4rem; font-size: .8rem; }
.shadow-controls input[type="range"] { flex: 1 1 200px; max-width: 320px; }
.shadow-svg {
  width: 100%; max-height: 420px; display: block;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
}
/* Stroke widths are in metres, because the drawing is. */
.sv-face { fill: #fff; stroke: var(--border-strong); stroke-width: 0.06; }
.sv-module { fill: var(--grid); stroke: #0e3a73; stroke-width: 0.02; }
.sv-module.shaded { fill: #7f8c9b; }
.sv-shadow { fill: rgba(20, 33, 46, .26); stroke: none; }
.sv-box-top { fill: var(--sun); stroke: #b97c20; stroke-width: 0.03; }
.sv-box-front { fill: #d99433; stroke: #b97c20; stroke-width: 0.03; }
.sv-box-side { fill: #c07f22; stroke: #b97c20; stroke-width: 0.03; }

/* ---- Settings ---------------------------------------------------------- */

/* The find-and-jump bar stays put while the groups scroll past under it. */
.settings-bar { position: sticky; top: var(--topbar-h); z-index: 10; }
.settings-find { display: flex; align-items: center; gap: .85rem; flex-wrap: wrap; }
.settings-find input[type="search"] { flex: 1 1 300px; min-width: 0; margin: 0; }
.settings-find .spacer { flex: 1; }
.settings-jump { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .6rem; }
.settings-jump a {
  font-size: .74rem; padding: .18rem .5rem; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--muted); text-decoration: none; white-space: nowrap;
}
.settings-jump a:hover { background: var(--brand-light); border-color: var(--brand-light); color: var(--brand-dark); }
.settings-jump a em { font-style: normal; font-weight: 650; color: var(--warn); margin-left: .25rem; }

/* Enough room to land under the sticky bar rather than behind it. */
[id^="group-"] { scroll-margin-top: calc(var(--topbar-h) + 5.5rem); }

.setting-key { font-size: .68rem; color: var(--faint); }
.settings-table th:nth-child(1) { width: 26%; }
.settings-table th:nth-child(2) { width: 16%; }
.settings-table th:nth-child(3) { width: 12%; }

/* Inputs sitting inside a dense table row. */
.input-sm { padding: .25rem .4rem; font-size: .8rem; margin: 0; }
.badge.tiny-badge { font-size: .62rem; }

/* ---- Badges ------------------------------------------------------------ */

.badge {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .12rem .5rem; border-radius: 999px;
  font-size: .74rem; font-weight: 600; letter-spacing: .01em;
  background: var(--surface-2); color: var(--muted); border: 1px solid var(--border);
  white-space: nowrap;
}
.badge.ok { background: var(--ok-light); color: var(--ok); border-color: transparent; }
.badge.warn { background: var(--warn-light); color: var(--warn); border-color: transparent; }
.badge.bad { background: var(--bad-light); color: var(--bad); border-color: transparent; }
.badge.brand { background: var(--brand-light); color: var(--brand-dark); border-color: transparent; }
.badge.info { background: var(--grid-light); color: var(--grid); border-color: transparent; }
.badge.sun { background: var(--sun-light); color: #8a5a00; border-color: transparent; }
/* A count sitting at the end of a nav row. */
.badge.count { margin-left: auto; font-size: .68rem; }

/* ---- Buttons ----------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .45rem .85rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text); font-size: .85rem; font-weight: 500;
  cursor: pointer; text-decoration: none; line-height: 1.4;
}
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn.primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
.btn.danger { background: #fff; border-color: #e7bcbc; color: var(--bad); }
.btn.danger:hover { background: var(--bad-light); }
.btn.small { padding: .28rem .6rem; font-size: .78rem; }
/* A secondary action beside a primary one - clearing a search, cancelling out
   of a form - that should not compete with it for attention. */
.btn.ghost { background: none; border-color: transparent; color: var(--muted); }
.btn.ghost:hover { background: var(--surface-2); color: var(--text); }
.btn[disabled], .btn.disabled { opacity: .5; pointer-events: none; }
.btn-row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
/* A form that sits in a line of text rather than blocking it. */
.inline { display: inline; }

/* ---- Forms ------------------------------------------------------------- */

label { display: block; font-size: .8rem; font-weight: 500; color: var(--muted); margin-bottom: .25rem; }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=url], input[type=search], select, textarea {
  width: 100%; padding: .45rem .6rem; font-size: .875rem; font-family: inherit;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: #fff; color: var(--text);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light);
}
textarea { min-height: 84px; resize: vertical; }
.field { margin-bottom: .85rem; }
/* A field whose control sits on the baseline of the row beside it. */
.field-inline { display: flex; align-items: flex-end; }
.field .help { font-size: .75rem; color: var(--faint); margin-top: .2rem; }
.field-row { display: grid; gap: .85rem; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.check { display: flex; align-items: center; gap: .45rem; font-size: .85rem; color: var(--text); font-weight: 400; }
.check input { width: auto; }
fieldset { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .85rem; margin: 0 0 1rem; }
legend { font-size: .78rem; font-weight: 600; color: var(--muted); padding: 0 .35rem; text-transform: uppercase; letter-spacing: .04em; }

/* ---- Alerts ------------------------------------------------------------ */

.alert { padding: .7rem .95rem; border-radius: var(--radius-sm); margin-bottom: 1rem; font-size: .875rem; border: 1px solid transparent; }
.alert.ok { background: var(--ok-light); color: #14532d; border-color: #c3e6cd; }
.alert.bad { background: var(--bad-light); color: #7f1d1d; border-color: #f0c4c2; }
.alert.warn { background: var(--warn-light); color: #78350f; border-color: #f0dcb8; }
.alert.info { background: var(--grid-light); color: #303f9f; border-color: #ccd5fb; }
.alert ul { margin: .35rem 0 0; padding-left: 1.1rem; }

/* ---- Misc -------------------------------------------------------------- */

.muted { color: var(--muted); }
.faint { color: var(--faint); }
.tiny { font-size: .78rem; }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.mt0 { margin-top: 0; } .mt1 { margin-top: .5rem; } .mt2 { margin-top: 1rem; } .mt3 { margin-top: 1.5rem; }
.mb0 { margin-bottom: 0; } .mb1 { margin-bottom: .5rem; } .mb2 { margin-bottom: 1rem; }
.flex { display: flex; gap: .75rem; align-items: center; }
.flex.between { justify-content: space-between; }
.flex.wrap { flex-wrap: wrap; }
.empty { padding: 2rem 1rem; text-align: center; color: var(--faint); font-size: .875rem; }

.kv { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1rem; font-size: .85rem; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; font-weight: 500; text-align: right; font-variant-numeric: tabular-nums; }

.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin-bottom: 1.25rem; flex-wrap: wrap; }
.tabs a {
  padding: .5rem .85rem; font-size: .875rem; color: var(--muted);
  border-bottom: 2px solid transparent; text-decoration: none; font-weight: 500;
}
.tabs a:hover { color: var(--text); text-decoration: none; }
.tabs a.active { color: var(--brand); border-bottom-color: var(--brand); }

.pill-row { display: flex; gap: .35rem; flex-wrap: wrap; }

.progress { height: 6px; background: var(--border); border-radius: 999px; overflow: hidden; }
.progress > span { display: block; height: 100%; background: var(--brand); }

.check-row { display: flex; gap: .7rem; padding: .55rem 0; border-bottom: 1px solid var(--border); align-items: flex-start; }
.check-row:last-child { border-bottom: none; }
.check-row .mark { flex: 0 0 18px; font-weight: 700; line-height: 1.4; }
.check-row.pass .mark { color: var(--ok); }
.check-row.warning .mark { color: var(--warn); }
.check-row.fail .mark { color: var(--bad); }
.check-row .body strong { display: block; font-size: .85rem; }
.check-row .body span { font-size: .8rem; color: var(--muted); }

.legend { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .78rem; color: var(--muted); }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: .3rem; vertical-align: -1px; }

.scroll-x { overflow-x: auto; }

.roof-canvas { background: repeating-linear-gradient(45deg, #f1f4f8 0 8px, #eaeff5 8px 16px); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }

.pagination { display: flex; gap: .25rem; flex-wrap: wrap; margin-top: 1rem; font-size: .85rem; }
.pagination a, .pagination span { padding: .3rem .6rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: #fff; }
.pagination .active span { background: var(--brand); color: #fff; border-color: var(--brand); }

/* ---- Print ------------------------------------------------------------- */

@media print {
  .sidebar, .topbar, .no-print { display: none !important; }
  body { background: #fff; font-size: 11pt; }
  .content { padding: 0; max-width: none; }
  .card { box-shadow: none; border: 1px solid #d4d8dc; break-inside: avoid; page-break-inside: avoid; }
  .page-break { page-break-before: always; break-before: page; }
  a { color: inherit; text-decoration: none; }
}

/* ---- Inline actions inside tables -------------------------------------- */
/* A remove or a tick inside a row is a button for accessibility and keyboard
   use, but it should read as text rather than compete with the real buttons
   on the page. */
.link, .link-danger {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: .78rem; text-decoration: underline;
}
.link { color: var(--brand); }
.link-danger { color: #b4453a; }
.link:hover, .link-danger:hover { text-decoration: none; }

/* ---- Pipeline board ------------------------------------------------------ */
.board { display: flex; gap: .75rem; overflow-x: auto; padding-bottom: .5rem; align-items: flex-start; }
.board .column {
  flex: 0 0 250px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 8px;
}
.board .column > header {
  padding: .6rem .75rem; border-bottom: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: baseline; gap: .5rem;
}
.board .column > header strong { font-size: .82rem; }
.board .column > header .count { font-size: .75rem; color: var(--muted); }
.board .column .cards { padding: .5rem; display: flex; flex-direction: column; gap: .5rem; }
.board .card-mini {
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  padding: .55rem .6rem; font-size: .8rem;
}
.board .card-mini .ref { font-size: .72rem; color: var(--muted); }
.board .column .empty { padding: .75rem; font-size: .75rem; color: var(--muted); text-align: center; }

/* ---- Sticky save on long forms ------------------------------------------ */
/* A surface form runs to several screens once the survey questions are on it.
   A save button that only exists at the bottom is one the designer scrolls
   past, so it follows them down and stays legible over the fields behind. */
.save-bar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: 1rem -1.1rem -1.1rem; padding: .7rem 1.1rem;
  background: var(--surface); border-top: 1px solid var(--border);
  box-shadow: 0 -6px 14px rgba(16, 32, 52, .06);
}
.card-foot.save-bar { margin: 0; }
@media print { .save-bar { display: none; } }

/* A row whose figure has not been confirmed by anyone here. */
.row-warn > td { background: var(--warn-light); }

/* The winning figure in a comparison row. */
td.best { font-weight: 600; color: var(--ok); }
