/* Panel Optimizer — stylesheet. Light theme, flat, responsive. */

:root {
  --bg-page: #F7F6F3;
  --bg-surface: #FFFFFF;
  --bg-subtle: #F1EFE8;
  --border: #E2E0D8;
  --border-strong: #C9C7BE;
  --text: #2C2C2A;
  --text-muted: #6B6A65;
  --text-faint: #96948C;
  --accent: #185FA5;
  --accent-bg: #E6F1FB;
  --accent-border: #B5D4F4;
  --warn: #854F0B;
  --warn-bg: #FAEEDA;
  --warn-border: #FAC775;
  --danger: #A32D2D;
  --danger-bg: #FCEBEB;
  --success: #3B6D11;
  --success-bg: #EAF3DE;
  --radius: 10px;
  --radius-lg: 14px;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-page);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-weight: 600; margin: 0; }
h1 { font-size: 17px; }
h2 { font-size: 15px; }
h3 { font-size: 14px; }
p { margin: 0; }

a { color: var(--accent); }

/* ---------- shell ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
  /* With the back link added, the bar needs three slots (link, brand, actions).
     Below ~830px the actions drop to their own row instead of being squeezed,
     which keeps the product title whole. */
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--accent-bg);
  color: var(--accent);
  font-weight: 600;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.brand-text { min-width: 0; }
.brand-text .t { font-weight: 600; font-size: 15px; white-space: nowrap; }
.brand-text .s { font-size: 12px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.topbar-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* The input column holds a six-column editable table (part, length, width,
   qty, grain, remove). At 380px those columns had to shrink below the width of
   their own values, which clipped "1200" to "12". The editor is the primary
   tool here, so it gets the room it needs and the sheet map takes the rest. */
.layout {
  display: grid;
  grid-template-columns: minmax(0, 470px) minmax(0, 1fr);
  gap: 16px;
  padding: 16px 20px 40px;
  align-items: start;
  max-width: 1600px;
  margin: 0 auto;
}

@media (max-width: 1240px) {
  .layout { grid-template-columns: minmax(0, 420px) minmax(0, 1fr); }
}

@media (max-width: 1080px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
}

.col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

/* ---------- cards ---------- */

.card {
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.card-head h2 { font-size: 14px; font-weight: 600; }
.card-head .hint { font-size: 12px; color: var(--text-muted); }

/* ---------- form ---------- */

label.field { display: block; margin-bottom: 10px; }
label.field > .lbl {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
  margin-bottom: 5px;
}
label.field > .lbl .unit { color: var(--text-faint); }

/* States the allowed range under a bounded input (blade kerf, board margin).
   Sits inside the label so it always travels with its field. */
label.field > .hint {
  display: block;
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 4px;
}

.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }

input[type="number"], input[type="text"], select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--bg-surface);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
}

input:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(24, 95, 165, 0.12);
}

input[aria-invalid="true"] { border-color: var(--danger); }

button {
  padding: 8px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--bg-surface);
  color: var(--text);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}

button:hover { background: var(--bg-subtle); }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
button.primary:hover { background: #14507f; }

button.ghost { border-color: transparent; color: var(--text-muted); }
button.ghost:hover { background: var(--bg-subtle); color: var(--text); }

button.danger { color: var(--danger); border-color: var(--danger-bg); }
button.danger:hover { background: var(--danger-bg); }

button:disabled { opacity: 0.5; cursor: not-allowed; }

button.icon {
  padding: 4px 7px;
  font-size: 13px;
  line-height: 1;
  border-radius: 6px;
}

/* ---------- segmented toggle ---------- */

.segmented {
  display: flex;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  overflow: hidden;
}

.segmented button {
  flex: 1;
  border: none;
  border-radius: 0;
  background: var(--bg-surface);
  padding: 8px 10px;
  font-weight: 500;
}

.segmented button + button { border-left: 1px solid var(--border-strong); }
.segmented button[aria-pressed="true"] {
  background: var(--accent-bg);
  color: var(--accent);
  font-weight: 600;
}

/* ---------- presets ---------- */

.presets { display: flex; gap: 6px; flex-wrap: wrap; }

.chip {
  font-size: 12px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--bg-surface);
  color: var(--text-muted);
  cursor: pointer;
}

.chip[aria-pressed="true"] {
  background: var(--accent-bg);
  border-color: var(--accent-border);
  color: var(--accent);
  font-weight: 600;
}

/* ---------- cut list table ---------- */

/* The cut list is the one table where every value must stay legible. Six
   columns of real data (a part name plus three numbers) cannot fit the narrow
   input column at a readable size, and `table-layout: fixed` with percentage
   widths silently clipped "1200" down to "12". So: natural layout, an explicit
   comfortable floor width, and the wrapper scrolls if the column is narrower. */
.cutlist-wrap { width: 100%; overflow-x: auto; }

.cutlist {
  width: 100%;
  min-width: 420px;
  border-collapse: collapse;
  font-size: 13px;
}

.cutlist th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  padding: 0 6px 6px;
  border-bottom: 1px solid var(--border);
}

.cutlist td { padding: 5px 6px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.cutlist tr.row-bad td { background: var(--danger-bg); }
.cutlist tr:last-child td { border-bottom: none; }

.cutlist input, .cutlist select {
  padding: 6px 8px;
  font-size: 13px;
  border-color: transparent;
  background: transparent;
}

.cutlist input:hover, .cutlist select:hover { border-color: var(--border-strong); }
.cutlist input:focus, .cutlist select:focus { border-color: var(--accent); background: var(--bg-surface); }

/* Widths calibrated so the six columns total under the 420px floor: name (flex)
   + length 66 + width 66 + qty 42 + grain 56 + remove 28 + padding. */
.cutlist .col-name { width: auto; min-width: 88px; }
.cutlist .col-num { width: 66px; }
.cutlist .col-qty { width: 42px; }
.cutlist .col-grain { width: 56px; }
.cutlist .col-act { width: 28px; }

.cutlist .col-num input { min-width: 50px; }
.cutlist .col-qty input { min-width: 34px; }
.cutlist .col-name input { min-width: 80px; }

.cutlist .col-grain select { padding: 6px 2px; }

/* Number spinners steal horizontal room inside an already-tight cell and are
   useless for a millimetre field the operator types at a keyboard. */
.cutlist input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.cutlist input[type="number"]::-webkit-outer-spin-button,
.cutlist input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.cutlist input.col-num, .cutlist input[type="number"] { text-align: right; }

.grain-select { text-align: center; font-weight: 600; }

/* ---------- metric tiles ---------- */

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}

.metric {
  background: var(--bg-subtle);
  border-radius: var(--radius);
  padding: 12px 14px;
}

.metric .k { font-size: 12px; color: var(--text-muted); }
.metric .v { font-size: 22px; font-weight: 600; margin-top: 2px; line-height: 1.2; }
.metric .u { font-size: 13px; font-weight: 400; color: var(--text-muted); margin-left: 2px; }
.metric.good .v { color: var(--success); }
.metric.bad .v { color: var(--danger); }

/* ---------- sheet map ---------- */

.sheetmap-wrap { overflow: auto; }

.sheetmap {
  position: relative;
  background: repeating-linear-gradient(
    90deg,
    rgba(0,0,0,0.045) 0 1px,
    transparent 1px 7px
  );
  border: 2px solid var(--text);
  border-radius: 3px;
  width: 100%;
}

.sheetmap .trim {
  position: absolute;
  border: 1px dashed var(--border-strong);
  pointer-events: none;
}

.piece {
  position: absolute;
  border: 1px solid var(--accent);
  background: rgba(24, 95, 165, 0.11);
  border-radius: 2px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.piece .plabel {
  font-size: 10px;
  line-height: 1.25;
  color: var(--accent);
  text-align: center;
  padding: 0 3px;
  overflow: hidden;
}

.piece.cut {
  border-color: var(--danger);
  background: rgba(163, 45, 45, 0.12);
}
.piece.cut .plabel { color: var(--danger); }

.serial {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid var(--accent);
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  z-index: 2;
}

.serial.cut { border-color: var(--danger); color: var(--danger); }
.sheetmap.hide-serials .serial { display: none; }
.sheetmap.hide-labels .plabel { display: none; }

.grain-line {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 2px;
  background: var(--accent);
  opacity: 0.65;
  border-radius: 1px;
}
.grain-line::before, .grain-line::after {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
}
.grain-line::before { top: -5px; border-bottom: 6px solid var(--accent); }
.grain-line::after { bottom: -5px; border-top: 6px solid var(--accent); }

.grain-line.h {
  width: auto;
  height: 2px;
  top: 50%;
  left: 12%;
  right: 12%;
  transform: none;
}
.grain-line.h::before {
  top: 50%;
  left: -5px;
  transform: translateY(-50%);
  border-left: none;
  border-right: 6px solid var(--accent);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}
.grain-line.h::after {
  top: 50%;
  right: -5px;
  left: auto;
  transform: translateY(-50%);
  border-right: none;
  border-left: 6px solid var(--accent);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}

/* ---------- legend ---------- */

.legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.legend .swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: -2px;
}

.legend .swatch.piece { background: rgba(24,95,165,0.11); border: 1px solid var(--accent); }
.legend .swatch.cut { background: rgba(163,45,45,0.12); border: 1px solid var(--danger); }
.legend .swatch.trim { background: var(--bg-subtle); border: 1px dashed var(--border-strong); }

/* ---------- sheet pager ---------- */

.pager { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.pager .spacer { margin-left: auto; }

/* ---------- cut sequence ---------- */

ol.seq { margin: 0; padding-left: 0; list-style: none; font-size: 13px; }
ol.seq li {
  display: flex;
  gap: 10px;
  padding: 5px 0;
  color: var(--text);
}
ol.seq li .n {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent-bg);
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
}
ol.seq li.sub { color: var(--text-muted); font-size: 12px; padding-left: 30px; }
ol.seq li.sub .n { display: none; }

/* ---------- drop zone ---------- */

.dropzone {
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: 22px 16px;
  text-align: center;
  background: var(--bg-subtle);
  cursor: pointer;
}

.dropzone.over { border-color: var(--accent); background: var(--accent-bg); }
.dropzone .dz-t { font-size: 14px; font-weight: 600; }
.dropzone .dz-s { font-size: 12px; color: var(--text-muted); margin-top: 3px; }

/* ---------- import preview ---------- */

.import-table { width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
.import-table th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  padding: 0 6px 6px;
  border-bottom: 1px solid var(--border);
}
.import-table td { padding: 6px; border-bottom: 1px solid var(--border); }
.import-table tr.bad td { background: var(--danger-bg); color: var(--danger); }
.import-table input { padding: 5px 7px; font-size: 13px; }

.map-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  gap: 6px 10px;
  font-size: 13px;
}
.map-grid .h { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-faint); }
.map-grid .val { color: var(--text-muted); }

/* ---------- notices ---------- */

.notice {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 12.5px;
  padding: 10px 12px;
  border-radius: var(--radius);
  line-height: 1.5;
}

/* A notice is flex, so bare inline children (a <b> mid-sentence, say) would each
   become their own flex item and get spread apart along the row — the sentence
   visibly comes apart: "This app can handle till 60 ... sheets only".
   Only the sentence WRAPPER should flex and carry the text; anything nested
   inside it must stay inline. Hence :scope > * rather than a blanket
   descendant rule, and no flex on nested <b>. Text nodes that sit directly in
   the notice (no wrapper) are still safe: they are anonymous flex items that
   stay on one line. */
.notice > .notice-text { flex: 1 1 auto; min-width: 0; }
.notice b { font-weight: 600; display: inline; }
.notice.warn { background: var(--warn-bg); color: var(--warn); }
.notice.bad { background: var(--danger-bg); color: var(--danger); }
.notice.good { background: var(--success-bg); color: var(--success); }
.notice.info { background: var(--accent-bg); color: var(--accent); }
.notice + .notice { margin-top: 8px; }

/* ---------- modal ---------- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(30, 30, 28, 0.42);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  overflow: auto;
  z-index: 60;
}
.modal-backdrop[hidden] { display: none; }

.modal {
  background: var(--bg-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  width: 100%;
  max-width: 820px;
  padding: 18px 20px 20px;
}

.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 14px;
}

.modal-head .sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

.modal-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.modal-foot .spacer { margin-left: auto; }

/* ---------- misc ---------- */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

.muted { color: var(--text-muted); }
.tiny { font-size: 12px; }
.mono { font-family: var(--mono); }
.empty { padding: 26px 12px; text-align: center; color: var(--text-muted); font-size: 13px; }
.hidden { display: none !important; }
.stack { display: flex; flex-direction: column; gap: 8px; }
.inline { display: flex; align-items: center; gap: 8px; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 8px; }

.kv { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; padding: 4px 0; }
.kv .k { color: var(--text-muted); }

/* Shown only while the cut list total is over the piece limit, so the number
   that will be refused on Optimize is visibly flagged before it is pressed. */
.kv.kv-over { color: var(--danger); font-weight: 600; }
.kv.kv-over .k { color: var(--danger); }

.unplaced-list { font-size: 12.5px; color: var(--danger); }

/* ---------- site footer ---------- */

.site-footer {
  max-width: 1600px;
  margin: 0 auto;
  padding: 18px 20px 28px;
  border-top: 1px solid var(--border);
}

.site-footer p {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-muted);
}

.site-footer .copyright { font-size: 13px; }
.site-footer .sep { color: var(--text-faint); }

/* ---------- back to the Agswamy portal ---------- */

/* In the topbar, not a fixed corner pill like the single-column calculators.
   This page's left column is a dense editable table that runs to the bottom of
   the viewport, so a floating pill would sit on top of the cut list. The topbar
   is sticky, so the route home is always on screen either way. */
.home-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-surface);
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.home-link:hover {
  background: var(--bg-subtle);
  border-color: var(--accent-border);
  color: var(--accent);
}

@media print {
  .topbar, .col-input, .modal-backdrop, .legend, .pager { display: none !important; }
  .layout { display: block; padding: 0; }
  .card { border: none; padding: 0; page-break-inside: avoid; }
  body { background: #fff; }
  /* Keep the notice on printed layouts, without the screen-only top border. */
  .site-footer { border-top: none; padding: 12px 0 0; }
}
