/* =====================================================================
   CRM Design System - "Trade Ledger"
   A dashboard for a trading/export company: navy manifest chrome, warm
   paper working surface, brass stamp accent for status and actions.
   ===================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root {
  /* ---- color tokens ---- */
  --color-ink: #16283d;
  --color-ink-light: #21384f;
  --color-ink-lighter: #2d4864;
  --color-paper: #f6f3ea;
  --color-surface: #ffffff;
  --color-accent: #b6742a;
  --color-accent-deep: #8f5a1e;
  --color-line: #dfd8c6;
  --color-line-dark: #33506e;
  --color-text: #1c2a38;
  --color-text-soft: #5b6b7a;
  --color-text-inverse: #eef2f5;
  --color-danger: #a23b3b;
  --color-danger-bg: #f6e6e6;
  --color-success: #3f6b4a;
  --color-success-bg: #e7f0e8;
  --color-warning-bg: #f6ecd9;

  /* status palette used by the `status_css` template filter */
  --status-slate: #5b6b7a;
  --status-blue: #2e6f95;
  --status-amber: #b6742a;
  --status-rust: #8b3a3a;
  --status-green: #3f6b4a;
  --status-violet: #6a4c8c;
  --status-teal: #2c7a6d;

  /* ---- type ---- */
  --font-display: 'Fraunces', Georgia, serif;
  --font-body: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'IBM Plex Mono', 'Courier New', monospace;

  --radius: 6px;
  --shadow-card: 0 1px 2px rgba(22, 40, 61, 0.06), 0 1px 8px rgba(22, 40, 61, 0.04);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--color-paper);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
}

a { color: var(--color-accent-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { font-family: var(--font-display); font-weight: 600; color: var(--color-ink); margin: 0 0 .4em; }
h1 { font-size: 1.9rem; letter-spacing: -0.01em; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.05rem; }

code, .mono, .num { font-family: var(--font-mono); }

/* Respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---------------------------------------------------------------
   Shell layout: fixed navy sidebar + scrollable paper content
   --------------------------------------------------------------- */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: 232px;
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--color-ink) 0%, var(--color-ink-light) 100%);
  color: var(--color-text-inverse);
  display: flex;
  flex-direction: column;
  padding: 22px 0;
  position: sticky;
  top: 0;
  height: 100vh;
}

/* The nav list scrolls on its own so brand + footer stay put on short screens. */
.sidebar-nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(238, 242, 245, 0.28) transparent;
}
.sidebar-nav::-webkit-scrollbar { width: 8px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb {
  background: rgba(238, 242, 245, 0.22);
  border-radius: 4px;
}
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: rgba(238, 242, 245, 0.38); }

.brand {
  flex-shrink: 0;
  padding: 0 20px 18px;
  border-bottom: 1px solid rgba(238, 242, 245, 0.12);
  margin-bottom: 14px;
}
.brand .mark {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.01em;
}
.brand .sub {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .11em;
  color: #b9c6d3;
  margin-top: 2px;
}

.nav-section-label {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: #91a3b3;
  padding: 14px 20px 6px;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 20px;
  color: #d7e0e8;
  font-size: .92rem;
  font-weight: 500;
  border-left: 3px solid transparent;
}
.nav-link:hover { background: rgba(238, 242, 245, 0.06); text-decoration: none; color: #fff; }
.nav-link.active {
  background: rgba(182, 116, 42, 0.16);
  border-left-color: var(--color-accent);
  color: #fff;
}

.nav-dropdown-summary { list-style: none; cursor: pointer; justify-content: space-between; }
.nav-dropdown-summary::-webkit-details-marker { display: none; }
.nav-dropdown-summary::after { content: '▸'; font-size: .75rem; color: #91a3b3; transition: transform .15s ease; }
.nav-dropdown[open] > .nav-dropdown-summary::after { transform: rotate(90deg); }
.nav-sublink { padding-left: 40px; font-size: .87rem; }
.nav-subdropdown { margin: 0; }
.nav-subdropdown > .nav-dropdown-summary { padding-left: 40px; font-size: .87rem; }
.nav-subsublink { padding-left: 60px; font-size: .83rem; }

.sidebar-footer {
  flex-shrink: 0;
  margin-top: auto;
  padding: 14px 20px 0;
  border-top: 1px solid rgba(238, 242, 245, 0.12);
}
.sidebar-user { font-size: .85rem; color: #eef2f5; font-weight: 600; }
.sidebar-role {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: #b9c6d3;
  margin-bottom: 8px;
}
.logout-link { font-size: .82rem; color: #dcb27f; }

.main {
  flex: 1;
  min-width: 0;
  padding: 30px 40px 60px;
}

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 22px;
  gap: 16px;
  flex-wrap: wrap;
}
.topbar .eyebrow {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--color-text-soft);
  margin-bottom: 3px;
}
.topbar-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---------------------------------------------------------------
   Cards / surfaces
   --------------------------------------------------------------- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 20px 22px;
  margin-bottom: 20px;
}
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
  gap: 10px;
  flex-wrap: wrap;
}
.card-header h2, .card-header h3 { margin: 0; }

/* Collapsible <details class="card misc-card"> cards on the Miscellaneous
   page - native details/summary (no JS), same arrow-rotation treatment as
   .nav-dropdown-summary above. Collapsed by default (no `open` attribute);
   a URL fragment targeting a row/section inside a still-collapsed card
   auto-expands it via the browser's native details-fragment behavior. */
.misc-card > summary.card-header {
  list-style: none;
  cursor: pointer;
  margin-bottom: 0;
}
.misc-card > summary.card-header::-webkit-details-marker { display: none; }
.misc-card > summary.card-header::after {
  content: '▾';
  font-size: .8rem;
  color: #91a3b3;
  flex-shrink: 0;
  transition: transform .15s ease;
}
.misc-card[open] > summary.card-header {
  margin-bottom: 14px;
  border-bottom: 1px solid var(--color-line);
  padding-bottom: 14px;
}
.misc-card[open] > summary.card-header::after { transform: rotate(180deg); }

.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------
   Stat tiles
   --------------------------------------------------------------- */
.stat-tile {
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 16px 18px;
}
.stat-tile .value { font-family: var(--font-mono); font-size: 1.7rem; font-weight: 600; color: var(--color-ink); }
.stat-tile .label { font-size: .78rem; color: var(--color-text-soft); text-transform: uppercase; letter-spacing: .07em; margin-top: 2px; }

/* ---------------------------------------------------------------
   Tables (ledger style: hairlines, no heavy borders)
   --------------------------------------------------------------- */
table.ledger { width: 100%; border-collapse: collapse; }
table.ledger th {
  text-align: left;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--color-text-soft);
  font-weight: 600;
  padding: 8px 10px;
  border-bottom: 1px solid var(--color-line-dark, var(--color-line));
  border-bottom-color: var(--color-line);
}
table.ledger td {
  padding: 10px 10px;
  border-bottom: 1px solid var(--color-line);
  vertical-align: top;
  font-size: .89rem;
}
table.ledger tr:last-child td { border-bottom: none; }
table.ledger tr:hover td { background: rgba(182, 116, 42, 0.045); }
table.ledger td.num, table.ledger th.num { text-align: right; font-family: var(--font-mono); }
.table-wrap { overflow-x: auto; }

/* Jumped-to row after an add/edit on the Miscellaneous page (or any
   ledger table using row anchors) - briefly highlighted so it's obvious
   which row the page scrolled to, then fades on its own. */
table.ledger tr:target td { animation: target-row-fade 2.4s ease-out; }
@keyframes target-row-fade {
  from { background: rgba(182, 116, 42, 0.22); }
  to { background: transparent; }
}

/* ---------------------------------------------------------------
   Status "stamp" badges - the page's signature element
   --------------------------------------------------------------- */
.stamp {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: 3px 9px;
  border-radius: 3px;
  border: 1px dashed currentColor;
  white-space: nowrap;
}
.stamp-slate  { color: var(--status-slate);  background: rgba(91,107,122,0.08); }
.stamp-blue   { color: var(--status-blue);   background: rgba(46,111,149,0.08); }
.stamp-amber  { color: var(--status-amber);  background: rgba(182,116,42,0.10); }
.stamp-rust   { color: var(--status-rust);   background: rgba(139,58,58,0.08); }
.stamp-green  { color: var(--status-green);  background: rgba(63,107,74,0.08); }
.stamp-violet { color: var(--status-violet); background: rgba(106,76,140,0.08); }
.stamp-teal   { color: var(--status-teal);   background: rgba(44,122,109,0.08); }

.pill {
  display: inline-block;
  font-size: .74rem;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--color-line);
  color: var(--color-text);
}
.pill-role-admin { background: var(--color-ink); color: #fff; }
.pill-role-employee { background: #e4dcc8; color: var(--color-accent-deep); }

/* ---------------------------------------------------------------
   Forms
   --------------------------------------------------------------- */
label { display: block; font-size: .8rem; font-weight: 600; color: var(--color-ink); margin-bottom: 4px; }
.field { margin-bottom: 14px; }
.field .hint { font-size: .76rem; color: var(--color-text-soft); margin-top: 3px; }
.required-mark { color: var(--color-danger); margin-left: 2px; }

input[type="text"], input[type="email"], input[type="password"], input[type="tel"],
input[type="date"], input[type="datetime-local"], input[type="number"], input[type="url"],
select, textarea {
  width: 100%;
  padding: 9px 11px;
  font-family: var(--font-body);
  font-size: .9rem;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid #c9c1ab;
  border-radius: 5px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
textarea { resize: vertical; min-height: 70px; }
#items-table .js-product-name { min-height: 44px; margin-bottom: 4px; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(182, 116, 42, 0.18);
}
input[readonly] { background: var(--color-paper); color: var(--color-text-soft); cursor: not-allowed; }
input[readonly]:focus { box-shadow: none; border-color: #c9c1ab; }
.form-row { display: flex; gap: 12px; flex-wrap: wrap; }
.form-row > .field { flex: 1; min-width: 180px; }

fieldset { border: 1px solid var(--color-line); border-radius: var(--radius); padding: 14px 16px; margin: 0 0 16px; }
legend { font-size: .8rem; font-weight: 600; color: var(--color-ink); padding: 0 6px; }

/* Packing list edit form: one product block can hold several design rows
   without adding extra outer table rows - only the printed PDF splits them
   onto separate lines (see packing_lists/_sheet.html). */
.product-block { border: 1px solid var(--color-line); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 16px; background: var(--color-paper); }
.product-block-header { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 12px; }
.product-block-header .field { margin-bottom: 0; }
.product-block .ledger { background: var(--color-surface); }
.product-block-footer { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; }

.repeatable-row {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dashed var(--color-line);
}
.repeatable-row .field { margin-bottom: 0; flex: 1; }
.radio-wrap { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.radio-wrap[hidden] { display: none; }
.radio-wrap label { margin: 0; }
.repeatable-row .radio-wrap { display: flex; align-items: center; gap: 5px; padding-bottom: 9px; }
.repeatable-row .radio-wrap label { margin: 0; font-size: .74rem; font-weight: 500; }

.repeatable-row-stacked { flex-direction: column; align-items: stretch; gap: 10px; }
.repeatable-row-stacked textarea { resize: vertical; font: inherit; }

/* ---------------------------------------------------------------
   Buttons
   --------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-body);
  font-size: .85rem;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 5px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .06s ease, background .12s ease, border-color .12s ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--color-accent); color: #fff; }
.btn-primary:hover { background: var(--color-accent-deep); }

.btn-ink { background: var(--color-ink); color: #fff; }
.btn-ink:hover { background: var(--color-ink-light); }

.btn-ghost { background: transparent; border-color: #c9c1ab; color: var(--color-text); }
.btn-ghost:hover { border-color: var(--color-accent); color: var(--color-accent-deep); }

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

.btn-sm { padding: 5px 11px; font-size: .78rem; }
.btn-block { width: 100%; justify-content: center; }

/* ---------------------------------------------------------------
   Flash messages
   --------------------------------------------------------------- */
.flash-stack { margin-bottom: 18px; display: flex; flex-direction: column; gap: 8px; }
.flash {
  padding: 10px 14px;
  border-radius: 5px;
  font-size: .87rem;
  border: 1px solid transparent;
}
.flash-success { background: var(--color-success-bg); color: var(--color-success); border-color: rgba(63,107,74,0.25); }
.flash-error { background: var(--color-danger-bg); color: var(--color-danger); border-color: rgba(162,59,59,0.25); }
.flash-warning { background: var(--color-warning-bg); color: var(--color-accent-deep); border-color: rgba(182,116,42,0.3); }

/* ---------------------------------------------------------------
   Misc utility
   --------------------------------------------------------------- */
.text-soft { color: var(--color-text-soft); }
.text-sm { font-size: .82rem; }
/* Status wording inside a table cell (e.g. the export packing list's
   per-product "balanced / still unassigned / over" column). */
.text-success { color: var(--color-success); font-weight: 600; }
.text-danger { color: var(--color-danger); font-weight: 600; }
.text-warn { color: var(--color-accent-deep); font-weight: 600; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.flex { display: flex; }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.divider { border: none; border-top: 1px solid var(--color-line); margin: 18px 0; }
.empty-state {
  padding: 30px 20px;
  text-align: center;
  color: var(--color-text-soft);
  font-size: .9rem;
  border: 1px dashed var(--color-line);
  border-radius: var(--radius);
}
.subnav { display: flex; gap: 6px; margin-bottom: 18px; flex-wrap: wrap; }
.subnav a {
  padding: 6px 13px;
  border-radius: 999px;
  font-size: .8rem;
  font-weight: 600;
  color: var(--color-text-soft);
  border: 1px solid var(--color-line);
  background: var(--color-surface);
}
.subnav a:hover { text-decoration: none; border-color: var(--color-accent); color: var(--color-accent-deep); }
.subnav a.active { background: var(--color-ink); color: #fff; border-color: var(--color-ink); }

/* ---------------------------------------------------------------
   Product catalog: folder-tree browser
   --------------------------------------------------------------- */
.breadcrumb-trail { font-size: .84rem; color: var(--color-text-soft); margin-bottom: 16px; }
.breadcrumb-trail .crumb-sep { margin: 0 6px; }

.catalog-search { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.catalog-search input[type="text"] { max-width: 320px; flex: 1 1 auto; }

.folder-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 14px; }
.folder-tile {
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  padding: 14px 12px;
  text-align: center;
  background: var(--color-paper);
}
.folder-tile-link { display: block; color: var(--color-text); }
.folder-tile-link:hover { text-decoration: none; color: var(--color-accent-deep); }
.folder-icon { display: block; font-size: 2rem; margin-bottom: 6px; }
.folder-name { display: block; font-weight: 600; font-size: .87rem; word-break: break-word; }
.folder-tile-actions { display: flex; justify-content: center; gap: 10px; margin-top: 8px; }

/* A form's submit button styled as the plain inline link next to it - used
   where an action needs a POST (duplicate) but sits among <a> actions. */
.btn-link {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--color-accent-deep); font-family: var(--font-body); font-weight: 500;
}
.btn-link:hover { text-decoration: underline; }

.btn-link-danger {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--color-danger); font-family: var(--font-body); font-weight: 500;
}
.btn-link-danger:hover { text-decoration: underline; }

.thumb { width: 44px; height: 44px; object-fit: cover; border-radius: 4px; border: 1px solid var(--color-line); }
.thumb-lg { max-width: 160px; max-height: 160px; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--color-line); margin-bottom: 8px; }
.thumb-xl { max-width: 100%; max-height: 360px; object-fit: contain; border-radius: var(--radius); border: 1px solid var(--color-line); background: var(--color-paper); }

/* ---------------------------------------------------------------
   Product picker modal (quotation form)
   --------------------------------------------------------------- */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(22, 40, 61, 0.55);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px;
}
.modal-overlay[hidden] { display: none; }
.modal-box {
  background: var(--color-surface); border-radius: var(--radius); box-shadow: var(--shadow-card);
  width: 100%; max-width: 720px; max-height: 85vh; overflow-y: auto; padding: 20px 22px;
}
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.modal-header h3 { margin: 0; }

/* ---------------------------------------------------------------
   Searchable dropdown (.combo)
   A dropdown that carries its own search box inside the open panel -
   what a native <select> cannot do. Used by the HSN code field on the
   product form; the chosen value lives in a hidden input alongside, so
   forms post exactly as they did with a plain <select>.
   --------------------------------------------------------------- */
.combo { position: relative; }
.combo-toggle {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 9px 11px; font-family: var(--font-body); font-size: .9rem; text-align: left;
  color: var(--color-text); background: var(--color-surface);
  border: 1px solid #c9c1ab; border-radius: var(--radius); cursor: pointer;
}
.combo-toggle:focus { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.combo-toggle > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-caret { color: var(--color-text-soft); font-size: .7rem; }
.combo-panel {
  position: absolute; z-index: 50; top: calc(100% + 4px); left: 0; right: 0; min-width: 260px;
  background: var(--color-surface); border: 1px solid var(--color-line);
  border-radius: var(--radius); box-shadow: var(--shadow-card); padding: 8px;
}
.combo-panel[hidden] { display: none; }
.combo-search { margin-bottom: 6px; }
.combo-list { max-height: 240px; overflow-y: auto; }
.combo-option {
  padding: 6px 8px; border-radius: 4px; cursor: pointer; font-size: .88rem; line-height: 1.3;
}
.combo-option[hidden] { display: none; }
.combo-option:hover, .combo-option.is-active { background: var(--color-paper); }
.combo-option.is-selected { font-weight: 600; }
.combo-option-main { display: block; }
.combo-option-note {
  display: block; font-size: .74rem; color: var(--color-text-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combo-option-note:empty { display: none; }
.combo-empty { padding: 10px 8px; font-size: .82rem; color: var(--color-text-soft); text-align: center; }
.combo-empty[hidden] { display: none; }
.combo-add {
  display: block; width: 100%; margin-top: 6px; padding: 7px 8px;
  font-family: var(--font-body); font-size: .82rem; text-align: left; cursor: pointer;
  color: var(--color-accent); background: none; border: none; border-top: 1px solid var(--color-line);
}
.combo-add:hover { background: var(--color-paper); }

/* ---------------------------------------------------------------
   Quotation print sheet
   --------------------------------------------------------------- */
.quote-print-body { background: #d8d2c0; margin: 0; padding: 0; }
.quote-toolbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; justify-content: space-between; align-items: center;
  background: var(--color-ink); padding: 12px 24px;
}
/* .btn-ghost's default text color is a near-match for this dark toolbar
   background, so it's unreadable until :hover repaints it - give ghost/danger
   buttons here the same light-on-dark treatment the sidebar nav links use. */
.quote-toolbar .btn-ghost { color: var(--color-text-inverse); border-color: rgba(238, 242, 245, 0.35); }
.quote-toolbar .btn-ghost:hover { color: #fff; border-color: var(--color-text-inverse); }
.quote-toolbar .btn-danger { color: #e79a9a; border-color: #e79a9a; }
.quote-toolbar .btn-danger:hover { background: rgba(231, 154, 154, 0.15); }

/* Toolbar dropdown (<details>) - used where one document links to MANY of
   another, e.g. a proforma invoice's purchase orders. No JS: <summary> is
   styled as a .btn and the panel is absolutely positioned under it. */
.toolbar-menu { position: relative; }
.toolbar-menu > summary { list-style: none; cursor: pointer; }
.toolbar-menu > summary::-webkit-details-marker { display: none; }
.toolbar-menu-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20;
  min-width: 280px; max-height: 60vh; overflow-y: auto;
  background: var(--color-surface); color: var(--color-text);
  border: 1px solid var(--color-line); border-radius: var(--radius);
  box-shadow: var(--shadow-card); padding: 6px;
}
.toolbar-menu-item {
  display: block; padding: 7px 10px; border-radius: 4px;
  color: var(--color-text); font-size: .82rem; text-align: left;
}
.toolbar-menu-item:hover { background: var(--color-paper); text-decoration: none; }
.toolbar-menu-item .mono { font-weight: 600; }
.toolbar-menu-item .meta { display: block; font-size: .75rem; color: var(--color-text-soft); }
.toolbar-menu-empty { padding: 8px 10px; font-size: .8rem; color: var(--color-text-soft); }
.toolbar-menu-sep { border: 0; border-top: 1px solid var(--color-line); margin: 5px 2px; }

/* One design on a purchase order's Production Status page. A card that is
   also a disclosure: the summary row is the whole design at a glance, and
   its batch editor stays folded until that design is being worked on -
   an order can carry well over fifty of these. */
.production-design { padding: 0; }
.production-design > summary.production-design-summary {
  list-style: none; cursor: pointer; margin: 0;
}
.production-design > summary::-webkit-details-marker { display: none; }
.production-design > summary.production-design-summary::after {
  content: "▾"; font-size: .7rem; color: var(--color-text-soft); margin-left: 10px;
}
.production-design[open] > summary.production-design-summary::after { content: "▴"; }
.production-design > form { padding: 14px 18px 16px; }
.production-design[hidden] { display: none; }
.production-batches .repeatable-row:last-child { border-bottom: 0; }

/* Panels shown above a printable sheet (never printed): the confirmation
   banner and the "designs still to be ordered" table on a proforma invoice. */
.sheet-note {
  max-width: 960px; margin: 20px auto -6px; padding: 14px 18px;
  background: var(--color-surface); border: 1px solid var(--color-line);
  border-left: 4px solid var(--color-accent); border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
.sheet-note-warning { border-left-color: var(--status-amber); background: var(--color-warning-bg); }
.sheet-note-done { border-left-color: var(--status-green); background: var(--color-success-bg); }
.sheet-note-error { border-left-color: var(--color-danger); background: var(--color-danger-bg); }
.sheet-note h3 { margin: 0 0 4px; font-size: .95rem; }
.sheet-note p { margin: 0; font-size: .84rem; color: var(--color-text-soft); }
.sheet-note .ledger { margin-top: 12px; background: #fff; }

/* Bordered-grid printable sheets (Loading Planning, Packing Planning) - the
   plain-table counterpart to .quote-sheet's boxed layout, for documents that
   are one continuous list rather than a header + line-items form. */
.sheet { max-width: 1100px; margin: 24px auto 60px; background: #fff; padding: 24px 28px; box-shadow: var(--shadow-card); }
.sheet-title { text-align: center; font-family: var(--font-mono); font-weight: 600; letter-spacing: .08em; margin: 0 0 16px; font-size: 1rem; }
.sheet h3 { margin: 22px 0 8px; font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; }
.sheet-table { width: 100%; border-collapse: collapse; border: 1px solid var(--color-ink); margin-bottom: 6px; font-size: .7rem; }
.sheet-table th, .sheet-table td { border: 1px solid var(--color-line-dark); padding: 5px 8px; vertical-align: middle; text-align: left; }
.sheet-table th { background: var(--color-paper); font-size: .62rem; text-transform: uppercase; letter-spacing: .03em; }
.sheet-table td.num, .sheet-table th.num { text-align: right; font-family: var(--font-mono); }
.sheet-table tfoot th, .sheet-table tfoot td { background: var(--color-paper); }
/* A manual pallet's ACTUAL PACKING / PACKING NO cells span every batch line
   it holds (rowspan), so they must not repeat the border each inner row
   would otherwise draw between them. */
.sheet-table td.sheet-rowspan { vertical-align: middle; text-align: center; }

/* Packing labels - the stickers that go on the pallets themselves. One
   .label-page per printed page, tiled 1/2/4-up; the page is chunked
   server-side rather than left to CSS auto-pagination, which no two
   browsers agree on and which would slice labels in half. */
.label-page {
  margin: 0 auto 18px; background: #fff; padding: 8mm; box-sizing: border-box;
  box-shadow: var(--shadow-card); display: grid; gap: 0;
  break-after: page; page-break-after: always;
}
.label-page:last-of-type { break-after: auto; page-break-after: auto; }
/* The page's own footprint, so the grid below has a fixed area to stretch
   the labels across evenly - an A4 sheet's usable area after the @page
   margin, in each orientation the user picks. */
.label-page.orientation-portrait { width: 210mm; min-height: 297mm; }
.label-page.orientation-landscape { width: 297mm; min-height: 210mm; }
/* Rows as well as columns are given explicit fractions (not left to
   auto-size on content) so 2 or 4 labels split the page into equal-height
   strips/quadrants rather than clumping at the top with blank space below. */
.label-page-1up { grid-template-columns: 1fr; grid-template-rows: 1fr; }
.label-page-2up { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
.label-page-4up { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
/* A label must never be split across a page, and stretches to fill its
   grid cell (see .label-page-*up rows above) with its own content spread
   top-to-bottom rather than left bunched at the top. */
.label {
  break-inside: avoid; page-break-inside: avoid; padding: 5mm;
  box-sizing: border-box; display: flex; flex-direction: column;
  justify-content: space-between;
}
/* Dotted cut lines between labels sharing a page, in both directions, so
   the user can see exactly where to cut. */
.label-page-2up .label:nth-child(n+2) { border-top: 1px dashed var(--color-line-dark); }
.label-page-4up .label:nth-child(n+3) { border-top: 1px dashed var(--color-line-dark); }
.label-page-4up .label:nth-child(2n) { border-left: 1px dashed var(--color-line-dark); }
.label-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8mm; margin-bottom: 4mm; }
.label-line { font-size: .72rem; margin-bottom: 3mm; }
.label-qr-id { color: var(--color-accent); font-weight: 700; font-family: var(--font-mono); }
/* The SVG carries its own width/height in mm, sized from the symbol's module
   count so every code prints at a scannable density (see
   PackingPlanningService.QR_MM_PER_MODULE). Nothing here may override that -
   only stop an unusually dense code overflowing a narrow 4-up label. */
.label-qr svg { display: block; max-width: 100%; height: auto; }
.label-table { width: 100%; border-collapse: collapse; border: 1px solid var(--color-ink); font-size: .62rem; }
.label-table th, .label-table td { border: 1px solid var(--color-line-dark); padding: 3px 6px; text-align: left; }
.label-table thead th { text-align: center; font-weight: 600; }
.label-table td.num, .label-table th.num { text-align: right; font-family: var(--font-mono); white-space: nowrap; }
.label-table tbody td { font-weight: 600; }
.label-table tfoot th { text-align: center; }
.label-table tfoot th.num { text-align: right; }
.label-origin { text-align: center; font-weight: 700; letter-spacing: .02em; margin-top: 4mm; font-size: 1.6rem; }
.label-page-4up .label-origin { font-size: 1rem; margin-top: 2mm; }
.label-page-1up .label-origin { font-size: 2.4rem; }

/* 4x6in / 4x4in modes - one sticker per page, sized for a TTP-244-class
   desktop label printer's die-cut stock rather than an A4 sheet. Thermal
   stock has little printable margin, so page/label padding is tighter than
   the A4 variants above, and text is scaled down to fit the much smaller
   area. */
.label-page.size-4x6.orientation-portrait { width: 4in; min-height: 6in; }
.label-page.size-4x6.orientation-landscape { width: 6in; min-height: 4in; }
.label-page.size-4x4 { width: 4in; min-height: 4in; }
.label-page.size-4x6,
.label-page.size-4x4 { padding: 2mm; }
.label-page.size-4x6 .label,
.label-page.size-4x4 .label { padding: 3mm; }
.label-page.size-4x6 .label-line,
.label-page.size-4x4 .label-line { font-size: .62rem; margin-bottom: 2mm; }
.label-page.size-4x6 .label-table,
.label-page.size-4x4 .label-table { font-size: .56rem; }
.label-page.size-4x6 .label-table th, .label-page.size-4x6 .label-table td,
.label-page.size-4x4 .label-table th, .label-page.size-4x4 .label-table td { padding: 2px 4px; }
.label-page.size-4x6 .label-origin,
.label-page.size-4x4 .label-origin { font-size: 1.1rem; margin-top: 2mm; }
/* 4x4 is a square, ~a third less area than 4x6, and squeezes the same six
   table rows into a shorter box - shave the table and QR down further so
   nothing clips the sticker's edge. */
.label-page.size-4x4 .label-line { font-size: .56rem; margin-bottom: 1.5mm; }
.label-page.size-4x4 .label-table { font-size: .5rem; }
.label-page.size-4x4 .label-origin { font-size: .9rem; }
.label-page.size-4x4 .label-qr svg { max-width: 32mm; }

.quote-sheet {
  max-width: 960px; margin: 24px auto 60px; background: #fff; padding: 30px 34px;
  box-shadow: var(--shadow-card); font-size: .6975rem; color: var(--color-text);
}
.quote-banner {
  text-align: center; font-family: var(--font-mono); font-weight: 600; letter-spacing: .1em;
  color: var(--color-ink); margin-bottom: 14px; font-size: .8275rem;
}
.quote-meta-table { width: 100%; border-collapse: collapse; border: 1px solid var(--color-ink); margin-bottom: 16px; }
.quote-meta-table td { border: 1px solid var(--color-line-dark); padding: 6px 9px; vertical-align: middle; text-align: left; }
.quote-left { text-align: left; }
.quote-side-label {
  text-align: center; vertical-align: middle;
  font-weight: 700; font-size: .5975rem; letter-spacing: .08em; background: var(--color-paper); width: 26px;
}
/* The rotation must live on an inner span, never on the <td> itself:
   Chromium's print/PDF rasterizer drops the collapsed table borders owned by
   a transformed cell, which erased the top/left border of the EXPORTER and
   IMPORTER cells in downloaded PDFs (screen rendering was unaffected). */
.quote-side-label span {
  display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg);
}
.quote-side-label-upright {
  text-align: center;
  font-weight: 700; font-size: .5975rem; letter-spacing: normal; line-height: 1.3;
  background: var(--color-paper); width: 78px;
}
.quote-side-label-upright span { writing-mode: horizontal-tb; transform: none; }
.quote-block { width: 40%; text-align: left; vertical-align: top; }
.quote-field-label { font-weight: 600; font-size: .5975rem; text-transform: uppercase; color: var(--color-text-soft); width: 26%; background: var(--color-paper); }
.quote-field-value { font-weight: 500; }

.quote-remarks { border: 1px solid var(--color-line-dark); padding: 8px 10px; margin-bottom: 16px; font-size: .6575rem; }

.quote-items-table { width: 100%; table-layout: fixed; border-collapse: collapse; border: 1px solid var(--color-ink); margin-bottom: 6px; }
.quote-items-table th {
  border: 1px solid var(--color-line-dark); background: var(--color-paper); padding: 6px 8px;
  font-size: .5575rem; text-transform: uppercase; letter-spacing: .05em; text-align: left;
}
.quote-items-table td { border: 1px solid var(--color-line-dark); padding: 6px 8px; vertical-align: middle; text-align: left; overflow-wrap: break-word; }
/* PRICE (USD) / TOTAL (USD) columns are numeric-only - never let them wrap,
   even a 7-figure amount ("$ 1,234,567.89") must sit on one line. */
.quote-items-table td.num, .quote-items-table th:nth-child(6), .quote-items-table th:nth-child(8) {
  white-space: nowrap;
}
/* QTY / ALT QTY carry a trailing unit; kept inline right after the number, the
   same way the Export Invoice sheet prints it. */
.quote-items-table td.num.quote-qty-cell { white-space: normal; }
.quote-items-table tfoot td { border: 1px solid var(--color-line-dark); padding: 6px 8px; background: var(--color-paper); vertical-align: middle; text-align: left; }
.quote-unit-sm { font-size: .85em; font-weight: normal; text-transform: uppercase; }
.quote-product-cell { vertical-align: bottom; }
.quote-charge-row td { padding: 2px 8px; }
.quote-total-row td { background: var(--color-paper); }
.quote-amount-words {
  vertical-align: top; text-align: left; font-size: .5975rem; text-transform: uppercase;
  letter-spacing: .02em; line-height: 1.4;
}

.quote-footnote { font-size: .6175rem; color: var(--color-text-soft); margin-bottom: 16px; }

.quote-bank-table { width: 100%; table-layout: fixed; border-collapse: collapse; border: 1px solid var(--color-ink); margin-bottom: 30px; }
.quote-bank-table th { border: 1px solid var(--color-line-dark); background: var(--color-paper); padding: 6px 8px; font-size: .6175rem; text-align: left; }
.quote-bank-table td { border: 1px solid var(--color-line-dark); padding: 8px 10px; vertical-align: top; text-align: left; overflow-wrap: break-word; }

/* Signature cell sits to the right of the bank name/address cell, sized to
   leave room for both a physical signature and a rubber stamp - mirrors the
   purchase order's po-sign-cell/po-sign-flex pattern instead of a separate
   full-width signature row. */
.quote-sign-cell { height: 110px; padding: 4px 6px; }
.quote-sign-flex {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 100%; text-align: left; font-weight: 600; font-size: .6175rem;
}

.quote-signature { display: flex; justify-content: space-between; align-items: flex-end; }
.quote-signature-box { text-align: left; min-width: 220px; border-top: 1px solid var(--color-line-dark); padding-top: 6px; }

@media print {
  .no-print { display: none !important; }
  .quote-print-body { background: #fff; }
  .quote-sheet { box-shadow: none; margin: 0; max-width: 100%; padding: 14px 34px; }
  .quote-banner { margin-bottom: 8px; }
  .quote-meta-table { margin-bottom: 8px; }
  .quote-footnote { margin-bottom: 8px; }
  .quote-bank-table { margin-bottom: 14px; }
  .quote-items-table td, .quote-items-table th, .quote-items-table tfoot td { padding: 4px 8px; }
  .quote-charge-row td { padding: 1px 8px; }
  /* Some browsers "print-economy" thin, dark table borders down to nothing
     (treating them like backgrounds to be lightened for ink-saving) - this
     is what was dropping the box around EXPORTER/IMPORTER. Forcing exact
     color adjustment keeps every border/background rendered as authored. */
  .quote-sheet, .quote-sheet * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .quote-meta-table, .quote-meta-table td,
  .quote-items-table, .quote-items-table th, .quote-items-table td,
  .quote-bank-table, .quote-bank-table th, .quote-bank-table td,
  .quote-remarks {
    border-color: var(--color-ink) !important;
  }
  /* The quotation sheet used to be forced to a fixed 278mm and its rows
     stretched by percentage to fill it. The blank filler row at the end of the
     item list now absorbs the leftover space instead, measured against the
     real page height (templates/_page_filler.html), so the sheet fills one
     page without the rows changing thickness with the item count - and
     without pushing itself onto a second page when the content is tall. */
}

.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at top left, var(--color-ink-lighter), var(--color-ink) 60%);
  padding: 20px;
}
.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--color-paper);
  border-radius: 10px;
  padding: 34px 32px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.login-card .mark { font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; color: var(--color-ink); }
.login-card .sub { font-size: .8rem; color: var(--color-text-soft); margin-bottom: 22px; }

@media (max-width: 800px) {
  .shell { flex-direction: column; }
  .sidebar { width: 100%; height: auto; position: relative; flex-direction: row; overflow-x: auto; padding: 10px 0; }
  .sidebar-nav { display: flex; overflow-x: auto; overflow-y: visible; }
  .sidebar-footer { display: none; }
  .brand { display: none; }
  .nav-section-label { display: none; }
  .nav-link { border-left: none; border-bottom: 3px solid transparent; white-space: nowrap; }
  .nav-link.active { border-left: none; border-bottom-color: var(--color-accent); }
  .main { padding: 20px; }
}
