:root {
  --primary: #2563eb;
  --bg: #f4f6fb;
  --card-bg: #ffffff;
  --border: #e2e6ee;
  --text: #1b2333;
  --muted: #667085;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
}

.topbar {
  background: var(--primary);
  color: white;
  padding: 20px 32px;
}
.topbar-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.topbar h1 { margin: 0 0 4px; font-size: 22px; }
.topbar p { margin: 0; opacity: 0.9; font-size: 14px; }
.lang-buttons {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
.lang-btn {
  background: rgba(255,255,255,0.15);
  color: white;
  border: 1px solid rgba(255,255,255,0.4);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
}
.lang-btn:hover { background: rgba(255,255,255,0.25); }
.lang-btn.active {
  background: white;
  color: var(--primary);
  border-color: white;
  font-weight: 600;
}

/* Tab bar. Sits directly under the blue header so the two pages read as one app rather than two
   separate screens, and matches the header's own max width. */
.tabbar {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 16px;
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
}
.tab-btn {
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  padding: 12px 18px;
  margin-bottom: -1px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}
.tab-btn:hover { color: var(--text); }
.tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); }
main[hidden] { display: none; }

.docs-intro { margin: 0 0 14px; font-size: 13px; color: var(--muted); }
.docs-empty { font-size: 13px; color: var(--muted); }
.docs-list { display: flex; flex-direction: column; gap: 8px; }
.doc-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border); border-radius: 8px;
  background: white;
}
.doc-row:hover { border-color: var(--primary); }
.doc-icon { font-size: 22px; flex-shrink: 0; }
.doc-info { flex: 1; min-width: 0; }
.doc-name { font-size: 14px; font-weight: 600; word-break: break-word; }
.doc-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
.doc-actions { display: flex; gap: 8px; flex-shrink: 0; }
.doc-actions .secondary-btn, .doc-actions .primary-btn {
  font-size: 13px; padding: 7px 14px; text-decoration: none; display: inline-block;
}

.doc-viewer-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 10px;
}
.doc-viewer-actions { display: flex; align-items: center; gap: 12px; }
.doc-viewer-frame { width: 100%; height: 75vh; border: 1px solid var(--border); border-radius: 6px; background: white; }
.doc-viewer-text {
  max-height: 75vh; overflow: auto; margin: 0;
  padding: 16px; border: 1px solid var(--border); border-radius: 6px; background: #fbfbfc;
  font-family: "Consolas", "Courier New", monospace; font-size: 13px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
}
.doc-viewer-img { max-width: 100%; border: 1px solid var(--border); border-radius: 6px; }

main {
  /* Widened from 1000px so the type filter's 13 TOP chips fit one row without that block having
     to break out of the card on its own - which looked like a layout bug. Everything on the page
     gets the extra room together: dropzone, match results and the items table all read better
     wide, since the variant column is long text. */
  max-width: 1400px;
  margin: 24px auto;
  padding: 0 16px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
}

.dropzone {
  border: 2px dashed var(--border);
  border-radius: 8px;
  padding: 24px;
  text-align: center;
  cursor: pointer;
  margin-bottom: 16px;
}
.dropzone.dragover { border-color: var(--primary); background: #eef2ff; }
.dropzone-hint { margin: 6px 0 0; font-size: 12px; color: var(--muted); }
/* Flashes when a pasted screenshot lands, so it is obvious the paste was picked up - without it
   a paste looks like nothing happened until you notice the thumbnail. */
.dropzone.pasted { border-color: #12b76a; background: #ecfdf3; }
.dropzone img { max-width: 220px; max-height: 220px; margin-top: 12px; border-radius: 6px; }
.pdf-badge {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 12px;
  padding: 8px 14px; border-radius: 6px; background: #eef2ff; border: 1px solid var(--border);
  font-size: 13px; color: var(--text);
}

.match-filter-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.match-filter-row label { font-size: 13px; color: var(--muted); }
.match-filter-row .meta-select { max-width: 260px; }
.match-filter-row-tiles { margin-bottom: 4px; }

/* Garment types sit in labelled bands (Top / Bottom / One-Piece / Accessory) as a two-column
   grid: the group name in a max-content column, its chips wrapping in the rest. Replaces a fixed
   10-column grid of equal cells, which stretched "All" as wide as "Pants/Trousers" and gave 30
   identical boxes with nothing to scan by. Chips shrink to their own text. */
.type-tiles {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 10px;
  align-items: start;
  margin-bottom: 10px;
}
/* An explicit display beats [hidden]'s own display:none, so the dropdown mode needs this to
   actually hide the board (same reason .modal[hidden] exists below). */
.type-tiles[hidden] { display: none; }
.type-band-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 7px;
  white-space: nowrap;
}
/* Every band shares one column track, so all cells are the same width and line up in columns
   down the whole board. auto-FILL (not auto-fit) is essential: auto-fit collapses the tracks a
   short band leaves empty and stretches its chips wider, which would knock the bands out of
   alignment. 88px resolves to the 13 columns TOP needs for a single row at the page's full
   width, with room to spare for the longest name ("Swim Cover Up"). */
.type-band-chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 3px;
}
.type-tile {
  /* Ellipsis + the title attribute are the safety net if a narrow window or a browser zoom
     squeezes a cell below its text. */
  padding: 4px 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: white;
  cursor: pointer;
  font-family: inherit;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text);
  white-space: nowrap;
  text-align: center;
}
.type-mode-btn { font-size: 11px; text-decoration: none; margin-left: auto; }

/* Type-to-filter box used in compact mode instead of a plain <select>. */
.type-combo { position: relative; }
.type-combo[hidden] { display: none; }
.type-combo-input { width: 220px; max-width: 260px; color: var(--text); background: white; cursor: text; }
.type-combo-list {
  position: absolute; top: calc(100% + 2px); left: 0; z-index: 50;
  min-width: 100%; max-height: 300px; overflow-y: auto;
  margin: 0; padding: 4px 0; list-style: none;
  background: white; border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 6px 18px rgba(27, 35, 51, 0.14);
}
.type-combo-list[hidden] { display: none; }
.type-combo-item { padding: 5px 10px; font-size: 13px; color: var(--text); cursor: pointer; white-space: nowrap; }
.type-combo-item.selected { font-weight: 600; }
.type-combo-item.active { background: var(--primary); color: white; }
.type-combo-item mark { background: #fde68a; color: inherit; padding: 0; border-radius: 2px; }
.type-combo-item.active mark { background: rgba(255, 255, 255, 0.3); }
.type-combo-empty { padding: 6px 10px; font-size: 12px; color: var(--muted); font-style: italic; }
/* The "All" chip rides on the label row, outside any band, so it keeps its own snug padding. */
#matchTypeAllSlot .type-tile { padding: 4px 10px; }
.type-tile:hover { border-color: var(--primary); background: #eef2ff; }
.type-tile.active { border-color: var(--primary); background: var(--primary); color: white; font-weight: 600; }

/* Save result, shown in place instead of a browser alert the user has to dismiss: green when the
   template was written, red when it wasn't, so the outcome is obvious at a glance. */
/* Floats at the top of the window rather than sitting under the buttons, where it was easy to
   miss - saving happens from the bottom of a long page, so an inline message stayed off-screen. */
.save-notice {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  max-width: min(680px, calc(100vw - 32px));
  padding: 12px 18px;
  border-radius: 10px;
  border: 1px solid;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  text-align: center;
  box-shadow: 0 8px 24px rgba(16, 24, 40, 0.18);
  animation: save-notice-in 0.18s ease-out;
}
.save-notice[hidden] { display: none; }
@keyframes save-notice-in {
  from { opacity: 0; transform: translate(-50%, -10px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
.save-notice.ok { background: #ecfdf3; border-color: #12b76a; color: #05603a; }
.save-notice.err { background: #fef3f2; border-color: #f04438; color: #912018; }

.link-btn {
  background: none;
  border: none;
  color: var(--primary);
  cursor: pointer;
  text-decoration: underline;
  font-size: inherit;
  padding: 0;
}

.primary-btn {
  background: var(--primary);
  color: white;
  border: none;
  padding: 10px 18px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}
.primary-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.primary-btn:hover:not(:disabled) { background: #1d4ed8; }

.grid {
  display: grid;
  /* auto-FIT, not auto-fill: a page of results is 5 cards, and on the now-wider page auto-fill
     would keep ~8 empty tracks, leaving the 5 cards squeezed to 140px against the left edge with
     a large gap on the right. auto-fit drops the empty tracks so the cards share the full row. */
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}
.matches-grid-wrap { position: relative; padding: 0 44px; }
.matches-side-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: white;
  color: var(--primary);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}
.matches-side-nav:hover:not(:disabled) { background: #eef2ff; }
.matches-side-nav:disabled { opacity: 0.35; cursor: not-allowed; }
.matches-side-nav-left { left: 0; }
.matches-side-nav-right { right: 0; }
.matches-page-label { text-align: center; font-size: 13px; color: var(--muted); margin-top: 12px; }
.match-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
  cursor: pointer;
  text-align: center;
  transition: box-shadow 0.15s, border-color 0.15s;
}
.match-card:hover { border-color: var(--primary); box-shadow: 0 2px 8px rgba(37,99,235,0.15); }
.match-card img { width: 100%; height: 220px; object-fit: contain; background: var(--bg); border-radius: 6px; margin-bottom: 6px; }
.match-card .mname { font-size: 12px; font-weight: 600; }
.match-card .mmeta { font-size: 11px; color: var(--muted); }
.match-card .mfacts {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 8px;
  margin-top: 5px; font-size: 11px;
}
.match-card .mstyle { color: var(--text); font-weight: 600; }
.match-card .msmv {
  color: #05603a; background: #ecfdf3; border: 1px solid #abefc6;
  border-radius: 999px; padding: 0 7px; font-weight: 600;
}
.match-card .mscore { font-size: 10px; color: var(--primary); margin-top: 4px; }

.detail-header {
  display: flex;
  gap: 16px;
  align-items: center;
  margin-bottom: 16px;
}
.detail-header img { width: 100px; height: 100px; object-fit: contain; background: var(--bg); border: 1px solid var(--border); border-radius: 8px; flex-shrink: 0; }
.detail-header-text { flex: 1; min-width: 0; }
.detail-header h2 { margin: 0 0 4px; }
.detail-header p { margin: 0; color: var(--muted); font-size: 13px; }
[contenteditable="true"] {
  border-radius: 4px;
  padding: 2px 4px;
  margin: -2px -4px;
  cursor: text;
}
[contenteditable="true"]:hover { background: #f4f6fb; box-shadow: 0 0 0 1px var(--border); }
[contenteditable="true"]:focus {
  outline: none;
  background: white;
  box-shadow: 0 0 0 2px var(--primary);
}

.meta-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}
.meta-select, .meta-tag-input {
  font-size: 13px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 4px 6px;
  background: #f4f6fb;
}
.meta-select { max-width: 220px; }
.meta-tag-input { flex: 1; min-width: 160px; }
.meta-style-input { flex: 0 0 auto; width: 130px; font-weight: 600; color: var(--text); }
.meta-select:focus, .meta-tag-input:focus { outline: none; border-color: var(--primary); background: white; }
.add-feature-btn {
  display: inline-block;
  margin-top: 12px;
  font-weight: 600;
}

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 600; font-size: 12px; }
th .th-sub { font-weight: 400; font-size: 11px; }
.no-smv { color: #b91c1c; font-style: italic; }
input.qty-input { width: 55px; padding: 4px; border: 1px solid var(--border); border-radius: 4px; }
/* Rows whose variant the user swapped out, so they stand apart from what the template shipped
   with. Amber rather than the app's blue, which already means hover/selection elsewhere. */
/* Construction group - a grouping aid beside the feature name, so it stays visually secondary. */
.group-cell { color: var(--muted); font-size: 12px; font-weight: 600; white-space: nowrap; }
/* Selected row: blue, and kept distinct from the amber "you changed this" tint so a row can
   show both at once. The inset shadow draws inside the cell, which a border on a table row
   would not do reliably. */
/* Order matters: a row can be both changed and selected, so the amber tint keeps the background
   (the "you edited this" cue is the one worth preserving) while selection always owns the left
   bar. A selected unchanged row gets the blue tint as well. */
tr.row-selected > td { background: #eef2ff; }
tr.item-changed > td { background: #fff8e6; }
tr.item-changed > td:first-child { box-shadow: inset 3px 0 0 #f59e0b; }
tr.row-selected > td:first-child { box-shadow: inset 3px 0 0 var(--primary); }
.qty-range { display: inline-block; margin-top: 2px; color: #98a2b3; font-size: 11px; white-space: nowrap; }

.total-row {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 16px;
  font-size: 16px;
  align-items: baseline;
}
.total-row strong { font-size: 22px; color: var(--primary); }
.export-buttons {
  display: flex;
  gap: 8px;
  margin-right: auto;
}
.secondary-btn {
  background: white;
  color: var(--primary);
  border: 1px solid var(--primary);
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
}
.secondary-btn:hover { background: #eef2ff; }
.secondary-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.modal {
  position: fixed; inset: 0; background: rgba(0,0,0,0.4);
  display: flex; align-items: center; justify-content: center; z-index: 50;
}
.modal[hidden] { display: none; }
.modal-content {
  background: white; border-radius: 10px; padding: 20px;
  width: 480px; max-height: 70vh; display: flex; flex-direction: column; gap: 10px;
}
.modal-header { display: flex; justify-content: space-between; align-items: center; }
.modal-header h3 { margin: 0; }
/* The variant picker can sit right on top of the row being edited, so its header doubles as a
   drag handle. user-select off stops a drag from just highlighting the title text instead. */
/* The variant picker is the one dialog people read a long list in, so it gets the screen rather
   than the default 480px: at that width long variant titles wrapped to three lines and only about
   five fitted before scrolling. Wide enough for two columns on a normal monitor, and it falls
   back to one column on a narrow window. */
#pickerModal .modal-content { width: min(1100px, 95vw); max-height: 92vh; }
#pickerModal .picker-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(430px, 1fr));
  align-content: start;
  gap: 6px;
}
/* Labels, group headings and the operations panel belong to the whole width, not to one cell. */
#pickerModal .picker-results-label,
#pickerModal .picker-group-header,
#pickerModal .picker-ops,
#pickerModal .picker-group-item { grid-column: 1 / -1; }
.picker-results-label { color: var(--muted); font-size: 12px; margin-bottom: 4px; }

#pickerModal .modal-header { cursor: move; user-select: none; }
#pickerModal .modal-header button { cursor: pointer; }
.picker-lib-row { display: inline-flex; align-items: center; gap: 8px; margin-left: 18px; }
.picker-lib-row[hidden] { display: none; }
.picker-lib-row label { font-size: 13px; color: var(--muted); }

/* A row from the raw operation library: no photo to show, so the space goes to the trail that
   says where in the tree it came from. */
.op-item { display: block; }
.op-item .oi-top { display: flex; align-items: baseline; gap: 10px; }
.op-item .oi-title { flex: 1; min-width: 0; }
.op-item .oi-smv { color: var(--primary); font-weight: 600; flex-shrink: 0; }
.op-item .oi-meta { color: var(--muted); font-size: 11px; margin-top: 2px; }
.op-item .oi-machine {
  display: inline-block; margin-left: 6px; padding: 0 5px;
  border: 1px solid var(--border); border-radius: 3px; background: #f8fafc;
}
.op-capped { font-size: 11px; color: #93370d; background: #fffaeb; border: 1px solid #fedf89;
  border-radius: 5px; padding: 5px 8px; }

.picker-search-wrap { position: relative; display: flex; }
#pickerSearch { flex: 1; padding: 8px 34px 8px 8px; border: 1px solid var(--border); border-radius: 6px; }
/* Clearing a long multi-keyword search by holding backspace is tedious; one button resets it. */
.picker-search-clear {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  color: var(--muted); font-size: 14px; line-height: 1;
  padding: 4px 6px; border-radius: 4px;
}
.picker-search-clear:hover { color: var(--text); background: #eef2ff; }
.picker-search-clear[hidden] { display: none; }
.picker-results { overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: 4px; }
.picker-item { padding: 8px; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; font-size: 13px; display: flex; gap: 10px; align-items: center; }
.picker-item:hover { background: #eef2ff; }

/* Operation list inside a picker row - for taking one operation out of a feature instead of
   the whole thing (a style can need a second topstitch line the feature only has once). */
.pi-ops-btn {
  background: none; border: 1px solid var(--border); border-radius: 4px;
  color: var(--primary); cursor: pointer; font-size: 11px; padding: 1px 7px; margin-left: 8px;
}
.pi-ops-btn:hover { background: #eef2ff; border-color: var(--primary); }
.picker-ops {
  margin: 0 0 6px 24px; padding: 8px 10px;
  border: 1px solid var(--border); border-left: 3px solid var(--primary);
  border-radius: 6px; background: #fbfbfc;
}
.picker-ops-hint { font-size: 11px; color: var(--muted); margin-bottom: 6px; }
.picker-op {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 8px; border-radius: 5px; cursor: pointer; font-size: 12px;
}
.picker-op:hover { background: #eef2ff; }
.picker-op-title { flex: 1; min-width: 0; }
.picker-op-code { color: var(--muted); font-size: 10px; }
.picker-op-smv { color: var(--primary); font-weight: 600; flex-shrink: 0; }
.picker-op-take { flex-shrink: 0; font-size: 10px; color: var(--primary); opacity: 0; white-space: nowrap; }
.picker-op:hover .picker-op-take { opacity: 1; }

/* Marks an items-table row that is a lone operation rather than a whole feature. */
.op-only-badge {
  display: inline-block; margin-left: 6px;
  font-size: 9px; font-weight: 700; letter-spacing: 0.03em;
  padding: 1px 5px; border-radius: 999px;
  background: #fffaeb; color: #93370d; border: 1px solid #fedf89;
}
/* The variant the row is already using. Without this every option looked alike, so there was no
   way to tell which one you were about to replace. */
.picker-item-current {
  border-color: var(--primary);
  background: #eef2ff;
  box-shadow: inset 3px 0 0 var(--primary);
}
.pi-code { color: #98a2b3; font-size: 11px; }
.picker-item-current .pi-code { color: var(--primary); font-weight: 700; }
.pi-current-tag {
  display: inline-block; margin-left: 6px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.03em;
  padding: 1px 6px; border-radius: 999px;
  background: var(--primary); color: white;
}
.picker-item .pi-smv { color: var(--primary); font-weight: 600; float: right; }
.picker-item .pi-body { flex: 1; min-width: 0; }
.picker-item .pi-thumb {
  flex-shrink: 0; width: 44px; height: 44px; border-radius: 5px; overflow: hidden;
  background: #f4f6fb; border: 1px solid var(--border);
}
.picker-item .pi-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.picker-image-preview {
  position: fixed;
  width: 380px;
  height: 380px;
  border-radius: 10px;
  overflow: hidden;
  border: 2px solid var(--primary);
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
  background: white;
  z-index: 100;
  cursor: zoom-in;
}
.picker-image-preview img { width: 100%; height: 100%; object-fit: contain; display: block; background: var(--bg); }
.picker-image-preview-open {
  position: absolute; top: 6px; right: 6px; z-index: 1;
  width: 28px; height: 28px; border-radius: 6px; border: none;
  background: rgba(0,0,0,0.55); color: white; font-size: 15px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.picker-image-preview-open:hover { background: rgba(0,0,0,0.75); }
.picker-image-preview-rotate { right: 40px; }
.picker-group-header {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--primary);
  background: #eef2ff;
  padding: 4px 8px;
  border-radius: 4px;
  margin-top: 6px;
}

.picker-tree-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
}
.picker-tree-row .meta-select { font-size: 12px; padding: 3px 5px; max-width: 200px; }

.picker-breadcrumb {
  font-size: 12px;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}
.picker-breadcrumb button {
  background: none; border: none; color: var(--primary); cursor: pointer;
  font-size: 12px; padding: 2px 4px; text-decoration: underline;
}
.picker-breadcrumb button:last-child { color: var(--muted); text-decoration: none; font-weight: 600; cursor: default; }
.picker-group-item {
  padding: 10px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.picker-group-item:hover { background: #eef2ff; border-color: var(--primary); }
.picker-group-item .pgi-arrow { color: var(--muted); }

.change-btn {
  background: none; border: 1px solid var(--border); border-radius: 4px;
  padding: 3px 8px; cursor: pointer; font-size: 11px; color: var(--muted);
}
.change-btn:hover { border-color: var(--primary); color: var(--primary); }

.reorder-cell { white-space: nowrap; }
.reorder-btn {
  background: none; border: 1px solid var(--border); border-radius: 4px;
  width: 22px; height: 22px; line-height: 1; cursor: pointer; font-size: 10px;
  color: var(--muted); padding: 0; margin-right: 2px;
}
.reorder-btn:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.reorder-btn:disabled { opacity: 0.3; cursor: not-allowed; }

.delete-btn {
  background: none; border: 1px solid var(--border); border-radius: 4px;
  padding: 3px 8px; cursor: pointer; font-size: 12px; color: #b91c1c;
}
.delete-btn:hover { border-color: #b91c1c; background: #fef2f2; }

.detail-toggle-btn {
  background: none; border: 1px solid var(--border); border-radius: 4px;
  width: 22px; height: 22px; line-height: 1; cursor: pointer; font-size: 10px;
  color: var(--muted); padding: 0;
}
.detail-toggle-btn:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.detail-toggle-btn:disabled { opacity: 0.25; cursor: not-allowed; }

.bol-detail-row td { padding: 0; border-bottom: 1px solid var(--border); }
.bol-detail-wrap { padding: 10px 14px 14px 46px; background: #f9fafc; }
.bol-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.bol-table th { text-align: left; color: var(--muted); font-weight: 600; padding: 4px 6px; border-bottom: 1px solid var(--border); }
.bol-table td { padding: 4px 6px; border-bottom: 1px solid #eef0f5; }
.bol-table .bol-smv-col { text-align: right; color: var(--primary); font-weight: 600; white-space: nowrap; }
.bol-empty { color: var(--muted); font-size: 12px; font-style: italic; padding: 4px 6px; }

.export-modal-content { width: 360px; }
.export-modal-prompt { font-size: 13px; color: var(--muted); margin: 0 0 4px; }
.export-modal-option { width: 100%; text-align: center; }

/* Overwrite picker: the save dialog has to show WHICH template is about to be replaced, with its
   photo, because two templates of the same garment look identical by name alone. */
/* Two scrolling lists inside one flex column: without this the shared 70vh squeezed the
   suggestion list down to a sliver while the browse list kept its height. Everything that is not
   a list holds its size, and each list keeps at least one row visible and scrolls inside itself. */
.overwrite-modal-content { width: min(520px, 92vw); max-height: 88vh; }
.overwrite-modal-content > *:not(.overwrite-list) { flex: 0 0 auto; }
.overwrite-section-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted);
}
.overwrite-current {
  display: flex; gap: 10px; align-items: center;
  padding: 8px; margin-bottom: 12px;
  border: 1px dashed var(--border); border-radius: 8px; background: #f8fafc;
}
.overwrite-current img {
  width: 56px; height: 56px; object-fit: contain;
  background: white; border: 1px solid var(--border); border-radius: 6px; flex-shrink: 0;
}
.overwrite-current-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.overwrite-current-text strong { font-size: 13px; }
.overwrite-meta { font-size: 11px; color: var(--muted); }
.overwrite-list { flex: 0 1 auto; min-height: 92px; max-height: 30vh; overflow-y: auto; margin: 6px 0 12px; }
.overwrite-list:empty { display: none; }
.overwrite-filters { display: flex; gap: 8px; margin: 6px 0; }
.overwrite-filters select { flex: 0 0 42%; }
.overwrite-filters input {
  flex: 1; min-width: 0;
  padding: 7px 10px; border: 1px solid var(--border); border-radius: 6px;
  font-family: inherit; font-size: 13px; color: var(--text);
}
.overwrite-filters input:focus { outline: none; border-color: var(--primary); }
.overwrite-empty { font-size: 12px; color: var(--muted); padding: 8px 2px; }
.overwrite-replace-image {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; color: var(--text);
  margin: 2px 0 12px; cursor: pointer;
}
.overwrite-replace-image input { margin: 0; cursor: pointer; }
.overwrite-badge.builtin { background: #fffaeb; color: #93370d; border-color: #fedf89; }
.overwrite-option {
  display: flex; gap: 10px; align-items: center;
  padding: 8px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
}
.overwrite-option:hover { border-color: var(--primary); background: #f5f8ff; }
.overwrite-option.selected { border-color: var(--primary); background: #eef2ff; }
.overwrite-option.locked { cursor: not-allowed; opacity: 0.75; background: #fbfbfc; }
.overwrite-option.locked:hover { border-color: var(--border); background: #fbfbfc; }
.overwrite-option img {
  width: 56px; height: 56px; object-fit: contain;
  background: white; border: 1px solid var(--border); border-radius: 6px; flex-shrink: 0;
}
.overwrite-option-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.overwrite-option-text strong { font-size: 13px; }
.overwrite-badge {
  align-self: flex-start; font-size: 10px; font-weight: 700;
  padding: 1px 6px; border-radius: 999px;
  background: #eef2ff; color: var(--primary); border: 1px solid #c7d2fe;
}
.overwrite-badge.locked { background: #fef3f2; color: #912018; border-color: #fecdca; }
.overwrite-actions { display: flex; gap: 8px; }
.overwrite-actions button { flex: 1; }
.overwrite-actions button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Password box with a show/hide eye: typed characters stay masked so nobody reading over the
   user's shoulder can pick the password up, but it can be revealed to check a typo. */
.password-field { position: relative; margin-bottom: 10px; }
.password-input {
  width: 100%;
  padding: 9px 40px 9px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
}
.password-input:focus { outline: none; border-color: var(--primary); }
.password-eye {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 4px 6px;
  border-radius: 4px;
  opacity: 0.65;
}
.password-eye:hover { opacity: 1; background: #eef2ff; }

.video-modal-content { width: min(720px, 90vw); }
.video-modal-content video { width: 100%; max-height: 70vh; background: #000; border-radius: 6px; }
.bol-video-btn {
  background: none; border: 1px solid var(--primary); border-radius: 4px;
  color: var(--primary); cursor: pointer; font-size: 11px; padding: 2px 6px; margin-left: 6px;
}
.bol-video-btn:hover { background: #eef2ff; }
