* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; font-family: Tahoma, Arial, sans-serif; font-size: 13px; color: #222; }

.lp-app { display: flex; height: 100vh; }

/* LEFT — tree */
.lp-tree { width: 300px; flex: 0 0 300px; border-right: 1px solid #ddd; display: flex; flex-direction: column; }
.lp-search { padding: 8px; border-bottom: 1px solid #eee; }
.lp-search input { width: 100%; padding: 6px 8px; border: 1px solid #ccc; border-radius: 4px; }
.lp-tree-body { overflow: auto; padding: 6px 4px; flex: 1; }
.lp-node { padding: 3px 4px; display: flex; align-items: center; gap: 6px; cursor: default; }
.lp-node input { margin: 0; }
.lp-node.lp-model { font-weight: bold; }
.lp-node.lp-sheet { padding-left: 8px; font-weight: 600; }
.lp-node.lp-sheet > span:last-child { cursor: pointer; }
.lp-node.lp-part { padding-left: 26px; color: #444; }
/* Part name is clickable — it scrolls the preview to that part's card. */
.lp-node.lp-part .lp-part-name { cursor: pointer; }
.lp-node.lp-part .lp-part-name:hover { color: #0a7d46; text-decoration: underline; }
/* Note sits at sheet level: lp-sheet supplies the 8px indent; keep colour only
   and don't inherit the sheet name's pointer cursor (note isn't collapsible). */
.lp-node.lp-note-node { font-weight: 600; color: #2b6cb0; cursor: default; }
.lp-node.lp-note-node > span:last-child { cursor: default; }
.lp-note-icon { font-size: 12px; }
.lp-caret { width: 12px; display: inline-block; cursor: pointer; color: #888; text-align: center; user-select: none; }
.lp-caret-spacer { width: 12px; display: inline-block; flex-shrink: 0; }

/* MIDDLE — preview */
.lp-preview { flex: 1; overflow: auto; background: #8a8a8a; padding: 16px; display: flex; flex-wrap: wrap; gap: 14px; align-content: flex-start; }
.lp-card {
  width: var(--cw, 320px); height: var(--ch, 210px);
  background: #fff; border: 1px solid #000;
  position: relative; overflow: hidden;
}
/* Content authored portrait (short side = card height, long side = card
   width) then rotated 90° to fill the landscape label. */
.lp-card-inner {
  position: absolute; top: 50%; left: 50%;
  width: var(--ch, 210px); height: var(--cw, 320px);
  transform: translate(-50%, -50%) rotate(90deg);
  transform-origin: center center;
  padding: 4px; box-sizing: border-box;
  display: flex; flex-direction: column; overflow: hidden;
}
.lp-head-row { flex: 0 0 auto; display: flex; justify-content: flex-start;
  align-items: flex-start; gap: 6px; }
.lp-card-head { display: flex; flex-direction: column; align-items: flex-start;
  text-align: left; flex: 1 1 auto; min-width: 0; overflow: hidden; }
/* Brand name above the title: bold and 1px larger than the title line. */
.lp-brand { font-weight: bold; font-size: 14px; letter-spacing: 1px; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-card-top { display: flex; justify-content: flex-start; align-items: flex-start; min-width: 0; max-width: 100%; }
.lp-index { background: #000; color: #fff; font-weight: bold; padding: 2px 8px; font-size: 15px; }
/* Break a long unspaced title (URL) across lines instead of overflowing. */
.lp-logo { font-weight: bold; letter-spacing: 1px; padding: 0 4px; font-size: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; display: block; }
.lp-title { font-weight: bold; margin-top: 6px; }
.lp-part-name-line { margin-top: 2px; font-size: 12px; font-weight: bold; max-width: 100%;
  white-space: normal; overflow-wrap: anywhere; word-break: break-word; }
.lp-body { flex: 1 1 0; min-height: 0; display: flex; flex-direction: row;
  align-items: stretch; gap: 2px; }
.lp-body-main { flex: 1 1 0; min-width: 0; min-height: 0; display: flex;
  flex-direction: column; }
.lp-side { flex: 0 0 1.15em; display: flex; align-items: center; justify-content: center;
  overflow: hidden; min-height: 0; }
.lp-side-dim { flex: 0 0 1.4em; }
.lp-side-text {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  max-height: 100%;
  max-width: 100%;
  box-sizing: border-box;
  font-size: 11px;
  line-height: 1.15;
  text-align: center;
}
.lp-side-mat .lp-side-text { font-weight: normal; white-space: nowrap; }
.lp-side-dim .lp-side-text { font-weight: bold; white-space: nowrap; }
.lp-bandline { flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  gap: 6px; margin: 0; }
.lp-bands { font-size: 11px; text-align: center; }
.lp-band { white-space: nowrap; }
.lp-shape { flex: 1 1 0; display: flex; align-items: stretch; justify-content: stretch;
  margin: 0; min-height: 0; width: 100%; }
.lp-outline-svg { width: 100%; height: 100%; display: block; flex: 1 1 auto; min-height: 0; }
.lp-bottom { flex: 0 0 auto; margin-top: 6px; border-top: 1px solid #ccc; padding-top: 4px;
  display: flex; flex-direction: row; align-items: stretch; gap: 3px; }
.lp-sheet-ids { flex: 0 0 1.6em; display: flex; flex-direction: column;
  justify-content: space-evenly; align-items: center; overflow: visible; }
.lp-sheet-id, .lp-part-id {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  transform: rotate(-90deg);
  transform-origin: center center;
  white-space: nowrap;
  font-size: 12px;
  font-weight: bold;
  line-height: 1.2;
  padding: 1px 6px;
  min-width: 2.4em;
  min-height: 1.35em;
}
.lp-sheet-id { color: #000; border: 1px solid #000; background: #fff; }
.lp-part-id { background: #000; color: #fff; border: 1px solid #000; }
.lp-thumb { flex: 1 1 auto; min-width: 0; }
.lp-sheet-svg { width: 100%; height: auto; display: block; }
/* Strokes use user-unit widths that SCALE with the SVG — NOT
   vector-effect:non-scaling-stroke, which the Chromium/CEF print rasteriser
   renders DOUBLED (one solid + one dashed overlay). The part outline has a fixed
   100×60 viewBox, so a constant width is fine here; the sheet preview's viewBox is
   mm-sized, so its width is set inline in JS (lpSheetThumbnailSvg), proportional
   to the sheet. */
.lp-outline-svg polygon { fill: none; stroke: #000; stroke-width: 0.7; }
/* Interior holes: drawn as inner outlines (no fill) on the part preview. */
.lp-outline-svg .lp-outline-hole { fill: none; stroke: #000; stroke-width: 0.7; }
.lp-outline-svg .lp-marker-line { fill: none; stroke: #c0392b; stroke-width: 0.4; }
.lp-outline-svg .lp-marker-area { fill: rgba(192,57,43,0.25); stroke: #c0392b; stroke-width: 0.4; }
.lp-band-num { fill: #000; font-weight: bold; text-anchor: middle; dominant-baseline: central; font-family: Tahoma, Arial, sans-serif; }
.lp-sheet-bg { fill: #fff; stroke: #000; }
.lp-sheet-part { fill: none; stroke: #666; }
.lp-sheet-part-hl { fill: #000; stroke: #000; }
/* Part holes on the sheet thumbnail: white knockout so they read as cut-throughs
   on the filled (highlighted) part, with a thin outline on the others. */
.lp-sheet-hole { fill: #fff; stroke: #666; }
.lp-qrs { display: flex; gap: 6px; }
.lp-qr { width: 40px; height: 40px; border: 1px solid #bbb; position: relative;
  overflow: hidden; font-size: 9px; color: #888; flex: 0 0 40px; }
.lp-qr canvas, .lp-qr img, .lp-qr table { width: 100% !important; height: 100% !important;
  display: block; max-width: 100%; max-height: 100%; }
.lp-empty { color: #eee; padding: 24px; }
/* Brief highlight when a card is jumped-to from the left list. */
.lp-card.lp-card-flash { outline: 3px solid #0a7d46; outline-offset: 2px; transition: outline-color 0.3s ease; }
.lp-note-sub { font-size: 12px; color: #333; margin-top: 4px; }
.lp-note-bands { margin-top: 10px; font-size: 12px; }
.lp-note-row { padding: 2px 0; border-bottom: 1px solid #ccc; }

/* RIGHT — settings */
.lp-settings { width: 320px; flex: 0 0 320px; border-left: 1px solid #ddd; padding: 12px; overflow: auto; }
.lp-hint { color: #666; font-size: 11px; text-align: center; }
.lp-actions { display: flex; gap: 10px; justify-content: center; margin: 10px 0 16px; }
.lp-btn { padding: 8px 22px; border: 1px solid #aaa; background: #f4f4f4; border-radius: 4px; cursor: pointer; }
.lp-btn:hover { background: #e9e9e9; }
.lp-btn-save { background: #0a7d46; color: #fff; border-color: #0a7d46; }
.lp-btn-save:hover { background: #096b3c; }
.lp-save-status { align-self: center; color: #0a7d46; font-size: 12px; }
.lp-section { border-top: 1px solid #eee; padding-top: 10px; margin-top: 10px; }
.lp-section-head { font-weight: bold; margin-bottom: 8px; }
.lp-input, .lp-select { width: 100%; padding: 6px 8px; border: 1px solid #ccc; border-radius: 4px; margin-bottom: 8px; }
.lp-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.lp-label { width: 70px; flex: 0 0 70px; color: #444; }
.lp-sub { color: #666; }
.lp-sub-r { margin-left: 78px; }
.lp-num { width: 70px; padding: 5px 6px; border: 1px solid #ccc; border-radius: 4px; }
.lp-qr-opts { display: flex; flex-direction: column; gap: 4px; }
.lp-qr-opts label { display: flex; align-items: center; gap: 6px; }

/* PRINT — VECTOR (sharp), one label per page. The on-screen card rotates its
   inner 90° (absolute + transform) to show a landscape preview; that rotation is
   what the print engine fragments (1 label spilling onto 2-3 sheets, wrong
   ratios). So for print we DROP the rotation and print the label in its authored
   PORTRAIT orientation — a normal-flow box that prints cleanly as one page. The
   page is portrait (W/H swapped); set the printer driver to rotate 90° if the
   label feeds landscape. */
@media print {
  @page { size: var(--lp-h, 38mm) var(--lp-w, 58mm); margin: 0; }
  html, body { margin: 0; padding: 0; }
  .lp-tree, .lp-settings { display: none !important; }
  .lp-app { display: block; }
  .lp-preview { display: block; background: #fff; padding: 0; gap: 0; }
  .lp-card {
    width: var(--lp-h, 38mm); height: var(--lp-w, 58mm); /* portrait page */
    border: none; overflow: hidden;
    page-break-after: always; break-after: page;
    page-break-inside: avoid; break-inside: avoid;
  }
  .lp-card:last-child { page-break-after: avoid; break-after: avoid; }
  /* Un-rotate: normal flow at the portrait size — no transform/absolute, so the
     print engine lays it out as exactly one page. */
  .lp-card-inner {
    position: static; transform: none; top: auto; left: auto;
    width: var(--lp-h, 38mm); height: var(--lp-w, 58mm);
    overflow: hidden;
  }

  /* Printed-tem proportions (user 2026-06-25) — applied to the PRINT ONLY, the
     on-screen preview keeps its normal sizes: text ~2/3, QR ~1/3, part shape
     dominant (~5x), sheet diagram bigger (~1.5x), sheet index a filled badge. */
  .lp-brand { max-width: 100%; }
  .lp-index { padding: 1px 5px; font-size: 10px; }
  .lp-logo { max-width: 100%; }
  .lp-part-name-line { font-size: 8px; }
  .lp-side-text { font-size: 8px; }
  .lp-side-dim { flex-basis: 1.2em; }
  .lp-bands { margin-top: 3px; font-size: 7px; }
  .lp-qr { width: 34px; height: 34px; }
  .lp-shape { flex: 1 1 0; margin: 0; }
  .lp-body { flex: 1 1 0; min-height: 0; }
  .lp-bottom { flex: 0 0 auto; margin-top: 3px; padding-top: 3px; }
  .lp-thumb { aspect-ratio: auto; }
  .lp-sheet-id, .lp-part-id { font-size: 9px; padding: 1px 4px; min-width: 2.2em; }
  /* Browsers DROP background colours when printing by default — force them so the
     index badges print filled black with white text (like the on-screen preview). */
  .lp-card { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  /* PURE BLACK, not grey: a printer renders grey with a halftone DOT pattern, so
     thin grey lines print as dots. Pure #000 prints solid. */
  .lp-sheet-part, .lp-sheet-hole { stroke: #000; }
  .lp-outline-svg .lp-marker-line { stroke: #000; fill: none; stroke-width: 0.35; }
  .lp-outline-svg .lp-marker-area { stroke: #000; fill: #000; fill-opacity: 0.2; stroke-width: 0.35; }
  /* Drop the CSS divider on the printout: it sits right on top of the sheet
     preview's own (black) top frame, so the two render as a DOUBLED line. The
     sheet frame alone is the section separator → one clean line. */
  .lp-bottom { border-top: none; }
  /* Pure black text (the base body colour is #222) so small print type prints
     solid instead of thin / broken; the ID badges keep their own white-on-black. */
  .lp-card-inner { color: #000; }
}
