/* ============================================================================
   Document builder — one engine for quotation, tax invoice, credit note,
   delivery note and completion certificate.

   Assumes: the sheet is ink on paper. It never inherits the app theme, and it
   is the print layout itself — there is no second renderer for export.
   Must never: put the page margin on the sheet's padding in print. A margin on
   the block is applied once, so a document running to a second page would print
   that page edge to edge.
   ========================================================================== */

.db-wrap { display: flex; flex-direction: column; gap: 12px; }

.db-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 12px; border: 1px solid var(--border);
  background: var(--surface); border-radius: 12px;
}
.db-group { display: flex; align-items: center; gap: 6px; }
.db-sep { width: 1px; height: 20px; background: var(--border); }
.db-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-muted);
}
.db-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 6px; font-size: 12px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--ink); cursor: pointer;
  transition: background-color 130ms cubic-bezier(.2,0,.2,1), color 130ms cubic-bezier(.2,0,.2,1);
}
.db-btn:hover { background: var(--elevated); }
.db-btn-primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--rail); font-weight: 600;
}
.db-btn-primary:hover { opacity: .9; background: var(--accent); }
.db-chip {
  font-size: 11px; padding: 4px 9px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface); color: var(--ink-muted);
  transition: all 130ms cubic-bezier(.2,0,.2,1);
}
.db-chip[aria-pressed="true"] {
  background: var(--accent-tint); border-color: var(--accent); color: var(--accent); font-weight: 600;
}
/* Greyed, whatever it is showing: the choice is made elsewhere. */
.db-chip:disabled { cursor: not-allowed; filter: grayscale(1); opacity: .5; }
.db-select {
  background: var(--elevated); border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 10px; font-size: 12px; color: var(--ink);
}
.db-select:disabled { opacity: .45; cursor: not-allowed; }

.db-stage {
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: 12px; padding: 28px; overflow: auto; max-height: 76vh;
}

/* ------------------------------------------------------------------ sheet */
.doc-sheet {
  width: 210mm; min-height: 297mm; box-sizing: border-box;
  margin: 0 auto; padding: 12mm;            /* screen only; print uses @page */
  --doc-fs: 1;
  background: #ffffff; color: #111111;
  font-family: Calibri, "Segoe UI", Candara, Optima, "Trebuchet MS", system-ui, sans-serif;
  font-size: calc(9.5pt * var(--doc-fs)); line-height: 1.35;
  box-shadow: 0 2px 18px rgba(0,0,0,.45);
  /* The shades are part of the document - the heading row, the section
     bands, the totals - and print exactly as they are drawn. Without this the
     print dialog's "Background graphics", off by default, prints them white,
     and a heading set in white on a dark band disappears along with them. */
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.doc-sheet * { box-sizing: border-box; }
.doc-sheet [contenteditable]:focus {
  outline: 2px solid #2FA9A2; outline-offset: 1px; background: #f0fbfa;
}
.doc-sheet [contenteditable]:hover:not(:focus) { background: #f6f8f9; }

.doc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10mm; }
.doc-logo { height: 20mm; width: auto; display: block; }
.doc-org { text-align: right; font-size: calc(8pt * var(--doc-fs)); line-height: 1.4; }
.doc-org-name { font-size: calc(11pt * var(--doc-fs)); font-weight: 700; letter-spacing: .01em; }

.doc-title {
  margin: 4mm 0 3mm; text-align: center;
  font-size: calc(18pt * var(--doc-fs)); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  border-top: 1.5pt solid #111; border-bottom: 1.5pt solid #111; padding: 1.4mm 0;
}

.doc-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 0 8mm; margin-bottom: 4mm; }
.doc-meta-row { display: flex; gap: 2mm; padding: .5mm 0; font-size: calc(9pt * var(--doc-fs)); border-bottom: .4pt dotted #bbb; }
.doc-meta-key { min-width: 22mm; font-weight: 700; color: #333; }
/* the label and its value sit on one line — "Client: Sharjah Cooperative Society" */
.doc-meta-key::after { content: ':'; }
.doc-meta-val { flex: 1; }

.doc-table { width: 100%; border-collapse: collapse; margin-top: 2mm; }
.doc-table th {
  background: #eef1f4; border: .5pt solid #666; padding: 1.6mm 1.2mm;
  font-size: calc(8pt * var(--doc-fs)); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  text-align: center; color: #111;
}
.doc-table td { border: .5pt solid #999; padding: 1.2mm 1.2mm; font-size: calc(9pt * var(--doc-fs)); vertical-align: top; }
.doc-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.doc-ctr { text-align: center; font-variant-numeric: tabular-nums; }
/* A description is one field, shown as written: a line break typed or pasted
   into it is kept, and nothing in it is bold unless the layout says so. */
.doc-desc { white-space: pre-wrap; }
.doc-row-section td {
  background: #dfe5ea; font-weight: 700; text-transform: uppercase;
  font-size: calc(8pt * var(--doc-fs)); letter-spacing: .05em;
}
.doc-row-note td { color: #333; font-style: italic; }
.doc-row:hover { background: #fafcfc; }

.doc-totals { margin-top: 3mm; display: flex; justify-content: flex-end; }
.doc-totals table { border-collapse: collapse; min-width: 80mm; }
.doc-totals td { border: .5pt solid #999; padding: 1.2mm 2mm; font-size: calc(9pt * var(--doc-fs)); }
.doc-totals .k { font-weight: 700; background: #f2f5f7; }
.doc-totals .grand td { font-size: calc(11pt * var(--doc-fs)); font-weight: 700; background: #dfe5ea; }

.doc-words { margin-top: 2.2mm; font-size: calc(9pt * var(--doc-fs)); }
.doc-words b { text-transform: uppercase; }

.doc-terms { margin-top: 3mm; font-size: calc(8pt * var(--doc-fs)); color: #222; }
.doc-terms h4 { font-size: calc(8.5pt * var(--doc-fs)); margin: 0 0 1.5mm; text-transform: uppercase; letter-spacing: .06em; }
.doc-terms ol { margin: 0; padding-left: 5mm; }
.doc-terms li { margin-bottom: .45mm; line-height: 1.3; }

.doc-sign { margin-top: 4mm; display: grid; grid-template-columns: 1fr 1fr; gap: 14mm; font-size: calc(9pt * var(--doc-fs)); }
.doc-sign-box { }
.doc-sign-line { margin-top: 6mm; border-top: .6pt solid #111; padding-top: 1.2mm; }
.doc-signed { margin-top: 10mm; border-top: .6pt solid #111; padding-top: 1.2mm; font-size: calc(8pt * var(--doc-fs)); }

.doc-foot {
  margin-top: 3.5mm; padding-top: 1.5mm; border-top: .6pt solid #111;
  text-align: center; font-size: calc(7.6pt * var(--doc-fs)); color: #333;
}

/* The mark fills the page and CLIPS ITS OWN rotated text. Rotating this box
   instead would give it a bounding box far wider than the page - the sheet
   would gain 190mm of scrollable overflow, and the browser would scroll the
   page sideways the moment anything inside it took focus. */
.doc-draft-mark {
  position: absolute; inset: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  font-size: calc(60pt * var(--doc-fs)); font-weight: 700; color: rgba(220,38,38,.10);
  letter-spacing: .2em;
}
.doc-draft-mark > span { transform: rotate(-24deg); white-space: nowrap; }

/* A superseded document is marked in the REFUSAL colour, not the draft's own:
   a draft is unfinished, a superseded one is finished and no longer valid, and
   they must not be mistaken for one another at a glance. */
.doc-void-mark { color: rgba(220, 38, 38, .12); font-size: calc(40pt * var(--doc-fs)); }

/* The number stays legible under the rule: the reader has to be able to read
   which document has been superseded. */
.doc-struck { text-decoration: line-through; text-decoration-color: #dc2626; text-decoration-thickness: 1.5pt; }

.doc-void-note {
  margin: 0 0 3mm; padding: 1.6mm 2.4mm; border: .8pt solid #dc2626;
  border-radius: 1mm; color: #dc2626; font-weight: 700;
  font-size: calc(9pt * var(--doc-fs)); text-align: center;
}

/* `clip` rather than `hidden`: hidden still makes a SCROLL CONTAINER, which a
   browser is free to scroll programmatically to reveal a focused field. clip
   makes none, so the page can never be nudged sideways. */
.doc-sheet-pos { position: relative; overflow: hidden; overflow: clip; }

/* ------------------------------------------------ row grips, drafts only
   A grip beside every line, in the page's left margin: drag it to move the
   line, click it for the rest. On the paper, so in the paper's colours. The
   layer covers the page but takes no pointer except at the grips. */
.doc-row-grips { position: absolute; inset: 0; pointer-events: none; }
.doc-grip {
  position: absolute; width: 14px; padding: 0; border: 0; border-radius: 3px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: #b6bec7; cursor: grab; pointer-events: auto;
  touch-action: none;
}
.doc-grip:hover, .doc-grip:focus-visible { color: #1b8a84; background: #eefaf9; outline: none; }
.doc-grip.is-active { color: #1b8a84; background: #dff4f2; cursor: grabbing; }
body.doc-row-moving, body.doc-row-moving * { cursor: grabbing !important; user-select: none; }

/* ------------------------------------------------ column grips, drafts only
   A grip over every column, in the gap above the table: drag it sideways to
   move the column, click it for the rest. Only the grips move while one is
   dragged - a section line spans every column, and a column lifted out of a
   table with collapsed borders would tear those lines apart. */
.doc-col-grips { position: absolute; inset: 0; pointer-events: none; }
.doc-colgrip-bar {
  position: absolute; padding: 0; border: 0; border-radius: 3px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  background: transparent; color: #b6bec7; cursor: grab; pointer-events: auto;
  touch-action: none;
  transition: translate .18s cubic-bezier(.2,0,.2,1), background-color .13s, color .13s;
}
.doc-colgrip-bar:hover, .doc-colgrip-bar:focus-visible { color: #1b8a84; background: #eefaf9; outline: none; }
.doc-colgrip-bar.is-held {
  color: #1b8a84; background: #dff4f2; cursor: grabbing; z-index: 2; transition: none;
}
.doc-colgrip-bar.is-settling { transition: translate .18s cubic-bezier(.2,0,.2,1); }

/* A column being moved. What moves is a copy of the columns laid over the
   table (column-grips.tsx): the held one lifts and follows the pointer, the
   ones it passes slide aside, and the tinted slot is where it will land. */
.doc-sort-col {
  position: absolute; top: 0; bottom: 0; z-index: 1;
  transition: translate .18s cubic-bezier(.2,0,.2,1);
}
.doc-sort-col > table { margin: 0 !important; border-radius: 0 !important; }
.doc-sort-col.is-held {
  z-index: 3;
  transition: scale .18s cubic-bezier(.2,0,.2,1), box-shadow .18s cubic-bezier(.2,0,.2,1);
}
/* Wider, not taller: a column is as tall as the table, and one grown even
   slightly taller would pull its lines off the section lines it slides past. */
.doc-sort-col.is-lifted {
  scale: 1.05 1;
  box-shadow: 0 12px 28px rgba(15, 23, 42, .20), 0 2px 6px rgba(15, 23, 42, .12);
}
.doc-sort-col.is-settling {
  transition: translate .18s cubic-bezier(.2,0,.2,1), scale .18s cubic-bezier(.2,0,.2,1),
    box-shadow .18s cubic-bezier(.2,0,.2,1);
}
/* Where a line that runs the width of the table crosses a column. */
.doc-sort-col td.doc-sort-gap { padding: 0; border: 0; background: transparent; }
/* Those lines - a section, a note, the bar that adds a row - belong to no
   column: they stay where they are, over the columns sliding past. */
.doc-sort-band { position: absolute; left: 0; right: 0; z-index: 2; }
.doc-sort-band > table { margin: 0 !important; border-radius: 0 !important; }
.doc-sort-colslot {
  position: absolute; top: 0; bottom: 0; z-index: 0;
  background: rgba(47, 169, 162, .08); box-shadow: inset 0 0 0 1px rgba(47, 169, 162, .45);
  transition: translate .18s cubic-bezier(.2,0,.2,1);
}

/* The gap the column grips sit in, above the table. It is as tall as a grip
   and its clearance (column-grips.tsx), and it is the builder's alone: an
   issued document is printed from this page, has no grips, and has no gap. */
.doc-grip-gap { height: 17px; }

/* A line being moved. What moves is a copy of the lines laid over the table
   (row-grips.tsx): the held one lifts and follows the pointer, the ones it
   passes slide aside, and the tinted slot is where it will land. */
.doc-sort-layer { position: absolute; z-index: 4; pointer-events: none; }
.doc-sort-item {
  position: absolute; left: 0; right: 0; z-index: 1;
  transition: translate .18s cubic-bezier(.2,0,.2,1);
}
.doc-sort-item > table { margin: 0 !important; border-radius: 0 !important; }
.doc-sort-item.is-held {
  z-index: 3;
  transition: scale .18s cubic-bezier(.2,0,.2,1), box-shadow .18s cubic-bezier(.2,0,.2,1);
}
.doc-sort-item.is-lifted {
  scale: 1.015;
  box-shadow: 0 12px 28px rgba(15, 23, 42, .20), 0 2px 6px rgba(15, 23, 42, .12);
}
.doc-sort-item.is-settling {
  transition: translate .18s cubic-bezier(.2,0,.2,1), scale .18s cubic-bezier(.2,0,.2,1),
    box-shadow .18s cubic-bezier(.2,0,.2,1);
}
.doc-sort-slot {
  position: absolute; left: 0; right: 0; z-index: 0;
  background: rgba(47, 169, 162, .08); box-shadow: inset 0 0 0 1px rgba(47, 169, 162, .45);
  transition: translate .18s cubic-bezier(.2,0,.2,1);
}
.doc-sort-mark { position: absolute; inset: 0; overflow: hidden; z-index: 2; }
.doc-sort-grip { pointer-events: none; }
.doc-row-grips.is-sorting .doc-grip:not(.doc-sort-grip) { visibility: hidden; }

/* ------------------------------------------------------------------ print */
@media print {
  @page { size: A4 portrait; margin: 12mm; }

  html, body { background: #fff !important; }
  aside, header, .no-print { display: none !important; }
  main { margin-left: 0 !important; }
  body * { visibility: hidden; }
  .doc-sheet, .doc-sheet * { visibility: visible; }

  .db-stage {
    padding: 0; border: 0; background: #fff; max-height: none; overflow: visible;
  }
  .doc-sheet {
    /* the margin belongs to the page, never to this block */
    width: auto; min-height: 0; margin: 0; padding: 0;
    box-shadow: none; position: absolute; left: 0; top: 0; right: 0;
  }
  .doc-row-grips, .doc-col-grips { display: none !important; }
  /* Only the editing tints go: a cell hovered or being typed in. Matching
     every [contenteditable] cleared the section bands of an issued document,
     whose cells all carry contenteditable="false". */
  .doc-sheet [contenteditable="true"]:hover,
  .doc-sheet [contenteditable="true"]:focus { outline: none !important; background: transparent !important; }
  .doc-table thead { display: table-header-group; }
  .doc-row, .doc-sign, .doc-totals { break-inside: avoid; }
}

@media (prefers-reduced-motion: reduce) {
  .db-btn, .db-chip { transition: none !important; }
}

/* ---------------------------------------------- toolbar rows, added later */
.db-toolbar { flex-direction: column; align-items: stretch; gap: 10px; }
.db-line { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.db-spacer { flex: 1; }

/* ------------------------------------------- picked / fixed field styling */
.doc-pick { cursor: pointer; padding-bottom: .3mm; }
/* box-shadow rather than a border: no layout shift, and a hover state can
   never print, so the sheet stays clean */
.doc-pick:hover { background: #f0fbfa; box-shadow: 0 1px 0 #9aa4ad; }
.doc-pick:focus { outline: 2px solid #2FA9A2; outline-offset: 1px; }
.doc-pick-caret { font-size: calc(7pt * var(--doc-fs)); color: #667; margin-left: 1.5mm; }
.doc-empty { color: #888; font-style: italic; }
.doc-muted { color: #666; }
.doc-fixed { font-weight: 700; }
.doc-hint {
  margin-left: 2mm; font-size: calc(6.5pt * var(--doc-fs)); color: #888; text-transform: uppercase; letter-spacing: .05em;
}

.doc-datewrap { position: relative; display: inline-block; }
.doc-date-input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer; border: 0; padding: 0;
}
.doc-datewrap:hover .doc-date-text { background: #f0fbfa; }

.doc-select {
  font: inherit; color: inherit; background: transparent;
  border: 0; border-bottom: 1px dashed #9aa4ad; padding: 0 0 .3mm;
  appearance: none; -webkit-appearance: none; cursor: pointer;
}
.doc-select:focus { outline: 2px solid #2FA9A2; outline-offset: 1px; }

.doc-subject { border-bottom: .6pt solid #111; margin-bottom: 3mm; }
.doc-currency-note { margin-top: 1.5mm; font-size: calc(7.5pt * var(--doc-fs)); color: #444; }
.doc-totals .cur { text-align: right; font-size: calc(7.5pt * var(--doc-fs)); color: #444; padding-right: 1mm; }
.doc-totals .grand .cur { font-size: calc(8.5pt * var(--doc-fs)); color: #111; font-weight: 700; }

/* ------------------------------------------------- add rows from the sheet */
.doc-addbar td { border: .5pt dashed #b9c2c9 !important; background: #fbfcfd; padding: 1.6mm 1.2mm; }
.doc-addbar-label {
  font-size: calc(7pt * var(--doc-fs)); text-transform: uppercase; letter-spacing: .06em; color: #778;
  margin-right: 2mm;
}
.doc-add {
  border: .5pt solid #cbd3d9; background: #fff; color: #17605c;
  border-radius: 3px; font-size: calc(7.5pt * var(--doc-fs)); font-weight: 600;
  padding: .8mm 2mm; margin-right: 1.5mm; cursor: pointer;
}
.doc-add:hover { background: #eefaf9; border-color: #2FA9A2; }

/* --------------------------------------------------------------- dialogs */
.db-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6, 8, 11, 0.62);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.db-overlay[hidden] { display: none; }
.db-modal {
  width: 100%; max-width: 460px; max-height: 80vh; overflow: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 20px;
  box-shadow: 0 12px 40px rgba(0,0,0,.5);
}
.db-modal-title { font-size: 14px; font-weight: 700; color: var(--ink-strong); margin: 0 0 4px; }
.db-modal-note { font-size: 12px; color: var(--ink-muted); margin: 0 0 12px; }
.db-field { display: block; margin-bottom: 12px; }
.db-field span { display: block; font-size: 12px; color: var(--ink-muted); margin-bottom: 4px; }
.db-input {
  width: 100%; background: var(--elevated); border: 1px solid var(--border);
  border-radius: 6px; padding: 8px 10px; font-size: 13px; color: var(--ink);
}
.db-input:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(47,169,162,.18);
}
.db-check { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--ink); margin-bottom: 12px; }
.db-check input { accent-color: var(--accent); margin-top: 2px; }
.db-error { font-size: 11px; color: var(--bad); margin: 0 0 10px; }
.db-error[hidden] { display: none; }
.db-modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

.db-list { max-height: 320px; overflow: auto; margin-top: 10px; border: 1px solid var(--border); border-radius: 6px; }
.db-list-item {
  display: block; width: 100%; text-align: left; padding: 9px 12px;
  background: transparent; border: 0; border-bottom: 1px solid var(--border); cursor: pointer;
}
.db-list-item:last-child { border-bottom: 0; }
.db-list-item:hover, .db-list-item:focus { background: var(--elevated); outline: none; }
.db-list-main { display: block; font-size: 13px; font-weight: 600; color: var(--ink-strong); }
.db-list-sub { display: block; font-size: 11px; color: var(--ink-muted); margin-top: 2px; }
.db-list-empty { padding: 16px; font-size: 12px; color: var(--ink-muted); text-align: center; }

@media print {
  .db-overlay, .doc-addbar, .doc-hint, .doc-pick-caret { display: none !important; }
  .doc-pick, .doc-select { border-bottom: 0 !important; }
  .doc-select { appearance: none; }
}

/* ------------------------------------------------------- lifecycle chrome */
.db-banner {
  padding: 10px 12px; border-radius: 8px; font-size: 12px; color: var(--ink);
  background: var(--accent-tint); border: 1px solid var(--accent);
}
.db-banner-issued { background: var(--good-tint); border-color: var(--good); }
/* Superseded, void, reversed - the record stands but no longer counts. */
.db-banner-void { background: var(--bad-tint); border-color: var(--bad); }
.db-banner b { color: var(--ink-strong); }
.db-banner-sub { color: var(--ink-muted); }
.db-note { font-size: 11px; color: var(--ink-muted); }
.db-facts { margin: 0 0 14px; padding-left: 18px; }
.db-facts li { font-size: 12px; color: var(--ink); margin-bottom: 6px; }
.db-facts b { color: var(--ink-strong); }

/* ------------------------------------------------- column width behaviour
   Fixed layout is what stops a long word widening a column. Without it the
   table is auto-sized and one unbroken string pushes the sheet out of bounds. */
.doc-table { table-layout: fixed; width: 100%; }
/* A word is broken only when it cannot fit on a line of its own, and then
   at a syllable with a hyphen - "Descrip-tion", never "Descripti on".
   `anywhere` broke them mid-word wherever the column got tight. */
.doc-table th, .doc-table td {
  overflow-wrap: break-word;
  hyphens: auto;
}
.doc-table th { position: relative; }
.doc-desc { overflow-wrap: break-word; }

/* drag handle between column headings */
.doc-colgrip {
  position: absolute; top: 0; right: -3px; width: 6px; height: 100%;
  cursor: col-resize; z-index: 3; user-select: none;
}
.doc-colgrip::after {
  content: ''; position: absolute; top: 15%; bottom: 15%; left: 2px;
  width: 2px; background: transparent; border-radius: 2px;
}
.doc-colgrip:hover::after, .doc-colgrip.is-dragging::after { background: #2FA9A2; }
body.doc-resizing { cursor: col-resize; user-select: none; }

@media print {
  .doc-colgrip { display: none !important; }
  /* A positioned heading cell is painted apart from the table's collapsed
     borders when printed, and takes some of the lines between the headings
     with it. The grip it anchors is not printed, so neither is the position. */
  .doc-table th { position: static; }
}

/* ------------------------------------------------- optional date field */
.doc-dateinput {
  font: inherit; color: inherit; background: transparent;
  border: 0; padding: 0; cursor: text; width: 24mm;
}
.doc-dateinput[aria-invalid="true"] { box-shadow: 0 1px 0 #dc2626; }

/* Typed first, picked second. The calendar button and the native box that
   opens it are screen-only; the sheet prints the date, not the control. */
.doc-dategroup { position: relative; display: inline-flex; align-items: baseline; gap: 1mm; }
.doc-calendar {
  border: 0; background: transparent; cursor: pointer; color: #667;
  font-size: calc(9pt * var(--doc-fs)); line-height: 1; padding: 0 1px;
}
.doc-calendar:hover { color: #111; }
.doc-datenative { position: absolute; left: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.doc-datebad { color: #dc2626; font-size: calc(7.5pt * var(--doc-fs)); margin-left: 2mm; }
.doc-dateinput:focus {
  outline: 2px solid #2FA9A2; outline-offset: 1px; background: #f0fbfa;
}
.doc-dateinput:hover:not(:focus) { background: #f6f8f9; }
.doc-dateinput::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .5; }
.doc-dateinput::-webkit-calendar-picker-indicator:hover { opacity: 1; }
.doc-clear {
  border: 0; background: transparent; cursor: pointer; color: #99a;
  font-size: calc(8pt * var(--doc-fs)); line-height: 1; padding: 0 2px; margin-left: 2mm;
}
.doc-clear:hover { color: #c00; }

@media print {
  .doc-dateinput::-webkit-calendar-picker-indicator { display: none; }
  .doc-dateinput { background: transparent !important; }
}


/* ============================================================================
   document view: zoom, pan, full window

   Zoom is a transform on .db-canvas. A transform does not change the layout
   box, so .db-fit is given the scaled size explicitly — without it the scroll
   container would still believe the document is its unscaled size and the
   scrollbars would describe the wrong thing.
   ========================================================================== */
.db-viewbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 2px; }

.db-zoom {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--border); border-radius: 6px; overflow: hidden;
  background: var(--surface);
}
.db-zoom button {
  border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1;
  padding: 5px 10px; cursor: pointer;
}
.db-zoom button:hover { background: var(--elevated); color: var(--accent); }
.db-zoom-level {
  min-width: 54px; display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-muted);
  border-left: 1px solid var(--border); border-right: 1px solid var(--border);
  padding: 0 4px;
}
.db-hint { font-size: 11px; color: var(--ink-muted); }
/* fit is a mode that stays on, so the control has to look like it is on */
.db-viewbar [data-zoom="fit"][aria-pressed="true"] {
  background: var(--accent-tint); border-color: var(--accent); color: var(--accent);
}

.db-fit { margin: 0 auto; }
/* max-content, not the parent's width: .db-fit is given an explicit pixel size
   by the zoom, and a canvas that inherited it would collapse to nothing the
   first time it was measured while the tab was hidden — and never recover,
   because its own measurement is what feeds that size. */
.db-canvas { transform-origin: 0 0; width: max-content; }

/* The background is draggable; the sheet is not, because a drag there is a text
   selection. In the full-window viewer nothing is editable, so the sheet drags
   too. */
.db-stage { cursor: grab; }
.db-stage .doc-sheet { cursor: auto; }
.db-stage.is-panning, .db-stage.is-panning .doc-sheet { cursor: grabbing; }
.db-stage.is-panning { user-select: none; }

/* ------------------------------------------------------- full-window viewer */
.db-full {
  /* above the sidebar's z-index 50; it is a child of <body>, so this is measured
     in the root stacking context and nothing in the page can paint over it */
  position: fixed; inset: 0; z-index: 200;
  display: flex; flex-direction: column;
  background: var(--ground);
}
.db-full[hidden] { display: none; }
.db-full-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 16px; border-bottom: 1px solid var(--border);
  background: var(--rail);
}
.db-full-title { font-size: 13px; font-weight: 700; color: var(--ink-strong); }
.db-full-sub { font-size: 12px; color: var(--ink-muted); }
/* The mount lives here in full screen, so the stage inside it has to stretch.
   Inline the stage is capped at 76vh; here it takes everything left over. */
.db-full-body { flex: 1; min-height: 0; display: flex; padding: 8px 12px 12px; }

/* The builder toolbar is hidden in full screen. Rows are added, moved and
   deleted from the sheet's own controls and cells are edited in place, so what
   it holds — columns, layout, templates, issuing — is setup, not writing. It
   cost 177px of a 1100px window, which is the whole point of full screen. */
.db-full .db-toolbar { display: none; }
/* min-width: 0 as well as min-height. A flex item defaults to min-width: auto,
   which is its content width — so once the document was zoomed past the window,
   these could not shrink back and narrowing the window left the sheet at its old
   scale instead of refitting. */
.db-full-body > * { flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column; }
.db-full .db-wrap { flex: 1; min-height: 0; min-width: 0; gap: 8px; }
.db-full .db-stage { max-height: none; flex: 1; min-height: 0; min-width: 0; }

/* --------------------------------- the two delivery documents, added later */
/* Shared by all four layouts. These carry no colour of their own beyond the
   print inks already in use here, so Sleek, Spectrum and Meridian inherit them
   and stay recognisably themselves. */

/* The sentence a certificate opens with, and the note a delivery note opens
   with. It sits between the meta block and the items, because it introduces
   them. */
.doc-statement {
  margin: 0 0 3mm; font-size: calc(9pt * var(--doc-fs)); line-height: 1.45; color: #111;
}

/* A completion certificate states one figure — the contract value, inclusive of
   VAT — and no other. It is not a totals table with rows hidden; it is a
   different statement, so it is set as a line rather than a stack. */
.doc-contract-value {
  margin-top: 3mm; padding: 1.8mm 2mm;
  border-top: 1pt solid #111; border-bottom: 1pt solid #111;
  font-size: calc(10pt * var(--doc-fs)); font-weight: 700; color: #111;
}
.doc-contract-note { font-weight: 400; font-size: calc(8pt * var(--doc-fs)); color: #333; }

/* The closing declaration, above the two signature boxes. */
.doc-declaration {
  margin-top: 3mm; font-size: calc(8.6pt * var(--doc-fs)); line-height: 1.4; color: #222;
}

@media print {
  .doc-statement, .doc-declaration, .doc-contract-value { break-inside: avoid; }
}

/* ------------------------------------- the payment voucher, added later */
/* A voucher is a form, not a grid: four labelled lines with a rule under each
   value, which is what a printed voucher looks like and what somebody signing
   one expects to see. Shared by all four layouts. */
.doc-pv { margin: 2mm 0 3mm; }
.doc-pv-row {
  display: flex; align-items: baseline; gap: 4mm;
  padding: 1.6mm 0; font-size: calc(9.5pt * var(--doc-fs));
}
.doc-pv-key {
  flex: 0 0 42mm; font-weight: 700; color: #111;
  text-transform: uppercase; letter-spacing: .04em;
  font-size: calc(8pt * var(--doc-fs));
}
.doc-pv-val { flex: 1; border-bottom: .6pt solid #111; padding-bottom: .8mm; min-height: 5mm; }
.doc-pv-fill { display: block; min-height: 4.4mm; }

/* the figure is the point of the document, so it is set larger than the prose
   around it and given room to be read across a desk */
.doc-pv-amount {
  display: block; min-height: 4.4mm;
  font-size: calc(13pt * var(--doc-fs)); font-weight: 700; color: #111;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
/* the words are the check on the figure — capitalised the way a cheque is */
.doc-pv-words { display: block; min-height: 4.4mm; text-transform: uppercase; font-weight: 600; }
.doc-pv-desc { min-height: 9mm; }

@media print {
  .doc-pv-row { break-inside: avoid; }
}
