/* Invoice document — the actual A4/Letter canvas: header, bill-to, items table, totals, footer */
/* Responsive document canvas: the invoice keeps true A4 proportions (210mm x 297mm)
   for accurate print/PDF output, while this wrapper lets it scale down as one
   modular unit to fit any viewport width instead of forcing horizontal scrolling. */
.canvaswrap{width:100%;max-width:var(--page-w);margin:0 auto;position:relative}
/* Searchable currency combobox — a text input + filtered listbox layered
   over the real (visually hidden) #currency <select>, which stays the
   source of truth so every other module keeps reading/writing it exactly
   as before. See js/currencySearch.js. Lives in the Right Sidebar's
   Currency panel (index.html). */
.currency-field{position:relative}
.combobox{position:relative;min-width:0}
/* Specificity note: this lives inside a Right Sidebar .field now (index.html),
   and the generic ".field input" rule (base.css) also matches this <input> —
   the extra ".combobox" ancestor class here (two classes vs. one class+type)
   keeps this rule winning, so the caret's reserved right-padding and rounded
   corners aren't silently overridden by the generic field style. */
.combobox .combobox-input{min-height:32px;padding:5px 26px 5px 8px;font-size:12px;width:100%;border:1px solid var(--line);border-radius:9px;background:#fff;color:var(--ink);font-family:inherit;cursor:text}
.combobox .combobox-input:focus{outline:2px solid var(--app-accent);outline-offset:1px;border-color:var(--app-accent)}
.combobox-caret{position:absolute;right:7px;top:50%;transform:translateY(-50%);width:14px;height:14px;color:var(--muted);cursor:pointer;transition:transform .15s ease}
.combobox.open .combobox-caret{transform:translateY(-50%) rotate(180deg)}
.combobox-list{position:absolute;top:calc(100% + 6px);left:0;right:0;min-width:260px;max-height:280px;overflow-y:auto;margin:0;padding:5px;list-style:none;background:#fff;border:1px solid var(--line);border-radius:11px;box-shadow:var(--shadow-lg);z-index:50;display:none}
.combobox.open .combobox-list{display:block}
.combobox-group-label{font-size:9.5px;font-weight:800;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);padding:8px 8px 3px}
.combobox-option{font-size:12.5px;padding:7px 8px;border-radius:7px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--ink)}
.combobox-option.active{background:#eef0f7}
.combobox-option.selected{font-weight:750;color:var(--app-accent)}
.combobox-option.selected::after{content:"✓";float:right;margin-left:8px}
.combobox-empty{font-size:12px;color:var(--muted);padding:10px 8px;text-align:center}
@media (max-width:640px){
  .combobox-list{min-width:0}
}
/* Unified toolbar row — Save/Duplicate/Saved invoices/Templates on the
   left, then a vertical divider, then Edit⇄Preview + Zoom pushed to the
   far right — all inside one visual pill instead of two stacked bars.
   #invoiceToolbar stays its own DOM node inside here (rather than being
   merged into one flat container) purely so js/layout.js can still
   teleport it whole into the hamburger drawer on phones — see
   .drawer-toolbar-slot in responsive.css — without this row's layout CSS
   following it there; the divider hides itself on phones (below) since
   there's nothing left of it once Save's group has moved to the drawer.
   Kept to a single line always (no wrap): it uses the full workspace
   width — wider than the page-width-constrained canvas below it — to fit
   everything, and falls back to horizontal scrolling (rather than ever
   wrapping to a second line) if a window is too narrow for that. */
.toolbar-row{width:100%;max-width:none;margin:0 auto 10px;display:flex;align-items:center;gap:10px;flex-wrap:nowrap;overflow-x:auto;background:#fff;border:1px solid var(--line);border-radius:13px;padding:6px;box-shadow:var(--shadow-sm)}
.toolbar-row .btn{box-shadow:none;border-color:transparent;white-space:nowrap}
.toolbar-row .btn:hover{border-color:var(--line);box-shadow:var(--shadow-sm)}
.toolbar-row .btn.primary{box-shadow:0 2px 8px rgba(var(--app-accent-rgb),.28)}
#invoiceToolbarAnchor{display:none}
.toolbar-row .invoice-toolbar{width:auto;max-width:none;margin:0;justify-content:flex-start;flex:none}
.toolbar-row .canvasbar{width:auto;max-width:none;margin:0;justify-content:flex-start;gap:16px;flex:none}
.invoice-toolbar-actions{flex-wrap:nowrap}
.canvasbar{display:flex;justify-content:flex-start;align-items:center;gap:14px;flex-wrap:nowrap}.canvasbar .meta{font-size:11px;color:var(--muted);display:inline-flex;align-items:center;white-space:nowrap}
.canvasbar-right{display:flex;align-items:center;gap:12px;flex:none}
.canvasbar-right .actions{flex-wrap:nowrap;margin-bottom:0}
/* The real #currency <select> underneath the searchable combobox must stay
   fully invisible AND non-interactive — otherwise generic rules elsewhere
   (e.g. ".field select" in the Right Sidebar it now lives in) can leak real
   width/padding onto it (they win over the single-class ".visually-hidden"
   on specificity), which gives it a real clickable box that can sit on top
   of the search input or its arrow and silently steal clicks/focus meant
   for the combobox. The ID selector here guarantees this always wins,
   regardless of what else targets "select" elsewhere in the stylesheet,
   now or in the future. */
#currency{position:absolute!important;width:1px!important;height:1px!important;min-width:0!important;min-height:0!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important;pointer-events:none!important}
.canvasmode-switch{flex:none}
/* Pushes the divider (and everything after it — the Edit/Preview switch +
   zoom) all the way to the right edge of the pill, while Save's button
   group stays left-aligned; the gap this creates lands only in front of
   the divider, not evenly across every gap in the row. */
.toolbar-divider{width:1px;align-self:stretch;background:var(--line);margin-left:auto;flex:none}
@media (max-width:640px){ .toolbar-divider{display:none} }
/* "A4 portrait preview · N pages" only makes sense as a description of the
   Preview mode (a faithful dry run of Print/PDF output) — in Edit mode the
   canvas isn't a page-accurate preview (it still shows every optional
   field's placeholder, even ones left blank), so the label only shows once
   Preview is switched on. */
#previewMeta{display:none}
body.canvas-preview-mode #previewMeta{display:inline-flex}
/* Edit/Preview canvas switch (js/layout.js setCanvasMode): Edit (default)
   shows every optional row/field so it's clear what's available to fill
   in, even when empty (see the "— " / "Add value" placeholders preview.js
   renders for them). Preview strips those empty optional rows exactly like
   @media print does (same .print-hide-empty class print.css already uses)
   for a faithful live dry run of the actual Print/PDF output. */
body.canvas-preview-mode .invoice .print-hide-empty{display:none!important}
/* Same reasoning as the @media print rules in print.css: Preview mode is a
   faithful dry run of the actual Print/PDF output, so the on-screen-only
   form chrome (dashed fillable-field underline, the status select's
   dropdown arrow, empty-field placeholder text) is hidden here too,
   alongside the logo upload toolbar hidden below. Excludes every
   "[id^=label]" field (Bill to, Invoice note, Payment details, Terms,
   INVOICE title, Balance due, and the Invoice date/Due date/Reference row
   labels): those use their placeholder as their actual default *content*
   (see main.js's fields-array comment — typing over one renames it, e.g.
   "Bill to" → "Client info"), not as a "fill this in" hint, so hiding it
   the same way as a real empty-value hint used to make headings like
   "BILL TO" disappear from Preview entirely. */
body.canvas-preview-mode .invoice input:not([id^="label"])::placeholder,
body.canvas-preview-mode .invoice textarea::placeholder{color:transparent!important}
body.canvas-preview-mode .status{background-image:none!important;padding:5px 9px!important}
/* Preview is a genuine read-only print preview, not a second editing
   surface — js/layout.js's setCanvasMode() marks every real field on the
   document readOnly/disabled the instant Preview turns on. These rules
   just make the *look* match: no text-input caret or pointer cursor, no
   focus ring (there's nothing to focus toward editing anymore), and none
   of the browser's default washed-out "disabled control" styling — so
   switching to Preview only removes the ability to edit, never changes
   how the document itself looks. */
body.canvas-preview-mode .invoice input,
body.canvas-preview-mode .invoice textarea,
body.canvas-preview-mode .invoice select{cursor:default;opacity:1;-webkit-text-fill-color:currentColor}
body.canvas-preview-mode .invoice input:focus,
body.canvas-preview-mode .invoice textarea:focus,
body.canvas-preview-mode .invoice select:focus{outline:none}
body.canvas-preview-mode .invoice input[type=number]::-webkit-outer-spin-button,
body.canvas-preview-mode .invoice input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
body.canvas-preview-mode .invoice input[type=date]::-webkit-calendar-picker-indicator{display:none}
/* Edit is an editing form, not a page-accurate mock-up — it shouldn't be
   held open to a fixed A4/Letter height (min-height, set below on the base
   .invoice rule) when the actual fields don't fill one, since that leaves a
   dead gap of blank "page" below the last field instead of the canvas
   simply ending there like an ordinary form. Preview keeps the fixed page
   height (a faithful dry run of Print/PDF, which really does paginate to
   the physical page size) — only Edit relaxes it; js/preview.js's
   fitInvoiceCanvas() sizes the wrapper to match on the Edit side so
   nothing beyond the real content is reserved. The footer likewise only
   belongs to that page-accurate view (and to the repeating print/PDF
   footer built separately in applyPrintTableWrap): it has nothing to
   attach to at the bottom of an auto-height Edit canvas, so it's hidden
   there and reappears once Preview is switched on.*/
body:not(.canvas-preview-mode) .invoice{min-height:0}
body:not(.canvas-preview-mode) .footer{display:none}
.canvasmode-switch{display:inline-flex;gap:2px;background:#eef0f7;padding:3px;border-radius:10px}
.canvasmode-btn{border:0;background:transparent;border-radius:7px;padding:6px 11px;font-size:11.5px;font-weight:750;color:var(--muted);display:inline-flex;align-items:center;gap:5px;transition:background-color .15s ease,color .15s ease,box-shadow .15s ease}
.canvasmode-btn.active{background:#fff;color:var(--app-accent);box-shadow:var(--shadow-sm)}
.canvasmode-btn:not(.active):hover{color:var(--ink)}
.invoice{--template-accent:var(--accent);width:var(--page-w);min-height:var(--page-h);margin:0;background:var(--invoice-bg,#fff);box-shadow:0 18px 55px rgba(16,24,40,.14);padding:12mm 12mm 11mm;position:relative;overflow:hidden;font-family:var(--font-modern)}
.invoice .section-hidden{display:none!important}.inv-header{display:grid;grid-template-columns:1.15fr .85fr;gap:18px;background:var(--header-bg,transparent);border-radius:10px}.invoice.has-header-bg:not(.template-medical) .inv-header{padding:14px 16px;margin:0 0 14px}
.invoice.has-header-text .inv-header .companyname,.invoice.has-header-text .inv-header .metaText,.invoice.has-header-text .inv-header .invtitle h2,.invoice.has-header-text .inv-header .invno,.invoice.has-header-text .inv-header .metatable td{color:var(--header-text)!important}
.companywrap{display:flex;gap:12px;align-items:flex-start}.invoice.logo-position-left .companywrap{flex-direction:row;align-items:flex-start}.invoice.logo-position-above .companywrap{flex-direction:column;align-items:flex-start}.logobox{display:inline-flex;align-items:center;justify-content:center;flex:none}.logobox:not(.has-logo){width:var(--logo-h,48px);height:var(--logo-h,48px);border:1px solid #d7dde6;border-radius:10px;background:#f7f9fc}.logobox img{display:none;max-height:var(--logo-h,48px);max-width:220px;width:auto;height:auto;object-fit:contain}.logobox.has-logo img{display:block}.logobox.has-logo .logofallback{display:none}.logofallback{width:100%;height:100%;border-radius:11px;background:var(--template-accent);color:#fff;font-size:calc(var(--logo-h,48px)*0.42);font-weight:900;display:grid;place-items:center}.companyname{font-size:20px;font-weight:800;margin:1px 0 5px}.invoice .metaText{font-size:10.5px;color:#485568;line-height:1.4}.metaText>div{white-space:pre-line}.invtitle{text-align:right}.invtitle h2{margin:0;font-size:34px;font-weight:300;letter-spacing:.04em}.invno{font-size:15px;color:#667085;font-weight:700;margin-top:3px}.metatable{width:100%;margin-top:10px;border-collapse:collapse;font-size:10.5px}.metatable td{padding:2.5px 0}.metatable td:first-child{text-align:left;color:#667085;padding-right:14px;white-space:nowrap;width:1%}.metatable td:last-child{text-align:right;font-weight:700}.balance{margin-top:10px;background:rgba(var(--accent-rgb),.08);border:1px solid rgba(var(--accent-rgb),.14);border-radius:8px;padding:8px 10px;display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:800}.balance span{color:var(--total-color,#1f2937)}.balance strong{font-size:18px;color:var(--total-color,#18181b)}

/* ---- Canvas form fields --------------------------------------------------
   Every field on the invoice (v3.15+) is a real <input>/<textarea>/<select>
   living directly at its spot on the document, reusing the exact same
   classes/tags the rules above (and every per-template override in
   templates.css) already target — .companyname, .metaText, .invtitle h2,
   .invno, .metatable td, .balance span/strong, .label, .clientname,
   .status, .sumrow span — so every template's typography/color/shape still
   applies untouched. This block only resets browser form-control chrome
   (border, background, native font) so each field looks exactly like the
   plain invoice text it replaced — no added visual styling of its own,
   just the browser's normal focus ring so it's still clear what's
   selected.

   ROOT CAUSE (fixed) of oversized Notes/Payment details/Terms text:
   "font:inherit" below is a shorthand — it resets font-size (and family/
   weight/line-height) to whatever the element's OWN PARENT computes to,
   ignoring any other rule that also targets the element itself. That's
   fine for #companyReg/#companyVat/#companyAddress etc., where ".metaText"
   is a wrapping <div> around them (so "inherit" correctly picks up that
   div's 10.5px) — but #notes/#paymentDetails/#terms put ".metaText"
   directly ON the <textarea>, and ".metaText{font-size:10.5px}" (a single
   class, specificity 0,1,0) can never win against this "font:inherit"
   rule (class+type, specificity 0,1,1) on that same element, no matter
   the source order. So those three fell through to inheriting their
   *parent's* (.notebox / .paymentgrid>div, neither of which set a
   font-size) font-size instead — all the way up to .invoice's own base
   16px, roughly 50% larger than every other piece of meta text on the
   document, in every template (none of them override .metaText's
   font-size either). Fixed at the source, line 165: ".metaText" is now
   ".invoice .metaText" (specificity 0,2,0), which safely beats this
   "font:inherit" rule's 0,1,1 regardless of which element ".metaText" is
   applied to or what order the rules appear in. */
.invoice input,.invoice textarea,.invoice select{font:inherit;color:inherit;letter-spacing:inherit;text-align:inherit;background:transparent;border:none;border-radius:0;padding:0;margin:0;width:100%;box-sizing:border-box}
.invoice input,.invoice select{appearance:none;-webkit-appearance:none}
.invoice input[type=range]{appearance:auto;-webkit-appearance:auto;width:auto}
.invoice input::placeholder,.invoice textarea::placeholder{color:#aab3c2;font-weight:400;opacity:1}
.invoice textarea{display:block;resize:none;overflow:hidden;line-height:inherit}
.invoice input[type=date]{cursor:pointer}
.invoice select{cursor:pointer}
.invoice input[type=number]::-webkit-outer-spin-button,.invoice input[type=number]::-webkit-inner-spin-button{margin:0}
.invoice input[type=number]{-moz-appearance:textfield}
.metaText input,.metaText textarea{display:block;margin:1px 0}
.invtitle h2 input{text-align:right}
.invno{display:flex;align-items:baseline;justify-content:flex-end;gap:2px}
/* #invoiceNumber's actual on-screen width is set by JS (sizeInvoiceNumberInput
   in preview.js) — a plain text <input> has no CSS-only way to shrink-wrap
   its own value (width:auto/min-content/fit-content all fall back to the
   browser's ~20-character default box for text inputs, not the value's
   rendered length), which is exactly what used to leave a wide gap of empty
   input box between "#" and a short invoice number. This just sets a sane
   floor so the field never collapses to nothing while typing/empty. */
.invno input{width:3ch;min-width:3ch;text-align:right}
.hashprefix{flex:none}
.metatable td:first-child input{text-align:left}
.metatable td:last-child input{text-align:right;font-weight:700}
/* .balance's label ("Balance due") is a real <input> living inside
   .invtitle (text-align:right — correct for the invoice title/number/dates
   above it, which really are right-aligned) — the base ".invoice input{
   text-align:inherit}" rule was carrying that inherited right-alignment
   all the way down to this label too, so its text hugged the *right* edge
   of its own flex:1 span, landing right up against the amount with zero
   gap between them ("Balance due$0.00"). This label is conceptually a
   left-aligned caption for the amount next to it, not part of the
   right-aligned title block, so it gets its own explicit left alignment;
   the span still grows to fill the row (flex:1) so the amount stays
   pinned to the far right, but the label's text now sits at the *start*
   of that space instead of the end, opening up a real, natural gap that
   scales with however much room is left over — not a fixed width tied to
   one label length, one currency symbol, or one amount's digit count. */
.balance span{display:inline-flex;flex:1;text-align:left}
/* Belt-and-suspenders minimum: on the rare label+amount combination long
   enough to leave little/no leftover space for the above to work with, a
   real gap is still guaranteed here rather than relying purely on
   left-over flex space. */
.balance{gap:8px}
.sumrow span{display:flex;align-items:baseline;gap:4px}
/* input.pct-input/input.money-input (not just .pct-input/.money-input): the
   base ".invoice input,.invoice textarea,.invoice select{width:100%}" rule a
   few lines up is a class+type selector, specificity (0,1,1) — a bare class
   selector like ".pct-input" alone is only (0,1,0) and always loses that
   fight regardless of source order, which is exactly why Discount/Tax used
   to render ~139px wide (100% of their flex container) instead of the
   intended ~2.6em, crushing the "%" sign and the computed amount right up
   against each other with no visible gap. Matching specificity here (also
   0,1,1, but declared later, which wins CSS's tie-break) restores the
   narrow, fixed widths these two were always meant to have.*/
.invoice input.pct-input{width:3.2em;text-align:center;flex:none}
.invoice input.money-input{width:5.5em;text-align:right}
/* Hide the native number spin buttons on these two: at their intended
   narrow width the up/down arrows ate most of the box, leaving barely
   enough room for the digits themselves (e.g. "12.5" rendering clipped to
   "2.5"). The app already supplies its own "%"/currency-symbol affordance
   next to each field, so the spinner isn't needed — same treatment
   body.canvas-preview-mode already gave every number input, just not
   conditional on Preview here since these two never needed the spinner in
   Edit mode either. */
.invoice input.pct-input::-webkit-outer-spin-button,.invoice input.pct-input::-webkit-inner-spin-button,
.invoice input.money-input::-webkit-outer-spin-button,.invoice input.money-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.invoice input.pct-input,.invoice input.money-input{-moz-appearance:textfield}

/* Logo upload/height/position controls — not invoice content, so they're
   hidden from print/PDF (print.css) and from the Edit/Preview canvas
   switch's Preview mode (invoice.css, alongside every other print-only
   exclusion) the same way the old inline-edit affordances always were. */
.logoboxwrap{display:flex;flex-direction:column;align-items:flex-start;gap:5px;flex:none}
.logotools{display:flex;flex-wrap:wrap;align-items:center;gap:5px;max-width:200px}
body.canvas-preview-mode .logotools{display:none}

/* Logo settings — a single "Logo settings" trigger opens a compact,
   professional-editor-style property panel (same floating-panel pattern as
   the History/Templates/Import dropdowns in the main toolbar: see
   js/layout.js). The panel markup itself (#logoSettingsPanel) lives in
   #floatingLayer at the end of <body>, not nested under this trigger —
   see the comment on #floatingLayer in index.html for why. */
.logo-settings-dropdown{position:relative}
.logo-settings-trigger{display:inline-flex;align-items:center;gap:5px;font:700 9.5px/1 var(--font-modern,inherit);padding:5px 9px;border:1px solid #d7dde6;border-radius:7px;background:#fff;color:#475467;cursor:pointer;white-space:nowrap;box-shadow:var(--shadow-sm);transition:border-color .12s ease,box-shadow .12s ease,transform .12s ease}
.logo-settings-trigger .icon{width:12px;height:12px;margin:0}
.logo-settings-trigger:hover{border-color:#c2c9d6;box-shadow:var(--shadow-md);transform:translateY(-1px)}
.logo-settings-trigger[aria-expanded=true]{border-color:var(--app-accent);color:var(--app-accent)}
.logo-settings-panel{width:min(280px,calc(100vw - 32px));padding:13px}
.logo-settings-section{margin-bottom:12px}
.logo-settings-section:last-of-type{margin-bottom:0}
.logo-settings-section>label,.logo-settings-label-row label{display:block;font-size:10px;font-weight:850;text-transform:uppercase;letter-spacing:.04em;color:#475467;margin-bottom:6px}
.logo-settings-uploadrow{display:flex;gap:6px;align-items:center}
.logo-settings-uploadrow .btn{flex:1 1 auto}
.logo-settings-uploadrow .btn.icon{flex:none}
.logotools-hint{display:block;font-size:9.5px;color:#98a2b3;margin-top:6px;line-height:1.4}
/* Size — a slider + a synced number field (two ways to set the same exact
   value, the standard pairing in professional design/photo tools) plus a
   permanently-locked padlock indicator: only *height* is ever settable, and
   width always follows it automatically via the logo image's own
   object-fit:contain (see .logobox img below) rather than exposing an
   independent width control, so the logo can never be stretched out of
   proportion the way an unlocked W/H pair could be. */
.logo-settings-label-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.logo-settings-label-row label{margin-bottom:0}
.logo-lock-indicator{display:inline-flex;align-items:center;gap:3px;font-size:9px;font-weight:800;color:#3a8a5e;background:rgba(58,138,94,.1);border-radius:6px;padding:2px 6px 2px 5px;text-transform:uppercase;letter-spacing:.03em}
.logo-lock-indicator .icon{width:10px;height:10px;margin:0}
.logo-size-controls{display:flex;align-items:center;gap:8px}
.logo-size-controls input[type=range]{flex:1 1 auto;accent-color:var(--app-accent)}
.logo-size-number{display:flex;align-items:center;gap:3px;border:1px solid #d7dce5;border-radius:7px;padding:3px 3px 3px 7px;flex:none;background:#fff}
.logo-size-number input{width:34px;border:0;padding:0;font-size:11px;font-weight:700;color:var(--ink);text-align:right;min-height:0;background:transparent}
.logo-size-number input:focus{outline:0;box-shadow:none}
.logo-size-number span{font-size:9.5px;color:#98a2b3;padding-right:2px}
.logo-size-meta{display:block;font-size:9.5px;color:#98a2b3;margin-top:6px}
/* Position — a 3-way segmented control (visual twin of .canvasmode-switch
   in the main toolbar, for the same "toggle between mutually exclusive
   states" convention) drives the real #logoPosition <select> that the rest
   of the app (state.js/preview.js) already reads, so no data-layer change
   was needed to modernize this from a dropdown into buttons. */
.logo-position-switch{display:flex;gap:2px;background:#eef0f7;padding:3px;border-radius:9px}
.logo-position-btn{flex:1 1 0;border:0;background:transparent;border-radius:6px;padding:6px 4px;font-size:10.5px;font-weight:750;color:var(--muted);cursor:pointer;transition:background-color .15s ease,color .15s ease,box-shadow .15s ease}
.logo-position-btn.active{background:#fff;color:var(--app-accent);box-shadow:var(--shadow-sm)}
.logo-position-btn:not(.active):hover{color:var(--ink)}
.logo-settings-footer{display:flex;justify-content:flex-end;padding-top:2px}
.logo-settings-footer .btn{width:100%;justify-content:center}
/* Inline "+ Add item" control on the invoice canvas table (js/preview.js):
   a real, clickable way to add a line item right where an empty (or
   in-progress) items table naturally draws the eye, instead of only via
   the "+ Add item" button tucked away in the sidebar's Items tab. Editing
   chrome, not invoice content, so — same treatment as .logotools above —
   it disappears in Preview mode and print/PDF (print.css); the trailing
   "add another" row is hidden as a whole row there too (an empty bordered
   table row would otherwise print/preview as a stray blank strip), while
   the empty-state row keeps its "No line items added." text visible and
   only its button hidden, so that placeholder still reads correctly in
   Preview/print exactly as it always has. */
.add-item-btn{font:750 10.5px/1 var(--font,inherit);padding:6px 12px;margin-top:8px;border:1px dashed #b6bfcc;border-radius:6px;background:#fbfcfe;color:var(--app-accent);cursor:pointer;white-space:nowrap}
.add-item-btn:hover{background:#f2f4f7;border-color:#98a2b3}
.add-item-btn:focus-visible{outline:2px solid var(--app-accent);outline-offset:1px}
.add-item-row td{text-align:center;padding:8px 7px!important}
body.canvas-preview-mode .add-item-btn{display:none}
body.canvas-preview-mode .add-item-row{display:none}
/* Editable item cells + per-row remove button (js/preview.js, Edit mode
   only — Preview always falls back to plain formatted text, see
   isPreviewMode there). The inputs reuse the exact same "looks like plain
   invoice text" reset every other canvas field already gets from the base
   ".invoice input" rule above, so a line item reads identically whether
   it's an <input> (Edit) or plain text (Preview/print) — only .item-actions-col
   needs its own layout (a narrow, centered slot for the "×" button) since
   nothing else on the canvas has an equivalent trailing icon-only column. */
.item-actions-col{width:6%;text-align:center!important;padding:4px!important}
.item-remove-btn{width:22px;height:22px;line-height:1;border:1px solid #e4a5a0;border-radius:5px;background:#fff5f4;color:#b42318;font-size:13px;font-weight:700;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
.item-remove-btn:hover{background:#fef3f2;border-color:#d92d20}
.item-remove-btn:focus-visible{outline:2px solid #b42318;outline-offset:1px}
th.item-actions-col{background:transparent!important;border:0!important}
.statusbalance{margin-top:10px;display:flex;flex-direction:column;align-items:flex-start;gap:6px}.statusbalance .balance{margin-top:0;width:100%}
.billrow{margin:14px 0}.label{font-size:9px;text-transform:uppercase;letter-spacing:.08em;color:#667085;font-weight:850;margin-bottom:4px}.clientname{font-size:14px;font-weight:850;margin-bottom:3px}.status{display:inline-flex;flex:none;white-space:nowrap;text-align:center;padding:5px 22px 5px 9px;border-radius:999px;font-size:9.5px;font-weight:850;border:1px solid #abefc6;background-color:#ecfdf3;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;background-size:11px;color:#18794e}
/* Line-items table toolbar (Import CSV) — Edit mode only, sits directly
   above the table it acts on rather than in the whole-invoice toolbar
   above the canvas, so it reads as belonging to the table specifically.
   Purely editing chrome, never invoice content: hidden in Preview mode
   (below) and print (print.css), the same way .add-item-btn already is,
   so removing it takes zero layout space rather than collapsing to an
   empty gap. */
.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 0 6px;padding:0 1px}
.table-toolbar-title{font-size:9px;text-transform:uppercase;letter-spacing:.08em;color:#667085;font-weight:850}
body.canvas-preview-mode .table-toolbar{display:none}
.invtable{width:100%;border-collapse:collapse;table-layout:fixed;font-size:10px}.invtable th{padding:7px}.invtable th{text-transform:none;letter-spacing:.04em;font-size:8.5px;background:#f4f6f9;color:#344054;border:1px solid #cfd6e0;text-align:left}.invtable td{padding:7px;border:1px solid #d7dde6;vertical-align:top;overflow-wrap:anywhere}.invtable .right{text-align:right}.invtable .center{text-align:center}.empty{text-align:center;color:#667085;padding:18px!important}

/* Editable table-column headers (js/columnCanvas.js), Edit mode only —
   Preview/print keep the old plain <span class="col-label-text"> header
   (see preview.js), so none of this ever reaches Preview or print output;
   print.css also excludes it by class, belt-and-braces, the same way it
   already excludes .item-actions-col/.add-item-btn. Each header cell reuses
   the narrow 6%-wide slot math the per-row remove button already uses
   (padding-left for the drag grip, padding-right for the resize handle,
   both absolutely positioned so they never eat into the heading input's
   own width) instead of adding new columns to the table. */
.col-head-cell{position:relative;padding-left:16px!important;padding-right:8px!important;overflow:visible}
.col-drag-handle{position:absolute;left:1px;top:50%;transform:translateY(-50%);width:14px;height:18px;display:flex;align-items:center;justify-content:center;color:#98a2b3;cursor:grab;touch-action:none;border-radius:3px}
.col-drag-handle:hover{color:#667085;background:#e9ecf2}
.col-drag-handle:focus-visible{outline:2px solid var(--app-accent);outline-offset:1px}
.col-drag-handle .icon{width:12px;height:12px}
.col-head-cell.col-dragging{opacity:.45}
.col-head-row{display:flex;align-items:center;gap:2px;min-width:0}
.col-label-input{flex:1;min-width:0;font:inherit;color:inherit;letter-spacing:inherit;background:transparent;border:none;border-radius:2px;padding:1px 2px;text-transform:none}
.col-label-input:hover{background:rgba(16,24,40,.05)}
.col-label-input:focus{background:#fff;outline:2px solid var(--app-accent);outline-offset:0}
.col-menu-btn{flex:none;width:15px;height:15px;line-height:1;border:none;border-radius:3px;background:transparent;color:#667085;font-size:12px;font-weight:900;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
.col-menu-btn:hover,.col-menu-btn[aria-expanded="true"]{background:#e9ecf2;color:#344054}
.col-resize-handle{position:absolute;right:-3px;top:0;bottom:0;width:7px;cursor:col-resize;touch-action:none;z-index:1}
.col-resize-handle:hover,.col-resize-handle.resizing{background:rgba(var(--app-accent-rgb),.25)}
/* Trailing "+" header cell — the same reserved slot as .item-actions-col,
   just with a real control in the header row specifically. */
.col-actions-head{background:transparent!important;border:0!important}
.col-add-btn{width:20px;height:20px;line-height:1;border:1px dashed #b6bfcc;border-radius:5px;background:#fbfcfe;color:var(--app-accent);font-size:13px;font-weight:800;cursor:pointer;display:inline-flex;align-items:center;justify-content:center}
.col-add-btn:hover{background:#f2f4f7;border-color:#98a2b3}
.col-add-btn:focus-visible{outline:2px solid var(--app-accent);outline-offset:1px}
/* Drop indicator shown while dragging a header to reorder it — lives in
   #floatingLayer (position:fixed, viewport coordinates), the same place
   every other floating popover in the app lives, so it's never mis-placed
   by #invoice's own zoom transform (see the #floatingLayer comment in
   index.html) and always draws above the table regardless of scroll/zoom. */
.col-drop-indicator{display:none;position:fixed;width:3px;background:var(--app-accent);border-radius:2px;z-index:120;pointer-events:none}
/* Per-column "⋮" settings popover (js/columnCanvas.js) reuses the same
   .history-panel look as every other floating popover in the app. */
.col-settings-panel .field{margin-bottom:9px}
.col-settings-panel .field:last-of-type{margin-bottom:0}

.bottomgrid{display:grid;grid-template-columns:1fr 240px;gap:18px;margin-top:12px}.notebox{border:1px solid #d8dee7;border-radius:8px;padding:9px;background:#fbfcfe;min-height:72px}.summary{border-top:2px solid #344054;padding-top:5px}.sumrow{display:flex;justify-content:space-between;gap:14px;padding:3px 0;font-size:10.5px}.sumrow span:first-child{color:#667085}.sumrow.total{border-top:1px solid #d0d5dd;margin-top:3px;padding-top:7px;font-size:14px;font-weight:850}.paymentgrid{display:grid;grid-template-columns:1fr 1fr;gap:18px;border-top:1px solid #d9dee7;margin-top:14px;padding-top:11px}.footer{position:absolute;bottom:var(--footer-bottom,9mm);left:var(--footer-left,12mm);right:var(--footer-right,12mm);display:flex;justify-content:space-between;font-size:8.5px;color:#667085}
.invoice.notes-align-left .notebox,.invoice.notes-align-left .paymentgrid>div{text-align:left}
.invoice.notes-align-center .notebox,.invoice.notes-align-center .paymentgrid>div{text-align:center}
.invoice.notes-align-right .notebox,.invoice.notes-align-right .paymentgrid>div{text-align:right}

/* Multi-page preview — when an invoice's content is taller than one page, it
   used to be silently clipped on screen (Print/PDF already paginated fine).
   These dashed guides + "Page N" chips mark each page boundary so a
   multi-page invoice is visibly obvious in the live preview, matching what
   will actually print/export. Purely visual — inserted/removed by JS. */
.page-break-line{position:absolute;left:0;right:0;height:0;border-top:1.5px dashed #b8c0cc;pointer-events:none}
.page-break-chip{position:absolute;left:50%;transform:translate(-50%,-50%);background:#667085;color:#fff;font-size:9px;font-weight:800;letter-spacing:.03em;padding:2px 9px;border-radius:999px;white-space:nowrap;pointer-events:none}

