/* ===============================
   PORTAL — BUILD SPECIFICATION TOOL
   Page-specific styles for the logged-in Portal spec-sheet tool
   (partials/portal.php). Layout is adapted from the Spec Sheet
   prototype but restyled onto the site's existing theme variables
   and card/button visual language instead of its own palette.
   =============================== */

.spec-tool {
  margin-top: 24px;
}

.spec-view {
  display: none;
}

.spec-view.active {
  display: block;
}

/* Print-only masthead (logo + "Specification" badge) — matches the
   Corteq invoice template's header banner. Hidden on screen; shown in
   the @media print block below. */
.spec-print-header {
  display: none;
}

/* --- Shared: toolbars, status text --- */

.spec-toolbar,
.spec-detail-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}

.spec-toolbar h3 {
  margin: 0;
}

.spec-detail-status {
  color: var(--text-muted);
  font-size: 14px;
}

.spec-detail-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* --- Buttons --- */

.spec-ghost-btn {
  border: 1px solid var(--border-card);
  background: var(--bg-details);
  color: var(--text-body);
  padding: 9px 14px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 16px;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.spec-ghost-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.spec-danger {
  color: var(--accent-secondary);
  border-color: var(--accent-secondary);
}

.spec-danger:hover {
  background: var(--accent-secondary);
  color: #fff;
}

/* --- Build list --- */

.spec-empty {
  color: var(--text-muted);
  padding: 24px;
  text-align: center;
  border: 1px dashed var(--border-card);
  border-radius: 4px;
}

.spec-build-row-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.spec-sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.spec-sortable:hover {
  color: var(--accent);
}

.spec-sortable::after {
  display: inline-block;
  width: 1em;
  margin-left: 4px;
  content: "";
}

.spec-sortable.sort-asc::after {
  content: "\25B2";
}

.spec-sortable.sort-desc::after {
  content: "\25BC";
}

/* --- Build header (title / date) --- */

.spec-build-header {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  padding: 14px 16px;
  border-radius: 4px;
  border: 1px solid var(--border-card);
  background: var(--bg-details);
}

.spec-title-block {
  flex: 0 1 160px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Only Build title grows to fill extra space when the window is resized. */
.spec-title-block--wide {
  flex: 1 1 240px;
}

.spec-title-block--client {
  flex: 0 1 260px;
}

.spec-title-block--narrow {
  flex: 0 0 auto;
  width: 20ch;
}

/* Print-only: the "Construction Date" relabel for .spec-title-block's Date
   field, and the whole "Print date" block — both only make sense on the
   printed sheet, not the on-screen editor. Shown in the @media print
   block below. */
.spec-print-only-label,
.spec-print-only {
  display: none;
}

/* Matches the default (unhovered) colour of the expand/contract icon
   (.spec-links-toggle) so the calendar icon isn't invisible in dark mode. */
input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(61%);
  cursor: pointer;
}

.spec-field-label {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* --- Tabs --- */

.spec-tab-row {
  display: inline-flex;
  gap: 4px;
  background: var(--bg-page);
  padding: 4px;
  border-radius: 4px;
  margin-bottom: 16px;
  border: 1px solid var(--border-card);
}

.spec-tab {
  border: 0;
  background: transparent;
  color: var(--text-muted);
  padding: 8px 16px;
  border-radius: 3px;
  cursor: pointer;
  font-weight: 600;
  transition: background 0.18s ease, color 0.18s ease;
}

.spec-tab.active {
  background: var(--accent);
  color: var(--accent-text);
}

.spec-tab-panel {
  display: none;
}

.spec-tab-panel.active {
  display: block;
}

.spec-panel-toolbar {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.spec-panel-toolbar h4 {
  margin: 0 0 4px;
}

.spec-panel-toolbar p {
  margin: 0;
  color: var(--text-muted);
  font-size: 14px;
}

.spec-toolbar-actions {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* --- Diagnostics panel --- */

.spec-diagnostics-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.spec-diagnostics-toggle .fa {
  font-size: 13px;
  transition: transform 0.2s ease;
}

.spec-diagnostics-toggle[aria-expanded="true"] .fa {
  transform: rotate(180deg);
}

.spec-diagnostics-panel {
  border: 1px solid var(--border-card);
  border-radius: 4px;
  background: var(--bg-page);
  padding: 14px 16px;
  margin-bottom: 18px;
}

/* --- Spam log --- */

.spec-log-layout {
  display: flex;
  align-items: stretch;
  gap: 16px;
}

.spec-log-viewer {
  flex: 1 1 auto;
  min-width: 240px;
  max-height: 70vh;
  overflow: auto;
  margin: 0;
  border: 1px solid var(--border-card);
  border-radius: 4px;
  background: var(--bg-main);
  padding: 14px 16px;
  color: var(--text-body);
  font-family: monospace;
  font-size: 13px;
  white-space: pre-wrap;
  word-break: break-word;
}

.spec-log-chart-panel {
  /* Default/minimum width — js/portal-spec.js grows this (via inline
     flex-basis) when a chart needs more room than this to fit its bars
     without scrolling, taking that space from .spec-log-viewer above. */
  flex: 0 0 400px;
  min-width: 400px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-card);
  border-radius: 4px;
  background: var(--bg-main);
  padding: 14px 16px;
}

.spec-log-chart-title {
  margin: 0 0 10px;
  font-size: 15px;
  color: var(--text-body);
}

.spec-log-chart {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-x: auto;
}

.spec-log-chart-empty {
  margin: 0;
  color: var(--text-muted);
  font-size: 14px;
}

.spec-log-chart-bar {
  fill: var(--accent);
  /* The hit rect (same slot, full plot height) sits behind this and owns
     the tooltip/hover — pointer-events:none here so hovering the visible
     bar itself still resolves to the wider hit target beneath it. */
  pointer-events: none;
}

.spec-log-chart-hit {
  fill: transparent;
  cursor: default;
}

.spec-log-chart-hit:hover + .spec-log-chart-bar {
  opacity: 0.8;
}

.spec-log-chart-gridline {
  stroke: var(--border-card);
  stroke-width: 1;
}

.spec-log-chart-axis-label {
  fill: var(--text-muted);
  font-size: 9px;
  font-family: inherit;
}

.spec-log-chart-value-label {
  fill: var(--text-muted);
  font-size: 10px;
  font-family: inherit;
}

/* --- Table --- */

.spec-table-wrap {
  overflow-x: auto;
  border-radius: 4px;
  border: 1px solid var(--border-card);
  background: var(--bg-main);
}

.spec-table-wrap table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

/* table-layout:fixed + width:100% has nothing to size against without a
   min-width: the page's "page" panels are position:absolute with an auto
   width, so they shrink-to-fit their content, and a 100%-width table
   contributes nothing definite to that calculation on its own. Each table
   needs its own floor, sized to its own columns.
   Fixed columns (Product Type, MPN, Serial No., SKU, Cost, Links, delete)
   measure ~1056px combined (Serial No./SKU were widened to actually show
   ~15 characters, up from the ~946px baseline); the remaining ~44px floor
   is Product Name/Model's minimum before this kicks in and the table
   scrolls instead of compressing further — deliberately tight, since that
   space was reassigned to Serial No./SKU. Measured (not guessed) against
   the actual page chrome: at a 1920px-wide screen with the default page-
   stacking layout, .spec-table-wrap only has ~1122px available — this
   stays under that with margin. Previously 1500px, which didn't. */
#specHardwarePanel .spec-table-wrap table,
#specSoftwarePanel .spec-table-wrap table {
  min-width: 1100px;
}

#specListView .spec-table-wrap table {
  min-width: 1300px;
}

/* Manufacturer/Category code tables are just Code + Name — the 1300px
   list-view default (sized for the wider build/inventory tables above)
   would leave them absurdly stretched. */
#specInvManufacturerPanel .spec-table-wrap table,
#specInvCategoryPanel .spec-table-wrap table {
  min-width: 360px;
}

/* Fixed-width columns hold steady under resizing; the unset Product
   Name/Model column (.spec-col-flex) absorbs whatever space is left. */
.spec-col-20ch {
  width: 20ch;
}

.spec-col-15ch {
  width: 15ch;
}

.spec-col-mpn {
  width: calc(20ch + 50px);
}

/* Serial No. and SKU in the inventory tables — not the same width as the
   shared .spec-col-15ch (also used by the build list's Date column, which
   this must not affect). Sized like .spec-col-mpn (Nch + 50px overhead for
   the cell/input padding and border) so ~15 characters are actually
   visible, instead of the ~8 that calc(15ch - 5px) left room for. The
   extra width is taken from the flex Product Name/Model column, which
   absorbs whatever's left (see note above .spec-col-20ch). */
.spec-col-serial-sku {
  width: calc(15ch + 50px);
}

.spec-col-cost {
  width: calc(15ch - 10px);
}

/* "Hide Cost" toggle (spec-detail-actions button) — collapses the Cost
   column in both inventory tables without touching the underlying data,
   so cost stays saved even while hidden. Also respected when printing:
   whatever's visible on screen is what prints.
   width: 0 alongside visibility: collapse — collapse alone shrinks the
   table's overall width by the column's width instead of handing that
   space to the other columns (verified in-browser); giving the column an
   explicit 0 width makes table-layout: fixed redistribute its freed
   width to the unset Product Name/Model column (.spec-col-flex) so the
   row stays exactly as wide as it was with costs showing. */
#specDetailView.spec-hide-cost .spec-col-cost,
#specInventorySection.spec-hide-cost .spec-col-cost {
  visibility: collapse;
  width: 0;
}

.spec-col-150px {
  width: 150px;
}

.spec-col-252px {
  width: 252px;
}

.spec-col-actions {
  width: 170px;
}

.spec-col-links {
  width: 100px;
}

.spec-col-delete {
  width: 60px;
}

.spec-col-code {
  width: 90px;
}

/* Manufacturer/Category codes are always exactly 3 characters, stored and
   shown uppercase — text-transform is display-only, so js/portal-spec.js
   also uppercases the value itself on input rather than relying on this
   alone. */
.spec-code-input {
  text-transform: uppercase;
  text-align: center;
  letter-spacing: 1px;
}

.spec-table-wrap thead {
  background: var(--bg-page);
}

.spec-table-wrap th,
.spec-table-wrap td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-card);
  vertical-align: top;
}

/* The build list's rows are simple single-line text (unlike the inventory
   tables, which need top-alignment for their taller expanded-link rows),
   so centre them instead of letting them hug the top of the row. */
#specListView .spec-table-wrap td {
  vertical-align: middle;
}

/* Inventory item rows (Hardware/Software tables) — 2px smaller than the
   16px page default, inherited down into the row's inputs via
   `font: inherit`. Build list rows in #specListView are unaffected. */
#specHardwareRows,
#specSoftwareRows {
  font-size: 14px;
}

.spec-table-wrap th {
  text-align: left;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.spec-table-wrap tr:hover td {
  background: var(--bg-page);
}

.spec-tool input[type="text"],
.spec-tool input[type="date"],
.spec-tool input[type="url"],
.spec-tool select {
  width: 100%;
  border: 1px solid var(--border-card);
  background: var(--bg-main);
  color: var(--text-body);
  border-radius: 3px;
  padding: 8px 10px;
  font: inherit;
}

/* Hints the browser which built-in palette to draw native form-control
   chrome with — for <select>, that's the pop-open option list, which
   isn't reachable with background/color alone and otherwise defaults to
   a plain white list even in dark mode. */
.spec-tool select {
  color-scheme: light;
}

html.dark-mode .spec-tool select {
  color-scheme: dark;
}

.spec-tool input[data-field="cost"],
.spec-tool input[data-prod-field="cost"] {
  text-align: right;
}

.spec-tool input:focus,
.spec-tool select:focus {
  outline: none;
  border-color: var(--accent);
}

/* Inventory item rows (Hardware/Software tables) — drop each field's own
   border/radius/padding box so only the row's border-bottom (see
   ".spec-table-wrap th, .spec-table-wrap td" above) shows between rows,
   letting the cell's own padding be the only vertical spacing and the
   row sit shorter. Header build-detail fields and the expanded-links row
   keep their normal boxed inputs — only .spec-item-row is scoped here. */
.spec-item-row input[type="text"],
.spec-item-row select {
  border: none;
  border-radius: 0;
  padding: 0;
  background: transparent;
}

/* The Product Type <select> still needs an opaque background/text colour
   of its own (unlike the plain-text inputs above) — its closed box
   renders those styles directly, and modern Chromium/Edge carry them
   into the pop-open option list too, so "transparent" here left both
   white in dark mode. */
.spec-item-row select {
  background: var(--bg-main);
  color: var(--text-body);
}

.spec-item-row input[type="text"]:focus,
.spec-item-row select:focus {
  outline: 1px solid var(--accent);
  outline-offset: -1px;
}

/* Item rows only (not the taller expanded-links row, which needs the
   base top-alignment) — the row's height is set by its tallest field
   (the Product Type <select>, whose native rendering is taller than a
   text input's line box), so top-aligning left extra space under the
   shorter text fields. Centering evens that out. */
.spec-item-row td {
  vertical-align: middle;
}

/* Vertical separator between Product Type and the rest of the row's
   fields — the one exception to "no line between fields". */
.spec-item-row td:first-child {
  border-right: 1px solid var(--border-card);
}

/* Deliberately NOT display:flex — a table-cell with display:flex drops out
   of normal table row-height stretching, which is what made this column's
   border-bottom sit above the other columns'. vertical-align centers the
   buttons within the row height instead. Selector needs the extra
   ".spec-table-wrap td" specificity to beat the base td{vertical-align:top}
   rule above. */
.spec-table-wrap td.spec-links-cell {
  vertical-align: middle;
  white-space: nowrap;
}

.spec-links-toggle,
.spec-links-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 3px;
  background: var(--bg-list-item);
  color: #9b9b9b;
  font-size: 18px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.spec-links-toggle {
  margin-right: 6px;
}

.spec-links-toggle:hover,
.spec-links-toggle:focus,
.spec-links-add:hover,
.spec-links-add:focus {
  background: var(--accent);
  color: #fff;
}

.spec-links-row td {
  background: var(--bg-page);
}

.spec-links-row[hidden] {
  display: none;
}

.spec-link-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.spec-link-line {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Bootstrap ships "input[type=file]{display:block}", which outranks the
   browser's own [hidden] rule on specificity and makes the native file
   input render (and overlap neighbouring buttons) instead of staying
   hidden behind its styled <label>. This selector must outrank it. */
.spec-link-add input[type="file"] {
  display: none;
}

.spec-link-type {
  flex: 0 0 160px;
}

/* Inventory link rows only (not the Diagnostics panel, which reuses
   .spec-link-type/.spec-link-line but still has its upload button) — the
   per-line "add" button was removed since the item row's own add button
   does the same job, so its reclaimed width (32px button + 6px gap) goes
   to the pick list instead of the URL field. Keeps .spec-link-open/
   .spec-link-remove flush against the same right edge as before. */
.spec-link-line-item .spec-link-type {
  flex-basis: 198px;
}

.spec-link-url {
  flex: 1 1 auto;
  min-width: 200px;
}

.spec-diag-filename {
  flex: 1 1 auto;
  min-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-body);
}

.spec-diag-filename.is-empty {
  color: var(--text-muted);
  font-style: italic;
}

.spec-link-open,
.spec-link-remove,
.spec-link-add {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 3px;
  background: var(--bg-list-item);
  color: #9b9b9b;
  font-size: 16px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

.spec-link-open:hover,
.spec-link-open:focus,
.spec-link-add:hover,
.spec-link-add:focus {
  background: var(--accent);
  color: #fff;
}

.spec-link-remove:hover,
.spec-link-remove:focus {
  background: var(--accent-secondary);
  color: #fff;
}

.spec-link-open.is-empty {
  opacity: 0.5;
}

/* Extra ".spec-table-wrap td" specificity needed to beat the base
   td{vertical-align:top} rule above — see .spec-links-cell. */
.spec-table-wrap td.spec-delete-cell {
  vertical-align: middle;
}

.spec-row-delete {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--accent-secondary);
  cursor: pointer;
  font-size: 18px;
}

.spec-row-delete:hover {
  background: var(--accent-secondary);
  color: #fff;
}

/* --- "Add from inventory" picker (build Hardware/Software tabs) --- */

.spec-inventory-picker {
  /* Appended to <body> by js/portal-spec.js, which sets top/left inline
     from the trigger button's measured position — avoids depending on any
     ancestor's box layout for placement. */
  position: absolute;
  /* The pager (js/custom.js "topz") sets the active .page's z-index to
     500 during/after slide transitions, so this must clear that or the
     whole page paints over the picker. */
  z-index: 600;
  width: 640px;
  max-width: 90vw;
  border: 1px solid var(--border-card);
  border-radius: 4px;
  background: var(--bg-main);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  padding: 10px;
}

.spec-inventory-picker-filter {
  width: 100%;
  margin-bottom: 8px;
}

.spec-inventory-picker-list {
  max-height: 240px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.spec-inventory-picker-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  border: 0;
  border-radius: 3px;
  background: transparent;
  padding: 6px 8px;
  text-align: left;
  cursor: pointer;
}

.spec-inventory-picker-item:hover,
.spec-inventory-picker-item:focus {
  background: var(--bg-list-item);
}

.spec-inventory-picker-name {
  color: var(--text-body);
  font-weight: 600;
}

.spec-inventory-picker-meta {
  color: var(--text-muted);
  font-size: 12px;
}

.spec-inventory-picker-empty {
  margin: 6px 8px;
  color: var(--text-muted);
  font-size: 14px;
}

/* --- Login error message --- */

.login100-error {
  background: rgba(255, 118, 134, 0.12);
  border: 1px solid var(--accent-secondary);
  color: var(--accent-secondary);
  padding: 10px 14px;
  border-radius: 3px;
  margin-bottom: 20px;
  font-size: 14px;
}

/* ===============================
   MEDIA QUERIES
   =============================== */

@media (max-width: 860px) {
  .spec-detail-toolbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .spec-log-layout {
    flex-direction: column;
  }

  .spec-log-chart-panel {
    flex: 1 1 auto;
    width: 100%;
  }
}

/* --- Print (build detail → Print button / browser "Save as PDF") ---
   Prints only the currently-open build: Build title/Client/Serial/PC
   Name/Date, then Hardware and Software inventories showing Product
   Type, Product Name, MPN, Serial No., SKU and Cost (Cost only if the
   "Hide Cost" toggle hasn't collapsed it — see .spec-hide-cost above).
   Links and the row-delete column are never printed; neither is any
   other page chrome (sidebar, toolbars, tab switcher, action buttons).

   The portal is a single-page-app: #wrapper/main/#portal(.page)/.section
   are position:absolute with a fixed (viewport) height and overflow:auto
   for on-screen paging, and .pageheader/.portal-heading-row/#specListView
   sit ahead of #specDetailView in the DOM — visibility:hidden hides them
   but still reserves their layout box. Left alone that (a) clips printed
   output to one screenful, cutting off later sections, and (b) pushes
   #specDetailView down by the hidden banner/list's height, and (c) caps
   its width to the on-screen content column (sidebar + section padding
   already subtracted). All three are flattened below so #specDetailView
   prints as normal flow, full page width, from the top of the page. */
@media print {
  body * {
    visibility: hidden;
  }

  #specDetailView,
  #specDetailView * {
    visibility: visible;
  }

  .pageheader,
  .portal-heading-row,
  #specListView {
    display: none !important;
  }

  /* html/body themselves are the outermost clipping box (height:100%,
     overflow:hidden — see global.css) — the SPA never scrolls the page,
     only .page panels scroll internally. Left as-is, anything taller than
     one screen's worth of #specDetailView content is clipped outright
     rather than flowing to a second printed page, regardless of what's
     reset further down the chain. */
  html,
  body,
  #wrapper,
  main,
  #portal,
  #portal .pagecontents,
  #portal .section,
  #portal .section-container {
    position: static !important;
    width: auto !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: visible !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  #specDetailView {
    position: static !important;
    width: 100% !important;
  }

  #specTool {
    margin-top: 0 !important;
  }

  /* Masthead — matches the Corteq invoice template: wordmark top-left in
     the same "Corteq" logo font and colour used on screen (.logo-text
     uses var(--accent) too — see global.css), theme-accent "Specification"
     badge top-right in a rounded box, mirroring the invoice's "TAX
     INVOICE" badge. Printing strips background-color/box-shadow by
     default unless the page opts in — color-adjust below is what makes
     the badge/column-heading fills actually appear on paper. */
  #specDetailView * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .spec-print-header {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
  }

  .spec-print-logo {
    font-family: "Corteq", sans-serif;
    font-size: 30px;
    letter-spacing: 1px;
    color: var(--accent) !important;
  }

  .spec-print-badge {
    background: var(--accent) !important;
    color: var(--accent-text) !important;
    font-size: 13px;
    font-weight: bold;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    /* +5mm each side = 10mm wider overall than the text's natural fit. */
    padding: 8px calc(18px + 5mm);
    border-radius: 6px;
  }

  /* Build info box: 3 columns, flush left, no per-block indent —
     Build Title/Serial No., Client/PC Name, Construction Date/Print date.
     Placed by grid position rather than DOM order (the DOM keeps the
     on-screen field order intact for the editor). */
  .spec-build-header {
    display: grid !important;
    grid-template-columns: repeat(3, 1fr) !important;
    column-gap: 24px;
    row-gap: 10px;
  }

  .spec-title-block {
    width: auto !important;
    flex: none !important;
    padding-left: 0 !important;
    margin-left: 0 !important;
  }

  .spec-title-block:nth-child(1) {
    grid-column: 1;
    grid-row: 1;
  }

  .spec-title-block:nth-child(2) {
    grid-column: 2;
    grid-row: 1;
  }

  .spec-title-block:nth-child(3) {
    grid-column: 1;
    grid-row: 2;
  }

  .spec-title-block:nth-child(4) {
    grid-column: 2;
    grid-row: 2;
  }

  .spec-title-block:nth-child(5) {
    grid-column: 3;
    grid-row: 1;
  }

  .spec-title-block:nth-child(6) {
    grid-column: 3;
    grid-row: 2;
  }

  .spec-build-header label[for="specBuildDate"] {
    display: none !important;
  }

  /* Bootstrap's unscoped `label{font-weight:700}` rule is what makes
     BUILD TITLE/CLIENT/etc. look bold — this replacement is a <span>. not
     a <label>, so it doesn't inherit that rule and printed lighter than
     its neighbours without this. */
  .spec-print-only-label {
    display: block !important;
    font-weight: 700;
  }

  /* Chrome's native date-input chrome (calendar icon, spin buttons)
     survives the general #specDetailView input reset below — appearance
     resets the border/background but not these sub-controls — and prints
     as a small empty box under the value. Strip them specifically. */
  #specDetailView input[type="date"]::-webkit-calendar-picker-indicator,
  #specDetailView input[type="date"]::-webkit-inner-spin-button,
  #specDetailView input[type="date"]::-webkit-clear-button {
    display: none !important;
  }

  .spec-print-only {
    display: flex !important;
    flex-direction: column;
    gap: 6px;
  }

  /* Print date's value is plain text, not an input like its siblings —
     match the 9px the #specDetailView input/select rule below gives them. */
  .spec-print-only span:not(.spec-field-label) {
    font-size: 9px;
  }

  .spec-detail-toolbar,
  .spec-tab-row,
  .spec-panel-toolbar .spec-toolbar-actions,
  .spec-links-row {
    display: none !important;
  }

  .spec-tab-panel {
    display: block !important;
  }

  .spec-col-links,
  .spec-col-delete {
    visibility: collapse !important;
    width: 0 !important;
  }

  /* Fixed layout with explicit percentage widths, rather than the
     on-screen ch-based colgroup (sized for a ~1100px-wide screen table),
     so Product Type/MPN/Serial No./SKU/Cost stay readable instead of
     being crushed to fit a portrait page, and the six visible columns
     always add up to exactly the page width. Product Name/Model
     (.spec-col-flex, left unset here as on screen) absorbs the rest. */
  #specHardwarePanel .spec-col-20ch,
  #specSoftwarePanel .spec-col-20ch {
    width: 15% !important;
  }

  #specHardwarePanel .spec-col-mpn,
  #specSoftwarePanel .spec-col-mpn {
    width: 18% !important;
  }

  #specHardwarePanel .spec-col-serial-sku,
  #specSoftwarePanel .spec-col-serial-sku {
    width: 16% !important;
  }

  #specHardwarePanel .spec-col-cost,
  #specSoftwarePanel .spec-col-cost {
    width: 8% !important;
  }

  /* When "Hide Cost" is on, the non-print rule above (.spec-hide-cost
     .spec-col-cost) already sets width: 0 so table-layout: fixed hands
     the freed space to Product Name/Model instead of Chrome just
     shrinking the table by the collapsed column's width — see that
     rule's comment. The 8% print override above (needed for when Cost
     IS shown) has !important and would otherwise beat it, leaving an
     unused 8%-wide gap on the right of the page. Higher specificity
     restores it whenever printing with costs hidden. */
  #specDetailView.spec-hide-cost .spec-col-cost {
    width: 0 !important;
  }

  .spec-table-wrap {
    overflow: visible !important;
    border: none !important;
  }

  .spec-table-wrap table {
    min-width: 0 !important;
    width: 100% !important;
    table-layout: fixed !important;
  }

  /* On screen, th/td get 10px/12px padding and 12-14px text sized for a
     1100px-wide table — on a portrait page that padding alone eats a
     large share of the available width. Both are cut down here so the
     field values (not whitespace) get the extra room the wider columns
     above free up. Headers also get to wrap instead of the fixed-width
     nowrap column overlapping its neighbour ("Product Type" bleeding
     into "Product Name/Model" at the old, narrower width). */
  .spec-table-wrap th,
  .spec-table-wrap td {
    padding: 3px 4px !important;
    font-size: 9px !important;
  }

  .spec-table-wrap th {
    white-space: normal !important;
    letter-spacing: 0.02em !important;
    vertical-align: middle !important;
  }

  /* Column title band — same theme accent as the masthead badge and the
     invoice template's table header row. */
  .spec-table-wrap thead {
    background: var(--accent) !important;
  }

  .spec-table-wrap thead th {
    color: var(--accent-text) !important;
  }

  .spec-table-wrap tr {
    page-break-inside: avoid;
  }

  .spec-table-wrap thead {
    display: table-header-group;
  }

  .spec-table-wrap tfoot {
    display: table-footer-group;
  }

  #specDetailView input,
  #specDetailView select {
    border: none !important;
    background: transparent !important;
    padding: 0 1px !important;
    font-size: 9px !important;
    color: #000 !important;
    -webkit-appearance: none;
    appearance: none;
  }

  @page {
    size: portrait;
    margin: 1.2cm 1.2cm 1.5cm 1.2cm;
  }
}
