/* GRP ductwork quotation app — light, dense engineering layout.
 * One type scale, one spacing rhythm, one table look.
 * Fixed label column + fixed control column; result tables left-justified
 * with the decimals of every numeric column aligned.
 * A4 portrait print stylesheet with repeating table headers and page counters.
 *
 * The palette is a set of CSS variables, so the dark theme (a single
 * data-theme="dark" attribute on <html>) reaches every table, the report
 * and the print output without a second set of rules.
 */

/* ------------------------------------------------------------------ */
/* tokens                                                              */
/* ------------------------------------------------------------------ */
:root {
  --label-w: 216px;
  --ctl-w: 236px;
  --gap: 10px;

  /* one type scale */
  --fs-1: 10.5px;   /* caption, badge, hint, table header */
  --fs-2: 11.5px;   /* table body, secondary */
  --fs-3: 13px;     /* control and body text */
  --fs-4: 15px;     /* panel heading */
  --fs-5: 17px;     /* app title */

  /* one spacing rhythm (4 px base) */
  --sp-1: 2px;
  --sp-2: 4px;
  --sp-3: 6px;
  --sp-4: 10px;
  --sp-5: 14px;
  --sp-6: 20px;

  /* the app bar height - the sticky table headers sit under it */
  --appbar-h: 40px;

  --ink: #16212a;
  --ink-2: #4d5b66;
  --ink-3: #7b8994;
  --line: #c3ced7;
  --line-2: #e3e9ee;
  --head: #e9eff3;
  --head-2: #dde5eb;
  --row-alt: #f1f6f9;
  --bg: #ffffff;
  --bg-2: #f4f7f9;
  --field: #ffffff;
  --warn: #8a5300;
  --warn-bg: #fff6e5;
  --warn-line: #e2c68a;
  --accent: #0f4c66;
  --accent-2: #e6eff4;
  --on-accent: #ffffff;
  --mono: Consolas, "Courier New", monospace;

  /* the select arrow - no default browser arrow in either theme */
  --sel-arrow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6'><path d='M1 1l3.5 3.5L8 1' fill='none' stroke='%234d5b66' stroke-width='1.3'/></svg>");
  --scroll-thumb: #b7c3cc;
  --scroll-thumb-hover: #8fa1ad;
}

/* the dark palette — the same names, the same rules */
html[data-theme="dark"] {
  --ink: #e2e9ee;
  --ink-2: #9db0be;
  --ink-3: #7b8d9a;
  --line: #36444e;
  --line-2: #212b33;
  --head: #1d262d;
  --head-2: #172027;
  --row-alt: #151d23;
  --bg: #0f151a;
  --bg-2: #131b21;
  --field: #151d23;
  --warn: #f0b429;
  --warn-bg: #262013;
  --warn-line: #6a5520;
  --accent: #74b6d4;
  --accent-2: #16242c;
  --on-accent: #0d1418;
  --sel-arrow: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='9' height='6' viewBox='0 0 9 6'><path d='M1 1l3.5 3.5L8 1' fill='none' stroke='%239db0be' stroke-width='1.3'/></svg>");
  --scroll-thumb: #3d4c57;
  --scroll-thumb-hover: #52636f;
}

* { box-sizing: border-box; }

/* no spinner arrows on any number input - the engineer types the value */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Segoe UI", Tahoma, Arial, sans-serif;
  font-size: var(--fs-3);
  line-height: 1.35;
}

body { padding-bottom: 30px; }

/* the scrollbars of the app are part of the look */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border: 2px solid var(--bg);
  border-radius: 5px;
}
*::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); }

/* ------------------------------------------------------------------ */
/* app bar + tabs                                                      */
/* ------------------------------------------------------------------ */
.appbar {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4);
  min-height: var(--appbar-h);
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* the job-file controls - grouped, on the right of the app bar */
.filebar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-left: auto;
  flex-wrap: nowrap;
  min-width: 0;
}

.filegroup {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  padding-left: var(--sp-3);
  border-left: 1px solid var(--line);
}

.filegroup:first-child { padding-left: 0; border-left: 0; }

.filegroup .grouplabel {
  font-size: var(--fs-1);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-right: var(--sp-1);
  white-space: nowrap;
}

/* one button look for the whole app */
.filegroup button,
.toolbar button,
.themetoggle,
.tab,
.filelabel {
  font: inherit;
  font-size: var(--fs-2);
  line-height: 1.3;
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  display: inline-block;
}

.filegroup button:hover,
.toolbar button:hover,
.themetoggle:hover,
.filelabel:hover,
.tab:hover { background: var(--head); border-color: var(--ink-3); }

.filegroup button:active,
.toolbar button:active,
.themetoggle:active { background: var(--head-2); }

/* the "Load file" control is a label for the file input, so the browser opens
   the file chooser natively on a real click */
.filegroup .filelabel { text-align: center; }

.brand { font-weight: 600; color: var(--accent); white-space: nowrap; font-size: var(--fs-4); }

.brandwrap { display: flex; align-items: center; gap: var(--sp-3); flex: 0 0 auto; }

/* the CLQA logo — small, and it must never push the layout around */
.logo {
  height: 24px;
  width: auto;
  display: block;
  background: #fff;
  padding: 1px 3px;
  border: 1px solid var(--line-2);
  border-radius: 2px;
}

.tabs { display: flex; gap: 2px; flex: 0 0 auto; }

.tab {
  border-radius: 3px 3px 0 0;
  border-bottom-color: transparent;
  color: var(--ink-2);
}

.tab.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

.themetoggle { min-width: 52px; text-align: center; }

/* the message sits just under the app bar - it never takes space in the
   bar, so the bar keeps one row at every width */
.flash {
  position: absolute;
  top: 100%;
  left: 12px;
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  visibility: hidden;
  color: var(--ink-2);
  font-size: var(--fs-2);
  background: var(--bg);
  border: 1px solid var(--line);
  padding: 2px 6px;
  z-index: 30;
}

/* the message takes space only while it is shown */
.flash.on { max-width: 300px; }

/* below 1700 px the title text steps aside and the job list is narrower;
   the separators still show the grouping */
@media (max-width: 1700px) {
  .brand { display: none; }
  .joblist { width: 128px; max-width: 128px; }
  .tab { padding: 3px 8px; }
  .filegroup button, .filelabel { padding: 3px 7px; }
}

@media (max-width: 1400px) {
  .filegroup .grouplabel { display: none; }
  .filegroup { padding-left: var(--sp-2); }
}

/* ------------------------------------------------------------------ */
/* panels                                                              */
/* ------------------------------------------------------------------ */
main { padding: var(--sp-4) var(--sp-4) 0; }

.tabpanel { display: none; }
.tabpanel.active { display: block; }

.panel-h {
  font-size: var(--fs-4);
  font-weight: 600;
  color: var(--accent);
  margin: var(--sp-2) 0 var(--sp-3);
  padding-bottom: var(--sp-1);
  border-bottom: 1px solid var(--line);
}

.block-h {
  font-size: var(--fs-1);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-2);
  margin: var(--sp-5) 0 var(--sp-2);
}

.form-block { margin-bottom: var(--sp-5); }

/* a sub-heading inside a form block - the standards that govern the
   group of fields below it */
.sub-h {
  font-size: var(--fs-2);
  font-weight: 600;
  color: var(--accent);
  margin: var(--sp-4) 0 var(--sp-1);
}

.capt {
  font-size: var(--fs-1);
  color: var(--ink-2);
  margin: var(--sp-2) 0 var(--sp-3);
}

/* ------------------------------------------------------------------ */
/* fixed two-column form rows                                          */
/* ------------------------------------------------------------------ */
.form {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(600px, 1fr));
  gap: var(--sp-1) 26px;
  align-items: center;
}

.frow {
  display: grid;
  grid-template-columns: var(--label-w) var(--ctl-w) 1fr;
  column-gap: var(--gap);
  align-items: center;
  min-height: 24px;
}

.frow > label {
  font-size: var(--fs-2);
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.frow input[type="text"],
.frow input[type="number"],
.frow input[type="date"],
.frow textarea,
.frow select {
  width: var(--ctl-w);
  max-width: var(--ctl-w);
  font: inherit;
  font-size: var(--fs-2);
  padding: 2px 4px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--field);
  color: var(--ink);
}

/* no default browser arrow on a select */
.frow select,
.joblist,
select.cellin {
  -webkit-appearance: none;
  appearance: none;
  background-image: var(--sel-arrow);
  background-repeat: no-repeat;
  background-position: right 5px center;
  padding-right: 18px;
}

.frow input[type="checkbox"] { width: 14px; height: 14px; margin: 0; }

.frow textarea { resize: vertical; }

/* a hint carries what the label cannot: the source, the rule, a bound */
.frow .hint {
  font-size: var(--fs-1);
  color: var(--ink-3);
  line-height: 1.25;
}

/* labels that carry a standard citation wrap instead of being clipped */
.form.cited .frow > label {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.2;
}

/* ------------------------------------------------------------------ */
/* toolbars                                                            */
/* ------------------------------------------------------------------ */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-2) 0 var(--sp-3);
}

.toolbar button { background: var(--bg); }

.toolnote { font-size: var(--fs-1); color: var(--ink-2); }

.joblist {
  font: inherit;
  font-size: var(--fs-2);
  width: 170px;
  max-width: 170px;
  padding: 2px 3px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background-color: var(--field);
  color: var(--ink);
  text-overflow: ellipsis;
}

/* The file input is visually hidden but NOT display:none - some browsers
   refuse to open the file chooser for an input that is not rendered. */
.hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  opacity: 0;
}

/* ------------------------------------------------------------------ */
/* tables — one shared look, cells left-justified                      */
/* ------------------------------------------------------------------ */
.tablewrap {
  overflow: auto;
  max-height: calc(100vh - 148px);
  border: 1px solid var(--line);
  border-radius: 3px;
  margin-bottom: var(--sp-3);
}

/* the scroll affordance - a shadow on the edge that still has content
   behind it.  The classes are set by the table helper. */
.tablescroll { position: relative; }

.tablescroll::before,
.tablescroll::after {
  content: "";
  position: absolute;
  top: 1px;
  bottom: 1px;
  width: 16px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .12s linear;
  z-index: 5;
}

.tablescroll::before {
  left: 1px;
  background: linear-gradient(to right, rgba(0, 0, 0, .18), rgba(0, 0, 0, 0));
}

.tablescroll::after {
  right: 1px;
  background: linear-gradient(to left, rgba(0, 0, 0, .18), rgba(0, 0, 0, 0));
}

.tablescroll.can-left::before,
.tablescroll.can-right::after { opacity: 1; }

.tbl {
  border-collapse: collapse;
  font-size: var(--fs-2);
  margin: 0 0 var(--sp-3);
  width: auto;
}

.tbl caption {
  caption-side: top;
  text-align: left;
  font-size: var(--fs-1);
  color: var(--ink-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-2);
  border-bottom: 1px solid var(--line-2);
}

.tbl th {
  text-align: left;
  font-weight: 600;
  font-size: var(--fs-1);
  color: var(--ink);
  background: var(--head);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line-2);
  padding: var(--sp-2) 5px;
  white-space: nowrap;
  vertical-align: bottom;
  position: sticky;
  top: var(--appbar-h);
  z-index: 3;
  cursor: pointer;
  user-select: none;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* inside a scrolling wrapper the header sits at the top of the wrapper */
.tablewrap .tbl th { top: 0; }

/* the sort caret — visible on hover, the active one always visible */
.tbl th .th-caret {
  display: inline-block;
  width: 10px;
  margin-left: 1px;
  font-size: 8px;
  line-height: 1;
  color: var(--accent);
  vertical-align: 1px;
}

.tbl th:hover .th-caret:empty::before {
  content: "\2195";
  color: var(--ink-3);
}

/* the drag handle on the right edge of every header cell */
.tbl th .th-resize {
  position: absolute;
  top: 0;
  right: 0;
  width: 8px;
  height: 100%;
  cursor: col-resize;
}

.tbl th .th-resize::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  right: 2px;
  width: 2px;
  background: var(--ink-3);
  opacity: 0;
  border-radius: 1px;
}

.tbl th:hover .th-resize::before { opacity: .55; }

.tbl th .th-resize:hover { background: var(--accent); opacity: .3; }

.tbl.resizing { user-select: none; }
.tbl.resizing th .th-resize:hover { background: transparent; }

/* the column widths: the base width of the table, or the width the user
   dragged the header edge to.  In print the dragged width is dropped. */
.tbl col:nth-child(1) { width: var(--uw-1, var(--bw-1, auto)); }
.tbl col:nth-child(2) { width: var(--uw-2, var(--bw-2, auto)); }
.tbl col:nth-child(3) { width: var(--uw-3, var(--bw-3, auto)); }
.tbl col:nth-child(4) { width: var(--uw-4, var(--bw-4, auto)); }
.tbl col:nth-child(5) { width: var(--uw-5, var(--bw-5, auto)); }
.tbl col:nth-child(6) { width: var(--uw-6, var(--bw-6, auto)); }
.tbl col:nth-child(7) { width: var(--uw-7, var(--bw-7, auto)); }
.tbl col:nth-child(8) { width: var(--uw-8, var(--bw-8, auto)); }
.tbl col:nth-child(9) { width: var(--uw-9, var(--bw-9, auto)); }
.tbl col:nth-child(10) { width: var(--uw-10, var(--bw-10, auto)); }
.tbl col:nth-child(11) { width: var(--uw-11, var(--bw-11, auto)); }
.tbl col:nth-child(12) { width: var(--uw-12, var(--bw-12, auto)); }
.tbl col:nth-child(13) { width: var(--uw-13, var(--bw-13, auto)); }
.tbl col:nth-child(14) { width: var(--uw-14, var(--bw-14, auto)); }
.tbl col:nth-child(15) { width: var(--uw-15, var(--bw-15, auto)); }
.tbl col:nth-child(16) { width: var(--uw-16, var(--bw-16, auto)); }
.tbl col:nth-child(17) { width: var(--uw-17, var(--bw-17, auto)); }
.tbl col:nth-child(18) { width: var(--uw-18, var(--bw-18, auto)); }
.tbl col:nth-child(19) { width: var(--uw-19, var(--bw-19, auto)); }
.tbl col:nth-child(20) { width: var(--uw-20, var(--bw-20, auto)); }
.tbl col:nth-child(21) { width: var(--uw-21, var(--bw-21, auto)); }
.tbl col:nth-child(22) { width: var(--uw-22, var(--bw-22, auto)); }
.tbl col:nth-child(23) { width: var(--uw-23, var(--bw-23, auto)); }
.tbl col:nth-child(24) { width: var(--uw-24, var(--bw-24, auto)); }

.tbl td {
  text-align: left;
  border-bottom: 1px solid var(--line-2);
  padding: 2px var(--sp-3);
  vertical-align: top;
  white-space: nowrap;
  background: var(--bg);
}

/* zebra - the eye follows a row across the wide schedules */
.tbl tbody tr:nth-child(even) td { background: var(--row-alt); }

/* a long text in a narrow cell is clipped, not allowed to run into the
   next column - the full text stays in the cell tooltip */
.tbl td.rate-src {
  overflow: hidden;
  text-overflow: ellipsis;
}

.tbl td.rate-src > span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* a long note is held to three lines on the screen; the print output
   carries it in full */
.tbl td.clamp > span {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* a cell whose text is allowed to wrap inside its own column */
.tbl td.wrap { white-space: normal; overflow-wrap: anywhere; }

/* the arithmetic in a build-up wraps instead of running into the value */
.tbl td.formula { white-space: normal; }

.tbl tfoot td {
  font-weight: 600;
  background: var(--head-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* the numeric cells - tabular figures, the decimals aligned down the
   column while the cell itself stays left-justified */
.tbl td.n {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-2);
}

.nfield { display: inline-flex; align-items: baseline; white-space: nowrap; }

.nfield .nint {
  display: inline-block;
  text-align: right;
  min-width: var(--nint, 0ch);
}

.nfield .nfrac { display: inline-block; text-align: left; }
.nfield .nunit { display: inline-block; color: var(--ink-2); }

/* the editable component schedule has 23 columns - it scrolls rather than
   squeezing the cells; a fixed layout makes a dragged column width exact */
.tbl-components { width: 100%; min-width: 1640px; table-layout: fixed; }
.tbl-supports { table-layout: fixed; }
.tbl-totals { margin-top: var(--sp-3); table-layout: fixed; }
.tbl-rates { table-layout: fixed; width: 100%; }
.tbl-summary { width: 100%; max-width: 900px; table-layout: fixed; }
.tbl-assumptions { width: 100%; max-width: 900px; table-layout: fixed; }

.tbl-components td { padding: 1px 3px; }

/* the two left-hand columns stay put while the schedule scrolls sideways */
.tbl-components td.sticky-l,
.tbl-components th.sticky-l {
  position: sticky;
  left: 0;
  z-index: 2;
}

.tbl-components td.sticky-l2,
.tbl-components th.sticky-l2 {
  position: sticky;
  left: var(--sel-w, 30px);
  z-index: 2;
  box-shadow: 1px 0 0 var(--line);
}

.tbl-components th.sticky-l,
.tbl-components th.sticky-l2 { z-index: 4; }

.cellin {
  font: inherit;
  font-size: var(--fs-2);
  width: 100%;
  padding: 1px 3px;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--ink);
}

.cellin:hover { border-color: var(--line); background: var(--field); }
.cellin:focus { border-color: var(--accent); background: var(--field); outline: none; }
.cellin[type="number"] { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* the supports cell carries a count or the word "Buried" - one fixed width */
.tbl td input[data-field="supports"] {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-2);
  width: 100%;
}

select.cellin {
  border-color: var(--line-2);
  background-color: var(--field);
  padding-right: 16px;
}

/* the assumed branch DN marker on a reducer row */
.tbl td .assume {
  font-family: var(--mono);
  font-size: var(--fs-1);
  color: var(--warn);
  white-space: nowrap;
}

.tbl td .brdn { display: inline-flex; align-items: center; gap: 2px; }
.tbl td .brdn .cellin { width: 52px; }

/* the per-row advisory column */
.tbl td.advisory {
  font-size: var(--fs-1);
  color: var(--warn);
  white-space: normal;
  min-width: 110px;
}

.cellchk { width: 13px; height: 13px; margin: 0; }

/* ------------------------------------------------------------------ */
/* warnings (advisory only)                                            */
/* ------------------------------------------------------------------ */
.warnbox {
  border: 1px solid var(--warn-line);
  border-left-width: 3px;
  border-radius: 3px;
  background: var(--warn-bg);
  padding: var(--sp-3) var(--sp-4);
  margin: var(--sp-3) 0 var(--sp-4);
  max-width: 900px;
}

.warntitle {
  font-size: var(--fs-1);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--warn);
  margin-bottom: var(--sp-1);
}

.warnbox ul { margin: 0; padding-left: 18px; font-size: var(--fs-2); color: var(--warn); }

/* ------------------------------------------------------------------ */
/* report document                                                     */
/* ------------------------------------------------------------------ */
.rep {
  background: var(--bg);
  color: var(--ink);
  padding: 0;
}

/* the report title block — the logo sits on a white chip so it reads the
   same in both themes and in print */
.rep-title {
  font-size: var(--fs-4);
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--accent);
  border-bottom: 2px solid var(--accent);
  padding-bottom: var(--sp-2);
  margin-bottom: var(--sp-3);
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

.rep-title .logo { height: 28px; }

.rep-h {
  font-size: var(--fs-3);
  font-weight: 600;
  margin: var(--sp-5) 0 var(--sp-2);
  color: var(--ink);
  border-bottom: 1px solid var(--line-2);
  padding-bottom: 1px;
}

/* every table in the report is a real table: a fixed column layout, a
   visible grid, and every cell wraps inside its own column */
.rep .tbl {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.rep .tbl th,
.rep .tbl td {
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  border: 1px solid var(--line);
}

/* a header label breaks at its spaces, never inside a word - unless the
   word itself does not fit the column */
.rep .tbl th {
  overflow-wrap: break-word;
  word-break: normal;
  hyphens: none;
  position: static;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

.rep .tbl th { background: var(--head); }

.rep .tbl td.n { white-space: nowrap; overflow-wrap: normal; word-break: normal; }

/* a value in the assumptions / audit table wraps inside its own column */
.rep .tbl td.assump-val { white-space: normal; overflow-wrap: anywhere; }

.rep .tbl td.basis-col { overflow-wrap: normal; }

.rep-cover { width: 100%; table-layout: fixed; }
.rep-cover td:nth-child(1), .rep-cover td:nth-child(3) { background: var(--bg-2); color: var(--ink-2); width: 130px; }
.rep-req { width: 100%; table-layout: fixed; }
.rep-components, .rep-supports, .rep-buildup { width: 100%; table-layout: fixed; }
.rep-components { page: wide; }
.rep-h-wide { page: wide; }
.rep-totals { width: 100%; table-layout: fixed; }
.tbl-assumptions { width: 100%; max-width: 900px; }
.rep-warn { font-size: var(--fs-2); color: var(--warn); margin: 0 0 var(--sp-4); padding-left: 18px; }

/* the vendor rate schedule — an interpolated row is marked, a DN with no
   vendor price is listed as such */
.tbl-rates td.interp, .rep-rates td.interp { background: var(--head-2); }
.tbl-rates td.interp .basisflag, .rep-rates td.interp .basisflag { font-weight: 600; color: var(--accent); }
.tbl-rates td.nodata, .rep-rates td.nodata { color: var(--warn); }
.tbl-rates td.note, .rep .tbl td.note { font-size: var(--fs-1); color: var(--ink-2); }

.rep-rates { width: 100%; table-layout: fixed; page: wide; }

/* a family block of the vendor rate schedule - the heading, the source and
   the table share one landscape page */
.rates-block { page: wide; }

.rates-head {
  font-size: var(--fs-3);
  font-weight: 600;
  color: var(--ink);
  margin: var(--sp-4) 0 var(--sp-1);
}

.rates-src {
  font-size: var(--fs-1);
  color: var(--ink-2);
  margin: 0 0 var(--sp-2);
  font-weight: 400;
}

.noteload {
  font-size: var(--fs-2);
  color: var(--ink-2);
  border: 1px solid var(--line);
  padding: var(--sp-3) var(--sp-4);
  margin: var(--sp-3) 0;
  max-width: 900px;
}

.rep-foot {
  font-size: var(--fs-1);
  color: var(--ink-2);
  border-top: 1px solid var(--line);
  margin-top: var(--sp-4);
  padding-top: var(--sp-1);
}

/* ------------------------------------------------------------------ */
/* print — A4 portrait, repeating headers, page counters               */
/* ------------------------------------------------------------------ */
@page {
  size: A4 portrait;
  margin: 14mm 12mm 16mm;

  @bottom-center {
    content: "GRP ductwork quotation — page " counter(page) " of " counter(pages);
    font-family: "Segoe UI", Tahoma, Arial, sans-serif;
    font-size: 8pt;
    color: #46525c;
  }
}

/* the component schedule carries many columns - it prints on a landscape
   A4 page so every column keeps its own width */
@page wide {
  size: A4 landscape;
  margin: 12mm 12mm 14mm;
}

@media print {
  html, body { background: #fff; font-size: 9pt; }

  /* the printed audit report is black on white in BOTH themes - a printed
     page must still read in greyscale */
  html[data-theme="dark"] {
    --ink: #16212a;
    --ink-2: #4d5b66;
    --ink-3: #7b8994;
    --line: #c3ced7;
    --line-2: #e3e9ee;
    --head: #eceff2;
    --head-2: #dfe5ea;
    --row-alt: #f4f6f8;
    --bg: #ffffff;
    --bg-2: #f4f7f9;
    --field: #ffffff;
    --warn: #8a5300;
    --warn-bg: #fff6e5;
    --warn-line: #e2c68a;
    --accent: #0f4c66;
    --accent-2: #e6eff4;
    --on-accent: #ffffff;
  }

  /* the column widths the user dragged on screen are dropped - the report
     keeps the layout it was built with */
  .tbl {
    --uw-1: initial !important;  --uw-2: initial !important;
    --uw-3: initial !important;  --uw-4: initial !important;
    --uw-5: initial !important;  --uw-6: initial !important;
    --uw-7: initial !important;  --uw-8: initial !important;
    --uw-9: initial !important;  --uw-10: initial !important;
    --uw-11: initial !important; --uw-12: initial !important;
    --uw-13: initial !important; --uw-14: initial !important;
    --uw-15: initial !important; --uw-16: initial !important;
    --uw-17: initial !important; --uw-18: initial !important;
    --uw-19: initial !important; --uw-20: initial !important;
    --uw-21: initial !important; --uw-22: initial !important;
    --uw-23: initial !important; --uw-24: initial !important;
  }

  .no-print, .appbar, .toolbar, .flash, .panel-h { display: none !important; }
  .tabpanel { display: none !important; }
  .tabpanel#tab-report { display: block !important; }
  main { padding: 0; }

  .tablewrap { overflow: visible; max-height: none; border: 0; }
  .tablescroll::before, .tablescroll::after { display: none; }
  /* the print carries the note in full */
  .tbl td.clamp > span { display: block; -webkit-line-clamp: none; overflow: visible; }

  .rep { background: #fff !important; color: #000 !important; }
  .rep-title { color: #0f4c66 !important; border-bottom-color: #0f4c66 !important; }
  .rep .tbl th { background: #eceff2 !important; color: #000 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .rep .tbl td { border-color: #c3ced7 !important; }
  .logo { background: #fff !important; }

  .tbl { font-size: 8.5pt; width: 100%; page-break-inside: auto; }
  /* the report tables are dense - one size for the text and the figures, so
     a column fits its own header without breaking a word */
  .rep .tbl { font-size: 7.5pt; }
  .tbl caption { font-size: 8pt; }
  .tbl th { background: #eceff2 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; white-space: normal; font-size: 7.5pt; }
  .tbl td { white-space: normal; word-wrap: break-word; overflow-wrap: anywhere; }
  .tbl td.n { font-size: 8pt; white-space: nowrap; }
  /* a long value in the assumptions / audit table wraps instead of running
     into the next column */
  .tbl td.assump-val { white-space: normal; }
  /* the report tables are tight - a number never breaks across two lines */
  .rep .tbl td { padding: 1px 3px; }
  .rep .tbl td.n { white-space: nowrap; overflow-wrap: normal; font-size: 7.5pt; }
  /* a value in the assumptions / audit table wraps inside its own column */
  .rep .tbl td.assump-val { white-space: normal; overflow-wrap: anywhere; }
  /* the zebra survives the print - a faint band reads in greyscale */
  .rep .tbl tbody tr:nth-child(even) td { background: #f4f6f8 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  thead { display: table-header-group; }
  tfoot { display: table-row-group; }
  tr { page-break-inside: avoid; page-break-after: auto; }
  .rep-h { page-break-after: avoid; break-after: avoid; }
  /* a heading and its table must not be split by a page break */
  .rep-keep { page-break-inside: avoid; break-inside: avoid; }
  .rep-keep .tbl { page-break-inside: avoid; break-inside: avoid; }
  .rep-keep h3 { break-after: avoid; page-break-after: avoid; }
  .rep-keep .tbl { break-before: avoid; page-break-before: avoid; }
  .rep-title { page-break-after: avoid; }

  .rep-foot {
    /* NOT fixed in print: a fixed footer is repeated by the print engine and
       lands on top of a table row when a page break falls inside a table.
       The page number comes from the @page margin box instead. */
    position: static;
    border-top: 1px solid #c3ced7;
    margin-top: 10px;
    padding-top: 3px;
  }
}
