/* LAK Portal — palette matched to the public site (dark + teal #1a6c7a). */

:root {
  --accent:        #1a6c7a;
  --accent-hover:  rgba(26,108,122,.78);
  --bg-dark:       #1a1a1a;
  --bg-darker:     #0d0d0d;
  --bg-mid:        #2a2a2a;
  --bg-card:       #1f1f1f;
  --text:          #fff;
  --text-muted:    rgba(255,255,255,.6);
  --text-dim:      rgba(255,255,255,.4);
  --border:        rgba(255,255,255,.12);
  --border-strong: rgba(255,255,255,.22);
  --red:           #D44A2E;
  --green:         #3DAA6B;
  --gold:          #C9A84C;  /* still used for price/status pills */
  /* Six rules already asked for var(--bg) and nothing ever defined it, so those
     six had no background at all. Invisible where they sit on a panel of the
     same colour; obvious the moment one of them floats over text, which is how
     the "Lisa fraas" menu came out see-through. It follows --bg-card, so every
     theme gets it. */
  --bg:            var(--bg-card);
}

/* Medium theme — warm grey paper. Cards lift off the background; text is
   near-black for proper daylight contrast (WCAG-ish), accents stay teal. */
:root[data-theme="medium"] {
  --bg-dark:       #cfd3d8;   /* page background */
  --bg-darker:     #b9bec5;   /* topbar / strong areas */
  --bg-mid:        #ffffff;
  --bg-card:       #f4f5f7;   /* cards lifted from page bg */
  --text:          #1a1f26;
  --text-muted:    rgba(20,25,30,.72);
  --text-dim:      rgba(20,25,30,.48);
  --border:        rgba(0,0,0,.18);
  --border-strong: rgba(0,0,0,.30);
}
:root[data-theme="medium"] .row-chip:not(.service-pill):not(.ledger-pos):not(.ledger-neg):not(.accent):not(.good),
:root[data-theme="medium"] .meta-item { background: rgba(0,0,0,.07); }
:root[data-theme="medium"] .ledger-pos,
:root[data-theme="medium"] .row-chip.good { background: rgba(61,170,107,.18); color: #1a5a3a; }
:root[data-theme="medium"] .ledger-neg { background: rgba(212,74,46,.18); color: #8a2a18; }

/* Light theme — daylight mode */
:root[data-theme="light"] {
  --bg-dark:       #f4f5f7;
  --bg-darker:     #e7e9ee;
  --bg-mid:        #ffffff;
  --bg-card:       #ffffff;
  --text:          #1a1a1a;
  --text-muted:    rgba(0,0,0,.62);
  --text-dim:      rgba(0,0,0,.42);
  --border:        rgba(0,0,0,.12);
  --border-strong: rgba(0,0,0,.22);
}
:root[data-theme="light"] .pp-cup.sel { color: #fff; }
:root[data-theme="light"] .row-chip:not(.service-pill):not(.ledger-pos):not(.ledger-neg):not(.accent):not(.good),
:root[data-theme="light"] .meta-item { background: rgba(0,0,0,.05); }
:root[data-theme="light"] .ledger-pos,
:root[data-theme="light"] .row-chip.good { background: rgba(61,170,107,.18); color: #1a5a3a; }
:root[data-theme="light"] .ledger-neg { background: rgba(212,74,46,.18); color: #8a2a18; }

* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: 'DM Sans', sans-serif;
  background: var(--bg-dark);
  color: var(--text);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; transition: .15s; }
a:hover { color: var(--accent-hover); }

/* ── Login screen ─────────────────────────────── */
.login-screen {
  position: fixed; inset: 0;
  background: linear-gradient(180deg, var(--bg-darker) 0%, var(--bg-dark) 100%);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  z-index: 1000; gap: 20px; padding: 24px;
}
.lcard {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 34px 30px;
  width: 100%; max-width: 420px;
  display: flex; flex-direction: column; gap: 13px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
}
.ltitle {
  color: var(--text);
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 300; font-size: 24px;
  letter-spacing: 6px; text-transform: uppercase;
  text-align: center;
}
.lsub {
  color: var(--text-dim);
  font-size: 11px; letter-spacing: 4px;
  text-align: center; margin-top: -6px;
}
.role-btns {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px;
  margin-top: 8px;
}
.rbtn {
  padding: 10px 4px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font-family: 'DM Sans', sans-serif;
  font-size: 11px; font-weight: 500;
  letter-spacing: 1.5px; text-transform: uppercase;
  cursor: pointer; transition: .15s;
}
.rbtn:hover { border-color: var(--border-strong); }
.rbtn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text);
  font-weight: 700;
}
.lin {
  width: 100%;
  padding: 12px 14px;
  border-radius: 8px;
  border: 1.5px solid var(--border);
  background: rgba(255,255,255,.04);
  color: var(--text);
  font: 14px 'DM Sans', sans-serif;
  outline: none; transition: .15s;
}
.lin::placeholder { color: var(--text-dim); }
.lin:focus { border-color: var(--accent); background: rgba(255,255,255,.06); }
.lbtn {
  width: 100%;
  padding: 13px;
  background: var(--accent);
  color: var(--text);
  border: none; border-radius: 8px;
  font: 600 12px 'DM Sans', sans-serif;
  letter-spacing: 2px; text-transform: uppercase;
  cursor: pointer; transition: .15s;
}
.lbtn:hover     { background: var(--accent-hover); }
.lbtn:disabled  { opacity: .5; cursor: wait; }
.lerr {
  color: #ff7a6b;
  font-size: 12px; text-align: center;
  min-height: 16px;
}

/* ── Signed-in shell ───────────────────────────── */
/* The header scrolls sideways rather than overflowing the page.
   Erik, 2026-09-26: on a narrow screen the five things in here did not fit,
   and because nothing could scroll they pushed the DOCUMENT wider than the
   viewport. Everything else then kept the old width and left a band of empty
   space down the right — it read as the page having gone narrow, but the page
   was fine; the header was too wide. Same treatment as .apptabs below. */
.topbar {
  background: var(--bg-darker);
  padding: 10px 14px;
  display: flex; align-items: center; gap: 12px;
  position: sticky; top: 0; z-index: 100;
  border-bottom: 1px solid var(--border);
  overflow-x: auto; scrollbar-width: none;
}
.topbar::-webkit-scrollbar { display: none; }
/* Nothing in the bar may be squeezed: shrinking is what turned the role badge
   into two cramped lines before the row gave up and overflowed anyway. */
.topbar > * { flex: 0 0 auto; }
.topbar-title {
  color: var(--text);
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 300; font-size: 18px;
  letter-spacing: 4px; text-transform: uppercase;
  /* Grows to push the rest right on a wide screen, keeps its own width on a
     narrow one and lets the bar scroll instead. */
  flex: 1 0 auto;
}
.role-badge, .logout-btn, .ask-btn, .lang-switcher { white-space: nowrap; }
.role-badge {
  background: rgba(255,255,255,.06);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 11px;
  font-size: 10px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
}
.logout-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 7px;
  padding: 6px 12px;
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: .5px;
  cursor: pointer; transition: .15s;
}
.logout-btn:hover { border-color: var(--red); color: var(--red); }

/* "Ask" — the customer's one way to start a conversation, on every tab.
   Shaped like the sign-out button so the header keeps one visual language,
   but tinted to the accent: it is the thing we WANT pressed. */
.ask-btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent);
  border-radius: 7px;
  padding: 6px 12px;
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: .5px;
  cursor: pointer; transition: .15s;
}
.ask-btn:hover { background: var(--accent); color: var(--text); }
/* On a phone the header already carries five things. Keep the envelope, drop
   the word — the title attribute still says what it is. */
@media (max-width: 560px) {
  .ask-btn-text { display: none; }
  .ask-btn { padding: 6px 9px; }
}

/* Section tabs under the topbar */
.apptabs {
  background: var(--bg-darker);
  display: flex; overflow-x: auto; gap: 2px;
  padding: 0 8px;
  border-bottom: 1px solid var(--border);
  scrollbar-width: none;
}
.apptabs::-webkit-scrollbar { display: none; }
.tab {
  padding: 12px 14px;
  background: transparent; border: none;
  color: var(--text-dim);
  font: 500 12px 'DM Sans',sans-serif;
  letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer; white-space: nowrap;
  border-bottom: 3px solid transparent;
  transition: .15s;
}
.tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.tab:hover:not(.active) { color: var(--text-muted); }

.main {
  padding: 18px;
  max-width: 1200px;
  margin: 0 auto;
}
.section { display: none; }
.section.active { display: block; }

.section-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 14px; flex-wrap: wrap; gap: 8px;
}
.section-title {
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 300; font-size: 24px;
  letter-spacing: 4px; text-transform: uppercase;
}
.section-count {
  color: var(--text-dim);
  font-size: 12px;
  letter-spacing: 1px;
}

/* Generic card (used for the empty-state shell) */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 10px;
}
.card-header {
  padding: 10px 14px;
  background: rgba(255,255,255,.04);
  border-bottom: 1px solid var(--border);
  font-weight: 600; font-size: 12px;
  letter-spacing: 1px; text-transform: uppercase;
  color: var(--text-muted);
}
.card-body {
  padding: 16px;
  color: var(--text-muted);
  font-size: 14px; line-height: 1.5;
}
.card-body strong { color: var(--text); }
.card-body code {
  background: rgba(255,255,255,.06);
  padding: 2px 6px; border-radius: 4px;
  font: 12px 'DM Mono', monospace;
  color: var(--accent);
}
.card-body p { margin-top: 10px; }

/* ── List rows (clients, orders, etc.) ──────────── */
.search-bar {
  display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap;
}
.search-input {
  flex: 1; min-width: 160px;
  padding: 9px 12px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--text);
  font: 13px 'DM Sans',sans-serif;
  outline: none; transition: .15s;
}
.search-input:focus { border-color: var(--accent); }

/* Copy-to-clipboard button on a client field (admin only). Sits in the field's
   bottom-right corner rather than beside the input, so adding it does not
   re-flow a form that was laid out without it. */
/* The wrapper is the input's own box, so the button cannot drift away from it
   however the field around it grows or shifts. */
.copy-wrap { position: relative; display: block; width: 100%; min-width: 0; }
.copy-wrap > input, .copy-wrap > textarea { width: 100%; }
.copy-btn {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: transparent; border: 1px solid var(--border); color: var(--text-dim);
  border-radius: 5px; width: 24px; height: 24px; line-height: 1;
  font-size: 13px; cursor: pointer; transition: .12s; padding: 0;
}
/* Every button on the same right edge, including the datalist ones — Erik
   asked for the column to line up. It sits over the arrow the browser draws
   there; tapping anywhere else in the field still opens the suggestions, so
   the arrow was never the only way in. */
/* A textarea is tall; centred would put the button in the middle of the text. */
.copy-wrap.is-area > .copy-btn { top: auto; bottom: 8px; transform: none; }
/* Keep the typed text out from under the button. */
.copy-wrap > input, .copy-wrap > textarea { padding-right: 36px; }
.copy-btn:hover { border-color: var(--accent); color: var(--accent); }
.copy-btn.ok { border-color: var(--green); color: var(--green); }
.copy-btn.ok::after { content: ' ✓'; }

/* On a narrow screen the text box gets a line of its own and the dropdowns
   pair up underneath it. Erik, 2026-09-27: the search box was too narrow to
   use — it was sharing a line with a 130-200px select and keeping whatever
   was left.
   `!important` is not decoration here: every one of these controls carries an
   inline `min-width` in index.php (about thirty of them), and an inline style
   beats a stylesheet rule. Overriding at the one place that knows the screen
   is narrow is better than editing thirty tags. */
@media (max-width: 620px) {
  .search-bar > .search-input        { min-width: 0 !important; }
  /* 0 0, not 1 1: a 100% basis still shares a line when the item is allowed to
     shrink, which left the box NARROWER than before (208px → 169px). Refusing
     to shrink is what actually puts it on a line of its own. */
  .search-bar > input.search-input   { flex: 0 0 100% !important; max-width: none !important; }
  .search-bar > select.search-input  { flex: 1 0 calc(50% - 3px) !important; }
}

.row-list { display: flex; flex-direction: column; gap: 6px; }
.row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: .12s;
}
.row:hover { border-color: var(--border-strong); }
.row-id   { font: 500 11px 'DM Mono',monospace; color: var(--text-dim); min-width: 60px; }
.row-name { font-weight: 600; font-size: 14px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-meta { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row-chip {
  background: rgba(255,255,255,.06);
  border: 1px solid var(--border);
  color: var(--text-muted);
  border-radius: 20px;
  padding: 2px 9px;
  font-size: 10px; font-weight: 600;
  letter-spacing: .5px; text-transform: uppercase;
}
.row-chip.accent      { background: var(--accent); border-color: var(--accent); color: var(--text); }
.row-chip.ledger-pos  { background: rgba(61,170,107,.15); border-color: rgba(61,170,107,.4); color: var(--green); font-family:'DM Mono',monospace; }
.row-chip.ledger-neg  { background: rgba(212,74,46,.15);  border-color: rgba(212,74,46,.4);  color: var(--red);   font-family:'DM Mono',monospace; }
.row-chip.good        { background: rgba(61,170,107,.15); border-color: rgba(61,170,107,.4); color: var(--green); }
.row-note {
  display: block; margin-top: 2px;
  font-size: 11px; color: var(--text-dim); font-weight: 400;
}

/* "How did it run?" — the client-side ask for rpm + speed, and the quick form
   behind it. Deliberately plain: the card has to read as a question, not as
   another list to scroll past. */
.dash-runs-lead {
  padding: 10px 14px 12px;
  font-size: 13px; line-height: 1.5; color: var(--text-muted);
}
.run-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.run-row-main { flex: 1 1 180px; min-width: 0; }
.run-best { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.run-pitch {
  font-family: 'DM Mono', monospace;
  font-size: 12px; font-weight: 500;
  color: var(--accent-text, var(--text-muted));
  opacity: .85; margin-left: 4px;
}
.run-odd  { color: var(--red); }

/* The AI packet's manual-copy fallback, for in-app browsers that refuse the
   clipboard API. Monospace so a stray line break is visible before pasting. */
.aip-open { font-size: 12px; color: var(--text-dim); }
.aip-open a {
  color: var(--accent); text-decoration: none; margin-left: 8px;
  border-bottom: 1px solid transparent;
}
.aip-open a:hover { border-bottom-color: var(--accent); }
.aip-text {
  width: 100%; font: 12px/1.45 'DM Mono', monospace;
  background: var(--bg-darker); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: 8px; padding: 10px;
  resize: vertical;
}

/* My LAK — the customer's album. Square tiles because the cropper already
   makes every photo a square, so the grid never has a ragged edge. */
.gal-year { margin-top: 18px; }
.gal-year-head {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 15px; font-weight: 600; letter-spacing: .5px;
  margin: 0 0 10px; padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.gal-year-n { font-size: 11px; color: var(--text-dim); font-weight: 400; }
.gal-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.gal-tile {
  position: relative; margin: 0; cursor: pointer;
  border-radius: 10px; overflow: hidden;
  background: var(--bg-darker); border: 1px solid var(--border);
}
.gal-tile img {
  display: block; width: 100%; aspect-ratio: 1/1; object-fit: cover;
}
.gal-tile figcaption {
  display: flex; flex-direction: column; gap: 3px;
  padding: 8px 10px 10px;
}
.gal-badge {
  align-self: flex-start;
  font-size: 9px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase;
  color: var(--text-dim);
}
.gal-cap  { font-size: 12px; line-height: 1.35; color: var(--text); }
.gal-prop { font-size: 11px; color: var(--text-dim); font-family: 'DM Mono', monospace; }
.gal-full {
  display: block; width: 100%; max-height: 52vh; object-fit: contain;
  border-radius: 8px; background: var(--bg-darker); margin-bottom: 14px;
}
.gal-cats { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.gal-cat input { position: absolute; opacity: 0; pointer-events: none; }
.gal-cat span {
  display: inline-block; padding: 6px 12px; border-radius: 20px;
  border: 1px solid var(--border); background: var(--bg-darker);
  font-size: 12px; color: var(--text-muted); cursor: pointer;
}
.gal-cat input:checked + span {
  border-color: var(--accent); color: var(--text); background: var(--accent);
}

/* Compare table. A table because the point is reading down a column — five
   props, one number each, differences visible without arithmetic. It scrolls
   sideways on a phone rather than squeezing the columns into unreadability. */
/* The "already in the comparison" pill, on the closed row between the serial
   and the name. Fixed size so it never eats the name's space. */
.cmp-pill { flex: 0 0 auto; }
.cmp-wrap  { overflow-x: auto; }
.cmp-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.cmp-table th,
.cmp-table td {
  padding: 9px 12px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.cmp-table th {
  font-size: 10px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-dim); text-align: right;
}
.cmp-table th:first-child,
.cmp-table td:first-child { text-align: left; }
.cmp-table td { font-family: 'DM Mono', monospace; color: var(--text); }
.cmp-table td.cmp-name { font-family: inherit; font-weight: 600; }
.cmp-table tbody tr:last-child td { border-bottom: 0; }
.cmp-table td:last-child { width: 1%; padding-left: 4px; }
.btn-ghost.is-on { border-color: var(--accent); color: var(--accent); }
.req-spec {
  padding: 10px 12px; margin-bottom: 14px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-darker); font-size: 13px; line-height: 1.5;
}
.run-more { display: block; margin: 10px auto 12px; }
.run-pair { display: flex; gap: 10px; }
.run-pair > * { flex: 1 1 0; min-width: 0; }
.run-slip {
  margin: 4px 0 14px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-darker);
  font-size: 13px; color: var(--text-dim);
}
.run-slip.ok   { border-color: rgba(61,170,107,.45); color: var(--text); }
.run-slip.ok b { font-size: 20px; color: var(--green); font-family: 'DM Mono', monospace; }
.run-slip.warn { border-color: rgba(212,74,46,.45);  color: var(--red); }
.run-done { text-align: center; padding: 14px 0 20px; }
.run-done-big {
  font-family: 'DM Mono', monospace;
  font-size: 46px; line-height: 1.1; color: var(--green);
}
.run-done-cap {
  font-size: 12px; letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-dim); margin-top: 4px;
}
.run-done p { margin-top: 16px; font-size: 14px; line-height: 1.55; color: var(--text-muted); }

/* Dashboard KPI tiles */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
.kpi {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
}
.kpi-label {
  font-size: 10px;
  color: var(--text-dim);
  letter-spacing: 1.4px;
  text-transform: uppercase;
  font-weight: 600;
}
.kpi-value {
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 300;
  font-size: 38px;
  letter-spacing: 1px;
  line-height: 1.1;
  color: var(--text);
  margin-top: 6px;
}
.kpi-sub {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 3px;
  letter-spacing: .5px;
}
.kpi.accent { border-color: rgba(26,108,122,.5); background: linear-gradient(135deg, rgba(26,108,122,.18), var(--bg-card)); }
/* Worker Pay: the tiles are recomputed by the server when the worker filter
   changes, so they are briefly stale. Dimmed rather than blanked — a number
   fading for a moment reads as "updating", an empty tile reads as "zero". */
.kpi-busy { opacity: .45; transition: opacity .12s; pointer-events: none; }
.kpi.accent .kpi-value { color: var(--accent); }
.kpi.green  { border-color: rgba(61,170,107,.4); background: linear-gradient(135deg, rgba(61,170,107,.15), var(--bg-card)); }
.kpi.green  .kpi-value { color: var(--green); }
.kpi.danger { border-color: rgba(212,74,46,.45); background: linear-gradient(135deg, rgba(212,74,46,.15), var(--bg-card)); }
.kpi.danger .kpi-value { color: var(--red); }

/* ── Castings inventory ──────────────────────────────────────────────
   Dense on purpose: two dozen moulds across ten classes has to fit on one
   screen, or finding one means scrolling past the rest. */
#stock-availability { display: flex; flex-wrap: wrap; gap: 6px; }
.ov-class {
  display: flex; align-items: center; gap: 5px;
  padding: 5px 9px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-card);
}
.ov-name { font-weight: 700; font-size: 12px; margin-right: 3px; }
.ov-cell {
  font-size: 11px; padding: 2px 6px; border-radius: 5px;
  background: rgba(128,128,128,.12); white-space: nowrap;
}
.ov-cell b { font-weight: 700; margin-left: 2px; }
.ov-cell.ok   { background: rgba(61,170,107,.18);  color: var(--green); }
.ov-cell.low  { background: rgba(201,168,76,.20);  color: #c9a84c; }
.ov-cell.out  { background: rgba(212,74,46,.18);   color: var(--red); }
.ov-cell.na   { opacity: .55; }

/* Castings list: one row per mould, read as a chain — the mould and its shelf
   count, then the classes it builds, then the bore pile each of those draws
   from. .stock-row below is still used by the invoice list. */
.cast-row { display: flex; align-items: stretch; margin-bottom: 7px; cursor: pointer; }
.cast-row.is-off { opacity: .5; }
.cast-row:hover .cast-head { background: var(--bg-mid); border-color: var(--border-strong); }

.cast-head {
  flex: 0 0 186px; background: var(--bg-mid);
  border: 1px solid var(--border); border-right: none; border-radius: 9px 0 0 9px;
  padding: 7px 9px; display: flex; flex-direction: column; gap: 2px; justify-content: center;
}
.cast-name { font-size: 12.5px; font-weight: 600; line-height: 1.25; }
.cast-qty { font-size: 19px; font-weight: 700; line-height: 1.1; }
.cast-qty > i { font-style: normal; font-size: 11px; font-weight: 500; color: var(--text-dim); margin-left: 5px; }
.cast-qty.zero { color: var(--text-dim); }
.cast-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.cast-tags:empty { display: none; }
.cast-tags .tag { font-size: 10px; padding: 1px 5px; border-radius: 4px;
  background: rgba(128,128,128,.18); color: var(--text-muted); }
.cast-tags .tag.part { background: rgba(26,108,122,.30); color: #7fd0dd; }
.cast-tags .tag.off  { background: rgba(212,74,46,.16);  color: var(--red); }
.cast-tags .tag.low  { background: rgba(201,168,76,.20); color: var(--gold); }
.cast-actions { display: flex; gap: 3px; margin-top: 3px; }
.cast-actions .btn-ghost { padding: 1px 7px; font-size: 12px; }

/* The connector between the two boxes. */
.cast-join {
  flex: 0 0 16px; position: relative; background: var(--bg-mid);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.cast-join::after {
  content: ''; position: absolute; top: 50%; left: 0; right: 0;
  height: 1px; background: var(--border-strong);
}

.cast-body {
  flex: 1; min-width: 0; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 0 9px 9px 0;
  padding: 4px 8px; display: flex; flex-direction: column; justify-content: center; gap: 2px;
}
.lane { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.lane + .lane { border-top: 1px dashed var(--border); padding-top: 2px; }
.lane-classes { display: flex; flex-wrap: wrap; gap: 4px; flex: 1; min-width: 0; }
.lane-classes .cls { font-size: 11px; padding: 1px 6px; border-radius: 5px;
  background: rgba(128,128,128,.14); white-space: nowrap; }
.lane-classes .cls b { font-weight: 700; color: var(--text-muted); margin-left: 3px; }
.lane-arrow { color: var(--text-dim); font-size: 12px; flex: 0 0 auto; }
.lane-none { font-size: 11px; color: var(--text-dim); font-style: italic; flex: 1; }
.pile { font-size: 11px; padding: 2px 7px; border-radius: 5px; white-space: nowrap;
  background: rgba(61,170,107,.15); color: var(--green); flex: 0 0 auto; }
.pile > i { font-style: normal; opacity: .75; }
.pile > b { font-weight: 700; font-size: 12px; margin-left: 4px; }
.pile.zero { background: rgba(212,74,46,.15); color: var(--red); }

@media (max-width: 720px) {
  .cast-row { flex-direction: column; }
  .cast-head { flex: none; border-right: 1px solid var(--border); border-bottom: none;
    border-radius: 9px 9px 0 0; }
  .cast-join { flex: none; height: 9px; border: none;
    border-left: 1px solid var(--border); border-right: 1px solid var(--border); }
  .cast-join::after { top: 0; bottom: 0; left: 50%; right: auto; width: 1px; height: auto; }
  .cast-body { border-radius: 0 0 9px 9px; }
}

.stock-row {
  display: grid; grid-template-columns: minmax(150px, 1.4fr) 2fr auto auto;
  align-items: center; gap: 8px;
  padding: 5px 6px; border-radius: 6px; cursor: pointer;
}
.stock-row:hover { background: rgba(128,128,128,.10); }
.stock-row.is-off { opacity: .55; }
.stock-name { font-size: 12.5px; font-weight: 600; }
.stock-specs { display: flex; flex-wrap: wrap; gap: 4px; }
.stock-spec, .stock-bore {
  font-size: 11px; padding: 1px 6px; border-radius: 5px;
  background: rgba(61,170,107,.15); color: var(--green); white-space: nowrap;
}
.stock-spec b, .stock-bore b { font-weight: 700; }
.stock-spec.zero, .stock-bore.empty { background: rgba(128,128,128,.14); color: inherit; opacity: .65; }
.stock-bore i { font-style: normal; opacity: .7; margin-right: 4px; }
.stock-flags { display: flex; gap: 4px; }
.stock-actions { display: flex; gap: 3px; opacity: 0; transition: opacity .12s; }
.stock-row:hover .stock-actions, .stock-row:focus-within .stock-actions { opacity: 1; }
.stock-actions .btn-ghost { padding: 2px 8px; font-size: 12px; }

/* A serial already in use by another prop. Amber, not red: it is sometimes
   deliberate, so this warns rather than blocks. */
input.serial-dup { border-color: rgba(201,168,76,.8) !important; background: rgba(201,168,76,.10); }
.serial-warn { color: #c9a84c; font-weight: 600; }

/* A field whose value the system no longer uses — greyed, but still readable,
   so it is obvious the number is there and equally obvious it is not in play. */
input.is-overridden{opacity:.5;font-style:italic;cursor:not-allowed}

/* Transport price list in Shop → Settings. */
.ship-methods{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:4px}
@media(max-width:820px){.ship-methods{grid-template-columns:1fr}}
.ship-method{border:1px solid var(--border);border-radius:10px;padding:12px;background:var(--bg-card)}
.ship-method-head{display:flex;align-items:center;gap:10px;margin-bottom:10px;flex-wrap:wrap}
.ship-name{flex:1;min-width:120px;font-weight:600}
.ship-rates{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}
.ship-rate,.ship-rate-head{display:grid;grid-template-columns:1fr 74px 74px 74px auto;gap:6px;align-items:center}
.ship-rate-head{margin-bottom:4px}
.ship-rate-head span{font-size:10px;letter-spacing:1px;text-transform:uppercase;opacity:.6}
.ship-rate .btn-ghost{padding:2px 9px}
@media(max-width:1100px){
  .ship-rate,.ship-rate-head{grid-template-columns:1fr 60px 60px 60px auto}
}

/* Admin housekeeping bar on an expanded client card. */
.cd-admin {
  display: flex; gap: 6px; flex-wrap: wrap;
  padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--border);
}
.cd-admin .btn-ghost { font-size: 12px; padding: 4px 10px; }

/* Shop purchases on a client card. The purchase is an issued invoice and keeps
   the details it was sent to; where those disagree with the record, the card
   says so rather than silently preferring one of them. */
.cd-shop { display: flex; flex-direction: column; gap: 7px; margin-bottom: 14px; }
.cd-shop-row { padding: 8px 11px; border-radius: 7px; font-size: 12.5px;
  border: 1px solid var(--border); background: var(--bg-darker); }
.cd-shop-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.cd-shop-date, .cd-shop-total { color: var(--text-muted); font-size: 12px; }
.cd-shop-total { margin-left: auto; font-weight: 600; color: var(--text); }
.cd-shop-addr { margin-top: 3px; color: var(--text-muted); }
.cd-shop-diff, .cd-shop-fill { margin-top: 6px; padding: 6px 9px; border-radius: 5px;
  font-size: 12px; line-height: 1.5; }
.cd-shop-diff { background: rgba(214,138,42,.12); border: 1px solid rgba(214,138,42,.35);
  color: #e7b168; }
/* Each mismatch on its own line — run together they read as one sentence and
   it stops being obvious how many fields actually disagree. */
.cd-shop-diff span { display: block; }
.cd-shop-diff b, .cd-shop-fill b { color: var(--text); font-weight: 600; }
.cd-shop-diff i { font-style: normal; color: #ffd79a; }
.cd-shop-fill { background: rgba(26,108,122,.12); border: 1px solid rgba(26,108,122,.35);
  color: var(--text-muted); }
.cd-admin-danger { color: var(--red); }
.cd-admin-danger:hover { border-color: rgba(212,74,46,.5); }

/* ── Manual invoice ──────────────────────────────────────────────────
   Propellers are picked off the orders list rather than retyped. */
.inv-pick { border: 1px solid var(--border); border-radius: 10px; padding: 8px; margin-bottom: 12px; }
.inv-pick-head { display: flex; gap: 10px; align-items: center; margin-bottom: 6px; flex-wrap: wrap; }
.inv-pick-head .search-input { flex: 1; min-width: 180px; }
.inv-pick-list { max-height: 260px; overflow-y: auto; }
.inv-cand {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 5px 7px; border-radius: 6px; cursor: pointer; font-size: 12.5px;
}
.inv-cand:hover { background: rgba(128,128,128,.10); }
.inv-cand.on { background: rgba(61,170,107,.14); }
.inv-cand-main { display: flex; gap: 8px; align-items: baseline; min-width: 0; }
.inv-cand-spec { opacity: .7; font-size: 11.5px; }
.inv-cand-meta { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.inv-cand-add { font-size: 11px; opacity: .6; min-width: 46px; text-align: right; }
.inv-cand.on .inv-cand-add { color: var(--green); opacity: 1; }

.inv-line {
  display: grid; grid-template-columns: 2fr 1fr .6fr .9fr auto;
  gap: 8px; margin-bottom: 6px; align-items: center;
}
.inv-line-src { grid-column: 1 / -1; font-size: 11px; opacity: .55; margin-top: -2px; }
.inv-totals { font-size: 13px; margin-left: auto; }

/* Shared with the storefront: a VAT number VIES confirmed turns the box green. */
.vat-status { font-size: 11px; line-height: 1.45; margin-top: 3px; display: none; }
.vat-status.checking, .vat-status.ok, .vat-status.warn { display: block; }
.vat-status.checking { opacity: .6; }
.vat-status.ok   { color: var(--green); }
.vat-status.warn { color: #c9a84c; }
input.is-valid   { border-color: rgba(61,170,107,.7) !important; background: rgba(61,170,107,.10); }
input.is-invalid { border-color: rgba(201,168,76,.7) !important; }
input.is-checking { border-color: var(--border) !important; }

@media (max-width: 720px) {
  .inv-line { grid-template-columns: 1fr 1fr auto; }
  .inv-cand { flex-direction: column; align-items: flex-start; gap: 3px; }
  .inv-cand-meta { justify-content: flex-start; }
}

/* "Used for" picker inside the casting editor: one row per class, tick the
   blade counts it is used for, pick the bore it draws on. */
.lk-filter { width: 100%; margin-bottom: 6px; }
.lk-grid {
  max-height: 260px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px; padding: 4px;
}
.lk-row {
  display: grid; grid-template-columns: 1fr auto auto;
  align-items: center; gap: 8px; padding: 3px 6px; border-radius: 6px;
}
/* Same trap as .psel-row: the grid above outranks the browser's
   `[hidden] { display: none }`, so the filter box in this modal set .hidden
   and nothing moved. Found 2026-09-27 while fixing the print picker. */
.lk-row[hidden] { display: none; }
.lk-row:hover { background: rgba(128,128,128,.10); }
.lk-row.on { background: rgba(61,170,107,.10); }
.lk-class { font-size: 12.5px; font-weight: 600; }
.lk-boxes { display: flex; gap: 4px; }
.lk-box {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
  font-size: 11px; padding: 2px 7px; border-radius: 5px;
  border: 1px solid var(--border); background: var(--bg-card); user-select: none;
}
.lk-box input { margin: 0; }
.lk-box.on { border-color: rgba(61,170,107,.55); background: rgba(61,170,107,.18); color: var(--green); }
.lk-bore { font-size: 11px; padding: 2px 4px; min-width: 88px; }

/* Per-bore entry inside the casting editor. */
.bore-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }
.bore-cell { display: flex; flex-direction: column; gap: 3px; }
.bore-cell > span { font-size: 11px; opacity: .7; }
.bore-cell input { width: 100%; }

@media (max-width: 720px) {
  .stock-row { grid-template-columns: 1fr auto; row-gap: 4px; }
  .stock-specs { grid-column: 1 / -1; }
  .stock-actions { opacity: 1; }
}

/* Design B zones inside the expanded detail */
.zone-b {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  background: rgba(0,0,0,.25);
  border-radius: 8px;
  padding: 6px;
}
.stat-cell {
  flex: 1 1 90px;
  min-width: 80px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  text-align: center;
}
.stat-cell.stat-price {
  background: rgba(61,170,107,.15);
  border-color: rgba(61,170,107,.4);
}
.stat-cell.stat-price .stat-value { color: var(--green); }
.stat-label {
  font-size: 9px; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 1px; font-weight: 600;
  margin-bottom: 2px;
}
.stat-value {
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 600; font-size: 17px;
  color: var(--text);
  letter-spacing: .5px;
}

.zone-c {
  display: flex; flex-wrap: wrap;
  gap: 4px 14px;
  padding: 6px 4px;
  font-size: 12px;
  color: var(--text-muted);
}
.meta-item { white-space: nowrap; }
.meta-label { color: var(--text-dim); text-transform: uppercase; font-size: 9px; letter-spacing: 1px; }
.meta-item strong { color: var(--text); font-weight: 600; margin-left: 4px; }

/* Status button strip */
.status-strip {
  display: flex; gap: 4px;
  flex-wrap: wrap;
}
.status-btn {
  border: 1.5px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  border-radius: 6px;
  padding: 6px 10px;
  font: 600 10px 'DM Sans',sans-serif;
  letter-spacing: .8px; text-transform: uppercase;
  cursor: pointer; transition: .12s;
}
.status-btn:hover { border-color: var(--border-strong); color: var(--text); }
.status-btn.s-inprogress.active { background: #E65100; border-color: #E65100; color: #fff; }
.status-btn.s-done.active       { background: #2E7D32; border-color: #2E7D32; color: #fff; }
.status-btn.s-ready.active      { background: #3949AB; border-color: #3949AB; color: #fff; }
.status-btn.s-shipped.active    { background: #1565C0; border-color: #1565C0; color: #fff; }
.status-btn.s-sendclient.active { background: #1a6c7a; border-color: #1a6c7a; color: #fff; }
.status-btn.s-sendacct.active   { background: #5e35b1; border-color: #5e35b1; color: #fff; }

/* Half / Full toggle */
.ht-toggle { display: flex; gap: 0; }
.ht-btn {
  border: 1.5px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  padding: 6px 10px;
  font: 600 10px 'DM Sans',sans-serif;
  letter-spacing: .8px;
  cursor: pointer; transition: .12s;
}
.ht-btn:first-child { border-radius: 6px 0 0 6px; border-right-width: 0; }
.ht-btn:last-child  { border-radius: 0 6px 6px 0; }
.ht-btn:hover { color: var(--text); }
.ht-btn.active {
  background: var(--accent); border-color: var(--accent); color: var(--text);
}

/* Worker "Mark Done" prominent button */
.btn-mark-done {
  background: var(--green); color: #fff;
  border: none; border-radius: 6px;
  padding: 7px 14px;
  font: 700 11px 'DM Sans',sans-serif;
  letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer; transition: .12s;
}
.btn-mark-done:hover { background: #4ABF7B; }

/* ── It rains money when a propeller is finished ──────────────────────
   Erik, 2026-09-29. Pure decoration: nothing here may catch a click or
   affect layout, so the layer is fixed, full-screen and transparent to
   the pointer, and it deletes itself when the last note lands. */
.cash-rain {
  position: fixed; inset: 0; z-index: 9000;
  pointer-events: none; overflow: hidden;
}
.cash-note {
  position: absolute; top: -12vh;
  width: 54px; height: 30px;
  animation: cash-fall var(--dur) cubic-bezier(.35,.05,.6,1) var(--delay) both;
  will-change: transform;
}
/* The note itself. A euro-green bill with a lighter panel and a rule top and
   bottom — enough to read as money at the size it falls past. */
.cash-face {
  display: grid; place-items: center;
  width: 100%; height: 100%;
  border-radius: 3px;
  font: 700 15px/1 'DM Sans', sans-serif; font-style: normal;
  color: rgba(255,255,255,.92);
  background:
    linear-gradient(90deg, rgba(255,255,255,.22) 0 4px, transparent 4px calc(100% - 4px), rgba(255,255,255,.22) calc(100% - 4px) 100%),
    linear-gradient(180deg, #7fc98f 0%, #4f9f68 45%, #3d8a57 100%);
  box-shadow: 0 1px 3px rgba(0,0,0,.45), inset 0 0 0 1px rgba(255,255,255,.28);
  animation: cash-flip var(--dur) linear var(--delay) both;
  will-change: transform;
}
/* Falls and drifts sideways; the flip is on the child so the two motions do
   not have to share one transform. */
@keyframes cash-fall {
  from { transform: translate3d(0, 0, 0) rotate(var(--tilt)) scale(var(--scale, 1)); opacity: 0; }
  8%   { opacity: 1; }
  85%  { opacity: 1; }
  to   { transform: translate3d(var(--drift), 118vh, 0) rotate(var(--tilt)) scale(var(--scale, 1)); opacity: 0; }
}
@keyframes cash-flip {
  from { transform: rotate3d(1, .35, 0, 0deg); }
  to   { transform: rotate3d(1, .35, 0, var(--spin)); }
}
/* Asked for less movement: the shower is skipped in JS as well, this is the
   belt to that pair of braces. */
@media (prefers-reduced-motion: reduce) {
  .cash-rain { display: none; }
}

/* Order row — clickable, expandable */
.row.order-row,
.row.hours-row,
.row.event-row,
.row.client-row,
.row.wp-row.admin { cursor: pointer; }
.row.hours-row:hover,
.row.event-row:hover,
.row.client-row:hover,
.row.wp-row.admin:hover { border-color: var(--border-strong); }
.row.client-row.expanded {
  border-color: var(--accent);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  background: rgba(26,108,122,.08);
}
.row.row-past { opacity: .55; }
.row.order-row.expanded {
  border-color: var(--accent);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  background: rgba(26,108,122,.08);
}
.row-detail {
  background: var(--bg-mid);
  border: 1px solid var(--accent);
  border-top: none;
  border-radius: 0 0 8px 8px;
  padding: 14px 18px 16px;
  margin-top: -7px;
  margin-bottom: 8px;
  display: flex; flex-direction: column; gap: 12px;
}
.row-detail-info {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px 18px;
}
.info-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.info-label {
  font-size: 9px; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 1.2px; font-weight: 600;
}
.info-value {
  font-size: 13px; color: var(--text);
  font-family: 'DM Mono', monospace;
  word-break: break-word;
}
.row-detail-pitches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(56px, 1fr));
  gap: 5px;
  background: rgba(0,0,0,.3);
  border-radius: 8px;
  padding: 10px;
}
.pitch-cell {
  display: flex; flex-direction: column; align-items: center;
  padding: 6px 4px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.pitch-cell.empty { opacity: .35; }
.pitch-label { font-size: 9px; color: var(--text-dim); font-weight: 700; letter-spacing: .5px; }
.pitch-value { font-family: 'DM Mono',monospace; font-size: 11px; color: var(--text); margin-top: 2px; }
.info-block {
  background: rgba(255,255,255,.04);
  border-left: 3px solid var(--border);
  padding: 9px 12px;
  border-radius: 4px;
  font-size: 13px;
  color: var(--text);
}
.info-block.notes-prod { border-left-color: var(--gold); background: rgba(201,168,76,.08); }
.info-block.notes-fb   { border-left-color: var(--accent); background: rgba(26,108,122,.08); }
.info-block .info-label { margin-bottom: 4px; }
.info-block .info-block-body { line-height: 1.5; white-space: pre-wrap; }

/* Pricing table */
.pr-table {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.pr-row {
  display: grid;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
/* Per-worker total, in the group header now that the KPI strip below it is
   gone. Matters when an admin is looking at several workers at once. */
.wp-worker-total {
  margin-left: 10px; padding: 3px 10px; border-radius: var(--r-pill, 999px);
  font-size: 12.5px; font-weight: 700;
  background: rgba(26, 108, 122, .18); color: var(--accent, #4bb3c2);
}

/* ── Square image cropper ───────────────────────────────────────────────
   Opened FROM inside the product editor, so it has to outrank it. `.modal`
   and `.login-screen` both sit at z-index 1000; 400 put the cropper
   underneath the very modal that launched it. 2000 leaves headroom above
   both without starting a z-index arms race. */
.crop-overlay {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .78); padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
}
.crop-card {
  background: var(--panel, #1b1f21); border: 1px solid var(--line, #2b302f);
  border-radius: 12px; width: 100%; max-width: 420px;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .7); overflow: hidden;
}
.crop-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--line, #2b302f);
  font-size: 12.5px; color: var(--muted, #9aa39c);
}
.crop-x {
  background: none; border: 0; color: var(--muted, #9aa39c);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.crop-x:hover { color: var(--text, #eef1ee); }
.crop-stage { position: relative; display: flex; justify-content: center; padding: 16px; }
.crop-canvas {
  width: 360px; height: 360px; max-width: 100%; aspect-ratio: 1/1;
  display: block; border-radius: 6px; cursor: grab; touch-action: none;
}
.crop-canvas:active { cursor: grabbing; }
/* Frame echoing the product card's 1:1 box, so what you see is what ships. */
.crop-mask {
  position: absolute; inset: 16px; pointer-events: none;
  border: 2px solid rgba(255, 255, 255, .85); border-radius: 6px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .5) inset;
}
.crop-tools { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 12px; }
.crop-zoom {
  display: flex; align-items: center; gap: 10px;
  font-size: 11px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--muted, #9aa39c);
}
.crop-zoom input { flex: 1; accent-color: var(--accent, #1a6c7a); }
.crop-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }

/* Order modal — is this client already on file?
   green = matched an existing client (the order will attach to them)
   blue  = no match, a new name that will save as free text
   Tinted background rather than only a border, so it reads at a glance while
   typing. Colour is not the only signal: the reseller tag and the serial hint
   next to the field both change too. */
#om-clientName.client-known {
  background: rgba(60, 170, 110, .14);
  border-color: rgba(60, 170, 110, .55);
}
#om-clientName.client-new {
  background: rgba(70, 140, 220, .14);
  border-color: rgba(70, 140, 220, .55);
}
#om-clientName.client-known:focus { border-color: rgba(60, 170, 110, .9); }
#om-clientName.client-new:focus   { border-color: rgba(70, 140, 220, .9); }

/* The word next to the label, carrying the same meaning as the field colour
   so it does not depend on colour vision alone. Reseller keeps the gold it
   already used, since that status outranks known/new. */
.om-client-badge {
  display: inline-block; margin-left: 6px;
  font-size: 9.5px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase;
  padding: 2px 7px; border-radius: var(--r-pill, 999px); vertical-align: middle;
}
.om-client-badge.is-known    { background: rgba(60, 170, 110, .18); color: #4fbf8b; }
.om-client-badge.is-new      { background: rgba(70, 140, 220, .18); color: #6ba6e8; }
.om-client-badge.is-reseller { background: rgba(201, 168, 76, .18); color: #c9a84c; }

/* ── "Who is this order for?" client picker ─────────────────────────── */
.pick-buyer {
  padding: 12px 14px; border-bottom: 1px solid var(--line, #2b302f);
  background: rgba(255, 255, 255, .02);
}
.pick-buyer-name { font-size: 14px; font-weight: 600; color: var(--text, #eef1ee); }
.pick-buyer-meta { font-size: 11.5px; color: var(--muted, #9aa39c); margin-top: 3px; }
.pick-body { padding: 12px 14px; max-height: 46vh; overflow-y: auto; }
.pick-label {
  font-size: 10.5px; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--muted, #9aa39c); margin-bottom: 6px;
}
.pick-row {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  width: 100%; text-align: left; cursor: pointer;
  padding: 9px 11px; margin-bottom: 5px;
  background: var(--panel, #1b1f21); border: 1px solid var(--line, #2b302f);
  border-radius: 7px; color: var(--text, #eef1ee); font: inherit;
}
.pick-row:hover { border-color: var(--accent, #1a6c7a); }
.pick-name { font-size: 13.5px; font-weight: 600; }
.pick-meta { font-size: 11.5px; color: var(--muted, #9aa39c); }
/* Why this row was suggested — e-mail match is a far stronger signal than
   a name match, so the reason travels with the suggestion. */
.pick-why {
  margin-left: auto; font-size: 10px; letter-spacing: .5px; text-transform: uppercase;
  padding: 2px 8px; border-radius: var(--r-pill, 999px);
  background: rgba(26, 108, 122, .22); color: var(--accent, #4bb3c2);
}

/* A card whose controls are deliberately switched off (the demo account's
   PIN form). Dimmed, but still readable, so the feature is visibly present. */
.card.is-locked { opacity: .68; }
.card.is-locked input, .card.is-locked button { cursor: not-allowed; }

/* ── Täna ──────────────────────────────────────────────────────────────
   One screen, three blocks, in the order they demand attention. Every row
   carries the action that moves it forward, so nothing sends you elsewhere. */
.tday-blk { margin-bottom: 20px; }
.tday-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.tday-title { font: 700 11px/1 'DM Sans',sans-serif; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--accent); }
.tday-note { font-size: 11px; color: var(--text-dim); }

.tday-item { padding: 11px 12px; border-bottom: 1px solid var(--border); }
.tday-item:last-child { border-bottom: none; }
.tday-top { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.tday-who { font-weight: 650; font-size: 14px; }
.tday-when { margin-left: auto; font-size: 11px; color: var(--text-dim); white-space: nowrap; }
.tday-msg { color: var(--text-muted); font-size: 13px; margin: 4px 0 7px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tday-ctx { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.tday-ctx .chip, .tday-top .chip {
  font-size: 10.5px; padding: 2px 7px; border-radius: 5px; white-space: nowrap;
  background: rgba(128,128,128,.16); color: var(--text-muted); }
.tday-ctx .chip.spd { background: rgba(26,108,122,.24); color: #7fd0dd; font-weight: 700; }
.tday-top .chip.new, .tday-ctx .chip.new { background: rgba(201,168,76,.24); color: var(--gold); font-weight: 700; }
/* Where a prop stands, in the workshop's words. Ready is the one that wants
   acting on — it is only a parcel away — so it is the one that carries colour. */
.tday-ctx .chip.wrk  { background: rgba(128,128,128,.2); color: var(--text); }
.tday-ctx .chip.rdy  { background: rgba(61,170,107,.22); color: #6fd39b; font-weight: 700; }
.tday-ctx .chip.late { background: rgba(212,74,46,.22); color: #f0917c; font-weight: 700; }
.tday-ctx .chip.miss { background: rgba(212,74,46,.14); color: #e8a898; }
.tday-ctx .chip.pay  { background: rgba(201,168,76,.18); color: var(--gold); font-weight: 700; }

/* Money in the action row: what comes in, what goes out. Sized to sit level
   with the status buttons rather than shout over them. */
.price-pill { font: 650 13px/1 inherit; padding: 7px 11px; border-radius: 7px;
  white-space: nowrap; align-self: center; }
.price-pill.p-in  { background: rgba(61,170,107,.18); color: #6fd39b; }
.price-pill.p-out { background: rgba(212,74,46,.16);  color: #f0917c; }
:root[data-theme="medium"] .price-pill.p-in,
:root[data-theme="light"]  .price-pill.p-in  { background: rgba(61,170,107,.20) !important; color: #1a5a3a; }
:root[data-theme="medium"] .price-pill.p-out,
:root[data-theme="light"]  .price-pill.p-out { background: rgba(212,74,46,.16) !important; color: #8a2a18; }

/* The repair description, written where the job is looked at. */
.job-note { padding: 10px 12px; }
.job-note-label { font: 700 9.5px/1 'DM Sans', sans-serif; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; }
.job-note-box { width: 100%; min-height: 76px; resize: vertical; font: inherit;
  font-size: 13px; line-height: 1.5; padding: 9px 11px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); }
.job-note-box:focus { outline: none; border-color: var(--accent); }

/* Money on an order card, on its own line rather than mixed in among the
   averages. What comes in and what goes out read differently on purpose. */
.row-money { display: flex; flex-wrap: wrap; gap: 8px; padding: 9px 12px;
  border-top: 1px solid var(--border); }
.rm-cell { display: flex; align-items: baseline; gap: 7px; padding: 5px 10px;
  border-radius: 7px; background: rgba(128,128,128,.10); }
.rm-label { font: 700 9.5px/1 'DM Sans', sans-serif; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--text-dim); }
.rm-value { font-size: 15px; font-weight: 650; color: var(--text); }
.rm-cell.m-sell .rm-value { color: #6fd39b; }
.rm-cell.m-cost .rm-value { color: var(--gold); }
:root[data-theme="medium"] .rm-cell, :root[data-theme="light"] .rm-cell {
  background: rgba(0,0,0,.05); }
:root[data-theme="medium"] .rm-cell.m-sell .rm-value,
:root[data-theme="light"]  .rm-cell.m-sell .rm-value { color: #1a5a3a; }
:root[data-theme="medium"] .rm-cell.m-cost .rm-value,
:root[data-theme="light"]  .rm-cell.m-cost .rm-value { color: #6b5313; }

/* Whose bench a prop is on. Unclaimed is the one worth spotting across a long
   list, so it is the one that carries colour. Defined for every theme,
   because the other two are not just the dark one with different paint. */
.assign-chip { font-weight: 600; }
.assign-chip.free  { background: rgba(201,168,76,.22); color: var(--gold); }
.assign-chip.mine  { background: rgba(26,108,122,.24); color: #7fd0dd; }
.assign-chip.taken { background: rgba(128,128,128,.18); color: var(--text-muted); }
:root[data-theme="medium"] .assign-chip.free,
:root[data-theme="light"]  .assign-chip.free  { background: rgba(201,168,76,.28) !important; color: #6b5313; }
:root[data-theme="medium"] .assign-chip.mine,
:root[data-theme="light"]  .assign-chip.mine  { background: rgba(26,108,122,.16) !important; color: #12525d; }
:root[data-theme="medium"] .assign-chip.taken,
:root[data-theme="light"]  .assign-chip.taken { background: rgba(0,0,0,.07) !important; color: rgba(20,25,30,.72); }
.tday-ctx .chip.off  { background: rgba(255,255,255,.05); color: var(--text-dim);
  border: 1px dashed var(--border); }

/* Two things worth having to hand while writing back: what he has already
   built for this person, and what has already been said to them. Both stay
   folded until asked for — the reply box is what the window is for. */
.thr-tools { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; }
.thr-tools .btn-ghost.is-on { border-color: var(--gold); color: var(--gold); }
.btn-ghost.is-on { border-color: var(--gold); color: var(--gold); }

.thr-props { border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  margin-bottom: 11px; font-size: 12.5px; }
.thr-props-head, .thr-props-row {
  display: grid; grid-template-columns: minmax(0,1.6fr) 44px 58px 60px 52px minmax(0,72px);
  gap: 8px; align-items: center; padding: 6px 10px; }
.thr-props-head { font: 700 10px/1 'DM Sans', sans-serif; letter-spacing: .9px;
  text-transform: uppercase; color: var(--text-dim);
  background: rgba(128,128,128,.08); border-bottom: 1px solid var(--border); }
/* Each prop is a <details>: the browser keeps the open/closed state, so there
   is no handler that can fail to bind. The default disclosure triangle is
   replaced by a chevron drawn at the end of the row, where there is space. */
.thr-prop-item { border-bottom: 1px solid var(--border); }
.thr-prop-item:last-child { border-bottom: none; }
.thr-props-row { cursor: pointer; list-style: none; position: relative;
  padding-right: 22px; }
.thr-props-row::-webkit-details-marker { display: none; }
.thr-props-row::marker { content: ''; }
.thr-props-row::after { content: '⌄'; position: absolute; right: 8px; top: 3px;
  color: var(--text-dim); font-size: 13px; line-height: 1; transition: transform .12s; }
.thr-props-row:hover { background: rgba(255,255,255,.04); }
.thr-props-row:hover::after { color: var(--text); }
details[open] > .thr-props-row { background: rgba(201,168,76,.08); }
details[open] > .thr-props-row::after { transform: rotate(180deg); }
details[open] > .thr-props-row .thr-props-id b { color: var(--gold); }

/* One prop, radius by radius. Indented under its own row so it is obvious
   which propeller the numbers belong to. */
.thr-props-det { background: rgba(0,0,0,.18); }
.thr-rad { padding: 7px 10px 8px 22px; }
.thr-rad-head, .thr-rad-row {
  display: grid; grid-template-columns: 62px 64px 48px minmax(0,1fr);
  gap: 8px; align-items: center; padding: 3px 0; font-size: 12px; }
.thr-rad-head { font: 700 9.5px/1 'DM Sans', sans-serif; letter-spacing: .9px;
  text-transform: uppercase; color: var(--text-dim); padding-bottom: 5px; }
.thr-rad-r { color: var(--text-muted); }
.thr-rad-raw { color: var(--text-dim); font-size: 11px; }
.thr-rad-foot { margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-dim); }
.thr-props-id { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thr-props-id b { color: var(--text); font-weight: 600; }
.thr-props-id span { color: var(--text-muted); margin-left: 6px; }
.thr-props-st { color: var(--text-dim); font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 560px) {
  .thr-props-head, .thr-props-row { grid-template-columns: minmax(0,1.4fr) 38px 52px 48px 44px; }
  .thr-props-st { display: none; }
}

/* Other conversations with the same person, listed under this one inside the
   same fold — one place for "what has been said", not two. */
.thr-prev { border-top: 1px solid var(--border); }
.thr-prev-head { font: 700 9.5px/1 'DM Sans', sans-serif; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--text-dim); padding: 9px 9px 0; }
.thr-prev-list { display: flex; flex-direction: column; gap: 5px; padding: 8px 9px 9px; }
.thr-prev-row { display: flex; flex-direction: column; gap: 3px; text-align: left;
  padding: 8px 11px; border-radius: 7px; cursor: pointer; font-family: inherit;
  border: 1px solid var(--border); background: transparent; color: var(--text); }
.thr-prev-row:hover { border-color: var(--border-strong); background: rgba(255,255,255,.03); }
.thr-prev-top { display: flex; align-items: baseline; gap: 7px; font-size: 12.5px; }
.thr-prev-when { margin-left: auto; color: var(--text-dim); font-size: 11px; white-space: nowrap; }
.thr-prev-snip { color: var(--text-muted); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Where a reply will actually land, when the thread arrived second-hand. */
.thr-via { font-size: 12.5px; color: var(--text-muted); margin: 0 0 10px;
  padding: 8px 11px; border-radius: 0 7px 7px 0;
  background: rgba(26,108,122,.10); border-left: 2px solid var(--accent); }
.thr-via b { color: var(--text); }

/* Whether this conversation is tied to a record in the database, said at the
   top where it is read before anything is written. Half the actions underneath
   need a linked client, and the only sign used to be that they were greyed. */
.thr-link { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 7px 11px; border-radius: 7px; font-size: 12.5px;
  background: var(--bg-soft, rgba(127,127,127,.07)); border: 1px solid var(--border); }
.thr-link.is-on { background: rgba(61,170,107,.09); border-color: rgba(61,170,107,.30); }
.thr-link b { color: var(--text); }
.thr-link-badge { font: 700 10px/1 'DM Sans', sans-serif; letter-spacing: 1.1px;
  text-transform: uppercase; padding: 4px 7px; border-radius: 4px;
  background: rgba(61,170,107,.20); color: #6fd39b; white-space: nowrap; }
.thr-link-badge.off { background: rgba(214,138,42,.16); color: #e7b168; }
.thr-link-id { font-size: 11px; color: var(--text-muted); }
/* Pushes the button to the right edge on a wide modal, and lets it fall onto
   its own line on a phone rather than squeezing the name. */
.thr-link #thr-open-client { margin-left: auto; }

/* Controls on a prop row. Small, because the row is a summary that happens to
   be adjustable — not a form. */
.tday-prop-sel, .tday-prop-date {
  font: inherit; font-size: 11.5px; padding: 3px 6px; border-radius: 5px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  max-width: 100%; }
.tday-prop-sel:hover, .tday-prop-date:hover { border-color: var(--border-strong); }
.tday-prop-date[data-late="1"] { color: #f0917c; border-color: rgba(212,74,46,.45); }
.tday-prop-sel:disabled { opacity: .5; }
/* The action that moves money or a parcel — distinct from the neutral ghosts,
   so the one thing worth doing on this card is the one that stands out. */
.btn-go { background: rgba(61,170,107,.18); border: 1px solid rgba(61,170,107,.55);
  color: #6fd39b; font-weight: 600; border-radius: 7px; cursor: pointer;
  font-family: inherit; }
.btn-go:hover { background: rgba(61,170,107,.28); }
.btn-go[disabled] { opacity: .5; cursor: default; }

/* Several conversations with one customer. Named, so answering one never
   makes another look like it disappeared. */
.tday-threads { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-bottom: 9px; }
.tday-threads-n { font-size: 11px; color: var(--text-dim); }
.tday-thr { font-size: 11.5px; padding: 3px 8px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--border); background: transparent; color: var(--text-muted);
  font-family: inherit; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.tday-thr:hover { border-color: var(--border-strong); color: var(--text); }
.tday-thr span { opacity: .75; margin-left: 5px; }
.tday-thr.nr { border-color: rgba(201,168,76,.45); color: var(--gold); }
.tday-thr.dn { opacity: .55; border-style: dashed; }   /* history, not work */
.tday-thr.is-on { background: rgba(255,255,255,.06); color: var(--text); font-weight: 600; }

/* Props folded out of the card. A grid so the columns line up down the list
   and the eye can run straight down the statuses. */
.tday-props { margin: 2px 0 9px; }
.tday-prop-list { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.tday-prop { display: grid; gap: 8px; align-items: center; padding: 7px 10px;
  grid-template-columns: minmax(0,1fr) auto auto auto auto;
  border-bottom: 1px solid var(--border); font-size: 12.5px; }
@media (max-width: 720px) { .tday-prop { grid-template-columns: minmax(0,1fr) auto auto; } }
.tday-prop:last-child { border-bottom: none; }
.tday-prop-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text-muted); }
.tday-prop-name b { color: var(--text); font-weight: 600; margin-left: 5px; }
.tday-prop-st { font-size: 11px; padding: 2px 7px; border-radius: 5px; white-space: nowrap;
  background: rgba(128,128,128,.16); color: var(--text-muted); }
.tday-prop-st.st-ready { background: rgba(61,170,107,.22); color: #6fd39b; font-weight: 700; }
.tday-prop-due { font-size: 11.5px; color: var(--text-dim); white-space: nowrap; }
.tday-prop-due.late { color: #f0917c; font-weight: 700; }
/* Invoice state on a prop row is a FACT, not a button — the invoice itself is
   made from the card, for the whole client at once. */
.tday-prop-inv { font-size: 11.5px; white-space: nowrap; color: var(--text-dim); }
.tday-prop-inv.done { color: #6fd39b; font-weight: 600; }
.tday-prop-inv.wait { color: var(--gold); }
.tday-prop-open { font-size: 11.5px; padding: 4px 8px; }
.tday-btn.is-on { border-color: var(--gold); color: var(--gold); }
.tday-btn.q { color: var(--text-muted); }
/* A guess at who this is. Marked, because pressing it changes a record. */
.tday-btn.sug { border-color: rgba(201,168,76,.5); color: var(--gold); }
@media (max-width: 560px) {
  .tday-prop { grid-template-columns: minmax(0,1fr) auto; }
  .tday-prop-date { display: none; }     /* the deadline has its own block */
}
.tday-acts { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.tday-btn { font-size: 12px; padding: 7px 11px; }

/* What the model made of the mail — one line on the card, the whole thing in
   the thread modal. Kept visually distinct from the customer's own words so
   it is never mistaken for something they wrote. */
.tday-ai { display: flex; align-items: baseline; gap: 6px; margin: 0 0 8px;
  font-size: 12.5px; color: var(--text); line-height: 1.4; }
.tday-ai .chip, .thr-ai .chip { font-size: 10.5px; padding: 2px 7px; border-radius: 5px;
  white-space: nowrap; font-weight: 700; flex: none;
  background: rgba(128,128,128,.16); color: var(--text-muted); }
.chip.ord { background: rgba(201,168,76,.24); color: var(--gold); }
.chip.qst { background: rgba(26,108,122,.24); color: #7fd0dd; }
.chip.cmp { background: rgba(190,70,60,.24); color: #e79a92; }
.chip.spm { background: rgba(128,128,128,.14); color: var(--text-muted); }
.chip.draft { background: rgba(26,108,122,.2); color: #7fd0dd; font-size: 10.5px;
  padding: 2px 7px; border-radius: 5px; font-weight: 700; }
/* Machine mail is on the board now, just quietly — loud enough to pick out and
   clear, faint enough not to compete with a customer. */
.chip.auto { background: rgba(128,128,128,.14); color: var(--text-muted); font-size: 10.5px;
  padding: 2px 7px; border-radius: 5px; font-weight: 700; }

.thr-ai { border: 1px solid var(--border); border-left: 3px solid var(--gold);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 12px;
  background: rgba(128,128,128,.06); }
.thr-ai.err { border-left-color: #be463c; color: var(--text-muted); font-size: 13px; }
.thr-ai-head { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.thr-ai-head .btn-ghost { margin-left: auto; }
.btn-ghost.sm { font-size: 11.5px; padding: 5px 9px; }
.thr-ai-sum { font-size: 14px; line-height: 1.45; }
.thr-ai-fields { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 7px;
  font-size: 12.5px; color: var(--text-muted); }
.thr-ai-fields b { color: var(--text); font-weight: 600; }
.thr-ai-notes { margin-top: 7px; font-size: 12.5px; color: var(--text-muted); }
.thr-ai-model { font-size: 10.5px; color: var(--text-dim); margin-left: auto; }
/* What the mail creates besides a reply. Above the letter, because it is the
   part that changes something outside the portal. */
.thr-acts { display: flex; flex-direction: column; gap: 6px; margin-top: 9px; }
.thr-act { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.thr-act-why { font-size: 11.5px; color: var(--text-muted); }
.thr-act-done { font-size: 11px; color: #6fd39b; }
.thr-act button[disabled] { opacity: .45; cursor: not-allowed; }
/* The model dropped the sentence that answers the customer. Loud on purpose:
   the letter around it reads as finished, which is exactly the danger. */
.thr-ai-warn { margin-top: 9px; padding: 8px 11px; border-radius: 6px; font-size: 12.5px;
  background: rgba(214,138,42,.12); border: 1px solid rgba(214,138,42,.42); color: #e7b168; }
.thr-ai-warn b { color: #ffd79a; font-weight: 600; }
.thr-found { margin-top: 9px; padding: 9px 11px; border-radius: 6px;
  background: rgba(61,170,107,.09); border: 1px solid rgba(61,170,107,.28); }
.thr-found-head { font: 700 10.5px/1 'DM Sans', sans-serif; letter-spacing: 1.2px;
  text-transform: uppercase; color: #6fd39b; margin-bottom: 7px; }
.thr-found-row { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px;
  padding: 2px 0; cursor: pointer; }
/* A row that would replace something, rather than fill a blank. Unticked by
   default and marked, because the old value is about to be gone. */
.thr-found-row.over { background: rgba(214,138,42,.09); border-radius: 4px; }
.thr-found-row.over s { color: var(--text-dim); }
.thr-found-k { color: var(--text-muted); flex: 0 0 82px; }
.thr-found-v { color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.thr-found .btn-ghost { margin-top: 7px; }

.thr-ai-draft { margin-top: 9px; }
.thr-ai-draft-body { white-space: pre-wrap; font-size: 13px; line-height: 1.5;
  margin: 8px 0; padding: 9px 11px; border-radius: 6px;
  background: var(--bg); border: 1px solid var(--border); }
/* The parts that change when he picks differently. Marked so it is obvious
   which sentences are choices and which are simply the letter. */
.thr-ai-draft-body mark.slot { background: rgba(201,168,76,.18); color: inherit;
  border-bottom: 1px solid rgba(201,168,76,.5); border-radius: 2px; padding: 0 1px; }

/* The draft is now an editable letter whose choices live inside it — the block
   of option buttons underneath is gone, because the eye had to travel from the
   sentence to the buttons and back for every decision.

   `.dslot`, not `.slot` or `.sw`: app.css already owns `.sw` (the test
   logbook's stopwatch), and a mockup that reused that name inherited its card
   border and flex layout before anyone noticed. */
.thr-ai-draft-body[contenteditable] { cursor: text; min-height: 120px; }
.thr-ai-draft-body[contenteditable]:focus { outline: none; border-color: var(--accent); }
/* This box is also the one used when the AI wrote nothing, so it has to say
   what it is when empty. */
.thr-ai-draft-body[contenteditable]:empty::before { content: 'Kirjuta vastus…';
  color: var(--text-dim); pointer-events: none; }

.dslot { position: relative; display: inline-block; cursor: grab;
  background: rgba(201,168,76,.18); border-bottom: 1px solid rgba(201,168,76,.5);
  border-radius: 3px; padding: 1px 16px; margin: 0 1px;
  user-select: none; -webkit-user-select: none;
  /* pan-y so the modal still scrolls vertically under a finger. */
  touch-action: pan-y; transition: background .12s; }
.dslot:hover { background: rgba(201,168,76,.28); }
.dslot.dragging { cursor: grabbing; background: rgba(201,168,76,.34); }
.dslot::before, .dslot::after { position: absolute; top: 50%; transform: translateY(-50%);
  font-size: 10px; line-height: 1; color: var(--gold); opacity: .55; pointer-events: none; }
.dslot::before { content: '‹'; left: 5px; }
.dslot::after  { content: '›'; right: 5px; }
.dslot-t { display: inline-block; will-change: transform, opacity; }
/* Only while settling — during the drag the text tracks the finger with no
   easing at all, or it feels like rubber. */
.dslot-t.anim { transition: transform .16s cubic-bezier(.3,0,.2,1), opacity .16s linear; }
.dslot-n { display: inline-block; margin-left: 6px; font-size: 9px;
  font-family: 'DM Mono', monospace; color: var(--gold); opacity: .75; }
/* Settled: no longer a widget, just words in the letter. */
.dslot-done { animation: dslotset .5s ease-out; border-radius: 2px; }
@keyframes dslotset {
  0%   { background: rgba(61,170,107,.40); }
  100% { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .dslot-t, .dslot-t.anim { transition: none !important; }
  .dslot-done { animation: none; }
}
.thr-draft-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
/* Stock sentences, folded away until wanted. */
.thr-phr { position: relative; }
.thr-phr > summary { list-style: none; cursor: pointer; display: inline-block; }
.thr-phr > summary::-webkit-details-marker { display: none; }
.thr-phr-list { position: absolute; z-index: 5; top: calc(100% + 4px); left: 0;
  min-width: 230px; display: flex; flex-direction: column; gap: 1px; padding: 4px;
  border-radius: 6px; background: var(--bg-mid); border: 1px solid var(--border-strong);
  box-shadow: 0 10px 26px rgba(0,0,0,.34); }
.thr-phr-b { text-align: left; font-size: 12.5px; padding: 7px 9px; border: 0; border-radius: 4px;
  background: transparent; color: var(--text); cursor: pointer; }
.thr-phr-b:hover:not([disabled]) { background: rgba(201,168,76,.16); color: var(--gold); }
.thr-phr-b[disabled] { opacity: .4; cursor: not-allowed; }
.thr-phr-d { color: var(--text-dim); font-size: 11px; }
.thr-draft-left { font-size: 11px; color: var(--text-dim); }
.thr-draft-hint { font-size: 11px; color: var(--text-dim); margin-top: 6px; }

.thr-wiz { display: flex; flex-direction: column; gap: 10px; margin: 10px 0 9px;
  padding: 10px 11px; border-radius: 6px; background: rgba(128,128,128,.07); }
.thr-wiz-ask { font-size: 12.5px; color: var(--text-muted); margin-bottom: 5px; }
.thr-wiz-opts { display: flex; flex-wrap: wrap; gap: 5px; }
.wopt { font-size: 12px; padding: 5px 10px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  font-family: inherit; line-height: 1.3; text-align: left; }
.wopt:hover { border-color: var(--gold); }
.wopt.is-on { border-color: var(--gold); background: rgba(201,168,76,.16);
  color: var(--gold); font-weight: 600; }
.wopt-free { font-style: italic; color: var(--text-muted); }
.thr-wiz-free { margin-top: 6px; width: 100%; font-family: inherit; font-size: 12.5px;
  padding: 7px 9px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text); resize: vertical; }

.tday-due { display: flex; align-items: center; gap: 9px; padding: 8px 12px;
  border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.tday-due:last-child { border-bottom: none; }
.tday-flag { flex: 0 0 66px; font: 700 10px/1 'DM Sans'; letter-spacing: .5px; text-transform: uppercase; }
.tday-flag.late { color: var(--red); }
.tday-flag.soon { color: var(--gold); }
.tday-flag.none { color: var(--text-dim); }
.tday-due-who { flex: 1 1 130px; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: 13px; }
.tday-due-what { flex: 0 0 auto; font-size: 11.5px; color: var(--text-muted); }
.tday-due-status { flex: 0 0 auto; font-size: 11px; color: var(--text-dim); }
.tday-due-date { flex: 0 0 auto; background: var(--bg-mid); border: 1px solid var(--border);
  border-radius: 6px; color: var(--text); font-size: 12px; padding: 4px 7px; }

.tday-quiet { display: flex; align-items: center; gap: 9px; padding: 10px 12px;
  border-bottom: 1px solid var(--border); font-size: 13px; }
.tday-quiet:last-child { border-bottom: none; }
.tday-quiet-why { color: var(--text-dim); font-size: 11.5px; margin-left: auto; }

/* The conversation inside the thread modal. */
/* The conversation flows at full height. It used to be capped at 320px with
   its own scrollbar, which put a scroll area inside the modal's own scroll
   area — a narrow slit onto a long forwarded chain. One scrollbar is enough. */
/* Folded by default: the summary and the draft are what he reads first, and
   the conversation is what he refers back to. One press opens it. */
/* flex-shrink:0 is load-bearing: #modal-body is a column flex container, and
   `overflow: hidden` here sets this item's automatic minimum size to 0 — so
   the flex layout squashed the whole fold, summary included, to its 2px of
   border. It rendered as a bare line, not as a missing element. */
.thr-log-wrap { border: 1px solid var(--border); border-radius: 8px; overflow: hidden;
  flex-shrink: 0; }
/* display:block is deliberate: a <summary> defaults to display:list-item, and
   a stray `list-style` or marker rule elsewhere can collapse it to nothing —
   which is exactly how this fold once rendered as a bare 1px line. */
.thr-log-wrap > summary { display: block; cursor: pointer; padding: 9px 11px;
  font: 600 12.5px/1.3 inherit; color: var(--text); list-style: none;
  background: rgba(128,128,128,.10); min-height: 18px; }
.thr-log-wrap > summary::-webkit-details-marker { display: none; }
.thr-log-wrap > summary::marker { content: ''; }
.thr-log-wrap > summary::after { content: ' ⌄'; color: var(--text-dim); }
.thr-log-wrap[open] > summary { color: var(--text); border-bottom: 1px solid var(--border); }
.thr-log-wrap[open] > summary::after { content: ' ⌃'; }
/* Read as a conversation: the customer down the left, Erik down the right,
   in the order it happened. They used to be full-width blocks separated only
   by a faint tint, so telling who said what meant reading the small grey name
   on every one. Erik, 2026-09-27. The markup already carried .in / .out — this
   is only where they sit. */
.thr-log { display: flex; flex-direction: column; gap: 8px;
  background: rgba(0,0,0,.25); border-radius: 8px; padding: 9px; }
/* 25% black is a recessed tray on the dark theme and a heavy grey slab on the
   other two, where the bubbles are white. Same idea, lighter hand. */
:root[data-theme="medium"] .thr-log,
:root[data-theme="light"]  .thr-log { background: rgba(0,0,0,.05); }
.thr-msg { border-radius: 10px; padding: 8px 10px; background: var(--bg-mid);
  max-width: 84%; border: 1px solid var(--border); }
.thr-msg.in  { align-self: flex-start; border-bottom-left-radius: 3px; }
.thr-msg.out { align-self: flex-end;   border-bottom-right-radius: 3px;
  background: rgba(26,108,122,.16); border-color: rgba(26,108,122,.34); }
/* The line the forwarder wrote above the chain — usually a signature. It
   belongs to neither side, so it sits in the middle. */
.thr-msg.note { align-self: center; max-width: 94%;
  background: transparent; border: 1px dashed var(--border); opacity: .75; }
/* Below this there is no room for a 16% gutter — the bubbles go full width and
   the side they sit on is carried by the colour alone. */
@media (max-width: 480px) {
  .thr-msg { max-width: 100%; }
}
.thr-meta { font-size: 10.5px; color: var(--text-dim); display: flex; gap: 8px; margin-bottom: 4px; }
.thr-meta > span { margin-left: auto; }
.thr-body { font-size: 13px; white-space: pre-wrap; word-break: break-word; }

@media (max-width: 560px) {
  .tday-due-what, .tday-due-status { display: none; }
  .tday-when { margin-left: 0; width: 100%; }
}

/* Demo props on the showcase client. Loud on purpose — a demo prop must never
   be read as work that was done. */
.demo-chip {
  background: rgba(201,168,76,.28) !important;
  color: var(--gold);
  font-weight: 700;
  letter-spacing: .8px;
}
:root[data-theme="medium"] .demo-chip { background: rgba(201,168,76,.26) !important; color: #6b5313; }

/* The theoretical speed is the one number a list of props gets scanned for,
   so it carries the accent rather than sitting in the grey run of chips. */
.speed-chip {
  background: rgba(26,108,122,.22) !important;
  color: var(--accent);
  font-weight: 700;
}
:root[data-theme="medium"] .speed-chip { background: rgba(26,108,122,.16) !important; color: #12525d; }

/* Speed estimate resting on an assumed slip rather than a measured one —
   dimmed and dashed so it never reads as a real figure. */
.row-chip-assumed {
  opacity: .72;
  border-style: dashed !important;
  font-style: italic;
}
.muted-warn { color: #c9a84c; }

/* Resellers view — archive controls */
.reseller-archive-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 8px; cursor: pointer; user-select: none;
  font-size: 12px; letter-spacing: .3px; color: var(--muted, #8b9398);
}
.reseller-archive-toggle input { cursor: pointer; margin: 0; }
.reseller-archive-toggle:hover { color: var(--text, #e8ecee); }
.reseller-archived-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; margin-bottom: 14px; padding: 10px 14px;
  border: 1px solid rgba(201, 168, 76, .45);
  background: rgba(201, 168, 76, .10);
  border-radius: 8px; font-size: 12.5px; line-height: 1.5; color: #c9a84c;
}
.reseller-archived-banner button { flex-shrink: 0; }

.pr-row.pr-cols-7 { grid-template-columns: 1.3fr .6fr 1fr 1fr 1fr 1fr .9fr; }
.pr-row.pr-cols-6 { grid-template-columns: 1.4fr .7fr 1fr 1fr 1fr 1fr; }
.pr-row.pr-cols-5 { grid-template-columns: 1.4fr .7fr 1fr 1fr .9fr; }
.pr-row.pr-cols-4 { grid-template-columns: 1.4fr .7fr 1fr 1fr; }
.pr-row.pr-cols-3 { grid-template-columns: 1.4fr .7fr 1fr; }

/* Read-only shop reference column. Dimmed so it reads as context rather than
   another editable cell; amber when it disagrees with the direct price. */
.pr-shop { color: var(--muted, #8b9398); font-size: 12px; }
.pr-shop-none { opacity: .4; }
.pr-shop-diff {
  color: #c9a84c; font-weight: 600;
  background: rgba(201, 168, 76, .10); border-radius: 5px;
}
.pr-row:last-child { border-bottom: none; }
.pr-row.pr-editable { cursor: pointer; transition: .12s; }
.pr-row.pr-editable:hover { background: rgba(255,255,255,.04); }
.pr-edit { padding-left: 4px; }
.pr-input {
  width: 100%; max-width: 110px;
  padding: 5px 8px;
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 6px;
  font: 12px 'DM Mono', monospace;
  color: var(--text);
  text-align: right;
  outline: none;
  transition: border-color .15s, box-shadow .25s;
}
.pr-input::placeholder { color: var(--text-dim); font-style: italic; }
.pr-input:focus { border-color: var(--accent); }
.pr-input.pr-saved { border-color: var(--green); box-shadow: 0 0 0 2px rgba(61,170,107,.2); }
.pr-input.pr-error { border-color: var(--red);   box-shadow: 0 0 0 2px rgba(212,74,46,.2); }

.hint-row {
  margin-top: 12px;
  padding: 10px 14px;
  background: rgba(255,255,255,.04);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.5;
}
.pr-row.pr-head {
  background: rgba(255,255,255,.04);
  color: var(--text-muted);
  font-size: 10px; font-weight: 600;
  letter-spacing: 1.5px; text-transform: uppercase;
}
.pr-cls { font-weight: 600; }
.pr-bld { color: var(--text-muted); font-family: 'DM Mono',monospace; }
.pr-num { font-family: 'DM Mono',monospace; color: var(--text); text-align: right; }
.pr-row.pr-head .pr-num { text-align: right; }

/* Settings: sub-tabs + add button + clickable rows */
/* Scrolls sideways like the main tab row, instead of wrapping onto a second
   and third line. Wrapping pushed the content down on exactly the screens
   where there is least room for it. */
.subtabs {
  display: flex; flex-wrap: nowrap; gap: 4px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto; scrollbar-width: none;
}
.subtabs::-webkit-scrollbar { display: none; }
.subtabs > * { flex: 0 0 auto; }
.subtab {
  background: transparent; border: none;
  color: var(--text-dim);
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: 1.5px; text-transform: uppercase;
  padding: 10px 14px; white-space: nowrap;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: .15s;
}
.subtab.active   { color: var(--accent); border-bottom-color: var(--accent); }
.subtab:hover:not(.active) { color: var(--text-muted); }

.subsection { display: none; }
.subsection.active { display: block; }
.subsection-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.subsection-count {
  color: var(--text-dim); font-size: 12px;
  letter-spacing: 1px; flex: 0 0 auto;
}
.btn-add {
  background: var(--accent); color: var(--text);
  border: none; border-radius: 8px;
  padding: 9px 16px;
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer; transition: .15s;
  margin-left: auto;
}
.btn-add:hover { background: var(--accent-hover); }

.row.settings-row { cursor: pointer; }
.row.settings-row:hover { border-color: var(--border-strong); background: rgba(255,255,255,.02); }

/* Modal */
.modal {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.6);
  backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  padding: 20px;
}
.modal[hidden] { display: none; }
/* dvh = dynamic viewport height; respects mobile URL bar / bottom nav.
   safe-area insets keep header/footer out from under Android Chrome chrome. */
.modal {
  padding: 20px;
  padding-top: max(20px, env(safe-area-inset-top));
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}
.modal-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  width: 100%; max-width: 520px;
  max-height: 90dvh;
  display: flex; flex-direction: column;
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0,0,0,.6);
}
@supports not (height: 100dvh) {
  .modal-card { max-height: 90vh; }
}
.modal-head {
  background: var(--bg-darker);
  padding: 14px 18px;
  display: flex; align-items: center;
  border-bottom: 1px solid var(--border);
}
.modal-title {
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 400; font-size: 16px;
  letter-spacing: 2px; text-transform: uppercase;
  flex: 1;
}
.modal-close {
  background: transparent; border: none;
  color: var(--text-dim);
  font-size: 24px; line-height: 1;
  cursor: pointer; padding: 0 4px;
  transition: .15s;
}
.modal-close:hover { color: var(--text); }
.modal-body {
  padding: 18px;
  display: flex; flex-direction: column; gap: 12px;
  overflow-y: auto;
  flex: 1;
}
.m-field {
  display: flex; flex-direction: column; gap: 5px;
}
.m-field > span {
  font-size: 10px;
  color: var(--text-dim);
  letter-spacing: 1px; text-transform: uppercase; font-weight: 600;
}
/* `:not([type])` matters: an <input> with no type attribute behaves as text but
   does NOT match input[type="text"], because that tests the attribute and not
   the default. Nineteen inputs in this file are written without one — the
   client-name picker among them, which is why it came out shorter than the
   fields beside it. Erik, 2026-09-28. One line here beats nineteen edits, and
   the next typeless input is already handled. */
.m-field input:not([type]),
.m-field input[type="text"],
.m-field input[type="email"],
.m-field input[type="tel"],
.m-field input[type="number"],
.m-field input[type="password"],
.m-field textarea {
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 7px;
  padding: 9px 12px;
  color: var(--text);
  font: 13px 'DM Sans',sans-serif;
  outline: none; transition: .15s;
}
.m-field input:focus, .m-field textarea:focus { border-color: var(--accent); }
/* The black triangle Chrome draws on a `list=` input. These are type-ahead
   fields — the suggestions come up as you type — and the copy button now sits
   on that corner anyway, so the arrow was unreachable as well as unnecessary.
   Scoped to input[list] on purpose: the same pseudo-element is the picker
   button on <input type="date">, where it is the only way in. */
.m-field input[list]::-webkit-calendar-picker-indicator { display: none; }
.m-field.m-check {
  flex-direction: row;
  align-items: center;
  gap: 9px;
}
.m-field.m-check span {
  text-transform: none;
  font-size: 13px;
  color: var(--text);
  letter-spacing: 0;
  font-weight: 500;
}
.m-field.m-check input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--accent);
  cursor: pointer;
}
.radii-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(70px, 1fr));
  gap: 6px;
  margin-top: 4px;
}
.radii-check {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 10px;
  border: 1.5px solid var(--border);
  border-radius: 7px;
  background: var(--bg-mid);
  font: 12px 'DM Mono', monospace;
  cursor: pointer; transition: .12s;
}
.radii-check input { accent-color: var(--accent); cursor: pointer; }
.radii-check:has(input:checked) { border-color: var(--accent); background: rgba(26,108,122,.12); }
.classes-panel { margin-bottom: 22px; }
.modal-foot {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
  padding: 12px 18px;
  background: var(--bg-darker);
  border-top: 1px solid var(--border);
}
/* The flex-1 spacer in modals (style="flex:1") loses its gap-to-zero on
   wrapped layouts — force minimum width so the right-side buttons stay
   pushed to the trailing edge until the row actually wraps. */
.modal-foot > [style*="flex:1"] { min-width: 0; }
@media (max-width: 620px) {
  .modal-foot { justify-content: flex-start; }
  .modal-foot > [style*="flex:1"] { display: none; }
}
.btn-primary, .btn-ghost, .btn-danger {
  border: none; border-radius: 7px;
  padding: 9px 16px;
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer; transition: .15s;
}
.btn-primary { background: var(--accent); color: var(--text); }
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:disabled { opacity: .5; cursor: wait; }
.btn-ghost { background: transparent; color: var(--text-muted); border: 1px solid var(--border); }
.btn-ghost:hover { color: var(--text); border-color: var(--border-strong); }
.btn-danger { background: transparent; color: var(--red); border: 1px solid rgba(212,74,46,.4); }
.btn-danger:hover { background: rgba(212,74,46,.15); border-color: var(--red); }
/* Stated rather than assumed. Twice now a [hidden] element stayed on screen
   because its own class set a display and beat the user-agent rule — the print
   picker's rows and the class-link rows. These set none, so hidden already
   works; this makes sure it keeps working if one ever gains a display. */
.btn-primary[hidden], .btn-ghost[hidden], .btn-danger[hidden] { display: none; }

/* Order edit modal — wider, multi-section, tabbed */
.modal-card.order-modal-card { max-width: 780px; }
.om-tabs {
  display: flex; gap: 2px;
  /* Hug the modal head — no gap above; pull left/right to the card edges. */
  margin: -18px -18px 14px;
  padding: 0 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-darker);
  position: sticky; top: 0;
  z-index: 2;
}
/* When the tabs strip is the first child of modal-body, it must sit flush
   against modal-head — kill the body's top padding above it. */
.modal-body:has(> .om-tabs:first-child) { padding-top: 0; }
.om-tab {
  background: transparent; border: 0;
  color: var(--text-dim);
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: 1.5px; text-transform: uppercase;
  padding: 12px 18px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: .15s;
}
.om-tab:hover:not(.active) { color: var(--text-muted); }
.om-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.om-tab-panel { display: none; }
.om-tab-panel.active { display: block; }
.om-section {
  display: flex; flex-direction: column;
  gap: 10px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.om-section:last-child { border-bottom: none; padding-bottom: 0; }
.om-section + .om-section { padding-top: 4px; }
.om-sec-title {
  font: 700 10px 'DM Sans',sans-serif;
  letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 2px;
}
.om-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px 14px;
}
.om-row .m-field { gap: 4px; }
.om-hint {
  font: 11px 'DM Sans',sans-serif;
  color: var(--text-dim);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}
.om-hint strong { color: var(--accent); font-weight: 600; }
.om-hint .link-btn { font-size: 11px; padding: 1px 6px; margin-left: 4px; }

/* Suggested prices on the order modal. Each chip names its own source, so it
   is always clear whether a figure came off the storefront or the rate list. */
.om-price-hint {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  background: rgba(0,0,0,.25); border-radius: 8px; padding: 7px 9px;
  font: 12px 'DM Sans',sans-serif;
}
.om-price-sug { display: inline-flex; align-items: baseline; gap: 5px; }
.om-price-sug > i { font-style: normal; color: var(--text-dim); }
.om-price-sug > b { font-weight: 500; font-size: 10.5px; color: var(--text-dim);
  background: rgba(128,128,128,.16); padding: 1px 5px; border-radius: 4px; }
.om-price-none { color: var(--text-dim); font-style: italic; }

/* "Blanks in stock" on the order modal — the summary the shop enforces, then
   one line per mould so it is clear which pile the number came off. */
.om-field-wide { grid-column: 1 / -1; }
.om-stock-hint {
  background: rgba(0,0,0,.25); border-radius: 8px;
  padding: 6px 8px; display: flex; flex-direction: column; gap: 2px;
}
.oms-note { font: 11px 'DM Sans',sans-serif; color: var(--text-dim); font-style: italic; }
.oms-sum { display: flex; flex-wrap: wrap; gap: 5px; padding-bottom: 4px; margin-bottom: 2px;
  border-bottom: 1px solid var(--border); }
.oms-sum-cell { font-size: 11px; padding: 2px 7px; border-radius: 5px;
  background: rgba(128,128,128,.14); white-space: nowrap; }
.oms-sum-cell b { font-weight: 700; margin-left: 3px; }
.oms-sum-cell.ok  { background: rgba(61,170,107,.18);  color: var(--green); }
.oms-sum-cell.low { background: rgba(201,168,76,.20);  color: var(--gold); }
.oms-sum-cell.out { background: rgba(212,74,46,.18);   color: var(--red); }
.oms-sum-cell.na  { opacity: .55; }
.oms-sum-cell.on  { outline: 1.5px solid var(--accent); outline-offset: 1px; }

.oms-row { display: flex; align-items: center; gap: 7px; font-size: 11.5px; }
.oms-row.zero { opacity: .55; }
.oms-name { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.oms-spec { flex: 0 0 auto; color: var(--text-dim); font-size: 10.5px; }
.oms-tag { flex: 0 0 auto; font-size: 9.5px; padding: 0 4px; border-radius: 3px;
  background: rgba(26,108,122,.30); color: #7fd0dd; }
.oms-tag.off { background: rgba(212,74,46,.16); color: var(--red); }
.oms-qty { flex: 0 0 30px; text-align: right; font-weight: 700; font-size: 13px; }
.oms-row:not(.zero) .oms-qty { color: var(--green); }
.oms-row.zero .oms-qty { color: var(--red); }
.om-pitch-grid {
  display: flex; flex-direction: column;
  gap: 6px;
  background: rgba(0,0,0,.25);
  border-radius: 8px;
  padding: 8px;
}
.pp-row {
  display: grid;
  grid-template-columns: 48px 1fr 120px;
  gap: 10px;
  align-items: stretch;
}
.pp-label {
  font: 700 12px 'DM Sans',sans-serif;
  color: var(--text-dim);
  letter-spacing: .5px;
  text-align: center;
  align-self: center;
}
.pp-picks-stack {
  display: flex; flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.pp-picks {
  display: flex; flex-wrap: wrap; gap: 4px;
  min-width: 0;
}
.pp-btn {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 14px;
  min-width: 48px;
  border-radius: 6px;
  font: 14px 'DM Mono',monospace;
  cursor: pointer;
  user-select: none;
  flex: 0 0 auto;
}
.pp-btn:hover { border-color: var(--accent); }
.pp-btn.sel {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.pp-cup { border-color: rgba(201,168,76,.6); }
.pp-cup.sel { background: #c9a84c; border-color: #c9a84c; color: #000; }
.pp-input {
  width: 100%;
  height: 100%;
  padding: 6px 8px;
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: 6px;
  font: 13px 'DM Mono',monospace;
  color: var(--text);
  text-align: center;
  outline: none;
  box-sizing: border-box;
  align-self: stretch;
}
.pp-input:focus { border-color: var(--accent); }
@media (max-width: 720px) {
  .pp-row { grid-template-columns: 40px 1fr 90px; gap: 6px; }
  .pp-btn { padding: 6px 10px; min-width: 38px; font-size: 12px; }
  .pp-input { font-size: 11px; }
}
.pitch-input {
  display: flex; flex-direction: column; gap: 2px;
  text-align: center;
}
.pitch-input span {
  font: 700 9px 'DM Sans',sans-serif;
  color: var(--text-dim);
  letter-spacing: .5px;
}
.pitch-input input {
  width: 100%;
  padding: 6px 4px;
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: 5px;
  font: 11px 'DM Mono',monospace;
  color: var(--text);
  text-align: center;
  outline: none;
}
.pitch-input input:focus { border-color: var(--accent); }

.row-detail-actions {
  display: flex; align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.row-detail-actions.row-detail-bottom {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.row-detail-build {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  margin: 8px 0;
}
.row-detail-build .zone-c { margin-bottom: 8px; }
.row-detail-build .row-detail-pitches,
.row-detail-build .row-detail-modifications {
  margin: 8px -4px;
}
.row-detail-build .zone-b { margin-top: 8px; }
.row-reseller-hint {
  font-size: 11px; color: var(--accent);
  font-weight: 500; font-style: normal;
  letter-spacing: .3px;
}
.quick-select {
  padding: 7px 10px;
  border: 1.5px solid var(--border);
  border-radius: 7px;
  background: var(--bg-card);
  color: var(--text);
  font: 12px 'DM Sans', sans-serif;
  outline: none;
  cursor: pointer;
  min-width: 130px;
}
.quick-select:hover { border-color: var(--border-strong); }
.quick-select:focus { border-color: var(--accent); }

.detail-head {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 18px;
}
.detail-title {
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 300; font-size: 26px;
  letter-spacing: 3px; text-transform: uppercase;
}
.block-title {
  font: 700 10px 'DM Sans',sans-serif;
  letter-spacing: 2px; text-transform: uppercase;
  color: var(--text-muted);
  margin: 22px 0 8px;
}
.block-row {
  display: flex; align-items: center; gap: 10px;
  margin-top: 22px;
}
.block-row .block-title { margin: 0; flex: 1; }

/* Stats tab — simple CSS bar charts */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
}
.stat-block {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
}
.stat-block-title {
  font: 700 10px 'DM Sans',sans-serif;
  letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.stat-bars { display: flex; flex-direction: column; gap: 4px; }
.stat-bar-row {
  display: grid;
  grid-template-columns: 110px 1fr 40px;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}
.stat-bar-label { color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat-bar-track {
  height: 14px;
  background: rgba(255,255,255,.05);
  border-radius: 7px;
  overflow: hidden;
}
.stat-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-hover));
  border-radius: 7px;
  transition: width .4s ease-out;
}
.stat-bar-value {
  font-family: 'DM Mono',monospace;
  color: var(--text-muted);
  text-align: right;
}

/* Worker Pay per-worker KPI tiles — compact variant of the dashboard tiles */
.wp-worker-kpis {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
  padding: 12px;
  background: rgba(0,0,0,.18);
  border-bottom: 1px solid var(--border);
  margin-bottom: 0;
}
.wp-worker-kpis .kpi { padding: 10px 12px; }
.wp-worker-kpis .kpi-value { font-size: 22px; }
.wp-worker-kpis .kpi-label { letter-spacing: 1px; }

/* Worker Pay — grouped completed list */
.wp-worker-group {
  margin-bottom: 18px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.wp-worker-header {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: rgba(255,255,255,.04);
  border-bottom: 1px solid var(--border);
}
.wp-worker-name {
  font-family: 'Montserrat','DM Sans',sans-serif;
  font-weight: 400; font-size: 14px;
  letter-spacing: 2px; text-transform: uppercase;
  flex: 1;
}
.wp-worker-counts {
  color: var(--text-dim);
  font-size: 11px; letter-spacing: 1px;
}
.row.wp-comp-row {
  border-radius: 0;
  border: none;
  border-bottom: 1px solid var(--border);
  background: transparent;
}
.row.wp-comp-row:last-child { border-bottom: none; }

/* Payment-record pick list (checkbox rows in modal) */
.pay-pick {
  display: grid;
  grid-template-columns: 24px 100px 1fr;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  margin-bottom: 4px;
  background: var(--bg-mid);
  cursor: pointer;
}
.pay-pick:has(input:checked) {
  border-color: var(--accent);
  background: rgba(26,108,122,.08);
}
.pay-pick input { accent-color: var(--accent); cursor: pointer; }
.pp-id  { font-family: 'DM Mono',monospace; font-size: 11px; color: var(--text); }
.pp-meta { font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Mobile polish — tighten layouts on narrow screens */
@media (max-width: 640px) {
  .row { padding: 9px 11px; gap: 8px; }
  .row-name { font-size: 13px; }
  .stat-bar-row { grid-template-columns: 90px 1fr 36px; font-size: 11px; }
  .topbar-title { font-size: 16px; letter-spacing: 3px; }
  .section-title { font-size: 20px; letter-spacing: 3px; }
  .pr-row { padding: 8px 10px; font-size: 12px; }
  .pr-row.pr-cols-7 { grid-template-columns: .9fr .45fr .65fr .65fr .7fr .7fr .6fr; }
  .pr-row.pr-cols-6 { grid-template-columns: 1fr .5fr .7fr .7fr .8fr .8fr; }
  .pr-row.pr-cols-5 { grid-template-columns: 1fr .5fr .8fr .8fr .7fr; }
  .pr-row.pr-cols-4 { grid-template-columns: 1fr .5fr .9fr .9fr; }
  .pr-input { max-width: 80px; padding: 4px 6px; font-size: 11px; }
  .om-pitch-grid { grid-template-columns: repeat(auto-fit, minmax(50px, 1fr)); }
  .pitch-input input { font-size: 10px; }
  .row-detail-pitches { grid-template-columns: repeat(auto-fit, minmax(48px, 1fr)); }
  .kpi-value { font-size: 30px; }
  .stat-cell { flex: 1 1 70px; }
  .stat-value { font-size: 15px; }
  .modal { padding: 0;
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .modal-card { max-width: 100%; max-height: 100dvh; border-radius: 0; }
  @supports not (height: 100dvh) {
    .modal-card { max-height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
  }
  .modal-card.order-modal-card { max-width: 100%; }
}

/* Drag handle for re-orderable client rows */
.drag-handle {
  cursor: grab;
  color: var(--text-dim);
  font-size: 14px;
  letter-spacing: -2px;
  padding: 2px 6px;
  user-select: none;
}
.drag-handle:active { cursor: grabbing; }
.row.dragging {
  opacity: .5;
  border-color: var(--accent) !important;
  background: rgba(26,108,122,.08) !important;
}

/* Inline × delete button on payment rows (admin only) */
.row-del-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  width: 22px; height: 22px;
  border-radius: 50%;
  font-size: 14px;
  line-height: 18px;
  padding: 0;
  cursor: pointer;
  margin-left: 6px;
}
.row-del-btn:hover {
  background: rgba(220, 64, 64, .12);
  border-color: #c44;
  color: #f88;
}
.row-del-btn:disabled { opacity: .4; cursor: wait; }

/* ── Calendar (Events tab) ───────────────────────────────────── */
.cal-toolbar {
  display: flex; align-items: center; gap: 10px;
  margin: 8px 0 12px;
}
.cal-nav {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text);
  width: 32px; height: 32px;
  border-radius: 8px;
  font: 700 18px 'DM Sans',sans-serif;
  cursor: pointer;
  line-height: 1;
}
.cal-nav:hover { border-color: var(--accent); color: var(--accent); }
.cal-title {
  font: 700 16px 'DM Sans',sans-serif;
  letter-spacing: .3px;
  min-width: 180px;
  text-align: center;
}
.cal-grid {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.cal-dow-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  background: rgba(0,0,0,.2);
}
.cal-dow {
  padding: 8px 6px;
  font: 700 10px 'DM Sans',sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
  text-align: center;
  border-right: 1px solid var(--border);
}
.cal-dow:last-child { border-right: none; }
.cal-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-auto-rows: minmax(96px, 1fr);
}
.cal-day {
  border-right: 1px solid var(--border);
  border-top: 1px solid var(--border);
  padding: 4px 4px 6px;
  display: flex; flex-direction: column;
  gap: 3px;
  cursor: pointer;
  position: relative;
  min-height: 0;
}
.cal-day:hover { background: rgba(26,108,122,.06); }
.cal-day:nth-child(7n) { border-right: none; }
.cal-day-off {
  color: var(--text-dim);
  background: rgba(0,0,0,.12);
}
.cal-day-off .cal-daynum { opacity: .5; }
.cal-day-today {
  background: rgba(26,108,122,.08);
}
.cal-day-today .cal-daynum {
  background: var(--accent);
  color: #fff;
  width: 22px; height: 22px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.cal-daynum {
  font: 700 12px 'DM Sans',sans-serif;
  color: var(--text);
  align-self: flex-end;
  padding: 0 2px;
}
.cal-events {
  display: flex; flex-direction: column;
  gap: 2px;
  overflow: hidden;
}
.cal-evt {
  background: var(--accent);
  color: #fff;
  padding: 2px 6px;
  border-radius: 4px;
  font: 600 10px 'DM Sans',sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.cal-evt:hover { background: #2487a0; }
.cal-evt-more {
  font: 700 9px 'DM Sans',sans-serif;
  color: var(--text-dim);
  text-align: right;
  padding: 0 2px;
}
.cal-list-head {
  margin: 18px 0 8px;
  font: 700 11px 'DM Sans',sans-serif;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--accent);
}
/* Calendar event chips with linked prop handovers get a gold accent */
.cal-evt-handover {
  background: #c9a84c !important;
  color: #000 !important;
}
.cal-evt-handover:hover { background: #d8b85e !important; }
.cal-handover-dot {
  font-size: 9px;
  margin-right: 3px;
  vertical-align: middle;
}
/* Special-agreement row + chip */
.special-paid-btn {
  margin-left: 8px;
  padding: 4px 10px;
  font-size: 11px;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: transparent;
  border-radius: 6px;
  cursor: pointer;
}
.special-paid-btn:hover { background: var(--accent); color: #fff; }
.special-paid-btn:disabled { opacity: .5; cursor: wait; }
.special-flag {
  color: #c9a84c !important;
  font-weight: 700 !important;
}

/* Service pill — highlight order rows for service jobs (Modification, Transport, etc.) */
.row-chip.service-pill {
  background: linear-gradient(135deg, #9263a7, #6b4582) !important;
  color: #fff !important;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  font-size: 10px;
  padding: 3px 9px;
  border: 1px solid #6b4582 !important;
  box-shadow: 0 0 0 1px rgba(146,99,167,.25);
}
/* Modification-changes block inside the order detail (replaces empty radii) */
.row-detail-modifications {
  margin: 10px 0;
  border-left: 3px solid #9263a7;
}

/* Motor-height stepper (Tools → Test logbook) */
.mh-wheel {
  display: flex; align-items: stretch; gap: 4px;
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: 8px;
  padding: 4px;
}
.mh-wheel .mh-step {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  width: 36px;
  border-radius: 6px;
  font: 700 16px 'DM Sans',sans-serif;
  cursor: pointer;
}
.mh-wheel .mh-step:hover { border-color: var(--accent); color: var(--accent); }
.mh-wheel input[type="number"] {
  flex: 1;
  text-align: center;
  font: 700 22px 'DM Mono',monospace;
  color: var(--accent);
  background: transparent;
  border: none;
  outline: none;
  -moz-appearance: textfield;
}
.mh-wheel input[type="number"]::-webkit-outer-spin-button,
.mh-wheel input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.mh-track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(90deg,
    rgba(212,74,46,.30) 0%,
    rgba(0,0,0,.15) 50%,
    rgba(61,170,107,.30) 100%);
  margin-top: 6px;
}
.mh-track::before {
  /* zero tick */
  content: '';
  position: absolute;
  left: 50%; top: -3px;
  width: 1px; height: 12px;
  background: var(--text-dim);
}
.mh-marker {
  position: absolute;
  top: -22px;
  transform: translateX(-50%);
  background: var(--accent);
  color: #fff;
  font: 700 10px 'DM Mono',monospace;
  padding: 2px 6px;
  border-radius: 4px;
  white-space: nowrap;
}
.mh-marker::after {
  content: '';
  position: absolute;
  left: 50%; top: 100%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--accent);
}

/* Test log row — 2-column: venue (bold) / date on left; prop, chips, notes right */
.tl-row {
  display: grid !important;
  grid-template-columns: 160px 1fr;
  gap: 14px;
  align-items: start;
}
.tl-when {
  display: flex; flex-direction: column;
  gap: 2px;
}
.tl-venue {
  font: 700 13px 'DM Sans',sans-serif;
  color: var(--text);
  word-break: break-word;
}
.tl-date {
  font: 500 12px 'DM Mono',monospace;
  color: var(--text-dim);
}
.tl-body {
  display: flex; flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.tl-head {
  display: flex; align-items: center; gap: 8px;
}
.tl-prop {
  font: 700 14px 'DM Sans',sans-serif;
  color: var(--text);
  flex: 1;
}
.tl-head .row-del-btn { margin-left: auto; }
.tl-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  align-items: center;
}
.tl-notes {
  font: 400 12px 'DM Sans',sans-serif;
  color: var(--text-dim);
  word-break: break-word;
}
.tl-laps {
  background: rgba(0,0,0,.18);
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
  user-select: none;
}
.tl-laps-summary {
  display: flex; align-items: center; gap: 10px;
  font: 12px 'DM Mono',monospace;
}
.tl-lap-best {
  font-weight: 700;
  color: var(--green);
}
.tl-lap-count { color: var(--text-dim); }
.tl-laps-chevron {
  margin-left: auto;
  color: var(--text-dim);
  font-size: 14px;
  transition: transform .15s;
}
.tl-laps.expanded .tl-laps-chevron { transform: rotate(180deg); }
.tl-laps-all {
  display: none;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  flex-direction: column;
  gap: 2px;
}
.tl-laps.expanded .tl-laps-all { display: flex; }
.tl-lap-row {
  display: flex; justify-content: space-between;
  font: 12px 'DM Mono',monospace;
  padding: 3px 4px;
  border-radius: 4px;
}
.tl-lap-row.best { background: rgba(61,170,107,.15); color: var(--green); font-weight: 700; }
.tl-lap-n { color: var(--text-dim); }
@media (max-width: 600px) {
  .tl-row { grid-template-columns: 110px 1fr; gap: 10px; }
  .tl-venue { font-size: 12px; }
  .tl-prop { font-size: 13px; }
}

/* Stopwatch widget (Test logbook → New entry) */
.sw {
  background: var(--bg-card);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  display: flex; flex-direction: column;
  gap: 10px;
}
.sw-display {
  font: 700 36px 'DM Mono',monospace;
  letter-spacing: 1px;
  color: var(--accent);
  text-align: center;
  padding: 4px 0;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.sw-actions {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.sw-btn {
  padding: 14px 0;
  border: 1.5px solid var(--border);
  background: var(--bg-card);
  color: var(--text);
  font: 700 13px 'DM Sans',sans-serif;
  letter-spacing: .5px;
  text-transform: uppercase;
  border-radius: 8px;
  cursor: pointer;
  /* "none" prevents Chrome from interpreting touch as scroll/zoom and
     hijacking the pointer mid-press */
  touch-action: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}
.sw-btn:active { transform: scale(.97); }
.sw-btn:disabled { opacity: .35; cursor: not-allowed; }
.sw-btn.sw-start { border-color: var(--green); color: var(--green); }
.sw-btn.sw-stop  { border-color: var(--red);   color: var(--red); }
.sw-btn.sw-lap   { border-color: var(--accent); color: var(--accent); }
.sw-btn.sw-reset { border-color: var(--text-dim); color: var(--text-muted); }
.sw-laps {
  display: flex; flex-direction: column;
  gap: 3px;
  max-height: 180px;
  overflow-y: auto;
}
.sw-lap-row {
  display: flex; justify-content: space-between;
  padding: 6px 10px;
  background: rgba(0,0,0,.15);
  border-radius: 5px;
  font: 12px 'DM Mono',monospace;
}
.sw-lap-row.best { background: rgba(61,170,107,.18); color: var(--green); font-weight: 700; }
.sw-lap-n { color: var(--text-dim); }
@media (max-width: 600px) {
  .sw-display { font-size: 30px; }
  .sw-btn { padding: 12px 0; font-size: 12px; }
}

/* Speed calculator unit toggle + result display */
.unit-toggle {
  margin-left: 6px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--accent);
  font: 700 10px 'DM Mono',monospace;
  padding: 2px 8px;
  border-radius: 4px;
  cursor: pointer;
  text-transform: lowercase;
  letter-spacing: .3px;
}
.unit-toggle:hover { border-color: var(--accent); }
.calc-out {
  font: 700 26px 'DM Mono',monospace;
  color: var(--accent);
  padding: 8px 0;
  letter-spacing: .5px;
}
/* Inline disclaimer block — used on the speed calculator props list */
.calc-disclaimer {
  display: flex; gap: 10px;
  margin: 10px 14px 6px;
  padding: 10px 12px;
  background: linear-gradient(135deg, rgba(26,108,122,.10), rgba(201,168,76,.08));
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  font: 12px 'DM Sans',sans-serif;
  color: var(--text-muted);
  line-height: 1.45;
}
.calc-disclaimer strong { color: var(--text); }
.calc-disclaimer-icon {
  font-size: 18px;
  color: var(--accent);
  line-height: 1;
  flex: 0 0 auto;
}

/* Two-number gear teeth input (pinion / driven) */
.gear-pair {
  display: flex; align-items: center; gap: 6px;
}
.gear-pair input {
  flex: 1;
  min-width: 0;
  text-align: center;
  font: 600 14px 'DM Mono',monospace;
}
.gear-sep {
  font: 700 18px 'DM Mono',monospace;
  color: var(--text-dim);
}
.special-group + .special-group { margin-top: 14px; }
.special-group-head {
  padding: 6px 10px;
  margin: 6px 0 4px;
  background: rgba(201,168,76,.10);
  border-left: 3px solid #c9a84c;
  border-radius: 4px;
  font: 13px 'DM Sans',sans-serif;
  color: var(--text);
}
.special-group-date {
  font-family: 'DM Mono',monospace;
  color: #c9a84c;
  font-weight: 700;
}
.special-group-none {
  background: rgba(0,0,0,.18);
  border-left-color: var(--text-dim);
}
.special-group-none .om-hint { color: var(--text-dim); }

/* ── Rental boxes ───────────────────────────────────────── */
.cal-rental-band {
  background: linear-gradient(90deg, rgba(146,99,167,.7), rgba(146,99,167,.55));
  color: #fff;
  font: 700 9px 'DM Sans',sans-serif;
  letter-spacing: .3px;
  padding: 2px 5px;
  margin: 1px 0;
  border-radius: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.cal-rental-band:hover { filter: brightness(1.15); }
.cal-rental-band.band-start { border-left: 3px solid #c9a84c; }
.cal-rental-band.band-end   { border-right: 3px solid #d04444; }
.rental-row {
  border-left: 3px solid var(--border);
}
.rental-row.rented { border-left-color: #9263a7; }
.rental-row.available { border-left-color: #4a8a4a; }
.rental-available-tag {
  color: #4a8a4a;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .5px;
  text-transform: uppercase;
}
.rental-send-btn,
.rental-return-btn {
  margin-left: 8px;
  padding: 4px 10px;
  font-size: 11px;
  border-radius: 6px;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent);
}
.rental-send-btn:hover,
.rental-return-btn:hover { background: var(--accent); color: #fff; }
.rental-send-btn:disabled,
.rental-return-btn:disabled { opacity: .5; cursor: wait; }
.rental-prop-list {
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px;
  background: rgba(0,0,0,.15);
}
.rental-prop-pick {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 6px;
  cursor: pointer;
  border-radius: 4px;
  font: 11px 'DM Mono',monospace;
  color: var(--text);
}
.rental-prop-pick:hover { background: rgba(26,108,122,.10); }
.rental-prop-pick input { margin: 0; }
.rental-box-preview {
  display: flex; flex-direction: column;
  gap: 8px;
}
.rental-mini-card {
  background: rgba(0,0,0,.20);
  border: 1px solid var(--border);
  border-left: 3px solid #9263a7;
  border-radius: 6px;
  padding: 8px 10px;
}
.rmc-head {
  font: 13px 'DM Mono',monospace;
  margin-bottom: 4px;
  display: flex; align-items: center; gap: 6px;
}
.rmc-head strong { color: var(--accent); }
.rmc-head .om-hint { color: var(--text-dim); font-size: 11px; }
.rmc-edit-btn {
  margin-left: auto;
  padding: 3px 8px;
  font-size: 10px;
  border-radius: 4px;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
}
.rmc-edit-btn:hover { border-color: var(--accent); color: var(--accent); }

/* Theme toggle button in the header */
.theme-toggle {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  width: 32px; height: 32px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  margin-right: 8px;
  padding: 0;
  transition: .15s;
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
/* ── Print picker ─────────────────────────────────
   Pick several propellers and print them as one PDF, a page each. The list
   sits beside the preview so the sheaf can be built while watching it.

   `psel-`, not `pp-`: the order modal's pitch picker already owns `.pp-row`
   and `.pp-btn`, and a second meaning for the same class is how the stopwatch
   once lent its border to a mock-up. */
.psel-wrap { display: flex; gap: 14px; align-items: flex-start; }
.psel-side { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.psel-main { flex: 0 0 auto; display: flex; flex-direction: column; gap: 10px;
  align-items: center; max-width: 100%; }
.psel-main > .om-hint { align-self: stretch; }
/* Shaped 100:150 so what is on screen is what comes out of the printer. */
#op-frame { width: 100mm; max-width: 100%; aspect-ratio: 100 / 150;
  border: 1px solid var(--border); border-radius: 6px; background: #fff; }
.psel-list { max-height: 52vh; overflow-y: auto; display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg-card); }
.psel-row { display: grid; grid-template-columns: auto minmax(0,1fr) auto minmax(0,1.1fr) auto;
  gap: 8px; align-items: baseline; padding: 6px 9px; cursor: pointer; font-size: 12.5px;
  border-bottom: 1px solid var(--border); }
/* `display: grid` above beats the browser's own `[hidden] { display: none }`
   — an author rule always does — so setting .hidden in JS did nothing and the
   list showed all 805 rows however it was filtered. Anything with an explicit
   display needs this line to be hideable at all. */
.psel-row[hidden] { display: none; }
.psel-row:last-child { border-bottom: none; }
.psel-row:hover { background: rgba(128,128,128,.10); }
.psel-row:has(.psel-cb:checked) { background: rgba(26,108,122,.14); }
.psel-serial { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.psel-cls { color: var(--accent); font-size: 11.5px; white-space: nowrap; }
.psel-who { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.psel-date { color: var(--text-dim); font-size: 11px; white-space: nowrap; }
.psel-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.psel-count { font-size: 11.5px; color: var(--text-muted); margin-left: auto; }
.psel-allbox { display: flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 11.5px; color: var(--text-muted); }
.psel-empty { padding: 14px 10px; font-size: 12px; color: var(--text-dim); text-align: center; }
/* Below this the two columns do not both fit; the list goes under the sheet. */
@media (max-width: 820px) {
  .psel-wrap { flex-direction: column; }
  .psel-main { align-self: stretch; }
  .psel-list { max-height: 34vh; }
}


/* Language switcher (client + reseller only) */
.lang-switcher {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  height: 32px;
  border-radius: 8px;
  font: 12px 'DM Sans',sans-serif;
  padding: 0 8px;
  margin-right: 8px;
  cursor: pointer;
  max-width: 140px;
}
.lang-switcher:hover { border-color: var(--accent); color: var(--accent); }
.lang-switcher option { color: #000; background: #fff; }
.rmc-meta {
  display: flex; flex-wrap: wrap; gap: 6px 10px;
  margin: 4px 0 6px;
  font-size: 11px;
}
.rmc-pitches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(54px, 1fr));
  gap: 3px;
}
.rmc-pitch-cell {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 4px;
  text-align: center;
}
.rmc-pitch-cell.empty { opacity: .35; }
.rmc-pitch-r {
  font: 700 8px 'DM Sans',sans-serif;
  letter-spacing: .5px;
  color: var(--text-dim);
}
.rmc-pitch-v {
  font: 11px 'DM Mono',monospace;
  color: var(--text);
}
@media (max-width: 720px) {
  .cal-days { grid-auto-rows: minmax(64px, 1fr); }
  .cal-daynum { font-size: 11px; }
  .cal-evt { font-size: 9px; padding: 1px 4px; }
  .cal-title { min-width: 120px; font-size: 14px; }
}

/* "Show more / Show less" toggle below collapsible lists */
.activity-toggle-wrap { display: flex; justify-content: center; padding: 8px 0 2px; }
.link-btn {
  background: transparent;
  border: none;
  color: var(--accent);
  font-size: 13px;
  cursor: pointer;
  padding: 4px 10px;
  border-radius: 6px;
}
.link-btn:hover { background: rgba(26,108,122,.12); color: var(--text); }

/* Modification history panel in order edit modal */
.mod-history {
  background: rgba(0,0,0,.25);
  border-radius: 8px;
  padding: 6px;
  max-height: 240px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 3px;
}
.mod-row {
  display: grid;
  grid-template-columns: 110px 80px 100px 1fr 16px 1fr;
  gap: 8px;
  align-items: center;
  padding: 5px 8px;
  background: var(--bg-card);
  border-radius: 5px;
  font-size: 11px;
}
.mod-when  { font-family: 'DM Mono',monospace; color: var(--text-dim); }
.mod-who   { color: var(--text-muted); }
.mod-field { color: var(--accent); font-weight: 600; }
.mod-from  { color: var(--text-dim); text-decoration: line-through; font-family: 'DM Mono',monospace; }
.mod-arrow { color: var(--text-dim); text-align: center; }
.mod-to    { color: var(--text); font-family: 'DM Mono',monospace; }

/* Grouped mod-history (one entry per save, multiple changes inside) */
.mod-group {
  background: var(--bg-card);
  border-radius: 6px;
  padding: 6px 8px;
  display: flex; flex-direction: column;
  gap: 3px;
}
.mod-group-head {
  display: flex; gap: 10px;
  font-size: 10px;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 3px;
}
.mod-group-head .mod-count {
  margin-left: auto;
  color: var(--accent);
  font-weight: 600;
}
.mod-row-line {
  display: grid;
  grid-template-columns: 100px 1fr 16px 1fr;
  gap: 8px;
  align-items: center;
  font-size: 11px;
  padding: 2px 4px;
}

/* Client detail — rich prop cards */
.client-prop {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 6px;
}
.cp-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
}
.cp-title {
  font-family: 'DM Mono', monospace;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
}
.cp-chips {
  display: flex; gap: 4px; flex-wrap: wrap;
  flex: 1;
}
.cp-meta {
  display: flex; flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 12px;
  color: var(--text-muted);
}
.cp-rider {
  margin-top: 4px;
  font-size: 11px; color: var(--text-dim);
}
.btn-edit-prop,
.row-copy-btn {
  font-size: 10px !important;
  padding: 4px 8px !important;
  letter-spacing: 1px;
  margin-left: 4px;
}

.empty-state {
  padding: 60px 20px; text-align: center;
  color: var(--text-dim); font-size: 13px;
}
.spinner {
  display: inline-block; width: 16px; height: 16px;
  border: 2px solid var(--border); border-top-color: var(--accent);
  border-radius: 50%; animation: spin .8s linear infinite;
  vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Shop tab ─────────────────────────────────────────────────── */
.row-main    { flex: 1 1 220px; min-width: 0; }
.row-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; flex-shrink: 0; }
/* Narrow screens: rows + sub-sub-tab heads stack instead of pushing content off-screen. */
@media (max-width: 780px) {
  .row { flex-wrap: wrap; }
  .row-actions { width: 100%; justify-content: flex-start; }
  .search-bar { flex-wrap: wrap; }
  .search-bar > .search-input { min-width: 0; }
}
.muted       { color: var(--text-dim); }

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .5px;
  text-transform: uppercase;
  border: 1px solid var(--border);
  background: rgba(255,255,255,.04);
  color: var(--text-muted);
}
.badge-ok    { background: rgba(61,170,107,.15); border-color: rgba(61,170,107,.4); color: var(--green); }
.badge-muted { background: rgba(255,255,255,.04); color: var(--text-dim); }

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px 14px;
  align-items: end;
}
.form-grid label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 12px; color: var(--text-dim);
}
.form-grid label input,
.form-grid label select {
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 9px;
  font: 13px 'DM Sans',sans-serif;
  outline: none;
  transition: .15s;
}
.form-grid label input:focus,
.form-grid label select:focus { border-color: var(--accent); }

.inv-line input {
  background: var(--bg-card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 9px;
  font: 13px 'DM Sans',sans-serif;
}

/* Shop product editor modal */
.sp-tabs {
  display: flex; gap: 4px;
  border-bottom: 1px solid var(--border);
  margin: -10px -4px 14px;
  padding: 0 4px;
}
.sp-tab {
  background: transparent; border: 0; color: var(--text-muted);
  padding: 10px 16px;
  font: 600 11px 'DM Sans',sans-serif;
  letter-spacing: 1.5px; text-transform: uppercase;
  cursor: pointer; border-bottom: 2px solid transparent;
  transition: .15s;
}
.sp-tab:hover { color: var(--text); }
.sp-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.sp-tab-panel[hidden] { display: none; }

.sp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px 14px;
  margin-bottom: 8px;
}
.sp-grid .m-field select {
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 7px;
  padding: 9px 12px;
  color: var(--text);
  font: 13px 'DM Sans',sans-serif;
  outline: none;
  cursor: pointer;
}
.sp-grid .m-field select:focus { border-color: var(--accent); }

.sp-options { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.sp-options-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px; }
.sp-opt-group {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 8px;
  background: var(--bg-darker);
  transition: .12s;
}
.sp-opt-group.on { border-color: rgba(26,108,122,.5); }
.sp-opt-toggle {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  cursor: pointer;
  user-select: none;
  font-size: 13px;
  font-weight: 600;
}
.sp-opt-toggle input { accent-color: var(--accent); cursor: pointer; }
.sp-opt-toggle .muted { font-weight: 400; font-size: 11px; }
.sp-opt-group-rm {
  margin-left: auto;
  background: transparent; border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 4px 9px; font-size: 10px; letter-spacing: 1px;
  border-radius: 5px; cursor: pointer;
}
.sp-opt-group-rm:hover { color: #f88; border-color: #c44; }
.sp-opt-group.custom { border-color: rgba(252,167,38,.3); }
.sp-opt-body {
  padding: 0 12px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.sp-unit-field { max-width: 130px; }
.sp-opt-rows { display: flex; flex-direction: column; gap: 5px; }
/* Flex rather than a grid: a row carries the value, optionally a price
   modifier, optionally a photo picker, then default + remove. Fixed columns
   would need a rule per combination and still overflow on a phone. */
.sp-opt-row {
  display: flex; flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.sp-opt-row .sp-opt-val { flex: 1 1 120px; min-width: 0; }
.sp-opt-row .sp-opt-mod { flex: 0 1 100px; min-width: 0; }
.sp-opt-row .sp-opt-default { flex: 0 0 auto; }
.sp-opt-row .sp-opt-rm { flex: 0 0 28px; margin-left: auto; }

/* Per-value gallery photo: thumbnail plus a picker listing the product's own
   images. Stores the url, so reordering the gallery cannot repoint it. */
.sp-opt-img { display: flex; align-items: center; gap: 5px; flex: 0 1 auto; }
.sp-opt-img > img,
.sp-opt-img > i {
  width: 28px; height: 28px; flex: 0 0 28px;
  border-radius: 5px; border: 1px solid var(--border);
  object-fit: cover; background: var(--bg-mid); display: block;
}
.sp-opt-img > select {
  background: var(--bg-mid); border: 1.5px solid var(--border);
  border-radius: 6px; padding: 6px 7px; color: var(--text);
  font-size: 12px; max-width: 120px; outline: none;
}
.sp-opt-img > select:focus { border-color: var(--accent); }
.sp-opt-img.gone > img, .sp-opt-img.gone > select { border-color: var(--red); }
.sp-opt-img.empty {
  font-size: 11px; color: var(--text-dim); font-style: italic;
  white-space: nowrap; align-self: center;
}

.sp-opt-row input[type="text"],
.sp-opt-row input[type="number"] {
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  color: var(--text);
  font: 13px 'DM Mono', monospace;
  outline: none;
}
.sp-opt-row input:focus { border-color: var(--accent); }
.sp-opt-default {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text-muted);
  letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer;
}
.sp-opt-default input { accent-color: var(--accent); cursor: pointer; }
.sp-opt-rm {
  background: transparent; border: 1px solid var(--border);
  color: var(--text-dim);
  width: 28px; height: 28px;
  border-radius: 6px;
  font-size: 16px; line-height: 1;
  cursor: pointer;
}
.sp-opt-rm:hover { border-color: #c44; color: #f88; }

.sp-image-row { display: flex; gap: 14px; align-items: stretch; }
.sp-image-preview {
  width: 140px; height: 140px;
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
}
.sp-image-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.sp-image-empty { color: var(--text-dim); font-size: 11px; letter-spacing: 1px; text-transform: uppercase; }
.sp-image-controls {
  display: flex; flex-direction: column; gap: 6px; flex: 1;
}
.sp-image-controls input[type="text"] {
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 7px;
  padding: 9px 12px;
  color: var(--text);
  font: 13px 'DM Sans',sans-serif;
  outline: none;
}
.sp-image-controls input[type="text"]:focus { border-color: var(--accent); }

/* Multi-image gallery */
.sp-gallery {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 8px;
}
.sp-gallery-empty { color: var(--text-dim); font-size: 12px; padding: 12px; grid-column: 1/-1; text-align: center; border: 1.5px dashed var(--border); border-radius: 8px; }
.sp-gallery-tile {
  position: relative; aspect-ratio: 1/1;
  background: var(--bg-mid); border: 1.5px solid var(--border); border-radius: 8px;
  overflow: hidden;
}
.sp-gallery-tile.cover { border-color: rgba(26,108,122,.6); }
.sp-gallery-tile img { width: 100%; height: 100%; object-fit: contain; }
.sp-gallery-badge {
  position: absolute; top: 4px; left: 4px;
  background: var(--accent); color: #fff;
  font-size: 9px; font-weight: 700; letter-spacing: 1px;
  padding: 2px 6px; border-radius: 3px;
}
.sp-gallery-tools {
  position: absolute; right: 4px; bottom: 4px;
  display: flex; gap: 3px; opacity: 0; transition: .12s;
}
.sp-gallery-tile:hover .sp-gallery-tools { opacity: 1; }
.sp-gallery-btn {
  background: rgba(0,0,0,.65); border: 0; color: #fff;
  width: 22px; height: 22px; font-size: 12px; line-height: 1;
  border-radius: 4px; cursor: pointer;
}
.sp-gallery-btn:hover:not(:disabled) { background: var(--accent); }
.sp-gallery-btn:disabled { opacity: .35; cursor: default; }

/* Variants editor */
.sp-variant-row {
  border: 1px solid var(--border); border-radius: 8px;
  padding: 12px; margin-bottom: 8px; background: var(--bg-darker);
  display: flex; flex-direction: column; gap: 8px;
}
.sp-variant-fields { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 10px; align-items: end; }
.sp-variant-fields .m-check { grid-column: 1/-1; }
.sp-variant-rm { align-self: flex-start; font-size: 10px; padding: 6px 10px; }
.sp-variant-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 6px;
}
.sp-variant-off { opacity: .55; }
.sp-variant-off .sp-variant-fields,
.sp-variant-off .sp-image-row { filter: saturate(.4); }

.row-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--text-muted); cursor: pointer;
  padding: 7px 10px;
  border: 1px solid var(--border); border-radius: 6px;
  user-select: none; transition: .12s;
}
.row-toggle:hover { border-color: var(--accent); color: var(--text); }
.row-toggle input { accent-color: var(--accent); cursor: pointer; }
.row-toggle:has(input:checked) { border-color: rgba(26,108,122,.5); color: var(--text); }

.cat-thumb {
  width: 40px; height: 40px;
  border-radius: 6px; object-fit: cover;
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.cat-thumb-empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-mid); color: var(--text-dim); font-size: 14px;
}
/* Category tree rows — depth colors + click-to-expand affordance. */
.cat-row {
  cursor: pointer;
  padding-left: calc(10px + var(--cat-depth, 0) * 18px);
  border-left: 3px solid;
}
.cat-row[data-depth="0"] { border-left-color: var(--accent); }
.cat-row[data-depth="1"] { border-left-color: rgba(26,108,122,.55); background: rgba(255,255,255,.015); }
.cat-row[data-depth="2"] { border-left-color: rgba(26,108,122,.35); background: rgba(255,255,255,.03);  }
.cat-row[data-depth="3"] { border-left-color: rgba(26,108,122,.2);  background: rgba(255,255,255,.045); }
.cat-chev {
  background: transparent; border: 0; cursor: pointer;
  color: var(--text-muted);
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px;
  transition: transform .15s;
  flex-shrink: 0; padding: 0;
}
.cat-chev.open { transform: rotate(90deg); color: var(--accent); }
.cat-chev:hover { color: var(--text); }
.cat-chev-spacer { cursor: default; opacity: 0; }

.rshop-lock { margin-right: 6px; opacity: .75; font-size: 13px; }
.btn-ghost[disabled] { opacity: .35; cursor: not-allowed; }

/* Expandable shop-order card. Allow the detail to wrap below the head row. */
.shop-order-row { flex-wrap: wrap; align-items: flex-start; }
.shop-order-row .row-main { flex: 1 1 60%; min-width: 0; }
.shop-order-row .row-actions { flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; }
.shop-order-row.open { background: var(--bg-darker); }
.shop-order-head { padding: 4px 0; }
.shop-order-detail {
  flex-basis: 100%;
  width: 100%;
  margin: 8px -14px -11px;       /* bleed to the card edges */
  padding: 12px 14px 14px;
  border-top: 1px solid var(--border);
  background: rgba(0,0,0,.18);
  font-size: 12px;
}
.shop-order-items {
  width: 100%; border-collapse: collapse;
  margin-bottom: 10px;
  font-family: 'DM Mono', monospace; font-size: 12px;
}
.shop-order-items th, .shop-order-items td {
  text-align: left; padding: 5px 9px;
  border-bottom: 1px solid var(--border);
}
.shop-order-items th {
  color: var(--text-dim); font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase;
  font-weight: 600; font-family: 'DM Sans', sans-serif;
}
.shop-order-buyer { color: var(--text-muted); line-height: 1.5; }
.shop-order-buyer strong { color: var(--text); }

.rshop-catalog-row { gap: 14px; }
.rshop-cat-thumb {
  width: 48px; height: 48px;
  background: var(--bg-mid);
  border: 1px solid var(--border);
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
  color: var(--text-dim); font-size: 14px;
}
.rshop-cat-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.rshop-cat-controls { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }
.rshop-cat-toggle { display: flex; align-items: center; gap: 6px; font-size: 12px; cursor: pointer; color: var(--text-muted); }
.rshop-cat-toggle input { accent-color: var(--accent); cursor: pointer; }
.rshop-cat-price { display: flex; flex-direction: column; gap: 3px; }
.rshop-cat-price > span { font-size: 9px; letter-spacing: 1px; text-transform: uppercase; color: var(--text-dim); }
.rshop-cat-price input {
  background: var(--bg-mid);
  border: 1.5px solid var(--border);
  border-radius: 6px;
  padding: 6px 9px;
  color: var(--text);
  font: 12px 'DM Mono', monospace;
  outline: none;
  max-width: 100px;
}
.rshop-cat-price input:focus { border-color: var(--accent); }

/* ── Lab → Test analysis (AiM .xrk analyser) ───────────────────── */
.xrk-drop {
  display: block; cursor: pointer;
  border: 1.5px dashed var(--border-strong);
  border-radius: 10px; padding: 26px 14px; text-align: center;
  background: var(--bg-mid); transition: .15s;
}
.xrk-drop:hover, .xrk-drop.drag { border-color: var(--accent); background: var(--bg-card); }
.xrk-drop-title { font-weight: 600; font-size: 15px; }
.xrk-drop-title code { background: var(--bg-card); padding: 1px 6px; border-radius: 4px; }
.xrk-drop-sub { color: var(--text-muted); font-size: 12px; margin-top: 4px; }

.xrk-row { cursor: pointer; }
.xrk-row:hover { background: var(--bg-mid); }
.xrk-del {
  margin-left: 8px; padding: 2px 8px; line-height: 1.4;
  font-size: 12px; min-width: 0;
}

.xrk-canvas { width: 100%; display: block; }

.xrk-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 10px;
}
.xrk-stat {
  background: var(--bg-mid); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; text-align: center;
}
.xrk-stat-v { font-size: 18px; font-weight: 700; }
.xrk-stat-k { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

.xrk-venue { margin-bottom: 16px; }
.xrk-venue:last-child { margin-bottom: 0; }
.xrk-venue-head {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: 15px; margin-bottom: 8px;
}
.xrk-infer {
  font-size: 12px; color: var(--text-muted);
  padding: 8px 10px; margin-top: 6px;
  background: var(--bg-mid); border-radius: 6px;
  border-left: 3px solid var(--gold);
}

.xrk-prop-setup {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
.xrk-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.xrk-field > span:first-child { color: var(--text-muted); }
.xrk-field select, .xrk-field input {
  background: var(--bg-mid); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 7px 9px; font-size: 14px; width: 100%;
}
.xrk-field .gear-pair { display: flex; align-items: center; gap: 6px; }
.xrk-field .gear-pair input { width: 100%; }
.xrk-field .gear-sep { color: var(--text-muted); }
.xrk-field #xrk-pitch-unit { flex-shrink: 0; min-width: 42px; }

.xrk-controls {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  margin-top: 10px; font-size: 12px;
}
.xrk-ctl { display: flex; align-items: center; gap: 6px; color: var(--text-muted); }
.xrk-ctl select {
  background: var(--bg-mid); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 8px; font-size: 13px;
}
.xrk-ctl-check { cursor: pointer; }
.xrk-sector-row { cursor: pointer; }
.xrk-sector-row:hover { background: var(--bg-mid); }

/* Lap list (left) + map (right) */
.xrk-maprow { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
.xrk-laplist {
  flex: 0 0 132px; display: flex; flex-direction: column; gap: 5px;
  max-height: 600px; overflow-y: auto;
}
.xrk-mapwrap { flex: 1 1 420px; min-width: 0; }
.xrk-overlay-panel { display: flex; flex-direction: column; gap: 4px; margin: 8px 0 2px; max-height: 190px; overflow-y: auto; }
.xrk-overlay-panel:empty { display: none; }
.xrk-overlay-panel .xrk-ctl { gap: 6px; align-items: center; }
.xrk-ovrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.xrk-lapchips { display: inline-flex; gap: 3px; flex-wrap: wrap; }
.xrk-lapchip { font: 11px system-ui; padding: 1px 6px; border-radius: 4px; border: 1px solid var(--border, #444); background: transparent; color: var(--text-muted, #999); cursor: pointer; }
.xrk-lapchip.on { background: var(--accent, #1a6c7a); color: #fff; border-color: var(--accent, #1a6c7a); }
.xrk-refbtn { font: 12px system-ui; padding: 0 5px; border-radius: 4px; border: 1px solid var(--border, #444); background: transparent; color: var(--text-muted, #999); cursor: pointer; flex: 0 0 auto; }
.xrk-refbtn.on { background: var(--accent, #1a6c7a); color: #fff; border-color: var(--accent, #1a6c7a); }
.xrk-ovrow.ovref { box-shadow: inset 0 0 0 1px var(--accent, #1a6c7a); border-radius: 6px; padding: 2px 4px; }
.xrk-ov-sw { display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto; vertical-align: middle; }
.xrk-reco { font-size: 14px; padding: 8px 10px; border-radius: 8px; background: var(--bg-mid); border: 1px solid var(--border); }
.xrk-row-active { background: var(--bg-card); box-shadow: inset 0 0 0 2px var(--accent); border-radius: 7px; }
.xrk-name-input { flex:1; min-width:0; background:transparent; border:1px solid transparent; border-radius:6px; color:inherit; font:inherit; font-weight:600; padding:3px 6px; }
.xrk-name-input:hover { border-color:var(--border); }
.xrk-name-input:focus { outline:none; border-color:var(--accent); background:var(--bg-card); }
.xrk-name-input::placeholder { color:var(--text-muted,#888); font-weight:500; }
.xrk-lap-card {
  display: flex; justify-content: space-between; align-items: center; gap: 6px;
  padding: 6px 9px; border-radius: 7px; font-size: 13px;
  background: var(--bg-mid); border: 1px solid var(--border); opacity: .5;
}
.xrk-lap-card.flying { opacity: 1; cursor: pointer; }
.xrk-lap-card.flying:hover { border-color: var(--border-strong); }
.xrk-lap-card.selected { border-color: var(--accent); background: var(--bg-card); box-shadow: inset 0 0 0 1px var(--accent); }
.xrk-lap-n { color: var(--text-muted); }
.xrk-lap-t { font-weight: 600; }
@media (max-width: 560px) {
  .xrk-laplist { flex-basis: 100%; flex-direction: row; flex-wrap: wrap; max-height: none; }
  .xrk-lap-card { flex: 0 0 auto; }
}
