/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 18px; border-radius: var(--radius-sm); border: 1px solid transparent;
  font-weight: 600; font-size: .92rem; cursor: pointer; transition: all var(--transition);
  white-space: nowrap; line-height: 1;
}
.btn svg { width: 16px; height: 16px; }
.btn-primary { background: var(--accent); color: var(--text-inv); }
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:active { background: var(--accent-press); }
.btn-ghost { background: var(--surface-2); color: var(--text); border-color: var(--line); }
.btn-ghost:hover { background: var(--surface-3); border-color: var(--text-3); }
.btn-danger { background: var(--surface-2); color: var(--neg); border-color: #4a3a3a; }
.btn-danger:hover { background: var(--neg-soft); border-color: var(--neg); }
.btn-sm { padding: 8px 12px; font-size: .84rem; }
.btn-lg { padding: 15px 22px; font-size: 1rem; border-radius: var(--radius); }
.btn-block { width: 100%; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ── Cards & tiles ───────────────────────────────────────────────────────── */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.card-pad { padding: 22px; }
.card-title { font-size: 1.05rem; font-weight: 700; margin-bottom: 4px; }

.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 20px; }
.tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 26px; cursor: pointer; transition: all var(--transition); box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 14px; min-height: 168px;
}
.tile:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--text-3); }
.tile .tile-icon {
  width: 52px; height: 52px; border-radius: 14px; background: var(--surface-3); color: var(--text);
  display: flex; align-items: center; justify-content: center;
}
.tile .tile-icon svg { width: 26px; height: 26px; }
.tile h3 { font-size: 1.2rem; }
.tile p { color: var(--text-3); font-size: .9rem; }
.tile .tile-go { margin-top: auto; color: var(--text); font-weight: 600; font-size: .88rem; display: flex; align-items: center; gap: 6px; }

/* Stat cards */
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 24px; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.stat .label { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); font-weight: 600; }
.stat .value { font-size: 2rem; font-weight: 800; margin-top: 4px; color: var(--text); }

/* ── Forms ───────────────────────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px 20px; }
.form-grid .full { grid-column: 1 / -1; }
/* Relative so that the visually-hidden native <select>/<input> behind an
   enhanced control stays inside its own field: the browser anchors a "please
   fill in this field" bubble to that element, and without a containing block
   here it would be reported against the modal's top corner instead of the
   control the message is about. */
.field { display: flex; flex-direction: column; gap: 7px; position: relative; }
.field label { font-size: .85rem; font-weight: 600; color: var(--text-2); }
.field .req { color: var(--neg); }
.field .optional { color: var(--text-3); font-weight: 400; font-size: .78rem; }
.input, .select, .textarea {
  width: 100%; padding: 13px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text); transition: all var(--transition); font-size: 1rem;
}
.input::placeholder, .textarea::placeholder { color: var(--text-3); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; background: var(--surface-3); border-color: var(--text-2); box-shadow: 0 0 0 4px var(--accent-ring);
}
.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237b8087' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 38px; }
.textarea { resize: vertical; min-height: 90px; }
/* datetime-local can overflow its container on mobile Safari - constrain it */
.input[type="datetime-local"], .input[type="date"], .input[type="time"] {
  min-width: 0; max-width: 100%; -webkit-appearance: none; appearance: none;
  text-align: left;
}
.input[type="datetime-local"]::-webkit-date-and-time-value { text-align: left; margin: 0; }

/* Password field with a peek (show/hide) toggle */
.input-with-peek { position: relative; }
.input-with-peek .input { padding-right: 44px; }
.peek-btn {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 34px; height: 34px; border: none; background: transparent; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; color: var(--text-3);
  cursor: pointer; transition: all var(--transition);
}
.peek-btn:hover { color: var(--text); background: var(--surface-3); }
.peek-btn svg { width: 19px; height: 19px; }

.form-actions { display: flex; gap: 12px; margin-top: 22px; }
.field-hint { font-size: .8rem; color: var(--text-3); }

/* Input with adjacent OCR button */
.input-with-ocr { display: flex; gap: 8px; }
.input-with-ocr .input { flex: 1; }
.ocr-btn {
  flex-shrink: 0; width: 48px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-3); color: var(--text-2); display: flex; align-items: center; justify-content: center;
  transition: all var(--transition);
}
.ocr-btn:hover { background: var(--accent); color: var(--text-inv); border-color: var(--accent); }
.ocr-btn svg { width: 20px; height: 20px; }
.ocr-status { font-size: .8rem; color: var(--text-3); margin-top: 4px; }

/* Segmented control (method toggle) */
.segment { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; padding: 4px; width: 100%; }
.segment button { flex: 1; border: none; background: transparent; padding: 12px 16px; border-radius: 999px; font-weight: 600; font-size: .92rem; color: var(--text-2); transition: all var(--transition); }
.segment button.active { background: var(--accent); color: var(--text-inv); }

/* Big method choice cards (wizard intro) */
.method-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.method-card {
  background: var(--surface-2); border: 2px solid var(--line); border-radius: var(--radius-lg);
  padding: 28px 22px; cursor: pointer; text-align: center; transition: all var(--transition);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}
.method-card:hover { border-color: var(--text-3); background: var(--surface-3); }
.method-card.active { border-color: var(--accent); background: var(--surface-3); }
.method-card .m-icon { width: 56px; height: 56px; border-radius: 16px; background: var(--surface-3); color: var(--text); display: flex; align-items: center; justify-content: center; }
.method-card.active .m-icon { background: var(--accent); color: var(--text-inv); }
.method-card .m-icon svg { width: 28px; height: 28px; }
.method-card h4 { font-size: 1.05rem; }
.method-card p { font-size: .82rem; color: var(--text-3); }

/* ── Multi-step wizard ───────────────────────────────────────────────────── */
.wizard { max-width: 640px; margin: 0 auto; }
.wizard-top { margin-bottom: 22px; }
.wizard-progress-meta { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.wizard-progress-meta .step-name { font-weight: 700; font-size: 1rem; }
.wizard-progress-meta .step-count { font-size: .85rem; color: var(--text-3); font-weight: 600; }
.wizard-bars { display: flex; gap: 6px; }
.wizard-bars .bar { flex: 1; height: 5px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.wizard-bars .bar .fill { display: block; height: 100%; width: 0; background: var(--accent); transition: width .3s ease; }
.wizard-bars .bar.done .fill { width: 100%; }
.wizard-bars .bar.active .fill { width: 60%; }

.wizard-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 28px; box-shadow: var(--shadow); }
.wizard-eyebrow { font-size: .72rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); margin-bottom: 8px; }
.wizard-card h2 { font-size: 1.5rem; margin-bottom: 6px; }
.wizard-card .w-sub { color: var(--text-3); font-size: .95rem; margin-bottom: 24px; }
.wizard-fields { display: flex; flex-direction: column; gap: 18px; }
.wizard-nav { display: flex; gap: 12px; margin-top: 26px; }
.wizard-nav .btn { flex: 1; }
.wizard-nav .btn.back { flex: 0 0 auto; }

/* Review screen */
.review-group { margin-bottom: 20px; }
.review-group h4 { font-size: .74rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-3); margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--line-2); display: flex; justify-content: space-between; align-items: center; }
.review-group h4 .edit-link { font-size: .8rem; color: var(--text-2); cursor: pointer; text-transform: none; letter-spacing: 0; font-weight: 500; }
.review-group h4 .edit-link:hover { color: var(--text); }
.review-row { display: flex; justify-content: space-between; gap: 20px; padding: 7px 0; font-size: .92rem; }
.review-row .rk { color: var(--text-3); }
.review-row .rv { color: var(--text); font-weight: 500; text-align: right; word-break: break-word; }
.review-imgs { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.review-imgs .ri { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 6px; background: var(--surface-2); }
.review-imgs .ri img { max-height: 120px; border-radius: 4px; }
.review-imgs .ri span { display: block; font-size: .72rem; color: var(--text-3); text-align: center; margin-top: 4px; }
.review-imgs .ri-doc { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100px; height: 120px; color: var(--text-2); text-decoration: none; cursor: pointer; }
.review-imgs .ri-doc:hover { border-color: var(--text-3); background: var(--surface); }
.review-imgs .ri-doc span { max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Tables ──────────────────────────────────────────────────────────────── */
/* A table scrolls inside its own frame rather than taking the page with it,
   which is what lets the header freeze: `position: sticky` on a <th> sticks to
   the nearest SCROLLING ancestor, and until this had a height it had nothing
   to stick within - the page scrolled and the header went with it.

   max-height, not height: a short table is still just as tall as its rows. */
.table-wrap {
  overflow: auto;
  /* max() floors it: on a short window the subtraction goes negative and the
     table would collapse to nothing. 320px still shows several rows. */
  max-height: max(320px, calc(100vh - var(--topbar-h) - 220px));
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
/* An expanded row's detail table scrolls with the table it sits inside; giving
   it its own scroll region would nest one scrollbar in another. */
.table-wrap .table-wrap { max-height: none; overflow: visible; }
table.data { width: 100%; border-collapse: collapse; font-size: .9rem; white-space: nowrap; }
table.data th {
  text-align: left; padding: 12px 14px; background: var(--surface-2);
  font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-3);
  font-weight: 700; position: sticky; top: 0; z-index: 2;
  /* An inset shadow rather than border-bottom: with border-collapse a sticky
     cell leaves its border behind when it detaches, so the divider vanishes
     the moment the header starts doing its job. */
  box-shadow: inset 0 -1px 0 var(--line);
}
table.data th.sortable { cursor: pointer; user-select: none; }
table.data th.sortable:hover { color: var(--text); }
table.data th .sort-ind { opacity: .6; margin-left: 4px; }
table.data td { padding: 12px 14px; border-bottom: 1px solid var(--line-2); vertical-align: middle; color: var(--text-2); }
table.data tr:last-child td { border-bottom: none; }
table.data tbody tr { transition: background var(--transition); }
table.data tbody tr:hover { background: var(--surface-2); }
table.data td .cell-strong { color: var(--text); font-weight: 500; }
.row-actions { display: flex; gap: 6px; }
.icon-btn {
  width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface-2); display: inline-flex; align-items: center; justify-content: center; color: var(--text-2);
  transition: all var(--transition);
}
.icon-btn:hover { background: var(--surface-3); color: var(--text); }
.icon-btn.danger:hover { background: var(--neg-soft); color: var(--neg); border-color: var(--neg); }
.empty { text-align: center; padding: 50px 20px; color: var(--text-3); }
.empty svg { width: 40px; height: 40px; margin: 0 auto 12px; opacity: .5; }

/* Tabs */
.tabs { display: inline-flex; gap: 4px; background: var(--surface-2); border: 1px solid var(--line); padding: 4px; border-radius: var(--radius-sm); }
.tabs button { border: none; background: transparent; padding: 9px 20px; border-radius: 7px; font-weight: 600; font-size: .88rem; color: var(--text-2); transition: all var(--transition); }
.tabs button.active { background: var(--accent); color: var(--text-inv); }
/* Not-yet-available tabs (e.g. Leave/Discipline/Documents while capturing a
   new employee) - blurred back so they read as "coming once this is saved"
   rather than as something that failed to open. */
.tabs button:disabled { opacity: .45; filter: blur(1.5px); cursor: not-allowed; user-select: none; }
.tabs button:disabled:hover { background: transparent; color: var(--text-2); }

/* Filter toolbar */
.filter-bar { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; margin: 16px 0; }
.filter-bar .search-box { position: relative; flex: 1 1 240px; min-width: 200px; }
.filter-bar .search-box svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-3); }
.filter-bar .search-box input { width: 100%; padding: 11px 12px 11px 36px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); }
.filter-bar .search-box input:focus { outline: none; border-color: var(--text-2); box-shadow: 0 0 0 4px var(--accent-ring); }
.filter-field { display: flex; flex-direction: column; gap: 5px; position: relative; }
.filter-field .fl { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.filter-field .select { padding: 9px 34px 9px 12px; font-size: .86rem; min-width: 150px; }
/* Every control in the toolbar to one height and one type size. The select
   had been given a compact metric and the text and date boxes had not, so a
   filter row rendered two or three different box heights side by side. */
.filter-bar .input,
.filter-bar .select,
.filter-bar .dd-trigger,
.filter-bar .dp-trigger,
.filter-bar .search-box input { font-size: .86rem; padding: 9px 12px; }
.filter-bar .select, .filter-bar .dd-trigger { padding-right: 34px; }
.filter-bar .search-box input { padding-left: 34px; }
.filter-field .input, .filter-field .dp-trigger { min-width: 150px; }
/* A disciplinary case's status: a label and a dropdown on one line, beside
   the status badge, rather than the stacked filter-toolbar arrangement. */
.case-status-pick { flex-direction: row; align-items: center; gap: 8px; margin-left: 6px; }
.case-status-pick .fl { margin: 0; }
.case-status-pick .select, .case-status-pick .dd-trigger { min-width: 200px; padding: 7px 34px 7px 12px; font-size: .86rem; }

/* A record's own status control, sitting under its title. */
.rd-status-row { margin: -6px 0 16px; display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.rd-status-row .muted { padding-bottom: 9px; }
.filter-chip-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.filter-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-3); border: 1px solid var(--line); border-radius: 999px; padding: 5px 10px 5px 12px; font-size: .8rem; color: var(--text); }
.filter-chip button { border: none; background: none; color: var(--text-3); cursor: pointer; font-size: 1rem; line-height: 1; }
.filter-chip button:hover { color: var(--text); }

/* Badges */
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px; font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }
.badge-tno { font-family: var(--mono); background: var(--surface-3); color: var(--text); text-transform: none; letter-spacing: 0; font-weight: 500; }
.badge-admin { background: var(--surface-3); color: var(--text); }
.badge-manager { background: var(--warn-soft); color: var(--warn); }
.badge-beta { background: var(--warn-soft); color: var(--warn); font-size: .64rem; padding: 2px 7px; vertical-align: middle; }
.badge-staff { background: var(--surface-2); color: var(--text-2); border: 1px solid var(--line); }
.badge-success { background: var(--pos-soft); color: var(--pos); }
.badge-muted { background: var(--surface-2); color: var(--text-3); }
.badge-inactive { background: var(--neg-soft); color: var(--neg); }
.badge-method { background: var(--surface-2); color: var(--text-2); border: 1px solid var(--line); text-transform: none; letter-spacing: 0; font-weight: 600; }

/* ── Modal ───────────────────────────────────────────────────────────────── */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.66); z-index: 100; display: flex; align-items: center; justify-content: center; padding: 20px; opacity: 0; transition: opacity var(--transition); }
.modal-overlay.open { opacity: 1; }
.modal {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  width: 100%; max-width: 560px; max-height: 92vh; overflow-y: auto; transform: translateY(8px); transition: transform var(--transition);
}
.modal-overlay.open .modal { transform: translateY(0); }
.modal-lg { max-width: 760px; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--surface); z-index: 2; }
.modal-head h2 { font-size: 1.25rem; }
.modal-close { width: 34px; height: 34px; border: none; background: var(--surface-2); border-radius: 9px; font-size: 1.1rem; color: var(--text-2); }
.modal-close:hover { background: var(--surface-3); color: var(--text); }
.modal-body { padding: 24px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 12px; padding: 18px 24px; border-top: 1px solid var(--line); flex-wrap: wrap; position: sticky; bottom: 0; background: var(--surface); }
/* Full screen: the dialog is the window. Its body is a column whose last
   child takes the rest of the height - an editor's page scrolls inside it,
   with the title above and the buttons below always in view. */
.modal-overlay-full { padding: 0; }
.modal-full {
  /* 100% of the overlay, not 100vh: the overlay is zoomed with the app
     (--app-zoom), and a zoomed 100vh falls short of the window. */
  max-width: none; width: 100%; height: 100%; max-height: none;
  border: 0; border-radius: 0; display: flex; flex-direction: column; overflow: hidden;
}
.modal-full .modal-head { padding: 12px 20px; flex-shrink: 0; }
.modal-full .modal-body { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 14px 20px 0; overflow: hidden; }
.modal-full .modal-foot { padding: 12px 20px; flex-shrink: 0; }

/* Detail list (record view) */
.detail-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 24px; }
.detail-list .full { grid-column: 1 / -1; }
.detail-item .dl-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; margin-bottom: 3px; }
.detail-item .dl-value { font-size: .95rem; color: var(--text); word-break: break-word; }
.pod-preview { margin-top: 6px; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; background: #fff; }
.pod-preview img { width: 100%; max-height: 320px; object-fit: contain; }

/* ── Signature pad ───────────────────────────────────────────────────────── */
.sig-pad-wrap { border: 1px dashed var(--line); border-radius: var(--radius-sm); background: #ffffff; }
.sig-pad { width: 100%; height: 200px; touch-action: none; display: block; border-radius: var(--radius-sm); cursor: crosshair; }
.sig-toolbar { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; border-top: 1px solid var(--line); background: var(--surface-2); border-bottom-left-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); }
.sig-toolbar .hint { font-size: .8rem; color: var(--text-2); font-weight: 600; }

/* Upload dropzone / camera */
.dropzone { border: 1px dashed var(--line); border-radius: var(--radius-sm); background: var(--surface-2); padding: 26px; text-align: center; color: var(--text-3); cursor: pointer; transition: all var(--transition); }
.dropzone:hover { border-color: var(--text-2); color: var(--text); background: var(--surface-3); }
.dropzone.has-file { border-style: solid; border-color: var(--pos); color: var(--pos); background: var(--pos-soft); }
.dropzone svg { width: 28px; height: 28px; margin: 0 auto 8px; }
.dropzone .thumb { max-height: 160px; margin: 8px auto 0; border-radius: 6px; }

/* ── Toast ───────────────────────────────────────────────────────────────── */
#toast-container { position: fixed; top: calc(var(--topbar-h) + 14px); right: 18px; z-index: 200; display: flex; flex-direction: column; gap: 10px; }
.toast {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: 13px 18px; min-width: 260px; max-width: 380px;
  font-size: .9rem; font-weight: 500; animation: toast-in .25s ease; color: var(--text);
}
.toast.success { border-color: var(--pos); }
.toast.error { border-color: var(--neg); }
@keyframes toast-in { from { transform: translateX(20px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }

/* ── Password card (printable) ───────────────────────────────────────────── */
.pw-card { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--surface-2); }
.pw-card .pw-head { background: var(--bg-2); color: var(--text); padding: 18px 22px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--line); }
.pw-card .pw-head img { height: 30px; filter: invert(1); }
.pw-card .pw-head .divider { width: 1px; height: 24px; background: var(--line); }
.pw-card .pw-head h3 { color: var(--text); font-size: 1.02rem; }
.pw-card .pw-body { padding: 22px; }
.pw-row { display: flex; justify-content: space-between; align-items: center; padding: 11px 0; border-bottom: 1px dashed var(--line); }
.pw-row:last-child { border-bottom: none; }
.pw-row .k { font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.pw-row .v { font-family: var(--mono); font-size: 1rem; font-weight: 500; color: var(--text); }
.pw-row .v.big { font-size: 1.25rem; color: var(--text); font-weight: 500; }
.pw-note { margin-top: 16px; font-size: .82rem; color: var(--text-3); background: var(--surface); padding: 12px 14px; border-radius: var(--radius-sm); }

/* ── Auth / login (dark greyscale) ───────────────────────────────────────── */
#login-screen { position: fixed; inset: 0; z-index: 9000; background: var(--bg); }
.auth-grid { display: grid; grid-template-columns: 1.05fr 1fr; min-height: var(--vh-full); }
.auth-visual {
  position: relative; overflow: hidden; color: var(--text); padding: 56px;
  display: flex; flex-direction: column; justify-content: space-between;
  background: linear-gradient(150deg, #ffffff 0%, #eef0f3 55%, #e2e6ea 100%);
  border-right: 1px solid var(--line);
}
.auth-visual::after { content: ''; position: absolute; top: -18%; right: -14%; width: 60%; height: 60%; background: radial-gradient(circle, rgba(20,22,26,.05) 0%, transparent 70%); filter: blur(40px); }
.auth-visual .a-logo img { height: 66px; width: auto; position: relative; z-index: 2; filter: invert(1); }
.auth-visual .a-copy { position: relative; z-index: 2; }
.auth-visual .a-copy h1 { color: var(--text); font-size: 2.6rem; line-height: 1.08; margin-bottom: 14px; }
.auth-visual .a-copy p { color: var(--text-2); font-size: 1.05rem; max-width: 440px; }
.auth-visual .a-foot { position: relative; z-index: 2; font-size: .76rem; text-transform: uppercase; letter-spacing: .12em; color: var(--text-3); }
.auth-form-side { display: flex; align-items: center; justify-content: center; padding: 40px; background: var(--bg-2); }
.auth-form { width: 100%; max-width: 380px; }
.auth-form .mobile-logo { display: none; text-align: center; margin-bottom: 28px; }
.auth-form h2 { margin-bottom: 6px; }
.auth-form .sub { color: var(--text-3); margin-bottom: 26px; font-size: .95rem; }
.auth-form .field { margin-bottom: 16px; }
.auth-err { color: var(--neg); font-size: .84rem; min-height: 20px; margin: 2px 0 6px; font-weight: 500; }
.auth-powered { margin-top: 34px; text-align: center; font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; color: var(--text-3); }
.auth-powered img { height: 30px; margin: 10px auto 0; opacity: .9; }

@media (max-width: 960px) {
  .form-grid { grid-template-columns: 1fr; }
  .detail-list { grid-template-columns: 1fr; }
  .auth-grid { grid-template-columns: 1fr; }
  .auth-visual { display: none; }
  .auth-form .mobile-logo { display: block; }
  .auth-form .mobile-logo img { height: 54px; margin: 0 auto; }
}
@media (max-width: 520px) {
  .method-cards { grid-template-columns: 1fr; }
  .wizard-card { padding: 20px; }
}

/* ── PDF / printable record document (light greyscale paper, fits one A4 page) ── */
.doc-paper {
  background: #ffffff; color: #1a1c1e; width: 794px; margin: 0 auto; padding: 34px 44px;
  font-family: var(--sans); box-sizing: border-box;
}
.doc-head { display: flex; justify-content: space-between; align-items: flex-start; padding-bottom: 16px; border-bottom: 2px solid #eceef1; margin-bottom: 20px; }
.doc-head .dh-brand .dh-logo { height: 34px; width: auto; display: block; }
.doc-head .dh-brand .dh-addr { margin-top: 8px; font-size: 10px; color: #6b7178; line-height: 1.6; }
.doc-head .dh-meta { text-align: right; }
.doc-head .dh-meta .dh-title { font-size: 22px; font-weight: 800; letter-spacing: -.5px; color: #1a1c1e; }
.doc-head .dh-meta .dh-row { margin-top: 6px; font-size: 11px; color: #6b7178; }
.doc-head .dh-meta .dh-row strong { color: #1a1c1e; margin-left: 10px; font-weight: 700; }
.doc-head .dh-meta .dh-tno { font-family: var(--mono); background: #f1f3f5; color: #1a1c1e; padding: 2px 8px; border-radius: 4px; font-size: 12px; }
.doc-section { margin-bottom: 16px; }
.doc-section-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9aa0a6; margin-bottom: 10px; display: flex; align-items: center; gap: 10px; }
.doc-section-title::after { content: ''; flex: 1; height: 1px; background: #eceef1; }
.doc-card { background: #f7f8f9; border: 1px solid #eceef1; border-radius: 8px; padding: 14px 18px; }
/* An explicit HTML <table>, not flexbox/grid/inline-block auto-wrapping.
   html2canvas (the doc's PDF-capture path) doesn't use the browser's real
   layout engine - it re-implements CSS layout itself, and that
   reimplementation's auto-wrap line-box calculation is unreliable: it was
   confirmed to silently drop the first field of every group-of-N (e.g. the
   1st, 4th, 7th... of a 3-column row) under CSS Grid, under Flexbox with
   wrap+gap, AND under plain inline-block with fixed pixel widths - the bug
   reproduced identically across all three, so it isn't about which
   auto-wrap mechanism is used. A <table>'s rows are laid out explicitly by
   RepairDoc.grid() in JS (RepairDoc.grid), so there's no wrapping
   calculation left for html2canvas to get wrong. (foreignObjectRendering,
   which would delegate to the browser's real engine, isn't viable either -
   it blanks the whole canvas the instant the doc contains an <img>, which
   this always does for the logo.) */
.doc-grid { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 12px; }
.doc-td { vertical-align: top; padding: 0 24px 12px 0; }
.doc-td .df-label, .doc-field-full .df-label { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: #9aa0a6; margin-bottom: 3px; }
.doc-td .df-value, .doc-field-full .df-value { font-size: 12px; color: #1a1c1e; word-break: break-word; }
.doc-field-full { margin-bottom: 12px; }
.doc-td img { width: 100%; max-height: 120px; object-fit: contain; border: 1px solid #eceef1; border-radius: 6px; background: #fff; margin-top: 5px; }
/* ── Printable doc: authorisation (sign-off) block ────────────────────────────
   The audit artifact for no-charge outcomes, so it is rendered whenever
   sign-off applied - including when it is still pending, which is stated
   rather than left blank. */
.doc-auth { margin-top: 12px; padding: 10px 12px; border: 1px solid #e3e6ea; border-radius: 6px; background: #fff; border-left: 3px solid #9aa0a6; }
.doc-auth.approved { border-left-color: #3a7d59; }
.doc-auth.pending  { border-left-color: #9c7620; background: #fffdf7; }
.doc-auth.rejected { border-left-color: #b4453d; }
.doc-auth-title { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: #6b7178; margin-bottom: 6px; }
.doc-auth .doc-auth-k { width: 110px; font-size: 10px; color: #9aa0a6; padding: 2px 10px 2px 0; }
.doc-auth .doc-auth-v { font-size: 11px; color: #1a1c1e; font-weight: 600; padding: 2px 0; }
.doc-auth-note { margin-top: 6px; font-size: 10px; color: #6b7178; font-style: italic; }
.doc-auth-sig { margin-top: 8px; }
.doc-auth-sig img { height: 54px; width: auto; max-width: 260px; object-fit: contain; display: block; border-bottom: 1px solid #d7dade; }
.doc-auth-sigcap { margin-top: 3px; font-size: 9px; color: #9aa0a6; }

/* Signature blocks on the mailroom delivery/dispatch document. Restored after
   the repair doc moved to table-based layout and took the shared .doc-imgs
   rules with it - this document still uses that markup, and without these the
   signature renders at its natural canvas size and overruns the page. */
.doc-imgs { font-size: 0; }
.doc-imgs .di { display: inline-block; vertical-align: top; box-sizing: border-box; width: 300px; margin: 0 20px 16px 0; font-size: 12px; }
.doc-imgs .di .df-label { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: #9aa0a6; margin-bottom: 5px; }
.doc-imgs .di img { width: 100%; max-height: 120px; object-fit: contain; border: 1px solid #eceef1; border-radius: 6px; background: #fff; }

.doc-foot { margin-top: 24px; padding-top: 12px; border-top: 1px solid #eceef1; text-align: center; color: #9aa0a6; font-size: 10px; line-height: 1.6; }

/* ── Line-item tables on printable documents ──────────────────────────────────
   The same shape as table.data on screen - a bordered, rounded wrapper, a
   tinted uppercase header, a rule between rows - in the fixed greyscale the
   paper uses, so a PDF reads like the screen it came from rather than a
   naked grid. Colours are literal, not tokens: html2canvas captures whatever
   the theme happens to be, and paper is always white. */
.doc-table-wrap { border: 1px solid #e1e4e8; border-radius: 8px; overflow: hidden; background: #ffffff; }
.doc-table { table-layout: auto; }
.doc-table th.doc-td, .doc-table thead th {
  padding: 9px 12px; background: #f6f7f9; font-size: 9px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px; color: #878d95; vertical-align: middle;
  border-bottom: 1px solid #e1e4e8;
}
.doc-table td.doc-td, .doc-table tbody td { padding: 9px 12px; border-bottom: 1px solid #eef0f3; vertical-align: middle; color: #1a1c1e; font-size: 12px; }
.doc-table tbody tr:last-child td { border-bottom: none; }
.doc-table tbody tr:nth-child(even) td { background: #fbfbfc; }
.doc-table tfoot td.doc-td, .doc-table tfoot td { padding: 9px 12px; background: #f6f7f9; border-top: 1px solid #e1e4e8; font-size: 12px; }
.doc-table-wrap, .doc-table thead, .doc-table tfoot { page-break-inside: avoid; break-inside: avoid; }

/* Keep sections/cards/rows intact across PDF page breaks (html2pdf reads these). */
.doc-head, .doc-section, .doc-card, .doc-grid tr, .doc-field-full,
.doc-auth, .doc-auth-sig, .doc-imgs, .doc-imgs .di {
  page-break-inside: avoid;
  break-inside: avoid;
}
.doc-scroll { overflow-x: auto; background: #e6e8eb; border-radius: var(--radius); padding: 20px; }

@media print {
  body * { visibility: hidden; }
  #print-area { display: block !important; position: absolute; left: 0; top: 0; width: 100%; }
  #print-area, #print-area * { visibility: visible; }
  .doc-paper { box-shadow: none; width: 100%; padding: 0; }
}
#print-area { display: none; }

/* ── Repairs: case timeline ───────────────────────────────────────────────── */
.timeline { position: relative; padding-left: 22px; }
.timeline::before { content: ''; position: absolute; left: 5px; top: 6px; bottom: 6px; width: 1px; background: var(--line); }
.timeline-item { position: relative; padding-bottom: 20px; }
.timeline-item:last-child { padding-bottom: 0; }
.ti-dot { position: absolute; left: -22px; top: 4px; width: 10px; height: 10px; border-radius: 50%; background: var(--surface); border: 2px solid var(--text-3); }
.ti-head { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; font-size: .92rem; }
.ti-head strong { text-transform: capitalize; }
.ti-note { font-size: .88rem; color: var(--text-2); margin-top: 3px; }

/* ── Repairs: new-case two-column intake ──────────────────────────────────── */
.rn-split { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 20px; align-items: start; }
.rn-side { position: sticky; top: calc(var(--topbar-h) + 20px); }
.rn-summary .rs-row { display: flex; justify-content: space-between; gap: 14px; padding: 7px 0; border-bottom: 1px solid var(--line-2); font-size: .87rem; }
.rn-summary .rs-row:last-child { border-bottom: 0; }
.rn-summary .rs-row.col { flex-direction: column; gap: 3px; }
.rs-k { color: var(--text-3); flex-shrink: 0; }
.rs-v { color: var(--text); font-weight: 600; text-align: right; word-break: break-word; }
.rs-row.col .rs-v { text-align: left; font-weight: 500; line-height: 1.5; }
.rs-sep { height: 1px; background: var(--line); margin: 10px 0; }
.rs-empty { font-size: .87rem; line-height: 1.55; }
.rs-logged { text-align: center; padding: 6px 0 14px; border-bottom: 1px solid var(--line-2); margin-bottom: 14px; }
.rs-ref { font-size: 1.05rem; padding: 7px 16px; }

/* Invoice lookup row */
.rn-lookup { display: flex; gap: 8px; align-items: flex-start; }
.rn-lookup > *:first-child { flex: 1; min-width: 0; }
.rn-lookup .btn { flex-shrink: 0; margin-top: 0; }

/* Order line-item picker */
/* .field is a bare flex column with no outer margin, so the blocks revealed
   after a lookup need their own rhythm or the labels crowd the field above. */
.rn-order-head { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px 14px; }
#rn-order-block > .field { margin-top: 18px; }
.rn-items { display: flex; flex-direction: column; gap: 8px; }
.rn-item { display: flex; gap: 11px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; transition: var(--transition); background: var(--surface); }
.rn-item:hover { border-color: var(--text-3); background: var(--surface-2); }
.rn-item.sel { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 3px var(--accent-ring); }
.rn-item input { margin-top: 3px; flex-shrink: 0; accent-color: var(--accent); }
.rn-item-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.rn-item-desc { font-weight: 600; font-size: .9rem; line-height: 1.4; }
.rn-item-meta { font-size: .8rem; color: var(--text-3); }
.rn-item-qty { width: 70px; flex-shrink: 0; }
.rn-manual-item { display: flex; gap: 8px; margin-top: 8px; }
.rn-manual-item #rn-manual-desc { flex: 1; }
.rn-manual-item #rn-manual-qty { width: 70px; flex-shrink: 0; }

/* Radio choices (lookup mode, error origin) - plain rows, not full cards
   like .rn-item, since these are always exactly-one-of-two/few. */
.rn-radio-row { display: flex; gap: 18px; flex-wrap: wrap; }
.rn-radio { display: flex; align-items: center; gap: 7px; font-size: .88rem; font-weight: 500; cursor: pointer; }
.rn-radio input { accent-color: var(--accent); }

/* GRV hand-off panel */
.rn-doc-preview { border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); height: 300px; position: relative; margin-bottom: 10px; }
.doc-thumb { transform: scale(.42); transform-origin: top left; width: 238%; pointer-events: none; }
.rn-doc-actions { display: flex; gap: 8px; }
.rn-doc-actions .btn { flex: 1; }
.rn-done { text-align: center; padding: 42px 24px; }
.rn-done-tick { width: 50px; height: 50px; border-radius: 50%; background: var(--pos-soft); color: var(--pos); display: flex; align-items: center; justify-content: center; font-size: 1.5rem; margin: 0 auto 16px; }
.rn-done h2 { margin: 0 0 8px; font-size: 1.25rem; }

/* ── Repairs: case detail ─────────────────────────────────────────────────── */
.rd-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.rd-row { display: flex; justify-content: space-between; gap: 14px; padding: 6px 0; font-size: .86rem; border-bottom: 1px solid var(--line-2); }
.rd-row:last-child { border-bottom: 0; }
.rd-row.col { flex-direction: column; gap: 3px; }
.rd-k { color: var(--text-3); flex-shrink: 0; }
.rd-v { font-weight: 600; text-align: right; word-break: break-word; }
.rd-row.col .rd-v { text-align: left; font-weight: 500; line-height: 1.55; }
.rd-sep { height: 1px; background: var(--line); margin: 9px 0; }
.rd-items { margin: 0; padding-left: 17px; font-size: .82rem; color: var(--text-2); line-height: 1.65; }

.rd-strip { margin-bottom: 20px; }
.rd-strip-left { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.rd-ref { font-size: 1rem; padding: 6px 14px; }
.rd-grv-note { margin-top: 14px; display: flex; justify-content: space-between; align-items: center; gap: 12px; }

/* Sign-off alert - deliberately loud, and mirrored in the resolution card */
.rd-signoff-alert { display: flex; gap: 16px; align-items: center; justify-content: space-between; flex-wrap: wrap;
  background: var(--neg-soft); border: 1px solid var(--neg);
  border-radius: var(--radius-sm); padding: 14px 18px; margin-bottom: 20px; }
.rsa-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rsa-body strong { color: var(--neg); font-size: .95rem; }
.rsa-body span { font-size: .85rem; color: var(--text-2); }
.rsa-actions { display: flex; gap: 8px; flex-shrink: 0; }

.rd-split { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; align-items: start; }
.rd-work { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.rd-timeline { position: sticky; top: calc(var(--topbar-h) + 20px); max-height: calc(100vh - var(--topbar-h) - 40px); overflow-y: auto; }

/* Resolution state banners */
.rd-res-state { display: flex; gap: 11px; align-items: flex-start; padding: 12px 14px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--surface-2); }
.rd-res-state > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.rd-res-state strong { font-size: .9rem; }
.rd-res-state .muted { font-size: .82rem; }
.rrs-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; margin-top: 6px; }
.rd-res-state.pending { background: var(--neg-soft); border-color: var(--neg); }
.rd-res-state.pending strong { color: var(--neg); }
.rd-res-state.pending .rrs-dot { background: var(--neg); }
.rd-res-state.approved { background: var(--pos-soft); border-color: var(--pos); }
.rd-res-state.approved strong { color: var(--pos); }
.rd-res-state.approved .rrs-dot { background: var(--pos); }
.rd-res-state.set .rrs-dot { background: var(--text-3); }
.rd-res-state.rejected { background: var(--warn-soft); border-color: var(--warn); }
.rd-res-state.rejected strong { color: var(--warn); }
.rd-res-state.rejected .rrs-dot { background: var(--warn); }

.rd-restorder summary { cursor: pointer; font-weight: 600; font-size: .82rem; color: var(--text-2); }
.rd-restorder .rd-items { margin-top: 8px; }

/* Error lines - one card per affected item */
.rd-lines-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.rd-chevron { transition: transform .15s ease; flex-shrink: 0; }
.rd-line { border: 1px solid var(--line); margin-bottom: 14px; }
.rd-line:last-child { margin-bottom: 0; }
.rd-line-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.rd-line-head.rd-line-toggle { cursor: pointer; user-select: none; }
.rd-line-head.collapsed { margin-bottom: 0; }
.rd-line-head:not(.collapsed) { margin-bottom: 14px; }
.rd-line-title-wrap { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.rd-line-title-wrap .rd-chevron { margin-top: 3px; }
.rd-line-head.collapsed .rd-chevron { transform: rotate(-90deg); }
.rd-line-title { font-weight: 700; font-size: .96rem; }
.rd-line-meta { font-size: .8rem; color: var(--text-3); margin-top: 2px; }
.rd-line-del { flex-shrink: 0; color: var(--neg); }
.rd-line-del:hover { background: var(--neg-soft); }
.rrs-sig-wrap { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; max-width: 200px; }
.rrs-sig { height: 46px; width: auto; max-width: 130px; object-fit: contain; background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 3px; flex-shrink: 0; }
.rrs-sig-comment { font-size: .78rem; color: var(--text-2); text-align: right; line-height: 1.4; }

/* Timeline: the diff is the point */
.timeline-item.latest .ti-dot { background: var(--accent); border-color: var(--accent); }
.timeline-item.approved .ti-dot { background: var(--pos); border-color: var(--pos); }
.timeline-item.rejected .ti-dot { background: var(--warn); border-color: var(--warn); }
.ti-actor { font-size: .78rem; color: var(--text-3); margin-top: 5px; }
.ti-change { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 6px; font-size: .82rem; }
.tic-label { color: var(--text-3); flex-shrink: 0; }
.tic-from { color: var(--text-2); background: var(--surface-3); padding: 2px 7px; border-radius: 5px; text-decoration: line-through; text-decoration-color: var(--text-3); }
.tic-to { color: var(--text); background: var(--accent-soft); padding: 2px 7px; border-radius: 5px; font-weight: 600; }
.tic-arrow { width: 12px; height: 12px; color: var(--text-3); flex-shrink: 0; }
.ti-sig { display: flex; align-items: center; gap: 9px; margin-top: 7px; }
.ti-sig img { height: 38px; width: auto; max-width: 110px; object-fit: contain; background: #fff; border: 1px solid var(--line); border-radius: 5px; padding: 2px; }
.ti-sig span { font-size: .78rem; }
.ti-sig-comment { font-size: .82rem; color: var(--text-2); margin-top: 5px; line-height: 1.45; }

/* Mailroom delivery stitched onto the repair timeline */
.ti-mail { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; width: 100%; text-align: left;
  margin-top: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); cursor: pointer; transition: var(--transition); font: inherit; color: inherit; }
.ti-mail:hover { border-color: var(--accent); background: var(--accent-soft); }
.tim-head { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: .84rem; }
.tim-row { font-size: .79rem; color: var(--text-2); }
.tim-open { font-size: .78rem; color: var(--accent); font-weight: 600; margin-top: 4px; }

@media (max-width: 1100px) {
  .rn-split, .rd-split { grid-template-columns: 1fr; }
  .rn-side, .rd-timeline { position: static; max-height: none; }
}

/* ── HR: progressive-discipline warnings panel ────────────────────────────── */
.warn-row { padding: 16px 0; border-bottom: 1px solid var(--line-2); }
.warn-row:last-child { border-bottom: 0; }
/* A repeat offence in the same category is the panel's whole point, so it gets
   its own tinted block - which needs real padding on all four sides, not the
   bare row rhythm. */
.warn-row-highlight {
  background: var(--neg-soft); border: 1px solid var(--neg); border-radius: var(--radius-sm);
  padding: 16px 18px; margin: 4px 0; border-bottom: 1px solid var(--neg);
}
.wr-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.wr-cat { font-size: 1rem; }
.wr-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 12px 20px; margin-top: 14px; }
.wr-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.wr-k { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 600; }
.wr-v { font-size: .88rem; font-weight: 600; word-break: break-word; }
.wr-left { font-weight: 500; color: var(--text-3); }
.wr-revoked { font-size: .82rem; color: var(--text-2); margin-top: 12px; line-height: 1.5; }
.wr-revoke { margin-top: 14px; }

/* ── HR: sectioned employee take-on form ──────────────────────────────────── */
.emp-section { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 12px; background: var(--surface); }
.emp-section > summary { cursor: pointer; padding: 12px 14px; margin: 0; list-style: none; user-select: none; }
.emp-section > summary::-webkit-details-marker { display: none; }
.emp-section > summary::before { content: '▸'; display: inline-block; width: 14px; color: var(--text-3); transition: transform var(--transition); }
.emp-section[open] > summary::before { transform: rotate(90deg); }
.emp-section > .form-grid { padding: 0 14px 16px; }
/* `.field` sets display:flex and `.form-grid` display:grid, and both beat the
   UA stylesheet's [hidden] rule - conditionally-shown blocks need this to
   actually hide. Without it the leave wizard showed the fraction time inputs
   even when "a full day or longer" was chosen. */
.field[hidden], .form-grid[hidden] { display: none; }

/* ── Settings-style section card: label + description left, fields right ──── */
.settings-card {
  display: grid; grid-template-columns: 260px 1fr; gap: 32px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 22px 24px; margin-bottom: 16px;
}
.settings-card-side { position: sticky; top: 90px; align-self: start; }
.settings-card-title { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: .95rem; color: var(--text); }
.settings-card-title svg { color: var(--text-3); flex-shrink: 0; }
.settings-card-desc { margin-top: 6px; font-size: .82rem; line-height: 1.5; color: var(--text-3); }
.settings-card-body { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px 20px; align-content: start; }

/* Icon-prefixed inputs. The icon sits inside the control, so the padding has
   to be pushed on the input itself rather than the wrapper. */
.field-input { position: relative; display: flex; }
/* The `.dd` / `.dp` wrappers are `display: contents`, so an enhanced select or
   date input still LAYS OUT as a direct child here - but it is no longer one
   as far as a `>` selector is concerned, which is why the triggers have to be
   named explicitly. Miss this and an enhanced control loses its width and its
   icon padding, and the icon lands on top of the text. */
.field-input > .input, .field-input > .select, .field-input > textarea.input,
.field-input > .dd > .dd-trigger, .field-input > .dp > .dp-trigger { width: 100%; }
.field-input.has-icon > svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-3); pointer-events: none; z-index: 1;
}
.field-input.has-icon > .input, .field-input.has-icon > .select,
.field-input.has-icon > .dd > .dd-trigger, .field-input.has-icon > .dp > .dp-trigger { padding-left: 36px; }
.field-input.has-icon > textarea.input { padding-left: 36px; }
.field-input.has-icon > textarea.input ~ svg { top: 18px; transform: none; }

@media (max-width: 900px) {
  .settings-card { grid-template-columns: 1fr; gap: 16px; }
  .settings-card-side { position: static; }
  .settings-card-body { grid-template-columns: 1fr; }
}

/* ── HR: leave balance cards ──────────────────────────────────────────────
   The labels wrap to different line counts ("Sick leave" vs "Family
   responsibility"), so the figures have to be pinned to a common baseline
   rather than flowing after the label - the label box grows, the number
   stays put. */
.balance-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; margin-bottom: 20px; }
.balance-card { display: flex; flex-direction: column; text-align: center; }
.balance-card .bc-label {
  flex: 1; font-size: .78rem; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .5px; line-height: 1.35;
}
.balance-card .bc-value { font-size: 1.9rem; font-weight: 800; margin-top: 10px; }

/* ── HR: leave application confirmation ───────────────────────────────────── */
.leave-confirm { padding: 14px 16px; border: 1px solid var(--accent); border-radius: var(--radius-sm); background: var(--surface-2); }
.leave-confirm .lc-net { font-size: 1.15rem; font-weight: 700; }
.leave-confirm .lc-why { font-size: .84rem; color: var(--text-2); margin-top: 6px; }
.leave-confirm .lc-why li { margin-left: 16px; }

/* ── Error Dashboard: dependency-free horizontal bar breakdowns ──────────── */
.err-dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px; }
.err-dash-full { grid-column: 1 / -1; }
.kpi-bars { display: flex; flex-direction: column; gap: 10px; }
.kpi-bar-row { display: grid; grid-template-columns: 140px 1fr auto; align-items: center; gap: 10px; }
.kpi-bar-label { font-size: .83rem; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kpi-bar-track { height: 8px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
.kpi-bar-fill { height: 100%; background: var(--accent); border-radius: 4px; min-width: 3px; }
.kpi-bar-value { font-size: .8rem; font-weight: 600; color: var(--text); white-space: nowrap; }

/* ── Notifications ─────────────────────────────────────────────────────── */
.notif-bell { position: relative; }
.notif-badge {
  position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px; background: var(--neg); color: #fff; font-size: .65rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}
.notif-list { display: flex; flex-direction: column; gap: 8px; }
.notif-row {
  display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface); cursor: pointer; transition: var(--transition);
}
.notif-row:hover { border-color: var(--text-3); background: var(--surface-2); }
.notif-row.unread { background: var(--accent-soft); border-color: var(--line); }
.notif-check { margin-top: 3px; flex-shrink: 0; accent-color: var(--accent); }
.notif-icon { flex-shrink: 0; color: var(--text-2); margin-top: 1px; }
.notif-body { flex: 1; min-width: 0; }
.notif-msg { font-size: .89rem; font-weight: 500; line-height: 1.4; }
.notif-row.unread .notif-msg { font-weight: 700; }
.notif-meta { font-size: .78rem; margin-top: 2px; }
.notif-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex-shrink: 0; margin-top: 6px; }

/* ── Error Dashboard: pie + line charts, segmented control ────────────────── */
.pie-wrap { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.pie-circle { width: 120px; height: 120px; border-radius: 50%; flex-shrink: 0; }
.pie-legend { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 160px; }
.pie-legend-row { display: flex; align-items: center; gap: 8px; font-size: .83rem; }
.pie-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.pie-legend-label { flex: 1; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pie-legend-value { font-weight: 600; white-space: nowrap; }

.err-dash-trend-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
/* As wide as its buttons - not stretched across whatever it sits in. */
.seg-control { display: inline-flex; max-width: 100%; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
/* A field stacks its children and stretches them; a toggle keeps its own width. */
.field > .seg-control { align-self: flex-start; }
.seg-btn { padding: 6px 14px; font-size: .82rem; font-weight: 600; background: var(--surface); color: var(--text-2); border: none; border-right: 1px solid var(--line); cursor: pointer; transition: var(--transition); }
.seg-btn:last-child { border-right: none; }
.seg-btn:hover { background: var(--surface-2); }
.seg-btn.active { background: var(--accent); color: var(--text-inv); }

.line-chart { width: 100%; height: 200px; overflow: visible; }
.line-chart-legend { display: flex; gap: 18px; margin-bottom: 6px; font-size: .78rem; color: var(--text-2); }
.lc-legend-item { display: flex; align-items: center; gap: 6px; }
.lc-swatch { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }

/* ── Error Admin: manager-owned dropdown taxonomy editor ──────────────────── */
.ea-note { border: 1px solid var(--warn); border-radius: var(--radius-sm); padding: 12px 14px; font-size: .88rem; line-height: 1.65; color: var(--text-2); }
.ea-note strong { color: var(--text); }
.ea-note .muted { display: block; margin-top: 6px; font-size: .83rem; }
.ea-editor { max-width: 860px; }
.ea-grouped { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 20px; align-items: start; }
.ea-grouped .ea-editor { max-width: none; }
.ea-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.ea-row { display: flex; gap: 8px; align-items: center; }
.ea-row .input { flex: 1; }
.ea-add { display: flex; gap: 8px; align-items: center; padding-top: 12px; border-top: 1px dashed var(--line); flex-wrap: wrap; }
.ea-add .input { flex: 1; min-width: 180px; }
.ea-add-check { display: flex; align-items: center; gap: 6px; font-size: .84rem; color: var(--text-2); white-space: nowrap; }
.ea-solutions td { vertical-align: middle; }
.ea-solutions .input { width: 100%; }

/* Hover flag on staff-facing dropdowns - explains that the list is curated and
   who to ask for a new option, since there's deliberately no "Other". */
.opt-info { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin-left: 5px;
  border-radius: 50%; border: 1px solid var(--line); color: var(--text-3); font-size: .62rem; font-weight: 700;
  cursor: help; vertical-align: middle; position: relative; font-style: normal; }
.opt-info:hover { border-color: var(--accent); color: var(--text); }
.opt-info::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
  width: 232px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--surface-3); color: var(--text);
  border: 1px solid var(--line); box-shadow: 0 6px 18px rgba(0,0,0,.18); font-size: .76rem; font-weight: 400;
  line-height: 1.5; text-transform: none; letter-spacing: 0; text-align: left; white-space: normal;
  opacity: 0; visibility: hidden; transition: opacity var(--transition); pointer-events: none; z-index: 40; }
.opt-info:hover::after { opacity: 1; visibility: visible; }

/* ── Media viewer (attachment lightbox) ───────────────────────────────────── */
.viewer-overlay {
  position: fixed; inset: 0; z-index: 200; background: rgba(10, 11, 13, .93);
  display: grid; grid-template-columns: 64px 1fr 64px; grid-template-rows: auto 1fr auto;
  grid-template-areas: "bar bar bar" "prev stage next" "count count count";
  align-items: center;
}
.viewer-bar { grid-area: bar; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 18px; }
.viewer-title { color: #fff; font-weight: 600; font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viewer-actions { display: flex; gap: 8px; flex-shrink: 0; }
.viewer-actions .btn { background: rgba(255,255,255,.12); color: #fff; border-color: rgba(255,255,255,.22); }
.viewer-actions .btn:hover { background: rgba(255,255,255,.22); }
.viewer-stage { grid-area: stage; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 8px; min-height: 0; height: 100%; }
.viewer-media { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius-sm); background: #000; }
.viewer-frame { width: 100%; height: 100%; min-height: 60vh; border: 0; border-radius: var(--radius-sm); background: #fff; }
.viewer-nav {
  width: 44px; height: 44px; margin: 0 auto; border-radius: 50%; border: 1px solid rgba(255,255,255,.22);
  background: rgba(255,255,255,.10); color: #fff; display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background var(--transition);
}
.viewer-nav:hover { background: rgba(255,255,255,.25); }
.viewer-nav.prev { grid-area: prev; }
.viewer-nav.next { grid-area: next; }
.viewer-count { grid-area: count; text-align: center; color: rgba(255,255,255,.65); font-size: .82rem; padding: 12px; }
.viewer-fallback { text-align: center; color: #fff; max-width: 380px; }
.viewer-fallback .vf-icon { color: rgba(255,255,255,.7); margin-bottom: 14px; }
.viewer-fallback .vf-name { font-weight: 600; margin-bottom: 8px; word-break: break-word; }
.viewer-fallback .vf-note { color: rgba(255,255,255,.6); font-size: .86rem; margin-bottom: 18px; line-height: 1.6; }

@media (max-width: 640px) {
  .viewer-overlay { grid-template-columns: 44px 1fr 44px; }
  .viewer-nav { width: 36px; height: 36px; }
}

/* Attachment tiles - a video/document gets a typed tile, not a broken <img>.
   The badge and play spans need explicit overrides because `.review-imgs .ri
   span` styles the caption as a centred block, which would otherwise drag
   both of them out of position. */
.ri-media { position: relative; cursor: pointer; }
.review-imgs .ri video { max-height: 120px; max-width: 160px; border-radius: 4px; display: block; background: #000; }
.review-imgs .ri-media .ri-badge {
  position: absolute; top: 8px; left: 8px; display: inline-block; width: auto;
  margin: 0; padding: 2px 7px; border-radius: 999px;
  background: rgba(10,11,13,.78); color: #fff; font-size: .64rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; text-align: center;
}
/* Sits over the media only - the bottom inset keeps it clear of the caption. */
.review-imgs .ri-media .ri-play {
  position: absolute; inset: 0 0 24px 0; margin: 0; display: flex;
  align-items: center; justify-content: center; color: #fff; pointer-events: none;
}
.ri-play svg { filter: drop-shadow(0 2px 6px rgba(0,0,0,.55)); }
.review-imgs .ri .ri-filemeta { font-size: .7rem; color: var(--text-3); margin-top: 2px; }
.review-imgs .ri-media:hover { border-color: var(--text-3); }

/* Upload progress */
.up-progress { margin-top: 12px; }
.up-progress-track { height: 6px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.up-progress-bar { height: 100%; width: 0%; background: var(--accent); transition: width .15s linear; }
.up-progress-label { font-size: .78rem; color: var(--text-3); margin-top: 6px; }

/* ── HR: Productivity Hours (demo) ────────────────────────────────────────── */
.prod-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; }
.prod-kpi {
  background: var(--surface); border: 1px solid var(--kpi); border-radius: var(--radius-sm);
  padding: 16px 18px;
}
.prod-kpi-label { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); font-weight: 600; }
.prod-kpi-value { font-size: 1.7rem; font-weight: 800; margin-top: 6px; line-height: 1.1; color: var(--kpi); }
.prod-kpi-sub { font-size: .78rem; color: var(--text-3); margin-top: 4px; }
.prod-line { width: 100%; height: 260px; display: block; }
.prod-donut {
  -webkit-mask: radial-gradient(circle at center, transparent 52%, #000 53%);
  mask: radial-gradient(circle at center, transparent 52%, #000 53%);
}
.kpi-bar-row[data-drill]:hover .kpi-bar-label { color: var(--text); text-decoration: underline; }

/* ── HR: case file - work panel left, timeline down the side ──────────────── */
.case-split { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start; }
.case-timeline { position: sticky; top: 90px; max-height: calc(100vh - 120px); overflow-y: auto; }
@media (max-width: 1100px) {
  .case-split { grid-template-columns: 1fr; }
  .case-timeline { position: static; max-height: none; }
}

/* Warning rows need to breathe inside the panel - the first row was butting
   straight up against the heading. */
.warn-list { display: flex; flex-direction: column; }
.warn-list .warn-row:first-child:not(.warn-row-highlight) { padding-top: 0; }

/* Incident facts read left-to-right rather than as a tall stack - the case
   file's narrative lives in the timeline, so this block is reference data. */
.rd-inline { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px 24px; }
.rd-cell { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; text-align: left; }
.rd-cell .rd-k { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 600; }
.rd-cell .rd-v { font-weight: 600; word-break: break-word; text-align: left; }

/* The incident detail is the case's own words - give it the same uppercase
   label as the facts above and a bordered block so it reads as a quoted
   statement rather than one more field. */
.rd-detail { margin-top: 20px; }
.rd-detail .rd-k { display: block; font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 600; margin-bottom: 8px; }
.rd-detail-body {
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface);
  padding: 14px 16px; line-height: 1.6; white-space: pre-wrap; word-break: break-word;
}

/* ── Blindata connection pill (topbar) ────────────────────────────────────── */
.bd-pill {
  display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0;
  padding: 6px 12px 6px 10px; margin-right: 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text-2);
  font-size: .78rem; font-weight: 600; line-height: 1; cursor: pointer;
  transition: all var(--transition); white-space: nowrap;
}
.bd-pill:hover { background: var(--surface-3); border-color: var(--text-3); }
.bd-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); flex-shrink: 0; }

/* Healthy: quiet green — a status that's fine shouldn't compete for attention. */
.bd-pill[data-status="connected"] { color: var(--pos); border-color: color-mix(in srgb, var(--pos) 35%, var(--line)); background: var(--pos-soft); }
.bd-pill[data-status="connected"] .bd-dot { background: var(--pos); }

/* Broken: red, and the dot pulses — lookups are silently failing right now. */
.bd-pill[data-status="unreachable"],
.bd-pill[data-status="unauthorized"],
.bd-pill[data-status="error"] { color: var(--neg); border-color: color-mix(in srgb, var(--neg) 35%, var(--line)); background: var(--neg-soft); }
.bd-pill[data-status="unreachable"] .bd-dot,
.bd-pill[data-status="unauthorized"] .bd-dot,
.bd-pill[data-status="error"] .bd-dot { background: var(--neg); animation: bd-pulse 1.8s ease-in-out infinite; }

/* Simulated/off: amber — working as configured, but the data isn't real. */
.bd-pill[data-status="simulated"],
.bd-pill[data-status="disabled"] { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, var(--line)); background: var(--warn-soft); }
.bd-pill[data-status="simulated"] .bd-dot,
.bd-pill[data-status="disabled"] .bd-dot { background: var(--warn); }

@keyframes bd-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .bd-pill .bd-dot { animation: none !important; } }

/* The label is the first thing to go on a narrow screen; the coloured dot
   still carries the status, and the tooltip/modal carry the detail. */
@media (max-width: 720px) {
  .bd-pill { padding: 6px; margin-right: 8px; }
  .bd-pill .bd-text { display: none; }
}

.bd-detail-head { margin-bottom: 12px; }
.bd-detail-head .bd-pill { cursor: default; margin: 0; font-size: .82rem; }
.bd-detail-note { color: var(--text-2); font-size: .9rem; line-height: 1.6; margin-bottom: 14px; }
.bd-detail-rows { border-top: 1px solid var(--line); }
.bd-detail-rows div { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: .86rem; }
.bd-detail-rows span { color: var(--text-3); }

/* ── New case: path choice ────────────────────────────────────────────────── */
.rn-path-cards { margin-top: 4px; }
.rn-path-card { cursor: pointer; }
.rn-path-card .rn-path-first { font-size: .74rem; color: var(--text-3); font-family: var(--mono); }
.rn-path-card.active .rn-path-first { color: var(--text-2); }

/* ── Stale-status reminder ────────────────────────────────────────────────── */
.rd-stale-alert {
  display: flex; align-items: center; gap: 14px; margin-bottom: 16px;
  padding: 14px 18px; border-radius: var(--radius); border: 1px solid var(--line);
  border-left: 3px solid var(--warn); background: var(--warn-soft);
}
.rd-stale-alert.severe { border-left-color: var(--neg); background: var(--neg-soft); }
.rd-stale-alert .rds-icon { color: var(--warn); display: flex; flex-shrink: 0; }
.rd-stale-alert.severe .rds-icon { color: var(--neg); }
.rd-stale-alert .rds-body { flex: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rd-stale-alert .rds-body strong { font-size: .95rem; }
.rd-stale-alert .rds-body span { font-size: .85rem; color: var(--text-2); line-height: 1.55; }
.rd-stale-alert .btn { flex-shrink: 0; }

/* Brief highlight when the banner's button jumps to the status control. */
.rd-flash { animation: rd-flash 1.6s ease-out; }
@keyframes rd-flash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  15%, 60% { box-shadow: 0 0 0 4px var(--accent-ring); border-color: var(--text-2); }
}
@media (prefers-reduced-motion: reduce) { .rd-flash { animation: none; } }

/* Compact form of the same signal, for scanning the records list. */
.stale-chip {
  display: inline-block; margin-left: 6px; padding: 2px 7px; border-radius: 999px;
  background: var(--warn-soft); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 30%, var(--line));
  font-size: .68rem; font-weight: 700; font-family: var(--mono); cursor: help; vertical-align: middle;
}
.stale-chip.severe { background: var(--neg-soft); color: var(--neg); border-color: color-mix(in srgb, var(--neg) 30%, var(--line)); }

/* ── Error Admin: status reminder thresholds ──────────────────────────────── */
.ea-thr-group { margin-bottom: 18px; }
.ea-thr-head {
  font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-3); padding-bottom: 6px; border-bottom: 1px solid var(--line); margin-bottom: 8px;
}
.ea-thr-row { display: flex; align-items: center; gap: 12px; padding: 5px 0; }
.ea-thr-status { flex: 1; font-size: .88rem; min-width: 0; }
.ea-thr-input { width: 88px; flex-shrink: 0; text-align: right; }
.ea-thr-unit { font-size: .8rem; color: var(--text-3); width: 34px; flex-shrink: 0; }

@media (max-width: 640px) {
  .rd-stale-alert { flex-wrap: wrap; }
  .rd-stale-alert .btn { width: 100%; }
}

/* ── Stock module ─────────────────────────────────────────────────────────────
   Panel headings and repeated "piece" rows. The module's screens are mostly
   lists of physical things - rolls, sticks, offcuts, transaction lines - and a
   plain stack of divs gives no sense of where one piece ends and the next
   begins, which on the return screen is exactly the mistake being designed out.

   `.card-head`/`.card-body`/`.page-actions` are used only by the Stock
   screens - checked before adding these rules, precisely because styling a
   class that older screens already use would have silently restyled them. The
   older pattern is `.card.card-pad` with a `.card-title`, and that is left
   exactly as it is; this is a head/body split alongside it, for panels that
   need a heading rule between the two. */
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding: 16px 22px; border-bottom: 1px solid var(--line);
}
.card-head h3 { font-size: 1.02rem; font-weight: 700; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.card-body { padding: 20px 22px; }
.card-body > .table-wrap { border-radius: var(--radius-sm); }

/* Button row at the foot of a screen. `.form-actions` already does this inside
   a form; this is its page-level twin, right-aligned because the primary
   action on these screens is a posting and belongs where the eye lands last. */
.page-actions { display: flex; gap: 12px; margin-top: 20px; flex-wrap: wrap; justify-content: flex-end; }
.page-actions .btn { min-width: 140px; justify-content: center; }

/* One physical piece, or one transaction line. */
.stk-row {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); padding: 14px 16px; margin-bottom: 12px;
}
.stk-row:last-child { margin-bottom: 0; }
.stk-row.active { border-color: var(--accent); background: var(--accent-soft); }
.stk-row-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; min-height: 32px;
}
.stk-row-head .stk-row-title { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-weight: 600; }
.stk-row .form-grid { margin-top: 12px; }
.stk-row-note { font-size: .82rem; color: var(--text-3); margin-top: 8px; }

/* A clickable location block in the makeup panel. */
.stk-loc { cursor: pointer; }
.stk-loc:hover { border-color: var(--text-3); }
.stk-loc .stk-loc-summary { color: var(--text-2); font-size: .88rem; }

/* The makeup sentence itself - the module's headline answer, so it gets to be
   the largest thing on the SKU screen. */
.stk-summary { font-size: 1.22rem; font-weight: 700; line-height: 1.35; margin-bottom: 6px; }

/* Live arithmetic on the return screen: issued / returned / consumed /
   outstanding, recomputed on every keystroke. Monospaced so the figures line
   up as they change rather than jittering sideways. */
.stk-maths {
  font-family: var(--mono); font-size: .78rem; color: var(--text-2);
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
}
.stk-maths strong { color: var(--text); font-weight: 500; }
.stk-maths .over { color: var(--neg); font-weight: 700; }
/* Separators between the figures. A flex gap alone leaves them reading as one
   run-on string - "issued 14.4m returned 4.8m consumed 0m" - which is the
   opposite of the point on a screen built to make the arithmetic legible. */
.stk-maths > *:not(:last-child)::after { content: '·'; margin-left: 10px; color: var(--text-3); }

/* Repeatable offcut-size rows. */
.stk-offcuts { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--line); }
/* A row of controls that belong side by side - an offcut size and its Remove
   button, a counted piece and its state. Deliberately NOT `.field`, which is a
   COLUMN flex container: putting an input and a button in a `.field` stacks
   and centres them, which is how these read before this existed. */
.stk-inline-row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }

/* Row actions, on one line, hugging the right edge. .stk-inline-row above is a
   FORM row - it wraps and carries a bottom margin, both wrong inside a cell,
   and full-size buttons made every row twice as tall as its own content. */
td.stk-row-actions { white-space: nowrap; width: 1%; text-align: right; }
td.stk-row-actions .btn { padding: 7px 12px; font-size: .82rem; margin-left: 6px; }

/* Expanding was being missed when the only cue was a caret in a narrow first
   column, so it is also a named button in the actions - and it says which way
   it will go. The caret stays as the at-a-glance marker of which rows have
   anything to open. */
.stk-expand-btn { font-variant-numeric: tabular-nums; }
.stk-expand-btn .stk-caret { margin-right: 2px; }
tr.stk-rec-row.open .stk-expand-btn { background: var(--surface-2); border-color: var(--line); }

/* The recycled number people read off the label. Loud, because on the floor it
   is the piece's name; the permanent id beside it is for the books. */
.stk-tag { font-variant-numeric: tabular-nums; letter-spacing: .01em; }

/* A quantity and its unit are two columns, so they have to line up as two:
   the number right-aligned against the unit beside it, which is how a column
   of quantities is read down. */
/* The foot of a capped table: what is being shown, and the way to see the
   rest. Sits directly under the table and reads as part of it. */
.stk-more-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px; margin-top: -1px;
  border: 1px solid var(--border); border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--surface-2);
  font-size: .82rem;
}

/* `table.data th` is a more specific selector than `th.stk-qty`, so the
   headers were staying left-aligned over right-aligned numbers and the Qty
   column read as if it belonged to the column before it. */
td.stk-qty, table.data th.stk-qty { text-align: right; padding-right: 6px; white-space: nowrap; }
td.stk-uom, table.data th.stk-uom { padding-left: 6px; white-space: nowrap; color: var(--text-3); width: 1%; }

/* A quantity box inside a table cell. Full-width inputs made the line builder
   twice as wide as the numbers going into it. */
.stk-qty-input { max-width: 130px; text-align: right; }
td.stk-qty .select, td.stk-qty .input { display: inline-block; }

/* The scoped SKU search shows what the chosen warehouse holds, so its results
   carry a header row - the unscoped one on Receive does not. */
.stk-sku-search .sp-results table.data th { font-size: .72rem; }
.stk-inline-row .input { max-width: 170px; }
.stk-inline-row .select { max-width: 190px; }
.stk-choice { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; font-size: .85rem; }
.stk-choice label { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; color: var(--text-2); cursor: pointer; }

/* Lineage tree - indent carries the generation, so a grandchild offcut reads
   as descended from the roll rather than as a sibling of it. */
.stk-lineage { display: flex; flex-direction: column; gap: 8px; }
.stk-lineage .stk-row { margin-bottom: 0; }
.stk-tree-line { border-left: 2px solid var(--line); padding-left: 14px; margin-left: 8px; }

/* SKU search on the transaction screens. The icon rules mirror
   `.filter-bar .search-box`, which this deliberately sits outside of - it is a
   panel control, not a filter toolbar, and it must not inherit the toolbar's
   margins. */
.stk-sku-search .search-box { position: relative; }
.stk-sku-search .search-box svg {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--text-3); pointer-events: none;
}
.stk-sku-search .search-box input {
  width: 100%; padding: 11px 12px 11px 36px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text);
}
.stk-sku-search .search-box input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }

/* SKU search results dropdown on the transaction screens. */
.sp-results { margin-top: 10px; }
.sp-results .table-wrap { max-height: 320px; overflow-y: auto; }
.sp-results tr { cursor: pointer; }
.sp-total { margin-top: 12px; font-weight: 700; font-size: .92rem; }

/* Attachment chips on a GRV. */
.stk-att { display: flex; align-items: center; gap: 8px; font-size: .85rem; color: var(--text-2); padding: 5px 0; }

/* The makeup sentence in a table cell. `table.data` is `white-space: nowrap`,
   which is right for codes and dates and wrong for the one column that carries
   a sentence - "68m: 2 x 30m sealed, 1 x 5m offcut..." was being clipped at the
   viewport edge, hiding the answer the screen exists to give. Let it wrap, and
   give it room without letting it crowd out the columns before it. */
td.stk-makeup-cell { white-space: normal; min-width: 260px; max-width: 460px; line-height: 1.45; color: var(--text-2); }

@media (max-width: 640px) {
  .card-head, .card-body { padding-left: 16px; padding-right: 16px; }
  .page-actions { justify-content: stretch; }
  .page-actions .btn { flex: 1; }
}

/* Shown only when a typed delivery reference turns out to be a repair case.
   There is no "miss" state on purpose - most references here are ordinary
   invoice or order numbers, and flagging those would be noise. */
.field-hint.ref-hit { color: var(--pos); font-weight: 600; }

/* Disciplinary matrix guidance shown on the outcome step of a case. */
.matrix-box { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; margin-bottom: 16px; background: var(--surface-2); }
.matrix-head { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 600; margin-bottom: 10px; }
.matrix-ladder { display: flex; flex-wrap: wrap; gap: 8px; }
.matrix-step { flex: 1 1 150px; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 10px; background: var(--surface); }
.matrix-step.current { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.matrix-step .ms-n { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 600; }
.matrix-step .ms-s { display: block; font-weight: 600; margin-top: 2px; }
.matrix-note { font-size: .83rem; color: var(--text-2); margin-top: 10px; line-height: 1.55; }

/* ── Stock: a table whose rows expand ────────────────────────────────────────
   Two screens want the same shape. The records list answers "what happened and
   when"; expanding a row answers "what was in it". The warehouse list answers
   "what is on which shelf"; expanding a row answers "in what pieces". Both
   stay scannable at fifty rows because only the row you asked about has to
   answer the second question. */
.stk-expand tbody tr.stk-rec-row { cursor: pointer; transition: background var(--transition); }
.stk-expand tbody tr.stk-rec-row:hover { background: var(--surface-2); }
.stk-expand tbody tr.stk-rec-row.open { background: var(--accent-soft); }
.stk-expand tbody tr.stk-rec-row.open td { border-bottom-color: transparent; }

/* A cancelled record still belongs in the list - it happened, and then it was
   reversed. Muted rather than hidden, and never struck through: the lines
   inside still need reading. */
.stk-expand tbody tr.stk-rec-void td { opacity: .55; }

.stk-caret-col { width: 28px; padding-right: 0 !important; }
.stk-caret { color: var(--text-3); font-size: .78rem; display: inline-block; width: 12px; }

/* The expanded half. Padded off the table's own grid so it reads as a panel
   hanging under the row rather than as more rows. */
.stk-rec-detail > td { padding: 0 !important; background: var(--surface-2); white-space: normal; }
.stk-rec-body { padding: 16px 22px 20px; border-bottom: 1px solid var(--line); }
.stk-rec-body .table-wrap { background: var(--surface); }

.stk-rec-facts {
  display: flex; flex-wrap: wrap; gap: 10px 28px; margin-bottom: 14px;
}
.stk-rec-facts > div { display: flex; flex-direction: column; gap: 2px; min-width: 120px; }
.stk-rec-facts span { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; }
.stk-rec-facts strong { font-size: .9rem; font-weight: 600; }

@media (max-width: 640px) {
  .stk-rec-body { padding: 14px 16px 16px; }
  .stk-rec-facts { gap: 8px 16px; }
}

/* ── Vertical section tabs (employee master) ──────────────────────────────────
   Sections down the left, the active section's fields on the right. Switching
   beats scrolling for a 60-field take-on form, and the same shell serves the
   read-only profile and the edit form so the Edit toggle changes the controls
   and nothing else. */
.vtabs {
  display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: 0;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
  overflow: hidden;
}
.vtabs-nav { display: flex; flex-direction: column; padding: 12px; gap: 2px; border-right: 1px solid var(--line); background: var(--surface-2); }
.vtab {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 11px 12px; border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-2); font-weight: 600; font-size: .89rem;
  cursor: pointer; transition: all var(--transition);
}
.vtab:hover { background: var(--surface-3); color: var(--text); }
.vtab.active { background: var(--surface); color: var(--text); border-color: var(--line); box-shadow: var(--shadow-sm); }
.vtab svg { width: 16px; height: 16px; flex-shrink: 0; }
.vtabs-body { padding: 24px 26px 28px; min-width: 0; }
.vtabs-head { margin-bottom: 20px; }
.vtabs-head h3 { font-size: 1.1rem; font-weight: 700; }
.vtabs-head p { font-size: .85rem; color: var(--text-3); margin-top: 3px; }
.vtabs-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.vtabs-head-row .btn { flex-shrink: 0; white-space: nowrap; }
.vtabs-grid { gap: 18px 22px; }

/* Read-only value sitting where its input would be, so switching to Edit does
   not reflow the section. */
.vfield-value {
  display: flex; align-items: center; gap: 8px; min-height: 44px;
  padding: 11px 0; font-weight: 600; word-break: break-word; border-bottom: 1px solid var(--line-2);
}
.vfield-value svg { width: 16px; height: 16px; color: var(--text-3); flex-shrink: 0; }

@media (max-width: 860px) {
  .vtabs { grid-template-columns: 1fr; }
  .vtabs-nav { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .vtab { width: auto; white-space: nowrap; }
}
.vfield-value.is-empty { color: var(--text-3); font-weight: 500; }

/* ── Case file stepper (sidebar step layout) ─────────────────────────────── */
.case-steps { align-self: start; }
.case-steps .vtabs-nav { min-width: 190px; }
.case-steps .step-dot {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .72rem; font-weight: 700; border: 1.5px solid var(--line);
  background: var(--surface); color: var(--text-3);
}
.case-steps .vtab.step-done .step-dot { background: var(--pos); border-color: var(--pos); color: #fff; }
.case-steps .vtab.step-current .step-dot { border-color: var(--accent); color: var(--accent); }
.case-steps .vtab.step-current { font-weight: 700; }
.case-steps .vtab.step-future { opacity: .62; }
@media (max-width: 1100px) {
  .case-steps .vtabs-nav { min-width: 0; }
}

/* Error dashboard drill-down: people beside causes. */
.ed-drill-cols { display: grid; grid-template-columns: 3fr 2fr; gap: 24px; margin-top: 14px; }
@media (max-width: 900px) { .ed-drill-cols { grid-template-columns: 1fr; } }

/* ── Stock document entry (GRV / Issue / Transfer line grids) ────────────── */
.doc-head-grid { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) { .doc-head-grid { grid-template-columns: repeat(2, 1fr); } }
.doc-lines .doc-cell { padding: 8px 10px; font-size: .9rem; }
.doc-lines td { vertical-align: middle; }

/* Stock master horizontal tabs with icons. */
.stk-tabs button { display: inline-flex; align-items: center; gap: 7px; }
.stk-tabs svg { flex-shrink: 0; }
.stk-shelf-select { padding: 8px 32px 8px 10px; font-size: .85rem; width: auto; min-width: 150px; }

/* ── Factory-floor leave application (shared iPad) ────────────────────────── */
.la-people-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.la-person {
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start; text-align: left;
  padding: 18px 18px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); cursor: pointer; transition: all var(--transition);
}
.la-person:hover { border-color: var(--text-3); box-shadow: var(--shadow-sm); }
.la-person-name { font-weight: 700; font-size: 1.02rem; }
.la-person-meta { font-size: .82rem; color: var(--text-3); }
.la-whoami { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.la-whoami-name { font-size: 1.2rem; font-weight: 800; }
.la-done { text-align: center; padding: 40px 24px; }
.la-done-tick { color: var(--pos); }
.la-done h2 { margin: 10px 0 6px; }
.la-idcheck { text-align: center; padding: 34px 24px; }
.la-id-input { text-align: center; font-size: 1.3rem; letter-spacing: .08em; padding: 16px; }
.la-idcheck .err-line { color: var(--neg); font-weight: 600; min-height: 22px; margin-top: 12px; font-size: .9rem; }

/* ── HR leave approvals: collapsible department groups of decision cards ──── */
.lap-dept { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); margin-bottom: 14px; overflow: hidden; }
.lap-dept-head {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 15px 18px; border: none; background: var(--surface-2); cursor: pointer;
  transition: background var(--transition);
}
.lap-dept-head:hover { background: var(--surface-3); }
.lap-dept.open .lap-dept-head { border-bottom: 1px solid var(--line); }
.lap-caret { color: var(--text-3); font-size: .9rem; width: 14px; }
.lap-dept-name { font-weight: 700; font-size: 1rem; }
.lap-dept-sum { margin-left: auto; font-size: .84rem; color: var(--text-3); }
.lap-dept-body { padding: 18px; }
.lap-card { display: flex; flex-direction: column; }
.lap-card-top { display: flex; gap: 8px; margin-bottom: 10px; }
.lap-card h3 { font-size: 1.08rem; }
.lap-what { font-weight: 700; margin-top: 6px; }
.lap-when { font-size: .88rem; margin-top: 2px; }
.lap-note { font-size: .85rem; margin-top: 8px; padding: 8px 10px; background: var(--surface-2); border-radius: var(--radius-sm); }
.lap-applied { font-size: .78rem; margin-top: 10px; }
.lap-actions { margin-top: auto; padding-top: 14px; }
.lap-decision { margin-top: 12px; display: flex; flex-direction: column; gap: 4px; font-size: .82rem; }

/* Floor-iPad choice cards: the delivery/dispatch method cards, sized for a
   gloved thumb and allowed to wrap past two across for the leave types. */
.la-choices { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.la-choices .method-card { padding: 26px 18px; }
.la-choices .method-card h4 { font-size: 1.08rem; }
.la-time-input { font-size: 1.25rem; padding: 16px; text-align: center; }

/* ── Signatures on a stock movement ──────────────────────────────────────── */
.stk-sigs { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.stk-sig { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px; background: var(--surface); }
.stk-sig img { width: 100%; height: 90px; object-fit: contain; background: #fff; border-radius: 6px; }
.stk-sig-meta { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; font-size: .82rem; }
.stk-sig-note { color: var(--text-2); }

/* The SKU master's tab body is the same white card the employee master's
   sections sit in - horizontal tabs above it instead of a rail beside it, but
   the panel underneath should read identically. */
.stk-tab-body {
  margin-top: 18px; padding: 24px 26px 28px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow-sm);
}
.stk-tab-body .form-grid { gap: 18px 22px; }

/* Floor-iPad idle prompt: fixed and unmissable on a wall-mounted screen,
   without covering what the person was in the middle of reading. */
.la-idle {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 300;
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap; justify-content: center;
  padding: 16px 22px; border-radius: var(--radius);
  background: var(--surface); border: 1.5px solid var(--warn);
  box-shadow: var(--shadow-lg); max-width: min(680px, calc(100vw - 32px));
}
.la-idle-text { display: flex; flex-direction: column; gap: 2px; }
.la-idle-text strong { font-size: 1.05rem; }
.la-idle-text span { color: var(--text-2); font-size: .9rem; }
.la-idle-actions { display: flex; gap: 10px; }


/* Employee → user links (profile ▸ System Access). One row per link, so the
   state (linked / not linked) is readable before the name is. */
.emp-link-row {
  display: grid; grid-template-columns: minmax(200px, 1fr) minmax(220px, 1.4fr) auto;
  gap: 18px; align-items: start;
  padding: 16px 0; border-bottom: 1px solid var(--line);
}
.emp-link-row:last-child { border-bottom: 0; }
.emp-link-what { display: flex; flex-direction: column; gap: 3px; }
.emp-link-what .muted { font-size: .82rem; }
.emp-link-who { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.emp-link-who .field-hint { flex-basis: 100%; margin: 2px 0 0; }
.emp-link-actions { display: flex; gap: 8px; }
@media (max-width: 760px) {
  .emp-link-row { grid-template-columns: 1fr; gap: 8px; }
}

/* ── Warehouse map: floor planner (2D) and warehouse view (3D) ───────────── */
.map-toolbar { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; margin-bottom: 14px; }
.map-toolbar .select { width: auto; min-width: 170px; }
.map-toolbar .spacer { flex: 1; }
.map-notice { display: flex; gap: 10px; align-items: center; padding: 10px 14px; border-radius: var(--radius-sm); font-size: .86rem; margin-bottom: 12px; border: 1px solid var(--line); background: var(--surface-2); }
.map-notice.warn { border-color: #e2b96b; background: #fdf6e6; color: #6b4d12; }
.map-notice .btn { margin-left: auto; }
.map-stage { display: grid; grid-template-columns: 220px minmax(0, 1fr) 300px; gap: 14px; min-height: 560px; }
.map-stage.no-rail { grid-template-columns: minmax(0, 1fr) 300px; }
.map-stage.no-panel { grid-template-columns: 220px minmax(0, 1fr); }
.map-stage.solo { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 1100px) { .map-stage, .map-stage.no-rail, .map-stage.no-panel { grid-template-columns: minmax(0, 1fr); } }
.map-rail, .map-panel { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 14px; overflow: auto; max-height: 72vh; }
.map-rail h4, .map-panel h4 { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); margin: 0 0 8px; }
.map-rail h4 + h4, .map-rail .map-tray { margin-top: 14px; }
.map-shelf-item { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-radius: var(--radius-sm); cursor: pointer; font-size: .86rem; border: 1px solid transparent; }
.map-shelf-item:hover { background: var(--surface-2); }
.map-shelf-item.active { border-color: var(--text-3); background: var(--surface-2); }
.map-shelf-item .code { font-weight: 700; font-family: var(--mono, monospace); font-size: .78rem; min-width: 34px; }
.map-shelf-item .sw { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.map-tray .map-shelf-item { cursor: grab; border-style: dashed; border-color: var(--line); }
.map-canvas-wrap { position: relative; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); overflow: hidden; min-height: 520px; }
.map-canvas-wrap svg { display: block; width: 100%; height: 100%; touch-action: none; user-select: none; }
.map-canvas-wrap canvas { display: block; width: 100%; height: 100%; touch-action: none; outline: none; }
.map-floor { fill: #f7f5f0; stroke: #a8a196; stroke-width: 1.5; }
.map-grid line { stroke: #e6e1d8; stroke-width: .5; }
.map-ruler text { font-size: 10px; fill: var(--text-3); }
.map-ruler line { stroke: var(--text-3); stroke-width: .8; }
.map-shelf rect { stroke: #4a4640; stroke-width: 1.2; cursor: move; }
.map-shelf.readonly rect { cursor: pointer; }
.map-shelf text { pointer-events: none; font-size: 11px; font-weight: 700; fill: #1f1d1a; }
.map-shelf .sub { font-weight: 500; font-size: 9.5px; fill: #4a4640; }
.map-shelf.selected rect { stroke: #1c5fb8; stroke-width: 2.5; }
.map-shelf.warn rect { stroke: #c62828; stroke-width: 2.5; stroke-dasharray: 5 3; }
.map-shelf.dim { opacity: .28; }
.map-handle { fill: #fff; stroke: #1c5fb8; stroke-width: 1.5; cursor: nwse-resize; }
.map-ghost rect { fill: rgba(28,95,184,.18); stroke: #1c5fb8; stroke-dasharray: 5 3; pointer-events: none; }
.map-overlay { position: absolute; left: 12px; bottom: 12px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; pointer-events: none; }
.map-overlay > * { pointer-events: auto; }
.map-legend { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; padding: 7px 10px; border-radius: var(--radius-sm); background: rgba(255,255,255,.92); border: 1px solid var(--line); font-size: .78rem; }
.map-legend .sw { width: 12px; height: 12px; border-radius: 3px; display: inline-block; margin-right: 5px; vertical-align: -2px; }
.map-tip { position: absolute; pointer-events: none; background: #1f1d1a; color: #fff; padding: 6px 9px; border-radius: 6px; font-size: .78rem; white-space: nowrap; transform: translate(12px, 12px); z-index: 3; }
.map-tip b { display: block; font-size: .82rem; }
.map-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; padding: 30px; color: var(--text-2); }
.map-panel .kv { display: grid; grid-template-columns: auto 1fr; gap: 5px 12px; font-size: .86rem; margin-bottom: 12px; }
.map-panel .kv .k { color: var(--text-3); }
.map-panel .field { margin-bottom: 9px; }
.map-panel .input, .map-panel .select { padding: 6px 9px; font-size: .86rem; }
.map-panel .two { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.map-sku-row { display: grid; grid-template-columns: 1fr auto; gap: 3px 10px; padding: 8px 0; border-top: 1px solid var(--line); font-size: .85rem; }
.map-sku-row:first-of-type { border-top: none; }
.map-sku-row .sku { font-weight: 700; }
.map-sku-row .desc, .map-sku-row .sum { grid-column: 1 / -1; color: var(--text-2); font-size: .8rem; }
.map-sku-row a { cursor: pointer; color: var(--accent, #1c5fb8); }
.map-locate-list { display: flex; flex-direction: column; gap: 6px; }
.map-locate-list button { text-align: left; }
.map-3d-fallback { padding: 10px 14px; }

/* ── Bulk stock count sheet ───────────────────────────────────────────────── */
.bc-toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 12px; }
.bc-toolbar .select, .bc-toolbar .input { width: auto; }
.bc-toolbar .spacer { flex: 1; }
.bc-wrap { overflow: auto; max-height: calc(100vh - var(--topbar-h) - 250px); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.bc-wrap table.data { white-space: nowrap; }
.bc-wrap table.data th.bc-fixed, .bc-wrap table.data td.bc-fixed { position: sticky; left: 0; background: var(--surface); z-index: 3; box-shadow: inset -1px 0 0 var(--line); }
.bc-wrap table.data th.bc-fixed { z-index: 4; background: var(--surface-2); }
.bc-wrap th .bc-wh { display: block; font-size: .64rem; color: var(--text-3); font-weight: 600; letter-spacing: 0; text-transform: none; }
.bc-wrap tr.bc-sku td { background: var(--surface-2); font-weight: 700; }
.bc-wrap tr.bc-piece td.bc-fixed { padding-left: 28px; font-weight: 500; }
.bc-wrap tr.bc-spare td { color: var(--text-3); }
.bc-qty { width: 78px; padding: 5px 8px; font-size: .88rem; text-align: right; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); }
.bc-qty:focus { outline: 2px solid var(--accent, #1c5fb8); outline-offset: -1px; }
.bc-qty.changed { background: #fff8e1; border-color: #e2b96b; font-weight: 700; }
.bc-serial { width: 150px; padding: 5px 8px; font-size: .84rem; border: 1px solid var(--line); border-radius: 6px; }
.bc-state { padding: 5px 24px 5px 8px; font-size: .82rem; width: auto; }
.bc-add { font-size: .78rem; }
.bc-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: .8rem; color: var(--text-3); margin-top: 8px; }
.bc-preview .var-pos { color: var(--pos, #2f9e6b); font-weight: 700; }
.bc-preview .var-neg { color: var(--neg, #c62828); font-weight: 700; }
.bc-preview .detail { font-size: .8rem; color: var(--text-3); white-space: normal; }
.bc-errors { margin-bottom: 12px; }
.bc-errors li { color: var(--neg, #c62828); font-size: .86rem; }

/* ── Searchable dropdowns (components/dropdown.js) ────────────────────────────
   The wrapper is `display: contents`, so the trigger sits exactly where the
   native <select> sat and inherits its classes - a `.select` inside a
   `.filter-field` keeps the same width, padding and position it always had.
   The native element stays in the DOM, visually hidden, still holding the
   value that every existing read-back path depends on. */
.dd { display: contents; }
.dd-native {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; opacity: 0; pointer-events: none;
}
.dd-trigger {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
  text-align: left; cursor: pointer; font-family: inherit;
  /* `.select` paints its chevron as a background image; this one draws its own. */
  background-image: none !important; padding-right: 12px;
}
.dd-trigger:disabled { cursor: not-allowed; opacity: .6; }
.dd-trigger .dd-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-trigger .dd-caret { flex-shrink: 0; color: var(--text-3); transition: transform var(--transition); }
.dd-trigger[aria-expanded="true"] .dd-caret { transform: rotate(180deg); }
.dd-trigger[aria-expanded="true"] { border-color: var(--text-2); box-shadow: 0 0 0 4px var(--accent-ring); }
.dd-trigger.dd-placeholder .dd-value { color: var(--text-3); }
/* A filter that is actually filtering should look different from one that is not. */
.dd-trigger.dd-filtering { border-color: var(--text-2); background: var(--accent-soft); color: var(--text); font-weight: 600; }

.dd-panel {
  position: fixed; z-index: 9500; display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); animation: ddIn 140ms cubic-bezier(.22, 1.2, .36, 1);
}
@keyframes ddIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.dd-search { padding: 8px; border-bottom: 1px solid var(--line-2); flex-shrink: 0; }
.dd-search .input { padding: 8px 10px; font-size: .88rem; }
.dd-list { overflow-y: auto; padding: 5px; flex: 1; min-height: 0; }
.dd-group { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; padding: 8px 9px 4px; }
.dd-item {
  display: flex; align-items: center; gap: 9px; padding: 9px 10px; border-radius: 7px;
  cursor: pointer; font-size: .9rem; color: var(--text); line-height: 1.3;
}
.dd-item:hover, .dd-item.active { background: var(--surface-2); }
.dd-item.active { box-shadow: inset 0 0 0 1px var(--line); }
.dd-item.selected { font-weight: 600; }
.dd-panel:not([aria-multiselectable]) .dd-item.selected { background: var(--accent-soft); }
.dd-item.disabled { opacity: .45; cursor: not-allowed; }
.dd-item-label { overflow: hidden; text-overflow: ellipsis; }
.dd-check {
  width: 16px; height: 16px; flex-shrink: 0; border: 1.5px solid var(--line); border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center; background: var(--surface);
}
.dd-item.selected .dd-check { background: var(--accent); border-color: var(--accent); color: var(--text-inv); }
.dd-empty { padding: 16px 12px; text-align: center; color: var(--text-3); font-size: .86rem; }
.dd-foot { display: flex; justify-content: space-between; gap: 8px; padding: 7px 10px; border-top: 1px solid var(--line-2); flex-shrink: 0; }
.dd-foot button { background: none; border: none; color: var(--text-2); font-size: .78rem; font-weight: 700; cursor: pointer; padding: 3px 2px; }
.dd-foot button:hover { color: var(--text); text-decoration: underline; }
.dd-list { overscroll-behavior: contain; }
/* On a phone: a sheet from the bottom, at full size (it is outside the app's
   90% zoom, so the 16px search box really is 16px and iOS does not zoom the
   page in when it is tapped), with rows big enough for a thumb. */
.dd-backdrop { position: fixed; inset: 0; z-index: 9499; background: rgba(0,0,0,.45); touch-action: none; }
.dd-panel.dd-sheet {
  left: 0; right: 0; bottom: 0; top: auto; min-width: 0; max-width: none; max-height: 82vh;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0; border-bottom: 0;
  padding-bottom: env(safe-area-inset-bottom);
  animation: ddSheetIn 160ms cubic-bezier(.22, 1, .36, 1);
}
@keyframes ddSheetIn { from { transform: translateY(16px); opacity: .5; } to { transform: none; opacity: 1; } }
.dd-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 8px 4px 16px; flex-shrink: 0; touch-action: none; }
.dd-sheet-title { font-weight: 700; font-size: 1rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-sheet .dd-search .input { font-size: 16px; padding: 10px 12px; }
.dd-sheet .dd-list { padding: 4px 8px; }
.dd-sheet .dd-item { padding: 13px 10px; font-size: 1rem; }
.dd-sheet .dd-check { width: 20px; height: 20px; }
.dd-sheet .dd-foot { padding: 6px 12px; touch-action: none; }
.dd-sheet .dd-foot button { font-size: .92rem; padding: 10px 6px; }
@media (prefers-reduced-motion: reduce) { .dd-panel, .dd-panel.dd-sheet { animation: none; } }

/* ── Date picker (components/datepicker.js) ───────────────────────────────────
   Same shape as the dropdown above, for the same reason: the wrapper is
   `display: contents` so the trigger inherits the native input's position and
   classes, and the native input stays in the DOM holding the ISO value. */
.dp { display: contents; }
.dp-native {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; opacity: 0; pointer-events: none;
}
.dp-trigger {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
  text-align: left; cursor: pointer; font-family: inherit; background-image: none !important;
}
.dp-trigger:disabled { cursor: not-allowed; opacity: .6; }
.dp-trigger .dp-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dp-trigger .dp-icon { flex-shrink: 0; color: var(--text-3); }
.dp-trigger[aria-expanded="true"] { border-color: var(--text-2); box-shadow: 0 0 0 4px var(--accent-ring); }
.dp-trigger.dp-placeholder .dp-value { color: var(--text-3); }

.dp-panel {
  position: fixed; z-index: 9500; width: 268px; padding: 10px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); animation: ddIn 140ms cubic-bezier(.22, 1.2, .36, 1);
}
.dp-panel:focus { outline: none; }
.dp-head { display: flex; align-items: center; gap: 4px; margin-bottom: 8px; }
.dp-nav {
  width: 28px; height: 28px; flex-shrink: 0; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: var(--text-2); font-size: 1.1rem; line-height: 1; cursor: pointer;
}
.dp-nav:hover { background: var(--surface-3); color: var(--text); }
.dp-title {
  flex: 1; border: none; background: none; cursor: pointer; border-radius: 8px; padding: 6px 4px;
  font-weight: 700; font-size: .9rem; color: var(--text); font-family: inherit;
}
.dp-title:hover { background: var(--surface-2); }
.dp-dow { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 2px; }
.dp-dow span { text-align: center; font-size: .66rem; font-weight: 700; letter-spacing: .05em; color: var(--text-3); padding: 4px 0; }
.dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp-grid-m { grid-template-columns: repeat(3, 1fr); gap: 4px; }
.dp-day, .dp-cell {
  border: none; background: none; border-radius: 8px; cursor: pointer; font-family: inherit;
  color: var(--text); font-size: .84rem; padding: 7px 0; line-height: 1;
}
.dp-cell { padding: 11px 0; font-size: .82rem; }
.dp-day:hover, .dp-cell:hover { background: var(--surface-2); }
.dp-day.muted { color: var(--text-3); }
.dp-day.off { color: var(--text-3); opacity: .35; cursor: not-allowed; }
.dp-day.off:hover { background: none; }
/* Today is outlined, the chosen day is filled - so "where am I" and "what did
   I pick" never look like the same thing. */
.dp-day.now { box-shadow: inset 0 0 0 1px var(--line); font-weight: 700; }
.dp-day.sel, .dp-cell.sel { background: var(--accent); color: var(--text-inv); font-weight: 700; }
.dp-day.sel:hover, .dp-cell.sel:hover { background: var(--accent-hover); }
.dp-foot { display: flex; justify-content: space-between; gap: 8px; padding: 8px 2px 0; margin-top: 8px; border-top: 1px solid var(--line-2); }
.dp-foot button { background: none; border: none; color: var(--text-2); font-size: .78rem; font-weight: 700; cursor: pointer; padding: 3px 2px; font-family: inherit; }
.dp-foot button:hover { color: var(--text); text-decoration: underline; }

/* ── Type-ahead suggestions (components/suggest.js) ─────────────────────── */
.sg-panel {
  position: fixed; z-index: 9500; overflow: hidden; padding: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); animation: ddIn 120ms cubic-bezier(.22, 1.2, .36, 1);
}
.sg-item {
  padding: 8px 10px; border-radius: 7px; cursor: pointer; font-size: .88rem; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sg-item b { color: var(--text); font-weight: 700; }
.sg-item:hover, .sg-item.active { background: var(--surface-2); color: var(--text); }

/* ── Saved account signature (components/saved-signature.js) ─────────────── */
.ss-slot:empty { display: none; }
.ss-offer {
  display: flex; align-items: center; gap: 14px; margin-bottom: 10px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.ss-offer.on { border-color: var(--text-2); background: var(--accent-soft); }
.ss-preview {
  width: 96px; height: 44px; object-fit: contain; flex-shrink: 0;
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
}
.ss-offer .ss-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ss-offer .ss-body strong { font-size: .9rem; color: var(--text); }
.ss-when { font-size: .76rem; color: var(--text-3); }
.ss-keep { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: .82rem; color: var(--text-2); cursor: pointer; }
.ss-keep input { width: 15px; height: 15px; accent-color: var(--accent); }
/* The pad is hidden, not removed: it keeps its canvas and its listeners, so
   switching back to drawing does not have to rebuild it. */
.ss-hidden { display: none !important; }

/* My-account page */
.acct-sig { display: flex; gap: 24px; flex-wrap: wrap; align-items: flex-start; }
.acct-sig-current { flex: 0 0 300px; }
/* Holds the covered signature at the height it will occupy, so revealing it
   does not shunt the Remove button down the page. */
.acct-sig-veil {
  min-height: 130px; display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border: 1px dashed var(--line); border-radius: var(--radius-sm);
}
.acct-sig-veil img:not([hidden]) + button { display: none; }
.acct-sig-current img {
  width: 100%; height: 130px; object-fit: contain; background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.acct-sig-draw { flex: 1 1 340px; min-width: 300px; }

/* A long name should not push every other column off the screen. The cell
   keeps its full text in a title, so nothing is lost - it is just not all
   demanded at once. Applied per column rather than to every cell: a reference,
   a status and a date are short by nature and clipping them would only ever
   hide something. */
.cell-clip {
  display: inline-block; max-width: 210px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: middle;
}
@media (max-width: 1200px) { .cell-clip { max-width: 150px; } }

/* The delivery/dispatch register is a dozen value columns wide, so it needs a
   tighter cap than a three-column table does: prose gets more room than a
   name, a name more than a method, and nothing gets as much as its longest
   value. Header cells are capped too - "Document / Reference Number" is a
   wider heading than most of the values under it. */
.rec-table td .cell-clip { max-width: 150px; }
.rec-table td .cell-clip.prose { max-width: 250px; }
.rec-table td .cell-clip.tight { max-width: 96px; }
.rec-table th { max-width: 160px; white-space: normal; }
@media (max-width: 1440px) {
  .rec-table td .cell-clip { max-width: 120px; }
  .rec-table td .cell-clip.prose { max-width: 180px; }
}

/* ── Notification settings ──────────────────────────────────────────────────
   One switch per notification type, grouped by the app it belongs to. The
   whole row is the label, so the tap target is the row rather than a 16px
   checkbox - these are read and set on a phone as often as at a desk. */
.notif-prefs { display: flex; flex-direction: column; gap: 18px; margin-top: 16px; }
.np-group { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); overflow: hidden; }
.np-group-title {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 700;
  color: var(--text-3); padding: 12px 16px; background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.np-row {
  display: flex; align-items: center; gap: 16px; padding: 14px 16px;
  border-bottom: 1px solid var(--line); cursor: pointer; transition: background var(--transition);
}
.np-row:last-child { border-bottom: none; }
.np-row:hover { background: var(--surface-2); }
.np-text { flex: 1; min-width: 0; }
.np-label { font-weight: 600; font-size: .92rem; }
.np-desc { font-size: .82rem; margin-top: 2px; line-height: 1.4; }
.np-check { width: 18px; height: 18px; flex-shrink: 0; cursor: pointer; accent-color: var(--accent); }

/* A type that cannot be switched off. Dimmed and not clickable, but still
   listed: leaving it out would suggest it doesn't exist, when the point is
   that it does and will always arrive. */
.np-row.np-locked { cursor: default; }
.np-row.np-locked:hover { background: transparent; }
.np-row.np-locked .np-check { cursor: not-allowed; opacity: .5; }
.np-always { display: block; margin-top: 3px; font-weight: 600; color: var(--text-3); }

/* ── Rich text editor (components/rich-editor.js) ─────────────────────────────
   A toolbar over a sheet of paper. The sheet is the A4 width the document
   prints at, so what HR lays out here is where it lands on the page. */
.re { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); overflow: hidden; }
.re-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 8px;
  background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 2;
}
.re-btn {
  min-width: 32px; height: 32px; padding: 0 7px; border: 1px solid transparent; border-radius: 7px;
  background: none; color: var(--text-2); cursor: pointer; font-size: .92rem; display: inline-flex; align-items: center; justify-content: center;
}
.re-btn:hover { background: var(--surface-2); color: var(--text); }
.re-btn.on { background: var(--accent-soft); border-color: var(--line); color: var(--text); }
.re-colour { position: relative; font-weight: 800; }
.re-colour input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.re-colour span { border-bottom: 3px solid currentColor; line-height: 1; padding-bottom: 1px; }
.re-sel {
  height: 32px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2);
  color: var(--text); font-size: .82rem; padding: 0 6px; max-width: 150px; font-family: inherit;
}
.re-sel-sm { max-width: 72px; }
.re-insert { font-weight: 600; border-color: var(--text-3); }
.re-sep { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }
.re-grow { flex: 1; }
.re-page { padding: 22px; max-height: 70vh; overflow: auto; }
.re-area {
  max-width: 794px; min-height: 620px; margin: 0 auto; padding: 48px 56px; background: #fff; color: #1a1c1e;
  box-shadow: var(--shadow); border-radius: 4px; outline: none; font-family: Inter, Arial, sans-serif; font-size: 12px; line-height: 1.55;
}
.re-area p { margin: 0 0 8px; }
.re-area h1, .re-area h2, .re-area h3 { margin: 6px 0 10px; }
.re-area ul, .re-area ol { margin: 0 0 8px 22px; }
/* The placeholders, as chips HR can see and cannot half-delete. */
.re-area .tpl-field {
  background: #eef3ff; color: #2b4bb5; border: 1px solid #c9d6ff; border-radius: 5px; padding: 0 5px;
  font-size: .95em; white-space: nowrap; cursor: default;
}
.re-area .tpl-sig {
  margin: 14px 0 6px; padding: 18px 12px 8px; border: 1.5px dashed #9aa0a6; border-radius: 8px;
  color: #6b7178; font-size: 11px; font-weight: 700; max-width: 320px; cursor: default; background: #fafbfc;
}
.re-area .tpl-pagebreak {
  height: 0; margin: 18px 0; border-top: 2px dashed #c5cad0; position: relative; cursor: default;
}
.re-area .tpl-pagebreak::after {
  content: 'Page break'; position: absolute; left: 50%; top: -9px; transform: translateX(-50%);
  background: #fff; padding: 0 8px; font-size: 10px; color: #9aa0a6; font-weight: 700; letter-spacing: .05em;
}
@media (max-width: 720px) { .re-area { padding: 24px 18px; } .re-page { padding: 10px; } }
/* An editor that fills whatever it sits in (the full-screen document dialog). */
.re-fill { flex: 1; min-height: 0; display: flex; flex-direction: column; margin-bottom: 14px; }
.re-fill > .re { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.re-fill .re-page { flex: 1; min-height: 0; max-height: none; overscroll-behavior: contain; }
/* The editor's own full screen (the template page): above the app's bars,
   below dialogs, so a prompt it raises still shows on top. */
.re-fsbar { display: none; }
.re.re-fs {
  position: fixed; inset: 0; z-index: 90; border: 0; border-radius: 0;
  display: flex; flex-direction: column;
}
.re.re-fs .re-fsbar {
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  background: var(--surface); border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.re.re-fs .re-fs-title { font-size: 1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.re.re-fs .re-toolbar { flex-shrink: 0; }
.re.re-fs .re-page { flex: 1; min-height: 0; max-height: none; overscroll-behavior: contain; }
/* The case document dialog's title row. */
.cde { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.cde-top { display: flex; gap: 8px 18px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 12px; flex-shrink: 0; }
.cde-top .field { flex: 1 1 340px; max-width: 620px; margin: 0; }
.cde-hint { flex: 1 1 260px; font-size: .83rem; margin: 0 0 10px; }

/* ── Employee photo (components/hr-photo.js) ─────────────────────────────────
   Round, always: the initials sit underneath and the photo covers them, so a
   photo that fails to load simply leaves the initials. */
.avatar {
  position: relative; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  border-radius: 50%; overflow: hidden; background: var(--accent-soft); color: var(--text-2); font-weight: 700;
  letter-spacing: .02em; user-select: none;
}
.avatar-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.avatar-sm { width: 30px; height: 30px; font-size: .72rem; }
.avatar-lg { width: 92px; height: 92px; font-size: 1.7rem; box-shadow: 0 0 0 4px var(--surface), var(--shadow-sm); }
.emp-cell { display: inline-flex; align-items: center; gap: 10px; }

.emp-head { align-items: center; }
.emp-ident { display: flex; align-items: center; gap: 20px; min-width: 0; }
.emp-ident .titles { min-width: 0; }
.emp-badges { margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }
.emp-avatar { position: relative; display: block; padding: 0; border: 0; background: none; border-radius: 50%; }
button.emp-avatar { cursor: pointer; }
button.emp-avatar:focus-visible { outline: 3px solid var(--accent-ring); outline-offset: 3px; }
button.emp-avatar:hover .avatar-lg { box-shadow: 0 0 0 4px var(--surface), 0 0 0 6px var(--line), var(--shadow-sm); }
.emp-avatar-cam {
  position: absolute; right: -2px; bottom: -2px; width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 3px var(--surface); transition: transform var(--transition);
}
button.emp-avatar:hover .emp-avatar-cam { transform: scale(1.08); }
@media (max-width: 600px) {
  .emp-ident { gap: 14px; }
  .avatar-lg { width: 68px; height: 68px; font-size: 1.3rem; }
  .emp-avatar-cam { width: 28px; height: 28px; }
}

.ph-crop { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.ph-stage { position: relative; border-radius: 12px; overflow: hidden; background: #111; max-width: 100%; touch-action: none; }
.ph-canvas { display: block; cursor: grab; }
.ph-canvas.dragging { cursor: grabbing; }
/* Everything outside the circle is dimmed: that part is not kept. */
.ph-ring { position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 0 0 999px rgba(0,0,0,.55); border: 2px solid rgba(255,255,255,.9); pointer-events: none; }
.ph-tools { display: flex; align-items: center; gap: 10px; width: 100%; max-width: 300px; color: var(--text-3); }
.ph-zoom { flex: 1; accent-color: var(--accent); }
.ph-hint { font-size: .82rem; text-align: center; }
.ph-view { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.ph-view img { width: 100%; max-width: 420px; aspect-ratio: 1; object-fit: cover; border-radius: 14px; background: var(--surface-2); }
.ph-view p { font-size: .82rem; }
.ph-remove { color: var(--neg); }

/* ── A rendered HR document (components/hr-doc-render.js) ───────────────────── */
.hrdoc-body { font-family: Inter, Arial, sans-serif; font-size: 12px; line-height: 1.55; color: #1a1c1e; }
.hrdoc-body p { margin: 0 0 8px; }
.hrdoc-body h1 { font-size: 20px; margin: 4px 0 10px; }
.hrdoc-body h2 { font-size: 16px; margin: 4px 0 10px; }
.hrdoc-body h3 { font-size: 13px; margin: 4px 0 8px; }
.hrdoc-body ul, .hrdoc-body ol { margin: 0 0 8px 22px; }
.hrdoc-body table { border-collapse: collapse; width: 100%; }
.hrdoc-body td, .hrdoc-body th { border: 1px solid #d7dade; padding: 4px 6px; vertical-align: top; }
.hrdoc-pagebreak { page-break-before: always; break-before: page; height: 0; }
.hrdoc-sig { display: inline-block; vertical-align: top; width: 46%; min-width: 220px; margin: 16px 3% 6px 0; page-break-inside: avoid; }
.hrdoc-sig-space { height: 52px; display: flex; align-items: flex-end; font-size: 10px; color: #b4453d; font-weight: 700; }
.hrdoc-sig.mine .hrdoc-sig-space { background: #fff7f6; border-radius: 4px 4px 0 0; padding: 0 6px 4px; }
.hrdoc-sig-img { height: 52px; width: auto; max-width: 100%; object-fit: contain; display: block; }
.hrdoc-sig-done { height: 52px; display: flex; align-items: flex-end; font-size: 11px; color: #3a7d59; font-weight: 700; font-style: italic; }
.hrdoc-sig-line { border-top: 1px solid #1a1c1e; margin-top: 2px; }
.hrdoc-sig-cap { font-size: 10px; margin-top: 4px; color: #1a1c1e; }
.hrdoc-sig-when { font-size: 9px; color: #9aa0a6; margin-top: 1px; }

/* ── Documents on a case (components/hr-case-docs.js) ───────────────────────── */
.cdoc-list { display: flex; flex-direction: column; gap: 12px; }
.cdoc { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; background: var(--surface); }
.cdoc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.cdoc-title { font-weight: 700; font-size: .95rem; margin-bottom: 2px; }
.cdoc-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.cdoc-signers { margin-top: 12px; border-top: 1px solid var(--line-2); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.cdoc-signer { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .85rem; }
.cdoc-role { font-weight: 700; min-width: 130px; }
.cdoc-state { color: var(--text-3); flex: 1; min-width: 180px; }
.cdoc-state.ok { color: var(--pos); font-weight: 600; }
.cdoc-state.wait { color: var(--warn); }
.cdoc-empty { color: var(--text-3); font-size: .88rem; padding: 14px; border: 1px dashed var(--line); border-radius: var(--radius-sm); }
.cdoc-pick { display: flex; flex-direction: column; gap: 8px; max-height: 50vh; overflow: auto; }
.cdoc-opt { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; }
.cdoc-opt:has(input:checked) { border-color: var(--text-2); background: var(--accent-soft); }
.cdoc-opt input { margin-top: 3px; accent-color: var(--accent); }
.cdoc-share { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px; background: var(--surface-2); }
.cdoc-share-btns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

/* ════════════════════════════════════════════════════════════════════════════
   Stock: shelf picker, transaction lines, the count, and the phone layout
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Shelf picker ─────────────────────────────────────────────────────────── */
.shelf-pick {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; min-width: 150px; min-height: 40px;
  padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font: inherit; font-size: .88rem;
  text-align: left; cursor: pointer; transition: border-color var(--transition), box-shadow var(--transition);
}
.shelf-pick:hover { border-color: var(--text-3); }
.shelf-pick:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.shelf-pick:disabled { opacity: .55; cursor: progress; }
.shelf-pick svg { width: 16px; height: 16px; flex: none; color: var(--text-3); }
.shelf-pick-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shelf-pick-code { font-weight: 700; font-family: var(--mono); letter-spacing: .01em; }
.shelf-pick-name { color: var(--text-3); }
.shelf-pick-qty { color: var(--text-2); font-weight: 600; margin-left: 4px; }
/* In a table row the code is what is read; the long name lives in the search. */
.shelf-pick-compact { min-height: 36px; padding: 6px 10px; min-width: 120px; max-width: 220px; }
.shelf-pick-compact .shelf-pick-name { display: none; }
.filter-field .shelf-pick { min-width: 190px; }

.sp-pop {
  position: fixed; z-index: 1200; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); overflow: hidden; max-height: 420px;
}
.sp-pop-head { display: flex; gap: 8px; padding: 10px; border-bottom: 1px solid var(--line-2); }
.sp-pop-search { flex: 1; min-width: 0; }
.sp-pop-list { overflow-y: auto; padding: 6px; flex: 1; overscroll-behavior: contain; }
.sp-opt {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 10px 12px; border: 0; border-radius: var(--radius-sm); background: transparent;
  font: inherit; font-size: .88rem; text-align: left; cursor: pointer; color: var(--text);
}
.sp-opt:hover, .sp-opt.is-active { background: var(--surface-2); }
.sp-opt.is-on { background: var(--accent-soft); }
.sp-opt-code { font-weight: 700; font-family: var(--mono); min-width: 56px; }
.sp-opt-plain .sp-opt-code { font-family: var(--sans); font-weight: 600; }
.sp-opt-name { color: var(--text-3); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-opt-qty { margin-left: auto; font-weight: 700; color: var(--text-2); white-space: nowrap; }
.sp-empty { padding: 18px 12px; color: var(--text-3); font-size: .86rem; text-align: center; }
.sp-pop-foot:empty { display: none; }
.sp-pop-foot { padding: 8px 12px; border-top: 1px solid var(--line-2); color: var(--text-3); font-size: .78rem; }
/* On a phone it is a sheet from the bottom, the list above the keyboard. */
.sp-backdrop { position: fixed; inset: 0; z-index: 1199; background: rgba(0,0,0,.45); }
.sp-pop.sp-sheet {
  left: 0; right: 0; bottom: 0; top: auto; width: auto;
  max-height: 78vh; border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.sp-sheet .sp-opt { padding: 14px 12px; font-size: 1rem; }
.sp-sheet .sp-pop-search { font-size: 16px; }

/* ── Paged lists ──────────────────────────────────────────────────────────── */
.stk-m-uom { display: none; }
.stk-loading { opacity: .55; pointer-events: none; transition: opacity 120ms; }
.stk-more-quiet { justify-content: flex-end; }
.stk-alt { font-size: .74rem; margin-top: 2px; }
.stk-sub { font-size: .78rem; margin-top: 3px; }
.stk-neg { color: var(--neg); }
.stk-pos { color: var(--pos); }

/* ── Transaction screens ──────────────────────────────────────────────────── */
.stk-card { margin-bottom: 18px; }
.stk-banner { margin-bottom: 18px; display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.stk-search-row { margin-bottom: 14px; }
.stk-route { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: end; margin-bottom: 4px; }
.stk-route-arrow { font-size: 1.3rem; color: var(--text-3); padding-bottom: 12px; }
.stk-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.stk-seg button {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font: inherit; cursor: pointer;
}
.stk-seg button strong { font-size: .92rem; }
.stk-seg button span { font-size: .78rem; color: var(--text-3); }
.stk-seg button.active { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
table.stk-lines td { vertical-align: top; }
table.stk-lines .stk-qty-input { width: 100%; min-width: 90px; max-width: 140px; }
table.stk-lines td.stk-qty { min-width: 110px; }
table.stk-lines input.doc-cell { min-width: 80px; }
table.stk-lines td[data-total] { white-space: nowrap; }
table.stk-lines td > .muted { white-space: normal; }
.btn.stk-x { padding: 6px 10px; min-width: 0; }
.stk-receive-default { max-width: 360px; }
.stk-receive-foot { display: flex; gap: 14px; align-items: center; justify-content: space-between; flex-wrap: wrap; margin-top: 14px; }
.stk-receive-foot .field-hint { margin: 0; flex: 1; min-width: 220px; }
.stk-piece-ticks { display: flex; flex-wrap: wrap; gap: 6px; }
.stk-tick { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 999px; font-size: .82rem; cursor: pointer; }
.stk-tick input { width: 16px; height: 16px; }

/* Incoming transfers: a card per load, opening to the receive controls. */
.stk-incoming { display: flex; flex-direction: column; gap: 10px; }
.stk-in-card { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.stk-in-card.open { box-shadow: var(--shadow-sm); }
.stk-in-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; width: 100%;
  padding: 14px 16px; border: 0; background: transparent; font: inherit; text-align: left; cursor: pointer; color: var(--text);
}
.stk-in-meta { margin-left: auto; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: .84rem; }
.stk-in-body { padding: 4px 16px 16px; border-top: 1px solid var(--line-2); }

/* ── The count ────────────────────────────────────────────────────────────── */
.stk-count-line { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; margin-bottom: 10px; background: var(--surface); }
.stk-count-line.is-done { border-color: var(--pos); background: var(--pos-soft); }
.stk-count-head { display: flex; justify-content: space-between; gap: 10px; align-items: flex-start; }
.stk-count-head > div { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.stk-count-books { font-size: .84rem; margin: 6px 0 10px; }
.stk-count-input { max-width: 180px; }
.stk-sizes-head, .stk-size-row { display: grid; grid-template-columns: minmax(80px, 140px) 60px minmax(150px, 190px) 70px 40px; gap: 8px; align-items: center; }
/* The number of rolls with − and + either side of it. */
.stk-stepper { display: flex; align-items: stretch; gap: 4px; min-width: 0; }
.stk-stepper .stk-qty-input { flex: 1; min-width: 44px; max-width: none; text-align: center; }
.stk-step {
  flex-shrink: 0; width: 38px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text); font-size: 1.2rem; font-weight: 700; line-height: 1;
  cursor: pointer; touch-action: manipulation; user-select: none;
}
.stk-step:hover { background: var(--surface-3); }
.stk-step:active { transform: scale(.94); }
.stk-sizes-head { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); margin-bottom: 4px; }
.stk-size-row { margin-bottom: 6px; }
.stk-count-foot { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.stk-count-total { margin-left: auto; font-size: .9rem; }
.stk-inline-row { display: flex; gap: 12px; flex-wrap: wrap; }
.stk-inline-row .field { margin: 0; }

/* ── Phones and small tablets ─────────────────────────────────────────────── */
@media (max-width: 720px) {
  /* 16px stops iOS zooming the page every time a box is tapped. */
  .input, .select, textarea.input, .shelf-pick, .sp-pop-search { font-size: 16px; }

  /* Tables become cards: each row a card, each cell a "label: value" line.
     The label comes off data-label, so a table opts in by setting both the
     class and the attribute and nothing else changes. */
  table.stk-cards, table.stk-cards tbody, table.stk-cards tr, table.stk-cards td { display: block; width: 100%; }
  table.stk-cards thead { display: none; }
  table.stk-cards tr { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; padding: 10px 12px; background: var(--surface); }
  table.stk-cards tr.stk-rec-detail, table.stk-cards tr.stk-grp-detail { border: 0; padding: 0 0 6px; background: transparent; }
  table.stk-cards tr.hidden { display: none; }
  table.stk-cards td { border: 0 !important; padding: 5px 0 !important; text-align: right !important; display: flex; gap: 6px; align-items: center; justify-content: flex-end; flex-wrap: wrap; }
  /* The label sits left and pushes everything after it to the right, so a
     value made of several pieces - "60" and "m", a badge and its alt code -
     stays together instead of being spread across the row. */
  table.stk-cards td[data-label]::before { content: attr(data-label); color: var(--text-3); font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; flex: none; max-width: 42%; margin-right: auto; text-align: left; }
  table.stk-cards td.stk-card-title { display: block; font-size: 1rem; padding-bottom: 8px !important; text-align: left !important; }
  table.stk-cards td.stk-card-title::before { display: none; }
  table.stk-cards td.stk-caret-col { display: none; }
  table.stk-cards td.stk-row-actions { width: 100%; justify-content: flex-end; flex-wrap: wrap; padding-top: 8px !important; }
  table.stk-cards td.stk-hide-mobile, table.stk-cards td:empty { display: none; }
  table.stk-cards td > .shelf-pick, table.stk-cards td > .input, table.stk-cards td > .stk-qty-input { max-width: 62%; }
  table.stk-cards td.stk-uom { color: var(--text-3); }
  table.data.stk-cards { border: 0; background: transparent; }
  .table-wrap:has(> table.stk-cards) { border: 0; background: transparent; box-shadow: none; overflow: visible; max-height: none; }
  /* "60 m" on one line: the unit column folds into the quantity on a card. */
  table.stk-cards td.stk-uom { display: none; }
  .stk-m-uom { display: inline; margin-left: 4px; color: var(--text-3); font-weight: 500; }

  .stk-route { grid-template-columns: 1fr; }
  .stk-route-arrow { display: none; }
  .stk-seg { grid-template-columns: 1fr; }
  .filter-bar .search-box { flex: 1 1 100%; }
  .filter-field { flex: 1 1 calc(50% - 8px); }
  .filter-field .shelf-pick, .filter-field .select { min-width: 0; width: 100%; }
  .tabs { display: flex; overflow-x: auto; max-width: 100%; }
  .tabs button { white-space: nowrap; padding: 9px 14px; }

  /* The Post button stays in reach of a thumb on a long form. */
  .stk-sticky-actions {
    position: sticky; bottom: 0; z-index: 20; margin: 18px -16px -80px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: var(--surface); border-top: 1px solid var(--line); box-shadow: 0 -6px 18px rgba(20,22,26,.06);
  }
  .stk-sticky-actions .btn { flex: 1; min-height: 48px; font-size: 1rem; }

  .stk-count-line { padding: 12px; }
  .stk-count-input { max-width: none; width: 100%; }
  .stk-sizes-head { display: none; }
  .stk-size-row { grid-template-columns: minmax(48px, 1fr) auto minmax(124px, 1.4fr) auto 36px; gap: 6px; }
  .stk-step { width: 40px; min-height: 44px; }
  .stk-count-foot .btn { flex: 1; min-height: 44px; }
  .stk-count-total { width: 100%; margin: 6px 0 0; }
  .stk-in-meta { margin-left: 0; width: 100%; }
  .btn-sm { min-height: 38px; }
}

/* ── Production Schedule ─────────────────────────────────────────────────── */
/* Priority travels with the order as a chip (Express, Must go) on every
   screen. Nothing is marked with a coloured edge: the app does not use
   part-borders on tiles, and these screens are no exception. */

.ps-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 6px;
  font-size: .7rem; font-weight: 700; letter-spacing: .02em; white-space: nowrap;
  background: var(--surface-2); color: var(--text-2); border: 1px solid var(--line);
}
.ps-chip-express { background: var(--neg); color: #fff; border-color: var(--neg); text-transform: uppercase; }
.ps-chip-mustgo { background: var(--warn-soft); color: var(--warn); border-color: #e4d3a3; text-transform: uppercase; }
.ps-chip-late { background: var(--neg-soft); color: var(--neg); border-color: #efc9c6; }
.ps-chip-haul { background: #e8eef8; color: #2f5597; border-color: #c9d6ec; }
.ps-chip-dept { font-weight: 600; }
.ps-chip-dept.done { background: var(--pos-soft); color: var(--pos); border-color: #c8e0d2; }
.ps-chip-dept.held { background: var(--warn-soft); color: var(--warn); border-color: #e4d3a3; }

.ps-status { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; font-size: .74rem; font-weight: 700; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.ps-st-ready { background: var(--surface-3); color: var(--text-2); }
.ps-st-in_progress { background: #e8eef8; color: #2f5597; }
.ps-st-part_hold, .ps-st-hold { background: var(--warn-soft); color: var(--warn); }
.ps-st-complete { background: var(--pos-soft); color: var(--pos); }
.ps-st-dispatched { background: var(--surface-2); color: var(--text-3); border: 1px solid var(--line); }
.ps-st-cancelled { background: var(--neg-soft); color: var(--neg); }

.ps-prog { display: inline-flex; flex-direction: column; gap: 4px; min-width: 64px; }
.ps-prog-n { font-size: .82rem; font-weight: 600; color: var(--text); white-space: nowrap; }
.ps-prog-bar { display: block; height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.ps-prog-bar i { display: block; height: 100%; background: var(--pos); border-radius: 2px; }

/* Sync line under the page title */
.ps-sync { display: flex; align-items: center; gap: 8px; font-size: .82rem; color: var(--text-3); margin: -10px 0 16px; flex-wrap: wrap; }
.ps-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); flex-shrink: 0; }
.ps-dot.ok { background: var(--pos); }
.ps-dot.warn { background: #c58a12; }
.ps-dot.bad { background: var(--neg); }

/* Day navigation and the fortnight ribbon */
.ps-daybar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.ps-daybar h2 { font-size: 1.25rem; margin: 0 6px; }
.ps-daybar .input { width: auto; padding: 8px 10px; font-size: .86rem; }
.ps-week { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 8px; margin-bottom: 18px; }
.ps-week-day {
  border: 1px solid var(--line); background: var(--surface); border-radius: var(--radius-sm);
  padding: 8px 10px; text-align: left; transition: all var(--transition); min-width: 0;
}
.ps-week-day:hover { border-color: var(--text-3); }
.ps-week-day.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ps-week-day .d { font-size: .78rem; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-week-day .n { font-size: .7rem; color: var(--text-3); white-space: nowrap; }
.ps-week-day .ps-bar { margin-top: 6px; height: 5px; }

/* Capacity cards */
.ps-cap { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; margin-bottom: 20px; }
.ps-cap-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; text-align: left; transition: all var(--transition); }
button.ps-cap-card:hover { border-color: var(--text-3); }
.ps-cap-card.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ps-cap-card.over { border-color: #efc9c6; background: #fffafa; }
.ps-cap-name { font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-cap-main { display: flex; align-items: baseline; gap: 6px; margin: 6px 0 8px; }
.ps-cap-main strong { font-size: 1.55rem; font-weight: 800; line-height: 1; }
.ps-cap-main span { font-size: .8rem; color: var(--text-3); }
.ps-cap-card.over .ps-cap-main strong { color: var(--neg); }
.ps-cap-sub { font-size: .76rem; color: var(--text-3); margin-top: 7px; display: flex; justify-content: space-between; gap: 8px; }
.ps-bar { position: relative; height: 8px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.ps-bar-fill { position: absolute; inset: 0 auto 0 0; background: #8a9099; border-radius: 4px; }
.ps-bar-done { position: absolute; inset: 0 auto 0 0; background: var(--pos); border-radius: 4px; }
.ps-bar.over .ps-bar-fill { background: var(--neg); }

/* Pools (tabs with counts) */
.ps-pools { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.ps-pool {
  border: 1px solid var(--line); background: var(--surface); border-radius: 999px; padding: 8px 14px;
  font-size: .86rem; font-weight: 600; color: var(--text-2); display: inline-flex; align-items: center; gap: 8px;
  transition: all var(--transition);
}
.ps-pool:hover { border-color: var(--text-3); color: var(--text); }
.ps-pool.active { background: var(--accent); color: var(--text-inv); border-color: var(--accent); }
.ps-pool .c { font-size: .74rem; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--surface-3); color: var(--text-2); }
.ps-pool.active .c { background: rgba(255,255,255,.18); color: #fff; }
.ps-pool.alert .c { background: var(--neg-soft); color: var(--neg); }
.ps-pool.active.alert .c { background: var(--neg); color: #fff; }

/* The queue: one row per order, a line of colour down its left edge */
.ps-queue { display: flex; flex-direction: column; gap: 6px; }
.ps-row {
  display: grid; grid-template-columns: 34px minmax(190px, 1.6fr) minmax(150px, 1.4fr) 96px 104px minmax(120px, auto) auto;
  align-items: center; gap: 14px; padding: 11px 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); cursor: pointer; transition: border-color var(--transition), box-shadow var(--transition);
}
.ps-row:hover { box-shadow: var(--shadow-sm); border-color: var(--text-3); }
.ps-row.is-closed { opacity: .62; }
.ps-pos { font-family: var(--mono); font-size: .86rem; color: var(--text-3); text-align: right; }
.ps-main { min-width: 0; }
.ps-main .t { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.ps-main .no { font-family: var(--mono); font-weight: 500; font-size: .92rem; color: var(--text); }
.ps-main .cust { font-size: .86rem; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.ps-hold-note { font-size: .78rem; color: var(--warn); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-depts { display: flex; flex-wrap: wrap; gap: 5px; min-width: 0; }
.ps-cell { font-size: .84rem; color: var(--text-2); min-width: 0; }
.ps-cell .k { display: block; font-size: .66rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.ps-cell .v { font-weight: 600; color: var(--text); white-space: nowrap; }
.ps-cell .v.bad { color: var(--neg); }
.ps-acts { display: flex; gap: 5px; justify-content: flex-end; }
.ps-acts .icon-btn { width: 34px; height: 34px; }
.ps-acts .icon-btn[disabled] { opacity: .3; cursor: default; }
.ps-queue-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 16px 0 10px; }
.ps-queue-head .muted { font-size: .84rem; }
.ps-section-title { font-size: .76rem; text-transform: uppercase; letter-spacing: .07em; font-weight: 700; color: var(--text-3); margin: 22px 0 10px; display: flex; align-items: center; gap: 8px; }
.ps-section-title .c { font-size: .74rem; padding: 1px 8px; border-radius: 999px; background: var(--surface-3); color: var(--text-2); letter-spacing: 0; }

/* Order detail */
.ps-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 14px 20px; }
.ps-fact .k { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.ps-fact .v { font-size: .95rem; font-weight: 600; color: var(--text); margin-top: 2px; word-break: break-word; }
.ps-fact .v small { font-weight: 400; color: var(--text-3); font-size: .78rem; }
.ps-toolbar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line-2); }
.ps-toolbar .segment { width: auto; }
.ps-toolbar .segment button { padding: 8px 14px; font-size: .84rem; white-space: nowrap; }
.ps-toolbar .spacer { flex: 1; }
.ps-lines td.wrap { white-space: normal; min-width: 220px; max-width: 420px; font-size: .82rem; line-height: 1.4; }
.ps-lines .dept-row td { background: var(--surface-2); font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; color: var(--text-3); padding: 8px 14px; }
.ps-lines tr.is-done td { color: var(--text-3); }
.ps-timeline { display: flex; flex-direction: column; }
.ps-ev { display: grid; grid-template-columns: 130px 1fr; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: .86rem; }
.ps-ev:last-child { border-bottom: none; }
.ps-ev .when { color: var(--text-3); font-size: .78rem; }
.ps-ev .who { color: var(--text-3); font-size: .78rem; }

/* Dialog pieces */
.ps-check-list { display: flex; flex-direction: column; gap: 4px; max-height: 220px; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px; background: var(--surface-2); }
.ps-check { display: flex; align-items: flex-start; gap: 9px; font-size: .86rem; padding: 6px 6px; border-radius: 6px; cursor: pointer; font-weight: 400 !important; color: var(--text) !important; }
.ps-check:hover { background: var(--surface-3); }
.ps-check input { margin-top: 3px; accent-color: var(--accent); width: 16px; height: 16px; flex-shrink: 0; }
.ps-check-inline { align-items: center; padding: 0; white-space: nowrap; }
.ps-check-inline input { margin-top: 0; }
.ps-inline-actions { display: flex; align-items: center; gap: 12px; margin-top: 14px; flex-wrap: wrap; font-size: .84rem; }
.ps-line-head, .ps-line-row { display: grid; grid-template-columns: minmax(150px, 1.6fr) 72px 1fr 1fr auto 34px; gap: 8px; align-items: center; }
.ps-line-head { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.ps-line-row { margin-bottom: 8px; }
.ps-line-row .input, .ps-line-row .select { padding: 10px 11px; font-size: .9rem; }
.ps-result { margin-top: 16px; padding: 16px 18px; border: 1px solid #c8e0d2; background: var(--pos-soft); border-radius: var(--radius-sm); }
.ps-result-main { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ps-result-label { display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.ps-result-main strong { font-size: 1.05rem; }

/* The floor: built for a tablet on a stand and a finger */
.ps-floor-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.ps-floor-tile { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px; text-align: left; transition: all var(--transition); display: flex; flex-direction: column; gap: 10px; }
.ps-floor-tile:hover { border-color: var(--text-3); box-shadow: var(--shadow); transform: translateY(-2px); }
.ps-floor-tile h3 { font-size: 1.15rem; }
.ps-floor-tile .big { font-size: 2.1rem; font-weight: 800; line-height: 1; }
.ps-floor-tile .big small { font-size: .9rem; font-weight: 600; color: var(--text-3); }
.ps-floor-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; margin-bottom: 16px; }
.ps-fstat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px 14px; }
.ps-fstat .k { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; }
.ps-fstat .v { font-size: 1.6rem; font-weight: 800; line-height: 1.15; }
.ps-fstat.bad .v { color: var(--neg); }
.ps-fstat.good .v { color: var(--pos); }
.ps-ops { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.ps-ops .lbl { font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; margin-right: 4px; }
.ps-op { border: 1px solid var(--line); background: var(--surface); border-radius: 999px; padding: 10px 16px; font-weight: 600; font-size: .9rem; color: var(--text-2); transition: all var(--transition); }
.ps-op.active { background: var(--accent); color: var(--text-inv); border-color: var(--accent); }
.ps-ops .input { width: 180px; padding: 9px 12px; font-size: .9rem; border-radius: 999px; }
.ps-job {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px 22px; margin-bottom: 12px;
}
.ps-job.is-now { box-shadow: 0 0 0 2px var(--accent-ring); border-color: var(--text-3); }
.ps-job-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: .86rem; color: var(--text-2); }
.ps-job-top .no { font-family: var(--mono); font-weight: 500; color: var(--text); }
.ps-job-title { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; margin: 8px 0 4px; }
.ps-job-size { font-family: var(--mono); font-size: 2.3rem; font-weight: 500; line-height: 1.1; letter-spacing: -.02em; }
.ps-job-size small { font-family: var(--sans); font-size: .9rem; color: var(--text-3); font-weight: 600; margin-left: 6px; }
.ps-job-spec { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px 22px; margin-top: 14px; font-size: .92rem; }
.ps-job-spec .k { font-size: .66rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); font-weight: 700; display: block; }
.ps-job-btns { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.ps-big-btn { flex: 1 1 180px; min-height: 64px; font-size: 1.15rem; font-weight: 700; border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface-2); color: var(--text); transition: all var(--transition); }
.ps-big-btn:hover { background: var(--surface-3); }
.ps-big-btn.go { background: var(--pos); border-color: var(--pos); color: #fff; }
.ps-big-btn.go:hover { filter: brightness(.94); }
.ps-big-btn.start { background: var(--accent); border-color: var(--accent); color: var(--text-inv); }
.ps-big-btn.flag { flex: 0 1 150px; color: var(--warn); }
.ps-big-btn[disabled] { opacity: .5; }
.ps-next { display: flex; flex-direction: column; gap: 6px; }
.ps-next-row {
  display: grid; grid-template-columns: 30px minmax(0, 1.3fr) minmax(0, 1.2fr) auto; gap: 12px; align-items: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px;
}
.ps-next-row .sz { font-family: var(--mono); font-weight: 500; font-size: 1rem; color: var(--text); }
.ps-next-row .meta { font-size: .8rem; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-next-row .btns { display: flex; gap: 6px; }
.ps-next-row .btn { min-height: 42px; }

/* Wall screen */
.ps-live-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.ps-live-clock { font-family: var(--mono); font-size: 1.6rem; font-weight: 500; }
.ps-live-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.ps-live-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.ps-live-card h3 { font-size: 1.05rem; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ps-live-num { display: flex; align-items: baseline; gap: 8px; }
.ps-live-num strong { font-size: 3rem; font-weight: 800; line-height: 1; letter-spacing: -.03em; }
.ps-live-num span { font-size: 1.1rem; color: var(--text-3); font-weight: 600; }
.ps-live-card .ps-bar { height: 12px; border-radius: 6px; }
.ps-live-jobs { display: flex; flex-direction: column; gap: 5px; font-size: .84rem; }
.ps-live-job { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--surface-2); border-radius: 6px; min-width: 0; }
.ps-live-job .sz { font-family: var(--mono); color: var(--text); white-space: nowrap; }
.ps-live-job .c { color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-live-job.is-now { background: #e8eef8; }
:fullscreen.page-frame, .page-frame:fullscreen { background: var(--bg); padding: 28px 32px; overflow: auto; }

/* Dispatch board */
.ps-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; align-items: start; }
.ps-col { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; min-width: 0; }
.ps-col h3 { font-size: .95rem; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.ps-col .hint { font-size: .78rem; color: var(--text-3); margin-bottom: 12px; }
.ps-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 12px 14px; margin-bottom: 8px; cursor: pointer; transition: box-shadow var(--transition);
}
.ps-card:hover { box-shadow: var(--shadow-sm); }
.ps-card .t { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ps-card .no { font-family: var(--mono); font-weight: 500; }
.ps-card .cust { font-size: .86rem; color: var(--text-2); margin: 3px 0 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ps-card .foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: .8rem; color: var(--text-3); }
.ps-card .foot .due.bad { color: var(--neg); font-weight: 700; }
.ps-card .btn { margin-top: 10px; width: 100%; }

/* Performance and settings */
.ps-day-bars { display: flex; align-items: flex-end; gap: 6px; height: 150px; padding-top: 8px; }
.ps-day-bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px; min-width: 0; height: 100%; }
.ps-day-bar .b { width: 100%; max-width: 42px; background: var(--accent); border-radius: 5px 5px 0 0; min-height: 2px; }
.ps-day-bar.off .b { background: var(--surface-3); }
.ps-day-bar .n { font-size: .72rem; font-weight: 700; color: var(--text); }
.ps-day-bar .l { font-size: .64rem; color: var(--text-3); white-space: nowrap; }
.ps-set-table td { padding: 8px 10px; }
.ps-set-table .input, .ps-set-table .select { padding: 9px 10px; font-size: .88rem; min-width: 76px; }
.ps-set-table .input.name { min-width: 190px; }
.ps-note { font-size: .84rem; color: var(--text-2); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 12px 14px; margin-bottom: 16px; }
.ps-date-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.ps-save-bar { display: flex; align-items: center; gap: 12px; margin-top: 18px; }

@media (max-width: 1180px) {
  .ps-row { grid-template-columns: 30px minmax(0, 1.5fr) minmax(0, 1.2fr) 90px minmax(110px, auto) auto; }
  .ps-row .ps-cell.blinds { display: none; }
  .ps-week { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .ps-cols { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .ps-row { grid-template-columns: 26px minmax(0, 1fr) auto; row-gap: 8px; padding: 10px 12px; }
  .ps-row .ps-depts { grid-column: 2 / -1; }
  .ps-row .ps-cell { display: none; }
  .ps-row .ps-cell.status { display: block; grid-column: 2; }
  .ps-row .ps-acts { grid-column: 3; grid-row: 1; }
  .ps-week { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 5px; }
  .ps-week-day { padding: 6px 7px; }
  .ps-week-day .n { display: none; }
  .ps-job { padding: 16px; }
  .ps-job-size { font-size: 1.8rem; }
  .ps-next-row { grid-template-columns: 24px minmax(0, 1fr) auto; }
  .ps-next-row .meta-col { display: none; }
  .ps-line-head { display: none; }
  .ps-line-row { grid-template-columns: 1fr 64px; }
  .ps-ev { grid-template-columns: 1fr; gap: 2px; }
  .ps-result-main { grid-template-columns: 1fr; }
}

/* ── Links that are not <a> (App.link) ───────────────────────────────────────
   The invisible real link put under the pointer for a right-click, so the
   browser's menu offers Open in New Tab for a row. Never seen, never kept. */
.ghost-link {
  position: fixed; width: 40px; height: 40px; z-index: 2147483000;
  opacity: 0; background: transparent; display: block;
}
[data-href] { cursor: pointer; }

/* ── Stock count: a saved count waiting, and a line that cannot post ─────── */
.stk-draft-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; margin-bottom: 14px; border-radius: 10px;
  background: var(--warn-soft); border: 1px solid var(--warn); color: var(--text);
}
.stk-draft-bar strong { display: block; }
.stk-draft-bar .stk-draft-actions { display: flex; gap: 8px; }
.stk-count-line.has-error { border-color: var(--neg); background: var(--neg-soft); }

/* ── Stock count page: Count | Count records ───────────────────────────── */
.stk-ad-tabs { margin-bottom: 16px; }
.stk-cr-system { display: flex; gap: 6px; align-items: center; font-size: .86rem; color: var(--text-2); white-space: nowrap; }
/* A count line whose SKU was retired or changed while the count was open. */
.stk-line-problem { margin: 6px 0 8px; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--warn-soft); color: var(--text); font-size: .88rem; border-left: 3px solid var(--warn); }
.stk-line-fix { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.stk-line-fix .btn { text-align: left; white-space: normal; }
/* The count dashboard (components/stock-count-dashboard.js). */
.cd-h { font-size: 1rem; margin: 6px 0 12px; }
.cd-rates td { padding: 8px 6px; white-space: normal; vertical-align: top; }
.cd-rate-v { text-align: right; }
.cd-rate-v .muted { font-size: .78rem; margin-top: 1px; }
.cd-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cd-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; margin-top: 20px; }
.cd-grid .cd-full { grid-column: 1 / -1; }
@media (max-width: 900px) {
  .cd-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cd-grid { grid-template-columns: minmax(0, 1fr); }
}
/* Charts drawn at their real size (components/charts.js). */
.ch { position: relative; width: 100%; }
.ch-svg { display: block; overflow: visible; }
.ch-grid { stroke: var(--line-2); stroke-width: 1; }
.ch-axis { font-size: 12px; fill: var(--text-3); font-family: var(--sans); font-variant-numeric: tabular-nums; }
.ch-guide { stroke: var(--text-3); stroke-width: 1; stroke-dasharray: 3 3; pointer-events: none; }
.ch-dots { pointer-events: none; }
.ch-hit { cursor: crosshair; touch-action: pan-y; }
.ch-tip {
  position: absolute; top: 4px; z-index: 5; pointer-events: none; min-width: 140px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); padding: 8px 10px; font-size: .82rem; white-space: nowrap;
}
.ch-tip-h { font-weight: 700; margin-bottom: 4px; }
.ch-tip-r { display: flex; align-items: center; gap: 7px; }
.ch-tip-r strong { margin-left: auto; padding-left: 12px; font-variant-numeric: tabular-nums; }
.ch-sw { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }
/* What a SKU is, under its code wherever a record carries only the code. */
.stk-sku-desc { font-size: .8rem; color: var(--text-2); margin-top: 3px; line-height: 1.3; white-space: normal; }

/* Picking Break Bulk by its makeup (StockPicker.openMakeupModal). */
.sp-mk-fill { margin: -4px 0 10px; }
.sp-mk-step { max-width: 170px; }
/* A length cut off one piece, under the whole-piece rows. */
.sp-mk-cut { margin-top: 12px; padding: 10px 12px; border: 1px dashed var(--line); border-radius: var(--radius-sm); }
.sp-mk-cut-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sp-mk-cut-row .stk-qty-input { width: 84px; flex: none; }
.sp-mk-cut-row .select, .sp-mk-cut-row .dd { flex: 1 1 220px; min-width: 0; max-width: 360px; }
.sp-mk-cut-note { font-size: .82rem; color: var(--text-2); margin-top: 6px; min-height: 1em; }
.sp-mk-cut-note.sp-mk-cut-bad { color: var(--warn); }
.sp-mk-tally {
  position: sticky; bottom: -1px; z-index: 2; margin-top: 12px; padding: 10px 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: .95rem;
}

/* Receiving a transfer by its makeup: a row per size. */
.stk-rcv-mk { display: flex; flex-direction: column; gap: 6px; min-width: 220px; }
.stk-rcv-row { display: flex; align-items: center; gap: 8px; }
.stk-rcv-size { min-width: 52px; }
.stk-rcv-row .stk-stepper { width: auto; flex: none; }
/* Line tables give quantity boxes a 90px minimum; a stepper's box sits between its buttons. */
table.stk-lines .stk-rcv-row .stk-stepper .stk-qty-input { width: 64px; min-width: 0; max-width: 64px; flex: none; }

/* ── Internal Sales ───────────────────────────────────────────────────────── */
/* One idea carries across every screen: the journey strip - the SOP's stages
   in a row, the ones behind filled in with who and when, the current one lit.
   The file reads left to right, the way the order moved. The board borrows the
   Production Schedule's pools, chips and pills so the two modules look like one
   app; what is new here is coloured by the desk whose turn it is. */
.sl-st-received { background: var(--surface-3); color: var(--text-2); }
.sl-st-entered { background: #e8eef8; color: #2f5597; }
.sl-st-stock_ok { background: #e6f1ef; color: #1f6b5a; }
.sl-st-released { background: #ece8f6; color: #5b3f9e; }
.sl-st-to_production { background: var(--warn-soft); color: var(--warn); }
.sl-st-in_production { background: #fbe9d7; color: #a2561a; }
.sl-st-manufactured { background: var(--pos-soft); color: var(--pos); }
.sl-st-dispatched { background: var(--surface-2); color: var(--text-3); border: 1px solid var(--line); }
.sl-st-invoiced { background: var(--surface-2); color: var(--text-3); border: 1px solid var(--line); }
.sl-st-cancelled { background: var(--neg-soft); color: var(--neg); }
.sl-st-linked { background: var(--surface-2); color: var(--text-3); border: 1px solid var(--line); }

.sl-table td { vertical-align: top; }
.sl-table .t { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sl-row { cursor: pointer; }
.sl-row.is-closed { opacity: .66; }
.sl-row.is-late td:first-child { box-shadow: inset 4px 0 0 var(--neg); }
.sl-bad { color: var(--neg); font-weight: 700; }
.sl-money { white-space: nowrap; }

/* The file's head card: a line of colour for the desk whose turn it is. */
.sl-head { border-left: 6px solid var(--line); }
.sl-desk-sales { border-left-color: #2f5597; }
.sl-desk-stores { border-left-color: #1f6b5a; }
.sl-desk-accounts { border-left-color: #5b3f9e; }
.sl-desk-factory { border-left-color: #a2561a; }
.sl-desk-dispatch { border-left-color: var(--pos); }

/* The journey strip */
.sl-journey { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 0; margin: 4px 0 18px; position: relative; }
.sl-journey::before { content: ''; position: absolute; left: 6%; right: 6%; top: 9px; height: 3px; background: var(--line); border-radius: 2px; }
.sl-step { position: relative; text-align: center; padding: 0 4px; min-width: 0; }
.sl-step-dot { width: 21px; height: 21px; border-radius: 50%; background: var(--surface); border: 3px solid var(--line); margin: 0 auto 8px; position: relative; z-index: 1; box-sizing: border-box; }
.sl-step.is-done .sl-step-dot { background: var(--pos); border-color: var(--pos); }
.sl-step.is-done .sl-step-dot::after { content: ''; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.sl-step.is-current .sl-step-dot { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
.sl-step.is-skipped .sl-step-dot { border-style: dashed; }
.sl-step-label { font-size: .74rem; font-weight: 700; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sl-step.is-done .sl-step-label, .sl-step.is-current .sl-step-label { color: var(--text); }
.sl-step.is-current .sl-step-label { color: var(--accent); }
.sl-step-meta { font-size: .68rem; color: var(--text-3); line-height: 1.35; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sl-step.is-skipped .sl-step-meta { font-style: italic; }
.sl-undo { border: none; background: transparent; color: var(--text-3); font-size: .66rem; text-decoration: underline; cursor: pointer; padding: 2px 4px; margin-top: 2px; }
.sl-undo:hover { color: var(--neg); }

/* The next step: what the desk whose turn it is has to do */
.sl-next { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 14px 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); font-size: .92rem; line-height: 1.45; }
.sl-next > div:not(.sl-next-btns) { flex: 1 1 320px; min-width: 0; }
.sl-next.is-problem { background: var(--warn-soft); border-color: #e4d3a3; }
.sl-next.is-closed { background: var(--surface-2); color: var(--text-2); }
.sl-next-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.sl-desk { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; background: var(--surface); border: 1px solid var(--line); color: var(--text-2); flex: 0 0 auto; }
.sl-office-note { margin-top: 12px; font-size: .9rem; padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm); border: 1px solid var(--line-2); white-space: pre-wrap; }

/* The stock check's outcomes, one card each */
.sl-outcomes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.sl-outcome { text-align: left; border: 1px solid var(--line); background: var(--surface); border-radius: var(--radius-sm); padding: 10px 12px; display: flex; flex-direction: column; gap: 3px; transition: all var(--transition); }
.sl-outcome strong { font-size: .9rem; }
.sl-outcome span { font-size: .76rem; color: var(--text-3); line-height: 1.35; }
.sl-outcome:hover { border-color: var(--text-3); }
.sl-outcome.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); background: var(--surface-2); }

/* Attachments: the scans */
.sl-atts { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.sl-att { position: relative; display: flex; gap: 10px; align-items: center; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px; background: var(--surface); cursor: pointer; min-width: 0; transition: box-shadow var(--transition); }
.sl-att:hover { box-shadow: var(--shadow-sm); }
.sl-att img { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; flex-shrink: 0; background: var(--surface-3); }
.sl-att-icon { width: 56px; height: 56px; border-radius: 6px; background: var(--surface-3); color: var(--text-2); display: flex; align-items: center; justify-content: center; font-size: .7rem; font-weight: 800; letter-spacing: .04em; flex-shrink: 0; }
.sl-att-body { min-width: 0; flex: 1; }
.sl-att-label { font-size: .84rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sl-att-x { position: absolute; top: 4px; right: 4px; width: 26px; height: 26px; font-size: .7rem; }

.sl-note-tag { display: inline-block; padding: 1px 7px; border-radius: 999px; background: #e8eef8; color: #2f5597; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.ps-ev.is-note { background: var(--surface-2); margin: 0 -8px; padding-left: 8px; padding-right: 8px; border-radius: 6px; }

@media (max-width: 900px) {
  .sl-journey { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 14px; }
  .sl-journey::before { display: none; }
  .sl-outcomes { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .sl-table th:nth-child(3), .sl-table td:nth-child(3), .sl-table th:nth-child(5), .sl-table td:nth-child(5) { display: none; }
  .sl-next { padding: 12px; }
}

/* ── Production Lines: one lane per department ───────────────────────────── */
.ps-chip-unsched { background: #eef0f3; color: var(--text-2); border-color: #d7dbe1; }
.ps-lanes { display: flex; gap: 14px; align-items: flex-start; overflow-x: auto; padding-bottom: 14px; scroll-snap-type: x proximity; }
.ps-lane { flex: 0 0 290px; max-width: 290px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); scroll-snap-align: start; display: flex; flex-direction: column; max-height: calc(100vh - var(--topbar-h) - 200px); min-height: 160px; }
.ps-lane-head { padding: 12px 14px 10px; border-bottom: 1px solid var(--line); background: var(--surface); border-radius: var(--radius) var(--radius) 0 0; position: sticky; top: 0; z-index: 1; }
.ps-lane-head h3 { font-size: .95rem; }
.ps-lane-head .n { font-size: .76rem; color: var(--text-3); margin: 3px 0 8px; }
.ps-lane-head .n .bad { color: var(--neg); font-weight: 700; }
.ps-lane-body { padding: 10px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.ps-lcard { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 9px 11px; cursor: pointer; transition: border-color var(--transition), box-shadow var(--transition), opacity var(--transition); }
.ps-lcard:hover { border-color: var(--text-3); }
.ps-lcard.is-hl { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ps-lcard.is-making { background: #f4f7fc; }
.ps-lcard.is-done { opacity: .6; }
.ps-lcard .t { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 24px; }
.ps-lcard .t .spacer { flex: 1; }
.ps-lcard .no { font-family: var(--mono); font-size: .88rem; font-weight: 500; color: var(--text); }
.ps-lcard .ps-pos { text-align: left; font-size: .78rem; }
.ps-lcard .cust { font-size: .82rem; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 2px 0 7px; }
.ps-lcard .foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ps-lcard .foot .ps-prog { flex: 1; min-width: 0; }
.ps-lcard .foot .ps-prog-n { font-size: .74rem; font-weight: 500; color: var(--text-2); }
.ps-lcard .else { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 7px; font-size: .7rem; color: var(--text-3); }
.ps-lcard .else .ok { color: var(--pos); }
.ps-lacts { display: inline-flex; gap: 3px; }
.ps-lacts .icon-btn { width: 26px; height: 26px; font-size: .7rem; }
.ps-lacts .icon-btn[disabled] { opacity: .3; cursor: default; }
.ps-lane-divider { font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; font-weight: 700; color: var(--text-3); margin: 8px 2px 2px; display: flex; align-items: center; gap: 6px; }
.ps-lane-divider .c { font-size: .7rem; padding: 0 7px; border-radius: 999px; background: var(--surface-3); letter-spacing: 0; }
@media (max-width: 760px) {
  .ps-lane { flex-basis: 82vw; max-width: 82vw; max-height: none; }
}

/* Picking list lines: the quantity cell stacks its box, the makeup button and
   the makeup itself in a column of its own width, so none of it runs into
   the UOM and notes beside it. */
.pk-lines th.pk-qty-col, .pk-lines td.pk-qty-col { width: 190px; }
.pk-qty { display: flex; flex-direction: column; align-items: stretch; gap: 6px; width: 180px; }
.pk-qty .doc-cell { width: 100%; }
.pk-qty .btn { white-space: nowrap; align-self: flex-start; }
.pk-here { font-size: .78rem; font-weight: 500; color: var(--pos); margin-top: 3px; }
.pk-here.pk-none { color: var(--neg); }
.pk-here.pk-short { color: var(--warn); }
/* Return to stores: how many pieces of each size came back, one row a size. */
.rts-sizes { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.rts-size { display: flex; align-items: center; gap: 6px; }
table.stk-lines .rts-size .doc-cell { width: 84px; min-width: 0; }
.rts-sum { font-weight: 500; white-space: normal; }
/* Access page: which departments a stock requester may ask for. */
.ac-dept-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px 14px; }
.ac-dept { display: flex; align-items: center; gap: 8px; padding: 6px 4px; cursor: pointer; }
.ac-dept input { width: 18px; height: 18px; flex: none; }
/* A partly picked list: how far along it is. */
.pk-progress { display: flex; align-items: center; gap: 12px; font-size: .85rem; }
.pk-progress-bar { flex: 1; max-width: 320px; height: 8px; border-radius: 99px; background: var(--surface-3); overflow: hidden; }
.pk-progress-bar span { display: block; height: 100%; background: var(--accent); }
/* Converting a SKU to Break Bulk: a row per shelf, kept to one line each. */
table.cv-rows td, table.cv-rows th { white-space: nowrap; vertical-align: middle; }
table.cv-rows .select, table.cv-rows .dd-trigger { max-width: 120px; }
table.cv-rows input.doc-cell { width: 84px; min-width: 0; }
table.cv-rows th .muted { font-weight: 500; text-transform: none; letter-spacing: 0; }
.cv-now { font-weight: 500; white-space: nowrap; }
.cv-now.cv-off { color: var(--warn); }
