/* SNF Opus - shared styles
   Light and dark are both first-class; the app follows the OS setting. */

:root {
  --bg: #f6f7f9;
  --card: #ffffff;
  --card-2: #fbfcfd;
  --border: #e3e6ea;
  --border-2: #d3d8de;
  --text: #11161c;
  --text-2: #4a5561;
  --text-3: #8a95a1;
  --sky: #0284c7;
  --sky-soft: #e0f2fe;
  --violet: #7c3aed;
  --emerald: #059669;
  --emerald-soft: #d1fae5;
  --amber: #d97706;
  --amber-soft: #fef3c7;
  --rose: #e11d48;
  --rose-soft: #ffe4e6;
  --shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 8px 24px rgba(0, 0, 0, .06);
  --mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d1117;
    --card: #161b22;
    --card-2: #1c222b;
    --border: #262c36;
    --border-2: #333b47;
    --text: #e6edf3;
    --text-2: #9aa7b4;
    --text-3: #6b7683;
    --sky: #38bdf8;
    --sky-soft: #0b3a52;
    --violet: #a78bfa;
    --emerald: #34d399;
    --emerald-soft: #06371f;
    --amber: #fbbf24;
    --amber-soft: #422006;
    --rose: #fb7185;
    --rose-soft: #4c0519;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .4);
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---------- brand ---------- */

.logo {
  width: 44px; height: 44px;
  border-radius: 11px;
  background: linear-gradient(135deg, var(--sky), var(--violet));
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 15px; letter-spacing: .5px;
  flex: none;
}
.logo.lg { width: 52px; height: 52px; border-radius: 12px; font-size: 17px; }

/* ---------- centred single-card layouts (login) ---------- */

.center-wrap {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}

.auth-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 36px;
  width: 100%; max-width: 420px;
  box-shadow: var(--shadow);
}

.auth-card h1 { font-size: 23px; font-weight: 700; letter-spacing: -.02em; margin-top: 20px; }
.auth-card .sub { color: var(--text-2); font-size: 14px; margin-top: 6px; }

.tabs {
  display: flex; gap: 4px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 4px;
  margin: 24px 0 20px;
}
.tab {
  flex: 1; text-align: center;
  padding: 8px 10px; border-radius: 6px;
  font-size: 13.5px; font-weight: 600; color: var(--text-2);
  cursor: pointer; border: none; background: none;
  font-family: inherit;
}
.tab.active { background: var(--card); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.06); }

/* ---------- forms ---------- */

.field { margin-bottom: 14px; }
.field label {
  display: block; font-size: 12.5px; font-weight: 600;
  color: var(--text-2); margin-bottom: 6px;
}
.field input, .field select, .field textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border-2);
  border-radius: 8px;
  background: var(--card);
  color: var(--text);
  font: inherit; font-size: 14px;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--sky);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sky) 18%, transparent);
}
.field .hint { display: block; font-size: 12px; color: var(--text-3); margin-top: 5px; }

/* ---------- search box ----------
   The roster's search was <input class="mini"> inside <div class="new-org">,
   and NEITHER did anything to it: every .mini rule in this file is scoped to a
   select or to the Settings card, and .new-org is a Settings container. So it
   rendered as a bare browser default, which is what the owner correctly called
   antiquated on 2026-09-03 - a styling class that silently matches nothing,
   the same cascade failure as the checkbox column in decisions.md 49.

   Deliberately the same border, radius, background and focus ring as
   `.field input` above, so the app has one input look and not two. The
   magnifier is drawn in CSS - a circle and a stroke - rather than pulled in as
   an image or a font, because this app has no build step and loads no assets it
   does not need. */
.searchbox { position: relative; max-width: 360px; }

.searchbox input {
  width: 100%;
  padding: 9px 32px;
  border: 1px solid var(--border-2);
  border-radius: 8px;
  background: var(--card);
  color: var(--text);
  font: inherit; font-size: 14px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.searchbox input::placeholder { color: var(--text-3); }
.searchbox input:hover { border-color: var(--text-3); }
.searchbox input:focus {
  outline: none;
  border-color: var(--sky);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sky) 18%, transparent);
}

/* the glass */
.searchbox::before {
  content: '';
  position: absolute; left: 11px; top: 50%;
  width: 11px; height: 11px; margin-top: -7px;
  border: 1.6px solid var(--text-3);
  border-radius: 50%;
  pointer-events: none;
  transition: border-color .12s ease;
}
/* the handle */
.searchbox::after {
  content: '';
  position: absolute; left: 20px; top: 50%; margin-top: 3px;
  width: 6px; height: 0;
  border-top: 1.6px solid var(--text-3);
  transform: rotate(45deg);
  transform-origin: left center;
  pointer-events: none;
  transition: border-color .12s ease;
}
.searchbox:focus-within::before,
.searchbox:focus-within::after { border-color: var(--sky); }

/* Chrome draws its own inset box on type=search; the app draws the border. */
.searchbox input::-webkit-search-decoration { -webkit-appearance: none; }

button.primary {
  width: 100%;
  padding: 10px 16px;
  border: none; border-radius: 8px;
  background: var(--sky); color: #fff;
  font: inherit; font-size: 14.5px; font-weight: 600;
  cursor: pointer;
}
button.primary:hover { filter: brightness(1.07); }
button.primary:disabled { opacity: .55; cursor: default; filter: none; }

button.ghost {
  padding: 7px 13px;
  border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card); color: var(--text-2);
  font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
}
button.ghost:hover { color: var(--text); border-color: var(--text-3); }

/* ---------- messages ---------- */

.msg {
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 13.5px;
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.msg.error   { background: var(--rose-soft);    color: var(--rose);    border-color: var(--rose); }
.msg.ok      { background: var(--emerald-soft); color: var(--emerald); border-color: var(--emerald); }
.msg.warn    { background: var(--amber-soft);   color: var(--amber);   border-color: var(--amber); }
.msg.info    { background: var(--sky-soft);     color: var(--sky);     border-color: var(--sky); }

/* The punch feed strip: one line per report, because the paired and unpaired
   files fail independently. No colours of its own - it inherits whichever
   .msg tone wraps it, so it stays readable in light and dark without a
   second palette to keep in step. This project once shipped five CSS
   variable names that did not exist and painted a white header onto a dark
   page; every value here is a variable checked against this file first. */
.msg .feed-lines {
  margin: 6px 0 0;
  padding-left: 18px;
  list-style: disc;
}
.msg .feed-lines li { margin: 2px 0; }
.msg .feed-note {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid currentColor;
  opacity: 0.85;
}

/* ---------- the punch screen's estimated values (0034) ----------
   decisions.md 83: "those rows should always be highlighted, with a key up
   top saying that that means the system is assigning punches."

   THREE MARKS, because 83 asks for a different key entry per reason:
     estimated      - a value with NO scan behind it
     inferred       - two REAL scans read as one shift
     contradiction  - a finished shift already exists for that person that day

   Every colour below is a variable checked against this file first. This
   project once shipped five variable names that did not exist and would have
   painted a white header onto a dark page; it looked perfect in light mode.

   A LEFT BORDER RATHER THAN A ROW FILL. A filled row fights the sticky
   header and the hover state, and at fifteen columns a tinted stripe is
   easier to follow across than a wash. */
tr.estimated     { box-shadow: inset 3px 0 0 var(--amber); }
tr.inferred      { box-shadow: inset 3px 0 0 var(--sky); }
tr.contradiction { box-shadow: inset 3px 0 0 var(--rose); }

/* The estimated CELLS, so the invented number never reads as measured.
   THE SPAN FORM IS NOT OPTIONAL: the Out cell carries class "t", and 0035
   marks the BORROWED clock-out by putting `est` on the inner span instead.
   Without this selector that class was dead code that read as though it
   worked - which is worse than no class at all. */
td.est,
.punch-table span.est { font-style: italic; color: var(--text-3); }

.punch-key {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
  color: var(--text-3);
}
.punch-key span { display: flex; align-items: flex-start; gap: 7px; max-width: 46ch; }
.punch-key i {
  flex: 0 0 auto;
  width: 3px;
  height: 16px;
  margin-top: 2px;
  border-radius: 2px;
}
.punch-key i.sw-est { background: var(--amber); }
.punch-key i.sw-inf { background: var(--sky); }
.punch-key i.sw-con { background: var(--rose); }

/* A SYMBOL entry, not a row-colour entry. The two badges in the table - `pair`
   and `+1` - are not row highlights, so they get no coloured stripe; a
   coloured swatch beside them would imply a row colour that does not exist.
   Muted, and it keeps the same left-edge alignment as the others. */
.punch-key i.sw-sym { background: var(--border); }

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

.header {
  background: var(--card);
  border-bottom: 1px solid var(--border);
  padding: 14px 22px;
  display: flex; align-items: center; gap: 14px;
  position: sticky; top: 0; z-index: 20;
}
.header .titles h1 { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.header .titles p  { font-size: 12.5px; color: var(--text-3); margin-top: 1px; }
.header .spacer { flex: 1; }

.badge {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12.5px; color: var(--text-2);
}
.dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--emerald); flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--emerald) 20%, transparent);
}

.content { max-width: 1180px; margin: 0 auto; padding: 26px 22px 60px; }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px;
  margin-bottom: 18px;
}
.card h2 { font-size: 15px; font-weight: 700; margin-bottom: 4px; }
.card .sub { font-size: 13px; color: var(--text-2); }

.kv { display: grid; grid-template-columns: 150px 1fr; gap: 9px 16px; margin-top: 16px; font-size: 13.5px; }
.kv dt { color: var(--text-3); }
.kv dd { color: var(--text); font-weight: 500; }
.kv dd.mono { font-family: var(--mono); font-size: 12.5px; }

.checklist { list-style: none; display: grid; gap: 9px; margin-top: 16px; }
.checklist li { display: flex; gap: 10px; font-size: 13.5px; color: var(--text-2); }
.checklist .mark { font-family: var(--mono); font-size: 12px; width: 16px; flex: none; text-align: center; }
.checklist .done { color: var(--emerald); }
.checklist .next { color: var(--amber); }
.checklist .wait { color: var(--text-3); }

.muted-note { font-size: 12.5px; color: var(--text-3); margin-top: 14px; line-height: 1.5; }

@media (max-width: 560px) {
  .auth-card { padding: 26px 20px; }
  .kv { grid-template-columns: 1fr; gap: 3px 0; }
  .kv dd { margin-bottom: 8px; }
}

/* ================= app shell: nav ================= */

.nav {
  background: var(--card);
  border-bottom: 1px solid var(--border);
  padding: 0 22px;
  display: flex; align-items: center; gap: 2px;
  position: sticky; top: 65px; z-index: 19;
}
.navtab {
  padding: 11px 15px;
  border: none; background: none;
  border-bottom: 2px solid transparent;
  font: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--text-3); cursor: pointer;
}
.navtab:hover { color: var(--text-2); }
.navtab.active { color: var(--sky); border-bottom-color: var(--sky); }
.navtab .soon {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-3);
  border: 1px solid var(--border-2); border-radius: 4px;
  padding: 1px 4px; margin-left: 5px;
}
.readonly {
  margin-left: auto;
  font-size: 12px; font-weight: 600; color: var(--amber);
  background: var(--amber-soft);
  border-radius: 999px; padding: 3px 11px;
}

.fac-picker {
  padding: 6px 10px;
  border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card); color: var(--text);
  font: inherit; font-size: 13px; font-weight: 600;
  max-width: 190px;
}

/* ================= metrics ================= */

.metrics {
  display: grid; gap: 12px; margin-bottom: 18px;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.metric {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--sky);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 2px;
}
.metric.amber { border-left-color: var(--amber); }
.metric.rose  { border-left-color: var(--rose); }
.metric .ml { font-size: 12px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em; }
.metric .mv { font-size: 26px; font-weight: 700; letter-spacing: -.02em; }
.metric .ms { font-size: 11.5px; color: var(--text-3); }

/* ================= cards, forms ================= */

.card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 14px; margin-bottom: 14px;
}
.head-actions { display: flex; gap: 8px; flex: none; }

.grid { display: grid; gap: 0 16px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.form-actions { margin-top: 20px; display: flex; gap: 10px; }
.form-actions .primary { width: auto; padding: 9px 22px; }

button.primary.sm, button.ghost.sm { padding: 7px 13px; font-size: 13px; width: auto; }

.empty { color: var(--text-3); font-size: 13.5px; padding: 18px 0; }

.status-row {
  margin-top: 20px; padding-top: 18px;
  border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.status-row label { font-size: 12.5px; font-weight: 600; color: var(--text-2); }
.status-row select {
  padding: 7px 10px; border: 1px solid var(--border-2);
  border-radius: 7px; background: var(--card); color: var(--text);
  font: inherit; font-size: 13.5px;
}

/* ================= table ================= */

.table-wrap { overflow-x: auto; margin: 0 -22px -22px; padding: 0 22px 4px; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
thead th {
  text-align: left; font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--text-3);
  padding: 8px 12px 8px 0; border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
tbody td { padding: 11px 12px 11px 0; border-bottom: 1px solid var(--border); white-space: nowrap; }
tbody tr:last-child td { border-bottom: none; }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: var(--card-2); }
td.mono, .mono { font-family: var(--mono); font-size: 12.5px; }
td.sky, .sky { color: var(--sky); }
td.strong, .strong { font-weight: 600; }
td.chev { color: var(--text-3); text-align: right; }

.pill {
  display: inline-block; border-radius: 999px;
  padding: 2px 10px; font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em;
}
.pill.open   { background: var(--amber-soft);   color: var(--amber); }
.pill.closed { background: var(--emerald-soft); color: var(--emerald); }

.gap { font-weight: 700; }
.gap.good { color: var(--emerald); }
.gap.warn { color: var(--amber); }
.gap.bad  { color: var(--rose); }

/* ================= audit trail ================= */

.audit { list-style: none; margin-top: 14px; display: grid; gap: 10px; }
.audit li {
  display: flex; gap: 12px; font-size: 13px; color: var(--text-2);
  padding-bottom: 10px; border-bottom: 1px solid var(--border);
}
.audit li:last-child { border-bottom: none; padding-bottom: 0; }
.audit .at { font-family: var(--mono); font-size: 11.5px; color: var(--text-3); white-space: nowrap; flex: none; }
.audit .fld { font-family: var(--mono); font-size: 11.5px; color: var(--violet); }
.audit .ov  { color: var(--rose); text-decoration: line-through; }
.audit .nv  { color: var(--emerald); font-weight: 600; }

/* ================= toast ================= */

.toast {
  position: fixed; left: 50%; bottom: 26px;
  transform: translateX(-50%) translateY(14px);
  background: var(--text); color: var(--bg);
  padding: 11px 20px; border-radius: 9px;
  font-size: 13.5px; font-weight: 600;
  box-shadow: var(--shadow);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
  z-index: 60; max-width: calc(100vw - 40px);
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.error { background: var(--rose); color: #fff; }

@media (max-width: 720px) {
  .header { padding: 12px 14px; gap: 10px; }
  .header .titles p { display: none; }
  .nav { padding: 0 14px; top: 61px; overflow-x: auto; }
  .content { padding: 18px 14px 60px; }
  .card { padding: 16px; }
  .table-wrap { margin: 0 -16px -16px; padding: 0 16px 4px; }
  .fac-picker { max-width: 130px; }
}

/* ================= accommodations ================= */

.violet { color: var(--violet); }

.fieldset {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  margin: 4px 0 16px;
  background: var(--card-2);
}
.fieldset-title {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-3); margin-bottom: 12px;
}

.pill.under_review    { background: var(--amber-soft);   color: var(--amber); }
.pill.approved        { background: var(--emerald-soft); color: var(--emerald); }
.pill.approved_closed { background: var(--emerald-soft); color: var(--emerald); }
.pill.denied          { background: var(--rose-soft);    color: var(--rose); }
.pill.openitems       { background: var(--sky-soft);     color: var(--sky); }
.pill.overdue         { background: var(--rose-soft);    color: var(--rose); }

/* follow-up items */

.items { list-style: none; margin-top: 12px; display: grid; gap: 2px; }
.item {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.item:last-child { border-bottom: none; }
.item.is-done .item-title { text-decoration: line-through; color: var(--text-3); }
.item-check { width: 16px; height: 16px; flex: none; accent-color: var(--emerald); cursor: pointer; }
.item-mark { width: 16px; flex: none; text-align: center; color: var(--text-3); }
.item-body { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.item-title { font-size: 13.5px; }
.item-due { font-size: 12px; color: var(--text-3); }

.due { font-weight: 700; margin-left: 6px; }
.due.overdue { color: var(--rose); }
.due.soon    { color: var(--amber); }

.linkbtn {
  border: none; background: none; padding: 2px 4px;
  font: inherit; font-size: 12px; font-weight: 600;
  color: var(--text-3); cursor: pointer; flex: none;
}
.linkbtn:hover { color: var(--text-2); text-decoration: underline; }
.linkbtn.danger:hover { color: var(--rose); }

.item-add {
  margin-top: 16px; padding-top: 16px;
  border-top: 1px solid var(--border);
  display: flex; gap: 9px; flex-wrap: wrap;
}
.item-add input {
  padding: 8px 11px; border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--card); color: var(--text); font: inherit; font-size: 13.5px;
}
.item-add input[type="text"] { flex: 1; min-width: 200px; }

/* ================= brand mark ================= */
/* Overrides the gradient placeholder that stood in before the real
   artwork existed. The mark is a transparent PNG, so it sits correctly
   on both the light and the dark background without a white plate. */

img.logo {
  width: auto; height: 38px;
  background: none; border-radius: 0;
  display: block; flex: none;
}
img.logo.lg { height: 92px; margin: 0 auto; }

.auth-card { text-align: center; }
.auth-card .tabs, .auth-card form, .auth-card .msg { text-align: left; }
.auth-card h1 { margin-top: 16px; }

.tagline {
  font-size: 11.5px; font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--text-3); margin-top: 7px;
}
.auth-card .sub { margin-top: 10px; }

/* ================= wordmark ================= */
/* Sampled from the supplied artwork: navy #001848, teal #00a0a0.
   Rendered as live text rather than baked into the image, so it stays
   sharp at any size and can recolour for the dark theme. */

:root { --brand-navy: #16315e; --brand-teal: #00a0a0; }
@media (prefers-color-scheme: dark) {
  :root { --brand-navy: #9db8e8; --brand-teal: #4fe0dc; }
}

img.lockup {
  display: block; margin: 0 auto 4px;
  width: 100%; max-width: 230px; height: auto;
}

h1.wordmark {
  font-size: 38px; font-weight: 700; letter-spacing: -.035em;
  line-height: 1; margin-top: 2px;
}
.wm-a { color: var(--brand-navy); }
.wm-b { color: var(--brand-teal); }

/* ================= recruiting + admin ================= */

.metric.violet  { border-left-color: var(--violet); }
.metric.emerald { border-left-color: var(--emerald); }

.pill.interviewing       { background: var(--sky-soft);     color: var(--sky); }
.pill.offered            { background: var(--sky-soft);     color: var(--sky); }
.pill.hired              { background: var(--emerald-soft); color: var(--emerald); }
.pill.onboarding         { background: var(--amber-soft);   color: var(--amber); }
.pill.active             { background: var(--emerald-soft); color: var(--emerald); }
.pill.probation_complete { background: var(--emerald-soft); color: var(--emerald); }
.pill.declined           { background: var(--rose-soft);    color: var(--rose); }
.pill.no_show            { background: var(--rose-soft);    color: var(--rose); }
.pill.terminated         { background: var(--rose-soft);    color: var(--rose); }

/* training progress */
.prog { display: inline-flex; align-items: center; gap: 7px; }
.prog-bar {
  width: 54px; height: 6px; border-radius: 3px;
  background: var(--border); overflow: hidden; display: inline-block;
}
.prog-fill { display: block; height: 100%; background: var(--text-3); border-radius: 3px; }
.prog-fill.good { background: var(--emerald); }
.prog-fill.warn { background: var(--amber); }
.prog-txt { font-family: var(--mono); font-size: 11.5px; color: var(--text-3); }

/* admin sub-navigation */
.subnav { display: flex; gap: 4px; margin-bottom: 16px; }
.subtab {
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card);
  font: inherit; font-size: 13px; font-weight: 600;
  color: var(--text-2); cursor: pointer;
}
.subtab.active { background: var(--sky); border-color: var(--sky); color: #fff; }

select.mini {
  padding: 5px 8px; border: 1px solid var(--border-2); border-radius: 6px;
  background: var(--card); color: var(--text);
  font: inherit; font-size: 12.5px; max-width: 175px;
}
select.mini:disabled { opacity: .55; }

tr.row-off td { opacity: .5; }
.you {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--sky);
  background: var(--sky-soft); border-radius: 4px; padding: 1px 5px; margin-left: 5px;
}
.muted { color: var(--text-3); }
.warn-text { color: var(--amber); font-weight: 600; }

/* ================= idle timeout ================= */

.idle-veil {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in srgb, var(--text) 55%, transparent);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  backdrop-filter: blur(2px);
}
.idle-box {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 14px; padding: 30px; max-width: 400px; width: 100%;
  box-shadow: var(--shadow); text-align: center;
}
.idle-box h2 { font-size: 20px; font-weight: 700; margin-bottom: 10px; }
.idle-box p { font-size: 14.5px; color: var(--text-2); }
.idle-box .idle-count { font-family: var(--mono); color: var(--rose); font-size: 16px; }
.idle-box .idle-note { font-size: 12.5px; color: var(--text-3); margin-top: 8px; }
.idle-box .primary { margin-top: 20px; }

@media (prefers-reduced-motion: reduce) {
  .idle-veil { backdrop-filter: none; }
}

/* ================= two-level navigation ================= */

.subnav-bar {
  background: var(--card-2);
  border-bottom: 1px solid var(--border);
  padding: 0 22px;
  display: flex; align-items: center; gap: 2px;
  position: sticky; top: 106px; z-index: 18;
  overflow-x: auto;
}
.subnav-bar .subtab {
  padding: 9px 14px; border-radius: 0; border: none; background: none;
  border-bottom: 2px solid transparent;
  font: inherit; font-size: 13px; font-weight: 600;
  color: var(--text-3); cursor: pointer; white-space: nowrap;
}
.subnav-bar .subtab:hover { color: var(--text-2); }
.subnav-bar .subtab.active { color: var(--text); border-bottom-color: var(--text-3); background: none; }

.hint-inline { font-size: 12.5px; color: var(--text-3); font-style: italic; }

/* ================= overview filters ================= */

.filters {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap;
  margin-bottom: 18px;
}
.filter { display: flex; flex-direction: column; gap: 5px; }
.filter label {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-3);
}
.filter select {
  padding: 7px 11px; border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--card); color: var(--text);
  font: inherit; font-size: 13.5px; font-weight: 600; min-width: 165px;
}
.filter-note { font-size: 12.5px; color: var(--text-3); padding-bottom: 8px; }

/* ================= worklist ================= */

.worklist { list-style: none; margin-top: 12px; display: grid; gap: 1px; }
.wl {
  display: grid;
  grid-template-columns: 108px 1fr auto 16px;
  align-items: center; gap: 14px;
  padding: 11px 12px; border-radius: 8px; cursor: pointer;
  border-left: 3px solid var(--border-2);
  background: var(--card);
}
.wl:hover { background: var(--card-2); }
.wl.warn { border-left-color: var(--amber); }
.wl.crit { border-left-color: var(--rose); }
.wl-fac {
  font-size: 11.5px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .04em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wl-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.wl-what { font-size: 13.5px; font-weight: 600; }
.wl-who { font-size: 12px; color: var(--text-3); }
.wl-why { font-size: 12.5px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
.wl.crit .wl-why { color: var(--rose); }
.wl.warn .wl-why { color: var(--amber); }
.wl-go { color: var(--text-3); text-align: right; }

td.bad { color: var(--rose); font-weight: 700; }
tr.total-row td { border-top: 2px solid var(--border-2); background: var(--card-2); }

@media (max-width: 720px) {
  .subnav-bar { top: 102px; padding: 0 14px; }
  .wl { grid-template-columns: 1fr auto; gap: 4px 10px; }
  .wl-fac { grid-column: 1 / -1; }
  .wl-go { display: none; }
}

/* ================= grouped, clickable tiles ================= */

.tile-group { margin-bottom: 16px; }
.tile-group-title {
  font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-3); margin-bottom: 8px;
}

button.metric {
  width: 100%; text-align: left; font: inherit;
  cursor: pointer; position: relative;
}
button.metric.linkable:hover { border-color: var(--sky); }
button.metric.linkable:hover .mgo { opacity: 1; }
.metric .mgo {
  position: absolute; top: 13px; right: 14px;
  font-size: 11.5px; font-weight: 600; color: var(--sky);
  opacity: 0; transition: opacity .12s ease;
}
@media (prefers-reduced-motion: reduce) { .metric .mgo { transition: none; } }

/* ================= filter chips ================= */

.chiprow {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 2px 0 14px;
}
.fchip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--border-2); background: var(--card);
  font: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--text-2); cursor: pointer;
}
.fchip:hover { border-color: var(--text-3); color: var(--text); }
.fchip.active { background: var(--sky); border-color: var(--sky); color: #fff; }
.fcount {
  font-family: var(--mono); font-size: 11px;
  background: var(--bg); color: var(--text-3);
  border-radius: 999px; padding: 1px 6px; min-width: 20px; text-align: center;
}
.fchip.active .fcount { background: rgba(255,255,255,.24); color: #fff; }

/* ================= password reset ================= */

.auth-sub {
  font-size: 15px; font-weight: 600; color: var(--text-2);
  margin: 22px 0 18px; text-align: left;
}
.auth-alt { margin-top: 16px; text-align: center; }
.auth-alt .linkbtn { font-size: 13px; color: var(--sky); }
.auth-alt .linkbtn:hover { color: var(--sky); text-decoration: underline; }

/* ================= OSHA form additions ================= */

.field.fu { grid-column: 1 / -1; }

label.check {
  display: flex; align-items: center; gap: 7px;
  margin-top: 7px; font-size: 12.5px; font-weight: 500; color: var(--text-2);
  cursor: pointer;
}
label.check input { width: auto; accent-color: var(--sky); cursor: pointer; }

.fieldset .kv { margin-top: 4px; }
.msg.ok, .msg.warn { margin-bottom: 14px; }

/* ================= case updates ================= */

.updates { list-style: none; margin-top: 14px; display: grid; gap: 12px; }
.upd {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 13px 15px; background: var(--card-2);
}
.upd-head {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  margin-bottom: 7px;
}
.upd-head .spacer { flex: 1; }
.upd-date {
  font-family: var(--mono); font-size: 12px; font-weight: 600; color: var(--text-2);
}
.upd-src { font-size: 12px; color: var(--text-3); }
.upd-summary { font-size: 14px; font-weight: 600; }
.upd-details { font-size: 13.5px; color: var(--text-2); margin-top: 4px; }

.upd-tag {
  margin-top: 9px; padding: 7px 11px; border-radius: 7px;
  font-size: 13px; background: var(--card); border: 1px solid var(--border);
}
.upd-tag.restriction { border-left: 3px solid var(--violet); }
.upd-tag.action { border-left: 3px solid var(--sky); }
.upd-tag.action.soon { border-left-color: var(--amber); }
.upd-tag.action.overdue { border-left-color: var(--rose); }

.upd-form {
  border: 1px solid var(--border-2); border-radius: 10px;
  padding: 16px; margin-bottom: 16px; background: var(--card-2);
}
.upd-form .form-actions { margin-top: 14px; }

.pill.restriction_change { background: var(--violet); color: #fff; }
.pill.appointment_set,
.pill.ime_set           { background: var(--sky-soft);     color: var(--sky); }
.pill.return_to_work    { background: var(--emerald-soft); color: var(--emerald); }
.pill.status_change     { background: var(--amber-soft);   color: var(--amber); }
.pill.correspondence,
.pill.note,
.pill.other             { background: var(--surface-2, var(--bg)); color: var(--text-3);
                          border: 1px solid var(--border); }

/* ================= attachments ================= */

.atts { list-style: none; margin-top: 12px; display: grid; gap: 1px; }
.att {
  display: grid; grid-template-columns: 140px 1fr auto auto;
  align-items: center; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
}
.att:last-child { border-bottom: none; }
.att-kind {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-3);
  background: var(--card-2); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 9px; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.att-kind.wc_packet { color: var(--sky); border-color: var(--sky); }
.att-name {
  border: none; background: none; padding: 0; text-align: left;
  font: inherit; font-size: 13.5px; font-weight: 600; color: var(--sky);
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.att-name:hover { text-decoration: underline; }
.att-sub { font-size: 12px; color: var(--text-3); white-space: nowrap; }

.att-add {
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border);
  display: flex; gap: 9px; align-items: center; flex-wrap: wrap;
}
.att-add input[type="file"] {
  flex: 1; min-width: 200px; font-size: 13px; color: var(--text-2);
}
.att-add input[type="file"]::file-selector-button {
  font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 6px 12px; margin-right: 10px;
  border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card); color: var(--text-2); cursor: pointer;
}

/* viewer */
.att-veil {
  position: fixed; inset: 0; z-index: 90;
  background: color-mix(in srgb, var(--text) 62%, transparent);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.att-box {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: var(--shadow);
  width: 100%; max-width: 940px; height: 86vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.att-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.att-bar .spacer { flex: 1; }
.att-bar a.ghost { text-decoration: none; display: inline-block; }
.att-title {
  font-size: 14px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 45%;
}
.att-meta { font-size: 12px; color: var(--text-3); }
.att-body { flex: 1; overflow: auto; background: var(--bg); display: flex; }
.att-body iframe { flex: 1; border: none; }
.att-body img { max-width: 100%; max-height: 100%; margin: auto; display: block; }
.att-body .empty { margin: auto; text-align: center; }

@media (max-width: 720px) {
  .att { grid-template-columns: 1fr auto; gap: 4px 10px; }
  .att-kind { grid-column: 1 / -1; justify-self: start; }
  .att-sub { grid-column: 1; }
  .att-box { height: 92vh; }
}

.packet-chosen {
  margin-top: 10px; padding: 9px 12px;
  background: var(--emerald-soft); color: var(--emerald);
  border-radius: 8px; font-size: 13px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.packet-chosen .linkbtn { color: var(--emerald); margin-left: auto; }
.packet-chosen .linkbtn:hover { color: var(--rose); }

/* Settings: scope as a set of buildings rather than one value. Each
   checkbox is an independent grant, so the cell has to read as a list of
   things that are on or off, not as one choice among several. */
.scope-set {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 4px 12px; max-width: 340px;
}
.scope-check {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--text-2);
  cursor: pointer; white-space: nowrap;
}
.scope-check input { cursor: pointer; margin: 0; accent-color: var(--sky); }
.scope-check:hover { color: var(--text); }
.scope-check input:disabled { cursor: default; }
.scope-check input:disabled + span { color: var(--text-3); }
.scope-label {
  flex-basis: 100%; margin-top: 2px;
  font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3);
}

/* Settings v2: closed controls that open, rather than checkboxes spread
   across every row. A flat list shows every building the VIEWER can see,
   which for the platform operator is every building of every customer. */
.settings-tabs { display: flex; gap: 6px; margin-bottom: 16px; }
.settings-tabs button {
  background: none; border: 1px solid var(--border); color: var(--text-2);
  padding: 7px 14px; border-radius: 8px; font-size: 13px; cursor: pointer;
}
.settings-tabs button:hover { color: var(--text); border-color: var(--border-2); }
.settings-tabs button.on {
  background: var(--card-2); color: var(--text);
  border-color: var(--border-2); font-weight: 600;
}

/* The closed control truncates; the OPEN one sizes to its content. An
   earlier version put max-width on the details element, which constrained
   the open panel too and cut the building names in half. */
details.picker { display: block; }
details.picker > summary {
  cursor: pointer; font-size: 12.5px; color: var(--text-2);
  padding: 5px 10px; border: 1px solid var(--border);
  border-radius: 999px; list-style: none; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  max-width: 200px; transition: border-color .12s, color .12s;
}
details.picker > summary::-webkit-details-marker { display: none; }
details.picker > summary::after { content: ' \25be'; color: var(--text-3); }
details.picker > summary:hover { color: var(--text); border-color: var(--border-2); }
details.picker[open] > summary {
  border-color: var(--border-2); color: var(--text); background: var(--card-2);
}
.picker-body {
  margin-top: 7px; padding: 12px 14px;
  background: var(--card-2); border: 1px solid var(--border);
  border-radius: 12px; display: flex; flex-direction: column; gap: 7px;
  width: max-content; min-width: 200px; max-width: 340px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}
.picker-body .mini { width: 100%; }
.picker-body .primary { margin-top: 4px; }

.sub-line { font-size: 11.5px; color: var(--text-3); margin-top: 3px; }
.titlebox { width: 130px; }
.new-org {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
}
.new-org .scope-label { flex-basis: 100%; margin: 0 0 2px; }

/* Settings reads as a control panel, and a control panel of hard-ruled
   boxes is tiring to look at. Softer rules, more air, and a row that
   responds to the cursor - so the eye follows a person across the row
   rather than being handed a grid. Scoped to Settings so no other table
   changes. */
/* Lists tab: an entry is a category, not a paragraph, and the order box
   holds a number. Sized so the two never look like the same kind of field. */
.settings-tabs ~ .card td input.mini { width: 100%; max-width: 260px; }
/* Both selectors have to out-specify the rule above, which is why they name
   the cell. An earlier version said `.card input.num` and lost, leaving the
   order box the same 260px as the entry box - caught by measuring the
   rendered width, not by reading the file. */
.settings-tabs ~ .card td input.num,
.settings-tabs ~ .card .new-org input.num { width: 74px; text-align: right; }

.settings-tabs ~ .card table { font-size: 13px; }
.settings-tabs ~ .card thead th {
  font-size: 10.5px; letter-spacing: .07em; color: var(--text-3);
  padding: 6px 16px 10px 0; border-bottom: 1px solid var(--border);
  font-weight: 600;
}
.settings-tabs ~ .card tbody td {
  padding: 14px 16px 14px 0; vertical-align: top;
  border-bottom: 1px solid var(--border); white-space: normal;
}
.settings-tabs ~ .card tbody tr { transition: background .12s; }
.settings-tabs ~ .card tbody tr:hover td { background: var(--card-2); }
.settings-tabs ~ .card tbody tr:last-child td { border-bottom: none; }

/* Row controls sit quietly until you reach for them. */
.settings-tabs ~ .card .mini {
  border-radius: 9px; padding: 5px 9px; font-size: 12.5px;
  border: 1px solid var(--border); background: var(--card);
  color: var(--text-2); transition: border-color .12s, color .12s;
}
.settings-tabs ~ .card .mini:hover,
.settings-tabs ~ .card .mini:focus { border-color: var(--border-2); color: var(--text); }
.settings-tabs ~ .card .scope-set { gap: 5px 14px; }
.settings-tabs ~ .card .scope-check { font-size: 12px; }
.settings-tabs ~ .card .pill { border-radius: 999px; }
.settings-tabs ~ .card .sub { max-width: 62ch; line-height: 1.55; }
.settings-tabs ~ .card .muted-note {
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border);
  line-height: 1.6; max-width: 78ch;
}
.titlebox { width: 132px; }

/* Buildings inside an organisation row, each with its retire/restore
   control. A retired building stays listed here - this is the only screen
   that shows it, because it is the only screen that can bring it back. */
.fac-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.fac-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 3px 4px 3px 11px; border-radius: 999px;
  border: 1px solid var(--border);
  white-space: nowrap;
}
.fac-chip.off { opacity: .7; }
.fac-chip.off > span { color: var(--text-3); text-decoration: line-through; }
.fac-chip .linkbtn { font-size: .82em; }

/* An organisation row's controls: "Add a building" plus retire/restore,
   side by side. Hidden on a retired organisation, which cannot take one. */
.org-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* tr.row-off dims the whole row, and opacity compounds down the tree, so
   Restore was landing at 50% of an already-muted grey - the faintest thing
   in the row was the only control that undoes it. The row stays dimmed; its
   controls do not. */
tr.row-off td.org-actions { opacity: 1; }

/* The not-eligible box sits at the top of the candidate form. Deliberately
   plain: it is a statement of fact, not a warning, and the record it makes
   is that somebody applied and nothing more. */
.inelig-box {
  border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 14px; margin-bottom: 16px;
  display: flex; flex-direction: column; gap: 6px;
}
.inelig-box .tick { display: flex; align-items: center; gap: 9px; cursor: pointer; }
.inelig-box .tick input { width: 16px; height: 16px; }
.inelig-box .field { margin-top: 6px; max-width: 380px; }

/* A frozen form still has to be readable - dimmed, not hidden, so the
   person can see there is nothing to fill in rather than wondering why
   nothing responds. The exempt controls keep full contrast. */
form.frozen .fieldset, form.frozen > .grid, form.frozen > .field { opacity: .55; }
form.frozen .inelig-box { opacity: 1; }
form.frozen input:disabled, form.frozen select:disabled, form.frozen textarea:disabled {
  background: var(--bg); cursor: not-allowed;
}

/* The computed tenure chips. Calculated from the dates, never typed, so
   they read as answers rather than fields. */
.tenure { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px; }
.tenure .gap { font-size: .9em; }

/* The derived stage on the form. It is an answer, not a control, so it must
   not look like a disabled dropdown - a greyed-out select invites clicking. */
.derived-now { padding: 4px 0 2px; }

/* How long they stayed. The hire date and the day count come first, then the
   milestones, because a computed answer that hides its input cannot be
   checked - which is exactly how the first version of this confused the
   owner. */
.tenure-head { font-size: .92em; color: var(--text-2); margin-bottom: 6px; }
.tenure-row { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.tenure-row .gap { font-size: .9em; font-weight: 600; }

/* The line under the filter chips saying what the selected one contains.
   The owner asked twice what a chip meant; the screen should say. */
.chiphint { color: var(--text-2); font-size: .9em; margin: -4px 0 10px; max-width: 74ch; }

/* The interview questionnaire, both halves: the library an administrator
   maintains in Settings, and the form a recruiter fills in on a candidate.
   A question is a sentence, so it gets a textarea rather than a one-line
   box - a question that scrolls sideways cannot be read at a glance. */
.q-row {
  padding: 14px 0; border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 8px;
}
.q-row:last-of-type { border-bottom: none; }
.q-new { border-top: 1px solid var(--border-2); margin-top: 6px; }
textarea.q-prompt {
  width: 100%; max-width: 620px; resize: vertical;
  padding: 8px 10px; border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--card); color: var(--text); font: inherit; font-size: 13px;
}
.q-positions {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  padding: 8px 12px; background: var(--card-2);
  border: 1px solid var(--border); border-radius: 10px;
  max-width: 620px;
}
.q-row .new-org { margin-top: 2px; padding-top: 10px; }

.qa { margin: 0; padding-left: 22px; display: flex; flex-direction: column; gap: 18px; }
.qa-item { padding-left: 4px; }
.qa-q { margin: 0 0 6px; font-size: 13.5px; font-weight: 600; color: var(--text); }
.qa-item textarea, .qa-comments textarea {
  width: 100%; max-width: 620px; resize: vertical;
  padding: 8px 10px; border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--card); color: var(--text); font: inherit; font-size: 13px;
}
.qa-item textarea:disabled, .qa-comments textarea:disabled { opacity: .6; }
.qa-item .scope-check { margin-top: 5px; font-size: 12.5px; }
.qa-comments { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--border); }
.qa-comments .scope-label { display: block; margin-bottom: 5px; }

/* Employee roster statuses. active / onboarding / terminated already exist
   from the recruiting derived statuses and are reused deliberately - the
   same word should look the same wherever it appears. */
.pill.leave              { background: var(--sky-soft);    color: var(--sky); }
.pill.unknown            { background: var(--amber-soft);  color: var(--amber); }

/* ---------- workforce structure (0015) ----------
   Positions, groups and departments. Only the genuinely new pieces are here;
   the screen otherwise uses the app's existing card, field, msg, pill and
   button styles rather than a parallel set. A module that invents its own
   class names is how the employees screen ended up with two unstyled status
   pills and a search box matching nothing at all. */

/* A table that can be wider than the card it sits in. The page itself must
   never scroll sideways, so the scrolling happens here. */
.tblscroll { overflow-x: auto; }
.tblscroll table { min-width: 720px; }

/* Payroll's own wording, which is never edited. */
td.raw { font-weight: 600; }
td.raw small { display: block; font-weight: 400; font-size: 12px; color: var(--text-3); }

/* Shown, not chosen: group and department follow from the position, and this
   is what tells somebody that at a glance. decisions.md 49. */
.derived {
  display: inline-block; min-width: 130px;
  padding: 5px 9px; border-radius: 7px;
  border: 1px dashed var(--border-2);
  background: var(--card-2); color: var(--text-2);
  font-size: 13px;
}

.numcell { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
th.numcell { text-align: right; }

/* What sits inside a group or a department. */
.chip {
  display: inline-block; font-size: 12px; font-weight: 600;
  padding: 2px 8px; border-radius: 999px; margin: 1px 0;
  background: var(--sky-soft); color: var(--sky);
}

tr.unmapped > td { background: color-mix(in srgb, var(--amber-soft) 45%, transparent); }
tr.retired  > td { color: var(--text-3); }

/* A double shift. Informational rather than a warning - it is a fact about
   hours worked, not a problem to fix. decisions.md 87. */
.pill.double  { background: var(--sky-soft);     color: var(--sky); }
.pill.mapped  { background: var(--emerald-soft); color: var(--emerald); }
.pill.todo    { background: var(--amber-soft);   color: var(--amber); }
.pill.retired { background: var(--card-2);       color: var(--text-3); }

.btnrow { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }

/* Creating a department, a group or a position. Drawn in place rather than
   over the page: this app has no modal anywhere else, and adding one pattern
   for one screen is how two vocabularies start. */
.dlgmount:empty { display: none; }
.dlgwrap { margin: 12px 0 16px; }
.dlg {
  max-width: 440px;
  border: 1px solid var(--border-2); border-radius: 11px;
  background: var(--card); box-shadow: var(--shadow); overflow: hidden;
}
.dlg .dhd { padding: 12px 15px; border-bottom: 1px solid var(--border); font-weight: 700; }
.dlg .dbody { padding: 15px; display: flex; flex-direction: column; gap: 13px; }
.dlg .dft {
  padding: 11px 15px; border-top: 1px solid var(--border);
  background: var(--card-2); display: flex; gap: 8px; justify-content: flex-end;
}

/* A validation message, written into one element so typing survives it. */
.err {
  background: var(--rose-soft); border: 1px solid var(--rose); color: var(--rose);
  border-radius: 8px; padding: 9px 11px; font-size: 13px; font-weight: 600;
}
.err:empty { display: none; }

/* button.primary is width:100% in this app on purpose - it is the full-width
   form submit. Inside a row of actions it has to be its own size, and the
   small actions beside it use the ghost button that already exists rather
   than a bare one. Reaching for primary everywhere is what made "New group"
   span the whole card and squashed Cancel to nothing. */
.btnrow button.primary, .dlg .dft button.primary { width: auto; }
.btnrow button, .dlg .dft button { white-space: nowrap; }

/* Dropdowns inside these tables. They were bare <select> elements with only a
   min-width, so the browser drew them - which is the same failure as the
   roster's search box: an unstyled control reads as ugly rather than as
   broken, so nobody reports it as a bug. Same border, radius, background and
   focus ring as `.field select`, so the app has one control look and not two,
   and a chevron drawn in CSS rather than the platform's own. */
/* .cmpick is the closed state of the column-mapping picker, and it is added
   to THESE selectors rather than given its own block on purpose: it must be
   the same control as the dropdowns on the Position mapping and Employment
   type mapping tabs, not something that resembles them. The owner looked at a
   row on 2026-09-10 and reported "there was no dropdown" - because it was a
   dim link under a box instead of the control they had already learned. */
.tblscroll td select,
.tblscroll th select,
.cmpick {
  min-width: 170px; max-width: 240px; width: 100%;
  appearance: none; -webkit-appearance: none;
  padding: 7px 30px 7px 10px;
  border: 1px solid var(--border-2); border-radius: 8px;
  background-color: var(--card); color: var(--text);
  font: inherit; font-size: 13.5px;
  cursor: pointer;
  transition: border-color .12s ease, box-shadow .12s ease;

  /* the chevron: two strokes, drawn rather than downloaded */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-3) 50%),
    linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
  background-position: right 15px center, right 10px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.tblscroll td select:hover, .cmpick:hover { border-color: var(--text-3); }
.tblscroll td select:focus, .cmpick:focus {
  outline: none;
  border-color: var(--sky);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sky) 18%, transparent);
}
.tblscroll td select:disabled { opacity: .6; cursor: default; }

/* Nothing chosen yet. Amber rather than red: it is unfinished, not wrong. */
.tblscroll td select.empty, .cmpick.unmapped {
  color: var(--amber); border-color: var(--amber); font-weight: 600;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--amber) 50%),
    linear-gradient(135deg, var(--amber) 50%, transparent 50%);
}

/* ---------- unsaved edits on the Lists and Interview questions tabs ----------
   Both tabs save a row at a time, with a Save button in its own column. The
   owner typed a change, moved on, lost it, and asked whether a save button
   was needed - which is the clearest possible evidence that the one already
   there is invisible. Nothing was broken; nothing said anything either.

   So an edited row now says so, and its Save button stops being one grey
   button among several. */
tr.rowdirty > td { background: color-mix(in srgb, var(--amber-soft) 40%, transparent); }
tr.rowdirty [data-listsave],
tr.rowdirty [data-qsave] {
  background: var(--amber); border-color: var(--amber); color: #1a1205;
  font-weight: 700;
}
.unsaved-note {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--amber-soft); border: 1px solid var(--amber);
  border-radius: 9px; padding: 10px 13px; margin: 10px 0;
  font-size: 14px;
}

/* ================= choosing an employee ================= */
/* The type-to-narrow roster picker (app/employeepicker.js). decisions.md 42:
   a name is chosen, never typed, and the payroll ID arrives with the person. */

.picklist {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-top: 4px;
  max-height: 240px;
  overflow-y: auto;
  background: var(--card);
}
.pickrow {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.pickrow:last-child { border-bottom: 0; }
.pickrow:hover, .pickrow:focus { background: var(--sky-soft); }
.pickrow.empty { cursor: default; color: var(--text-2); font-size: 13px; }
.pickrow.empty:hover { background: none; }
.pickrow .nm { font-weight: 600; }
.pickrow .sub, .picked .sub { color: var(--text-2); font-size: 12.5px; }

.picked {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
}
/* An existing record's person is fixed - 0017 makes the link fill-in-once - so
   it reads as a fact rather than as something half-editable. */
.picked.fixed { background: none; border-style: dashed; }
.hint.warn { color: var(--amber); }

/* ================= clearing a date ================= */
/* Every date input gets one - see attachDateClears in app/ui.js. The button
   sits inside the box, after the browser's own calendar icon. */

/* inline-block by default so it behaves like the input it replaced inside a
   flex row - the accommodation follow-up adder and the case-update adder both
   put a date in one - and block inside a .field, where inputs are full width. */
.datewrap { position: relative; display: inline-block; }
.field .datewrap { display: block; }
.datewrap > input[type="date"] { width: 100%; padding-right: 30px; }
.dateclear {
  position: absolute;
  top: 50%;
  right: 26px;
  transform: translateY(-50%);
  border: 0;
  background: none;
  color: var(--text-2);
  font-size: 17px;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
  border-radius: 4px;
}
.dateclear:hover { color: var(--rose); background: var(--rose-soft); }
/* Somebody who got through probation and left later. Not a recruiting loss -
   decisions.md, owner 2026-09-08 - so deliberately not the rose of a lost
   candidate, and not the green of somebody still employed. */
.pill.left_after_probation { background: var(--sky-soft); color: var(--sky); }

/* ---------------------------------------------------------------- column
   mapping (0020). Reuses .picklist, .pickrow and .picked from the employee
   picker rather than restating them - two controls that do the same job and
   look different make somebody learn it twice. Only what is genuinely new
   is below. */

.pickgroup {
  padding: 6px 10px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-2);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
}
.pickrow.special { background: var(--sky-soft); font-weight: 600; }
/* A field another column already claims. Shown, never hidden - every
   dropdown offers the whole list (decisions.md 47) - but visibly not
   available, and choosing it says which column has it. */
.pickrow.taken { opacity: .55; }
.pickrow.taken:hover { background: var(--rose-soft, #fdf2f2); }
.picknone { padding: 10px; }
/* .cmsearch is now inside .searchbox - see .cmsearchwrap at the end. */
.cmchoice { min-width: 260px; }
.cmtable td { vertical-align: top; }
/* Deliberately not stored is a decision somebody made, so it reads as
   settled rather than as an omission. An unmapped row uses .unmapped, which
   already means "needs a look" everywhere else in the product. */
tr.ignored td { color: var(--text-2); }

/* The mapping picker's closed button carries a longer label than a position
   name, so it is allowed to be wider than the shared maximum above.

   AND IT SAYS `.unmapped` RATHER THAN `.empty`, which is the name the sibling
   <select> uses for the same amber state. Not carelessness: `.empty` is
   already a GLOBAL class in this file - line 358, the grey "nothing here"
   text - with its own colour, font-size and 18px padding. `.tblscroll td
   select.empty` outranks it on specificity and gets away with it; a bare
   `.cmpick.empty` would have been winning on source order alone, so moving
   this block or adding one `.empty` rule below it would have silently
   restyled the control. */
.cmpick {
  /* 300px holds the longest label in the catalogue - "Employment status as
     payroll writes it", 38 characters - on one line, and anything longer
     wraps to two rather than widening the column. The shared 240px cap above
     was too tight for these; NO cap at all was worse, and is what made the
     whole page scroll sideways until the table was given .tblscroll. */
  max-width: 300px;
  text-align: left;
  white-space: normal;
  line-height: 1.35;
}

/* ---------- the hidden attribute must actually hide things ----------
   THIS IS A BUG CLASS, NOT A TWEAK. `hidden` gets its `display: none` from the
   browser's OWN stylesheet, which ANY author rule outranks. So an element with
   a `display` of its own ignores being hidden entirely, silently.

   It bit the column-mapping search on 2026-09-10: the code marked 16 of 18 rows
   hidden, `.pickrow { display: flex }` won, nothing disappeared, and the owner
   reported "it does not shorten the list as you type". The group headings DID
   vanish - they have no display rule - so typing made the list worse.

   One line, applied once, so no future `el.hidden = true` anywhere in this app
   can fail the same way. The column mapper no longer depends on it, but plenty
   of other screens set `hidden` on things that may one day get a display rule. */
[hidden] { display: none !important; }

/* The mapping picker's search box, which is the roster's search box. The first
   version was a bare input with a width and a margin and the owner's word for
   it was "ugly" - the same failure `styles.css` line 132 records for the roster.
   .searchbox draws the border, the focus ring and the magnifying glass; this
   only widens it, because a field label is longer than a person's name. */
.cmsearchwrap { max-width: 100%; margin-bottom: 6px; }
.cmsearchwrap input { font-size: 13.5px; }

/* ================= the column chooser =================
   decisions.md 72. Per person, inclusion and order in one list, remembered
   between sessions. Two columns on a desktop, stacked on a phone - where the
   up/down buttons rather than dragging are the working path. */

.ccgrid { display: grid; gap: 22px; grid-template-columns: 1fr 1fr; }
@media (max-width: 860px) { .ccgrid { grid-template-columns: 1fr; } }

.cch {
  font-size: 12px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .04em;
  margin: 0 0 4px;
}

.cclist { list-style: none; margin: 8px 0 12px; padding: 0; }

.ccrow {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; margin-bottom: 4px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card);
  cursor: grab;
}
.ccrow.locked { cursor: default; opacity: .8; background: none; border-style: dashed; }
.ccrow.dragging { opacity: .4; }
/* The drop target. A line would be ambiguous about which side, so the whole
   row is marked and the dragged item takes its place. */
.ccrow.dropinto { border-color: var(--sky); box-shadow: inset 0 0 0 1px var(--sky); }

.cchandle { color: var(--text-3); font-size: 12px; letter-spacing: -2px; flex: none; }
.ccname { flex: 1; font-size: 13.5px; }
/* The .ccbtns row of up/down arrows is GONE - decisions.md 72 and 73. It
   existed because dragging is unreliable on a phone, and changing a table's
   layout turned out not to be a phone job at all. Its rules are removed rather
   than left behind, so nobody wonders later what they styled.

   The remove link keeps its place at the end of a row. */
.ccrow > .linkbtn { flex: none; }

/* Dropping below the last row appends. Without a little room to aim at, the
   end of the list is unreachable - dropping ON the last row inserts before it. */
.cclist { padding-bottom: 10px; }

.ccsearchwrap { max-width: 100%; margin-bottom: 8px; }
.ccavail {
  max-height: 420px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--card);
}

.ccopt {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 10px; cursor: pointer;
  border-top: 1px solid var(--border);
}
.ccavail .pickgroup + .ccopt { border-top: none; }
.ccopt:hover { background: color-mix(in srgb, var(--sky) 7%, transparent); }
.ccopt input { flex: none; margin: 0; }
.ccopt > span:nth-of-type(1) { font-size: 13.5px; font-weight: 500; }
.ccopt .sub { margin-left: auto; text-align: right; }
/* Already shown. Marked rather than removed from the list, because a list that
   loses items as you tick them makes the next tick land somewhere unexpected. */
.ccopt.on { background: color-mix(in srgb, var(--sky) 10%, transparent); }

/* ---------- recording the names a building answers to ----------
   decisions.md 40. The add row is three controls that belong together, so it
   sits on one line where there is room and stacks on a phone - where, per
   decisions.md 72, nobody is expected to be doing this anyway. */
.fnadd { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.fnadd .field { margin: 0; }
.fnadd .field:first-child { flex: 1 1 260px; }
.fnadd .field:nth-child(2) { flex: 0 0 190px; }
.fnadd .primary { width: auto; padding: 9px 18px; flex: none; }
@media (max-width: 620px) {
  .fnadd { display: block; }
  .fnadd .primary { width: 100%; margin-top: 10px; }
}

/* ---------------------------------------------------------------- punches
   The punch list. Built from docs/punch-mockup.html, which the owner reviewed
   through seventeen versions, so the decisions here are theirs rather than
   mine - the frozen header, the checkbox filters, and keeping the Group
   column when I had twice removed it to solve a width problem.

   EVERY VARIABLE BELOW IS ONE THIS FILE ACTUALLY DEFINES, and the first draft
   of this block used FIVE THAT DO NOT EXIST: --panel, --line, --muted,
   --accent and --hover. Nothing threw. `border: 1px solid var(--line)` is
   simply an invalid declaration and drops, so the table had NO BORDER; and
   `background: var(--panel, #fff)` took its fallback, which would have painted
   the sticky header WHITE ON A DARK PAGE for anyone whose system is in dark
   mode. Invented variable names fail silently and look fine in light mode,
   which is the whole danger. The real ones are --card, --border, --text-3,
   --sky and --card-2.
*/

.punch-scroll {
  overflow: auto;
  max-height: 70vh;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.punch-table { width: 100%; border-collapse: separate; border-spacing: 0; }
.punch-table th, .punch-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  white-space: nowrap;
  font-size: 13px;
  color: var(--text);
}

/* THE HEADER STAYS PUT WHEN YOU SCROLL - the owner asked for this directly:
   "Can you also freeze the top row when scrolling down so the headers stay
   visible?" It needs an opaque background of its own, or the rows scroll
   through it. */
.punch-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--card);
  border-bottom: 2px solid var(--border-2);
  vertical-align: bottom;
}

.punch-table .th-sort {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-weight: 600; color: var(--text);
}
.punch-table .th-sort:hover { text-decoration: underline; }
.punch-table .arrow { margin-left: 3px; color: var(--sky); }
.punch-table .th-filter {
  background: none; border: 0; cursor: pointer; padding: 0 2px;
  color: var(--text-3); font-size: 11px;
}
.punch-table .th-filter.on { color: var(--sky); font-weight: 700; }

.punch-table td.num  { text-align: right; font-variant-numeric: tabular-nums; }
.punch-table td.t    { font-variant-numeric: tabular-nums; }
.punch-table td.date { font-variant-numeric: tabular-nums; }
.punch-table tbody tr:hover { background: var(--card-2); }

/* PAYROLL'S OWN WORDS SIT UNDER THE MAPPED POSITION, not beside it. The first
   run rendered "CNACNA" and "CookRN" because the two spans were inline with
   nothing between them - a defect that only exists once text is on a screen,
   and that reading the code would never have shown. */
.punch-table .pos { max-width: 210px; }
.punch-table .pos .ell { display: block; }
.punch-table .sub {
  display: block;
  font-size: 11px;
  color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; max-width: 200px;
}
.punch-table .sub:empty { display: none; }

.punch-table .nd {
  margin-left: 4px; font-size: 10px; padding: 0 3px;
  border-radius: 3px; background: var(--card-2);
  color: var(--text-3); border: 1px solid var(--border);
}
.punch-table .dash { color: var(--text-3); }

.warn-pill, .ok-pill {
  display: inline-block; font-size: 11px; padding: 1px 6px; border-radius: 10px;
}
.warn-pill { background: var(--amber-soft); color: var(--amber); }
.ok-pill   { background: var(--emerald-soft); color: var(--emerald); }

.warn-card { border-left: 3px solid var(--amber); }
/* The punch table saying what it could NOT load. It is a warning rather
   than a muted note on purpose: somebody reading 1,000 rows and believing
   that is all of them is the failure this exists to prevent. Same amber
   pair as every other warning here. */
.warn-note {
  margin: 10px 0 0; padding: 8px 12px; border-radius: 8px;
  background: var(--amber-soft); color: var(--amber);
  border: 1px solid var(--border-2); font-size: 13px; line-height: 1.5;
}
.warn-line { color: var(--amber); }
.ok-line   { color: var(--emerald); }
.warn-list { margin: 4px 0 0 18px; color: var(--amber); font-size: 13px; }

/* THE FILTER MENU IS FIXED-POSITIONED AND LIVES OUTSIDE THE SCROLLING BOX.
   The owner found why in the mockup: "The scroll bar makes the filter drop
   down disappear when I start to click it." A menu inside a container with
   overflow:auto is clipped by that container, and the scrollbar strip is
   exactly where it gets cut off. */
.filter-menu {
  position: fixed;
  z-index: 50;
  width: 260px;
  /* A COLUMN, so the list in the middle takes whatever height is left and
     scrolls inside the menu. max-height is set inline when the menu opens,
     from the room actually available above or below the button - a fixed
     menu cannot be scrolled to, so anything hanging off the screen is lost
     for good. */
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border-2);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 8px;
  font-size: 13px;
  color: var(--text);
}
.filter-menu .fm-head { font-weight: 600; margin-bottom: 6px; }
.filter-menu .fm-actions { display: flex; gap: 10px; margin-bottom: 6px; }
.filter-menu .fm-list {
  /* flex, not a fixed 240px: the menu's own max-height decides, and
     min-height:0 is what lets a flex child actually shrink and scroll. */
  flex: 1 1 auto; min-height: 0; overflow: auto;
}
.filter-menu .fm-row {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 6px; align-items: center; padding: 2px 0; cursor: pointer;
}
.filter-menu .fm-row .ell { overflow: hidden; text-overflow: ellipsis; }
.filter-menu .fm-row .muted { color: var(--text-3); }
.filter-menu .fm-foot {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--border);
}
.filter-menu input[type=text] { width: 100%; }

/* THE SEARCH BOX, which the owner called "very boxy" - the same note they
   made about the shift-times inputs, fixed the same way: a rounded field with
   room to breathe, a magnifier tucked inside it, and a focus ring that uses
   the brand colour rather than the browser's default outline. */
.filter-menu .fm-search { position: relative; margin-bottom: 8px; }
.filter-menu .fm-search-icon {
  position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  font-size: 12px; opacity: .55; pointer-events: none;
}
.filter-menu .fm-search input[type=text] {
  width: 100%; box-sizing: border-box;
  padding: 7px 10px 7px 28px;
  border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--bg); color: var(--text); font-size: 13px;
  transition: border-color .12s, box-shadow .12s;
}
.filter-menu .fm-search input[type=text]:focus {
  outline: none; border-color: var(--sky);
  box-shadow: 0 0 0 3px var(--sky-soft);
}
.filter-menu .fm-search input[type=text]::placeholder { color: var(--text-3); }

/* THE DATE TREE. Years open into months, months into days. The indent is on
   the row rather than the label so the checkboxes of one level still line up
   with each other. */
/* A TREE ROW HAS FOUR CHILDREN, NOT THREE. .fm-row is a three-column grid -
   checkbox, label, count - so adding the twist arrow pushed the checkbox into
   the 1fr column, stretched it across the row and wrapped the count onto a
   line of its own. Found by reading the computed grid rather than the markup. */
.filter-menu .fm-node {
  font-weight: 600;
  grid-template-columns: 16px auto 1fr auto;
}
.filter-menu .fm-lvl2 { padding-left: 16px; font-weight: 500; }
.filter-menu .fm-lvl3 { padding-left: 46px; font-weight: 400; }
.filter-menu .fm-twist {
  width: 16px; height: 16px; flex: 0 0 16px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: none; cursor: pointer;
  color: var(--text-3); font-size: 10px; padding: 0;
}
.filter-menu .fm-twist:hover { color: var(--text); }
.filter-menu .fm-foot { justify-content: space-between; align-items: center; }

.linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--sky); font: inherit; text-decoration: underline;
}

/* The upload row: controls sit side by side and wrap on a narrow screen,
   rather than one button stretching the width of the card. */
.punches .row {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 10px 0;
}
.punches .row .btn { width: auto; flex: 0 0 auto; }
.punches .preview {
  margin: 10px 0; padding: 10px; border-radius: 8px;
  background: var(--card-2); border: 1px solid var(--border);
}

/* Narrow screens. The table is the one thing allowed to scroll sideways -
   it has its own container for exactly that - and nothing else may. */
@media (max-width: 560px) {
  .punch-table th, .punch-table td { padding: 5px 7px; font-size: 12px; }
  .punch-table .pos, .punch-table .sub { max-width: 130px; }
  .filter-menu { width: calc(100vw - 24px); }
}

/* ------------------------------------------------------------ shift times
   Settings -> Workforce structure -> Shift times.

   The first version was boxy - the owner's word - because every field was a
   default control sitting in a flex row, so nothing lined up and each input
   drew its own heavy border. This lays the fields out in the TABLE'S columns
   so starts and ends align down the page, and softens the controls: one
   shared height, a quiet border that only asserts itself on focus, and
   tabular figures so 06:30 and 14:45 occupy the same width.

   Every variable here is one this file DEFINES. The punch styles shipped with
   five invented names that silently dropped and would have painted a white
   header on a dark page.
*/

.sub-card {
  margin: 14px 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  box-shadow: var(--shadow);
}
.sub-card .card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 4px;
}
.sub-card h3 { margin: 0; font-size: 15px; letter-spacing: .01em; }
.sub-card .empty.small {
  margin: 10px 0; padding: 12px; text-align: center;
  color: var(--text-3); font-size: 13px;
  background: var(--card-2); border-radius: 8px;
}

.shift-table { width: 100%; border-collapse: collapse; margin: 10px 0 4px; }
.shift-table th {
  padding: 4px 10px 6px;
  text-align: left;
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-3);
  border-bottom: 1px solid var(--border);
}
.shift-table td {
  padding: 5px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  vertical-align: middle;
}
.shift-table tbody tr:last-child td { border-bottom: 0; }
.shift-table th.num, .shift-table td.num { text-align: right; }
.shift-table th.sh-act, .shift-table td.sh-act { text-align: right; width: 1%; white-space: nowrap; }
.shift-table td.sh-name { font-weight: 500; }
.shift-table .mono, .shift-table td.len {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.shift-table td.len { color: var(--text-2); }
.shift-table tr.retired td { opacity: .5; }

/* A row with unsaved changes says so quietly, on the edge, rather than
   shouting. It is the only cue that Save has something to do. */
.shift-table tr.dirty td:first-child { box-shadow: inset 3px 0 0 var(--sky); }
.shift-table tr.newrow td:first-child { box-shadow: inset 3px 0 0 var(--emerald); }

/* Units (0044) borrow the shift table. Order and beds are narrow numbers, so
   they take only their own width and the name gets the rest - and the table
   stops at a readable width instead of stretching a short list across the
   screen. */
.shift-table.units-table { max-width: 620px; }
.shift-table.units-table th.num, .shift-table.units-table td.num { width: 1%; white-space: nowrap; }

/* THE CONTROLS. One height, one radius, a border that stays out of the way
   until focus. This is the whole of the "boxy" complaint. */
.sub-card input[type="time"],
.sub-card input[type="text"],
.sub-card input[type="number"],
.sub-card select {
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--border-2);
  border-radius: 7px;
  background: var(--card-2);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  line-height: 28px;
  transition: border-color .12s ease, box-shadow .12s ease, background .12s ease;
}
.sub-card input[type="time"] {
  /* Wide enough for the 12-hour rendering some browsers use - "06:30 AM"
     plus the clock icon - rather than the 24-hour width alone. */
  width: 132px;
  font-variant-numeric: tabular-nums;
}
.sub-card input[type="number"] { width: 78px; text-align: right; }
.sub-card input[type="text"] { width: 100%; min-width: 120px; }
.sub-card input:hover, .sub-card select:hover { border-color: var(--text-3); }
.sub-card input:focus, .sub-card select:focus {
  outline: none;
  background: var(--card);
  border-color: var(--sky);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sky) 22%, transparent);
}
.sub-card input::placeholder { color: var(--text-3); }

/* The row under each group: add on the left, the counter and Save on the
   right, wrapping to two lines on a narrow screen instead of squeezing. */
.sh-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--border);
}
.sh-foot .grow { flex: 1 1 auto; }
.sh-foot .pend { font-size: 12px; color: var(--text-3); }
.sh-foot .inline {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--text-2);
}
/* width:auto MATTERS. The app's buttons are full-width by default, so Save
   rendered as a wide blue bar across the bottom of every group - louder than
   anything else on the page and nothing like a footer control. */
.sh-foot button {
  height: 30px; padding: 0 14px; border-radius: 7px; font-size: 13px;
  width: auto; flex: 0 0 auto;
}
.sh-foot button[disabled] { opacity: .45; cursor: default; }

.switchrow {
  display: flex; gap: 22px; align-items: center; flex-wrap: wrap;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);
}
.switchrow > label {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-2);
}
.switchrow label.chk { cursor: pointer; }
.switchrow input[type="checkbox"] { width: auto; height: auto; margin: 0; }

@media (max-width: 620px) {
  .sub-card { padding: 12px; }
  .shift-table th, .shift-table td { padding: 5px 6px; font-size: 12px; }
  .sub-card input[type="time"] { width: 118px; }
  .switchrow { gap: 10px; }
  .switchrow > label { width: 100%; justify-content: space-between; }
}

/* Actual hours is OURS and the punch report's is THEIRS, so they do not get
   equal visual weight - decisions.md 92. The one the system stands behind is
   the one that reads as the answer; the file's own figure sits beside it,
   quieter, so nobody mistakes the gap between them for a fault. */
.punch-table td.strong { font-weight: 600; color: var(--text); }
.punch-table th.strong { color: var(--text-2); }
.punch-table td.muted-col { color: var(--text-3); }

/* --------------------------------------------- the punch comparison columns
   Added with 0026. Every variable is one styles.css defines - the first punch
   block shipped with five invented names that dropped silently and would have
   painted a white header on a dark page.
*/

/* THE BAND ROW. "Hours" appears twice on this table meaning two different
   things - the system's and the file's - so the reader needs to know which
   is which before reading either. */
.punch-table tr.bands th {
  position: sticky; top: 0; z-index: 3;
  background: var(--card);
  border-bottom: 0;
  padding: 5px 10px 2px;
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-3);
  text-align: left;
}
.punch-table tr.bands th.band:not(.blank) {
  border-bottom: 2px solid var(--border-2);
}
.punch-table tr.bands th.blank { border-bottom: 0; }
/* the real header row sits below the bands, so it cannot start at 0 */
.punch-table thead tr:not(.bands) th { top: 22px; }

.punch-table td.shift, .punch-table th.shift { white-space: nowrap; }
.punch-table td.mins, .punch-table th.mins { white-space: nowrap; text-align: right; }

/* OVER, UNDER AND LEVEL. Semantic colour, separate from the accent: over is
   not "good" and under is not "bad" - both are just worth a look, which is
   why neither is green. */
.diff-over  { color: var(--amber); font-variant-numeric: tabular-nums; }
.diff-under { color: var(--sky);   font-variant-numeric: tabular-nums; }
.diff-level { color: var(--text-3); }

.punch-table .head-right,
.punches .card-head .head-right {
  display: inline-flex; align-items: center; gap: 10px;
}
.punches .card-head .head-right select {
  height: 26px; padding: 0 6px; font-size: 12px;
  border: 1px solid var(--border-2); border-radius: 6px;
  background: var(--card-2); color: var(--text);
}

/* ---------------------------------------------------------------- payroll upload (0042)
   The punch upload's row and preview, for Analytics > Payroll. Scoped to the
   page, as the punch ones are, so the global full-width .primary button does
   not stretch across the card. */
.payroll .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 10px 0; }
.payroll .row button.primary,
.payroll .row button.ghost { width: auto; flex: 0 0 auto; }
.payroll .preview {
  margin: 10px 0; padding: 10px 12px; border-radius: 8px;
  background: var(--card-2); border: 1px solid var(--border); font-size: 14px;
}
.payroll .preview p { margin: 4px 0; }
.payroll ul.tight { margin: 2px 0 6px 18px; font-size: 13px; color: var(--text-2); }

/* Settings > Workforce structure > Column mapping holds two lists since 0042 -
   the employee file's and the payroll file's - each under a small label. */
.cm-file {
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-3); margin: 22px 0 8px;
}
.cm-file:first-of-type { margin-top: 6px; }
.cmsuggest button.ghost.sm { margin-left: 8px; vertical-align: middle; }

/* ---------------------------------------------------------------- assistant (demo)
   decisions.md 114, 115. Laid out like other AI assistants (the owner,
   2026-10-06): a panel the height of the window, the conversation scrolling
   inside it, the question box fixed at its foot. app/assistant.js fit() sets
   the real height; the calc() below is only the first paint. Built only from
   the site's own colour tokens, so it follows light and dark like every other
   card. */
.content:has(> .asst-shell) { padding-bottom: 18px; }
.asst-shell {
  display: flex; flex-direction: column;
  height: calc(100vh - 210px); min-height: 440px;
  background: var(--card); border: 1px solid var(--border); border-radius: 14px;
  overflow: hidden;
}
.asst-shell .sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

.asst-top {
  flex: none; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 18px; border-bottom: 1px solid var(--border);
}
.asst-top h2 { font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.asst-scope { font-size: 12.5px; color: var(--text-3); }
.asst-spacer { flex: 1; }
.asst-top button.ghost:disabled { opacity: .5; cursor: default; color: var(--text-3); border-color: var(--border-2); }

.asst-scroll { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; }
.asst-col {
  flex: 1 0 auto; width: 100%; max-width: 800px; margin: 0 auto;
  padding: 26px 22px 18px; display: flex; flex-direction: column; gap: 24px;
}

/* the empty page: a greeting and four example questions */
.asst-empty { margin: auto; max-width: 640px; text-align: center; padding: 12px 0; }
.asst-empty h3 { font-size: 22px; font-weight: 700; letter-spacing: -.015em; text-wrap: balance; }
.asst-empty > p { color: var(--text-2); font-size: 14px; margin: 6px auto 0; max-width: 52ch; text-wrap: balance; }
.asst-starters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 24px; text-align: left; }
.asst-starter {
  display: flex; flex-direction: column; gap: 3px;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card-2); color: var(--text); cursor: pointer;
  font: inherit; font-size: 13.5px; line-height: 1.4; text-align: left;
}
.asst-starter:hover { border-color: var(--border-2); background: var(--card); box-shadow: var(--shadow); }
.asst-starter-area {
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3);
}

/* the conversation */
.asst-avatar { flex: none; width: 28px; height: 28px; border-radius: 8px; display: block; }
.asst-avatar.lg { width: 46px; height: 46px; border-radius: 12px; margin: 0 auto 14px; }
.asst-row { display: flex; gap: 12px; align-items: flex-start; }
.asst-row-user { justify-content: flex-end; }
.asst-bubble {
  max-width: min(78%, 620px); padding: 10px 15px;
  border-radius: 18px 18px 4px 18px;
  background: color-mix(in srgb, var(--sky) 13%, var(--card)); color: var(--text);
  font-size: 14.5px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere;
}
.asst-body { flex: 1 1 auto; min-width: 0; padding-top: 3px; font-size: 14.5px; line-height: 1.6; color: var(--text); }
.asst-body p { margin: 0 0 10px; }
.asst-body ul, .asst-body ol { margin: 0 0 10px 20px; padding: 0; }
.asst-body li { margin: 3px 0; }
.asst-body h4 { font-size: 14.5px; font-weight: 700; margin: 16px 0 6px; }
.asst-body h4:first-child { margin-top: 0; }
.asst-body code {
  font-family: var(--mono); font-size: 12.5px; padding: 1px 5px;
  background: var(--card-2); border: 1px solid var(--border); border-radius: 5px;
}
.asst-table { overflow-x: auto; margin: 2px 0 12px; border: 1px solid var(--border); border-radius: 10px; }
.asst-table table { font-size: 13.5px; font-variant-numeric: tabular-nums; }
.asst-table thead th {
  padding: 8px 12px; background: var(--card-2);
  font-size: 11px; letter-spacing: .05em;
}
.asst-table tbody td { padding: 8px 12px; }
.asst-table .num { text-align: right; }
.asst-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-top: 10px; font-size: 12px; color: var(--text-3);
}
/* Held back while the answer types out. Needed: display:flex above would
   otherwise beat the browser's own rule for [hidden]. */
.asst-meta[hidden] { display: none; }
/* A cursor at the end of the line being typed. */
.asst-text.typing > p:last-child::after,
.asst-text.typing > h4:last-child::after,
.asst-text.typing > ul:last-child > li:last-child::after,
.asst-text.typing > ol:last-child > li:last-child::after {
  content: ''; display: inline-block; width: 7px; height: 1.05em; margin-left: 3px;
  vertical-align: -3px; border-radius: 1px; background: var(--sky);
  animation: asst-caret 1s steps(1) infinite;
}
@keyframes asst-caret { 50% { opacity: 0; } }
.asst-tag { padding: 1px 9px; border-radius: 999px; border: 1px solid var(--border); background: var(--card-2); color: var(--text-2); }
.asst-tag.bad { border-color: color-mix(in srgb, var(--amber) 50%, var(--border)); color: var(--amber); }
.asst-copy {
  margin-left: auto; padding: 3px 8px; border: none; border-radius: 6px;
  background: none; color: var(--text-3); font: inherit; font-size: 12px; cursor: pointer;
}
.asst-copy:hover { background: var(--card-2); color: var(--text); }
.asst-err {
  flex: 1 1 auto; min-width: 0; padding: 10px 14px; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--rose) 40%, var(--border));
  background: color-mix(in srgb, var(--rose) 6%, var(--card));
  font-size: 14px; line-height: 1.5; color: var(--text);
}
.asst-err strong { color: var(--rose); }
.asst-wait { display: flex; align-items: center; gap: 10px; padding-top: 4px; font-size: 13.5px; color: var(--text-3); }
.asst-dots { display: inline-flex; gap: 4px; }
.asst-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--text-3); animation: asst-blink 1.2s infinite ease-in-out; }
.asst-dots i:nth-child(2) { animation-delay: .15s; }
.asst-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes asst-blink {
  0%, 80%, 100% { opacity: .25; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-2px); }
}

/* the question box */
.asst-foot { flex: none; padding: 6px 22px 12px; background: var(--card); }
.asst-box {
  max-width: 756px; margin: 0 auto;
  display: flex; align-items: flex-end; gap: 8px;
  padding: 7px 7px 7px 16px;
  border: 1px solid var(--border-2); border-radius: 18px;
  background: var(--card); box-shadow: var(--shadow);
}
.asst-box:focus-within { border-color: var(--sky); box-shadow: 0 0 0 3px var(--sky-soft), var(--shadow); }
.asst-box textarea {
  flex: 1 1 auto; min-width: 0; max-height: 200px; padding: 7px 0;
  border: none; outline: none; resize: none; overflow-y: auto;
  background: transparent; color: var(--text);
  font: inherit; font-size: 14.5px; line-height: 1.5;
}
.asst-box textarea::placeholder { color: var(--text-3); }
.asst-send {
  flex: none; width: 36px; height: 36px; padding: 0;
  display: grid; place-items: center;
  border: none; border-radius: 12px; cursor: pointer;
  background: var(--sky); color: var(--card);
}
.asst-send:hover { filter: brightness(1.08); }
.asst-send:disabled { background: var(--border); color: var(--text-3); cursor: default; filter: none; }
.asst-send:focus-visible, .asst-starter:focus-visible, .asst-copy:focus-visible {
  outline: 2px solid var(--sky); outline-offset: 2px;
}
.asst-send svg { width: 18px; height: 18px; }
.asst-fine {
  max-width: 756px; margin: 8px auto 0; text-align: center;
  font-size: 11.5px; line-height: 1.45; color: var(--text-3); text-wrap: balance;
}

@media (max-width: 720px) {
  .asst-col { padding: 18px 14px 14px; gap: 20px; }
  .asst-foot { padding: 6px 12px 10px; }
  .asst-top { padding: 10px 14px; }
  .asst-starters { grid-template-columns: 1fr; }
  .asst-bubble { max-width: 88%; }
}
@media (prefers-reduced-motion: reduce) {
  .asst-dots i { animation: none; opacity: .6; }
}

/* =====================================================================
   CENSUS (0045, decisions.md 120) - the layout settled on
   docs/census-mockup.html: units down the left, each day a column, today
   first, each unit opening to its day. Every colour is one of this file's
   own names; the punch styles once shipped five that did not exist.
   ===================================================================== */
.census-card { margin-bottom: 14px; }
.census-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 6px 16px; margin-bottom: 10px;
}
.census-head h2 { margin: 0; font-size: 16px; }
.census-tools { display: flex; gap: 8px; align-items: center; font-size: 13px; }

.census-today { display: flex; flex-wrap: wrap; gap: 12px; align-items: stretch; }
.census-big {
  display: flex; flex-direction: column; justify-content: center; min-width: 140px;
  padding: 10px 18px; border-radius: 10px; background: var(--sky-soft);
}
.census-big .num { font-size: 40px; font-weight: 700; line-height: 1.05; font-variant-numeric: tabular-nums; }
.census-big .lbl { font-size: 13px; color: var(--text-2); }
.census-big .chg { font-size: 12.5px; color: var(--text-3); margin-top: 2px; }
.census-chips { display: flex; flex-wrap: wrap; gap: 10px; flex: 1; }
.census-chip {
  display: flex; flex-direction: column; justify-content: center; min-width: 120px;
  padding: 10px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--card-2);
}
.census-chip .n { font-size: 22px; font-weight: 650; line-height: 1.1; font-variant-numeric: tabular-nums; }
.census-chip .u { font-size: 13px; color: var(--text-2); }
.census-chip .h { font-size: 12px; color: var(--text-3); font-style: italic; }
.census-bh { width: 100%; margin: 0; font-size: 13.5px; color: var(--text-2); font-style: italic; }

.census-alert { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }

/* ONE SCROLLER per table, so the day headings stay put while the rows move
   under them and the unit names stay put while the days scroll sideways. */
.census-scroll { overflow: auto; border: 1px solid var(--border); border-radius: 10px; }
.census-scroll.tall { max-height: 560px; }
.census-table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13.5px; }
.census-table th, .census-table td { padding: 6px 10px; white-space: nowrap; text-align: right; }
.census-table td { border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.census-table th {
  position: sticky; top: 0; z-index: 2; background: var(--card-2);
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-2); border-bottom: 1px solid var(--border); vertical-align: bottom;
}
.census-table th .dl { display: block; font-size: 10px; color: var(--text-3); }
.census-table th .dl.fixed { color: var(--sky); text-transform: none; letter-spacing: 0; }
.census-table th:first-child, .census-table td:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--card); text-align: left; min-width: 160px;
}
.census-table th:first-child { z-index: 3; background: var(--card-2); }
.census-table .c-today { background: var(--sky-soft); }
.census-table .c-gap   { background: var(--amber-soft); }
.census-table tr.census-g td { font-weight: 600; }
.census-table tr.census-g.total td { border-top: 2px solid var(--border-2); font-weight: 700; }
.census-tog {
  display: flex; align-items: center; gap: 6px; width: 100%; padding: 0; border: 0;
  background: none; color: inherit; font: inherit; font-weight: inherit; text-align: left; cursor: pointer;
}
.census-tog .chev { display: inline-block; width: 12px; color: var(--text-3); transition: transform .12s; }
.census-tog[aria-expanded="true"] .chev { transform: rotate(90deg); }
.census-tog .muted { font-weight: 400; font-size: 12px; }
.census-table tr.census-sub td { color: var(--text-2); font-size: 12.5px; padding-top: 4px; padding-bottom: 4px; }
.census-table tr.census-sub td:first-child { padding-left: 30px; }
.census-table tr.census-sub.end td { color: var(--text); font-weight: 600; }
.census-table tr.census-sub.it td { font-style: italic; color: var(--text-3); }
.census-table tr.hide { display: none; }
.census-table tr.census-act td { border-bottom: 0; padding-top: 8px; }
.census-pend { color: var(--text-3); font-style: italic; font-weight: 400; }

.census-range { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; }
.census-range input {
  height: 30px; padding: 0 8px; border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card-2); color: var(--text); font: inherit;
}
.census-sum { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 0 0 6px; font-size: 14px; }
.census-sum b { font-variant-numeric: tabular-nums; }
.census-avgnote {
  font-size: 13px; color: var(--text-2); margin: 0 0 10px; padding: 6px 10px;
  border-radius: 8px; background: var(--card-2); border: 1px solid var(--border);
}

.census-filerow { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 8px 0; }
.census-preview { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.census-preview p { margin: 0; }
.census-diff { border-collapse: collapse; font-size: 13px; }
.census-diff th, .census-diff td { padding: 4px 10px; border-bottom: 1px solid var(--border); text-align: left; }
.census-diff .num { text-align: right; font-variant-numeric: tabular-nums; }
.census-actions { display: flex; gap: 8px; justify-content: flex-end; align-items: center; margin-top: 4px; }

/* The correction form - the site's first dialog, so it is drawn here. */
.census-modal {
  position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(10, 14, 20, .45);
}
.census-modal .modal {
  background: var(--card); color: var(--text); border: 1px solid var(--border-2); border-radius: 12px;
  box-shadow: var(--shadow); padding: 18px; width: min(760px, 100%); max-height: calc(100vh - 32px); overflow: auto;
}
.census-modal h2 { margin: 0 0 6px; font-size: 17px; }
.census-fix { border-collapse: collapse; width: 100%; font-size: 13px; }
.census-fix th, .census-fix td { padding: 5px 6px; text-align: center; white-space: nowrap; }
.census-fix th { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-2); }
.census-fix .l { text-align: left; }
.census-fix .l .muted { font-size: 11px; white-space: normal; }
.census-fix input {
  width: 74px; height: 30px; padding: 0 6px; text-align: right; border: 1px solid var(--border-2);
  border-radius: 7px; background: var(--card-2); color: var(--text); font: inherit;
}
.census-fix input::placeholder { color: var(--text-3); opacity: .7; }
.census-fix tr.census-fix-b td { border-top: 2px solid var(--border-2); }
.census-why { display: flex; flex-direction: column; gap: 4px; margin: 12px 0 4px; font-size: 13px; color: var(--text-2); }
.census-rule1 { margin: 0 0 4px; font-size: 12.5px; color: var(--text-2); }
.census-why input {
  height: 32px; padding: 0 8px; border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card-2); color: var(--text); font: inherit;
}


/* ==========================================================================
   STAFFING LEVELS (0046, decisions.md 121) - Settings > Staffing levels.
   Each picker has its own look so they do not read as one row - the owner's
   first edit to the mock-up: GROUP = tabs across the card, WHERE = tiles,
   DAY = one joined bar, FILL FROM = radio choices. Every variable here is one
   this file defines.
   ========================================================================== */

.sl { display: flex; flex-direction: column; gap: 14px; }
.sl .sub { margin: 0; }

.sl-gtabs { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 2px solid var(--border); }
.sl-gtabs button {
  border: 0; background: none; padding: 8px 14px 9px; margin-bottom: -2px;
  border-bottom: 3px solid transparent; cursor: pointer; color: var(--text-3);
  display: flex; flex-direction: column; align-items: flex-start; font: inherit; text-align: left;
}
.sl-gtabs button b { font-size: 16.5px; font-weight: 650; }
.sl-gtabs button small { font-size: 11.5px; }
.sl-gtabs button:hover { color: var(--text-2); }
.sl-gtabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--sky); }
.sl-gtabs button[aria-selected="true"] small { color: var(--text-2); }

.sl-sect { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; border-top: 1px solid var(--border); }
.sl-sect.first { border-top: 0; padding-top: 0; }
.sl-sect-h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.sl-sect-t { font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--text-2); }
.sl-sect-h .muted { font-size: 13px; }

.sl-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(138px, 1fr)); gap: 8px; }
.sl-tile {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 9px 30px 9px 12px; border: 1px solid var(--border-2); border-radius: 8px;
  background: var(--card); color: var(--text); cursor: pointer; text-align: left; font: inherit;
}
.sl-tile b { font-size: 15px; }
.sl-tile small { font-size: 12px; color: var(--text-3); }
.sl-tile .kind { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--sky); }
.sl-tile:hover { border-color: var(--sky); }
.sl-tile[aria-pressed="true"] { border: 2px solid var(--sky); padding: 8px 29px 8px 11px; background: var(--sky-soft); }
.sl-tile[aria-pressed="true"]::after { content: "\2713"; position: absolute; top: 7px; right: 10px; color: var(--sky); font-weight: 700; }
.sl-tile.add { border-style: dashed; color: var(--text-2); justify-content: center; padding-right: 12px; }

.sl-panel {
  display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; font-size: 14px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); padding: 12px 14px;
}
.sl-panel label { display: inline-flex; gap: 5px; align-items: center; cursor: pointer; }
.sl-panel input[type="text"] {
  height: 32px; padding: 0 8px; border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card); color: var(--text); font: inherit; width: 170px;
}
.sl-panel-units, .sl-panel-act { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; }
.sl-panel .muted-note { flex-basis: 100%; margin: 0; }

.sl-versions { display: flex; flex-wrap: wrap; gap: 6px; }
.sl-ver {
  display: flex; flex-direction: column; align-items: flex-start; padding: 6px 12px; font: inherit; font-size: 13.5px;
  border: 1px solid var(--border-2); border-radius: 8px; background: var(--card); color: var(--text); cursor: pointer;
}
.sl-ver small { font-size: 11.5px; color: var(--text-3); }
.sl-ver.on { border-color: var(--text-2); background: var(--card-2); font-weight: 600; }

.sl-how { display: flex; flex-wrap: wrap; gap: 10px; }
.sl-how label {
  flex: 1 1 240px; display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--border-2); border-radius: 10px; background: var(--card); font-size: 13px; color: var(--text-2);
}
.sl-how label b { display: block; font-size: 14.5px; color: var(--text); }
.sl-how label.on { border-color: var(--sky); background: var(--sky-soft); }
.sl-how input { margin-top: 3px; }

.sl-eff, .sl-opts { display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center; font-size: 14px; }
.sl-eff label, .sl-opts label { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; }
.sl-eff input[type="date"], .sl-opts select {
  height: 32px; padding: 0 8px; border: 1px solid var(--border-2); border-radius: 7px;
  background: var(--card); color: var(--text); font: inherit;
}
.sl-num {
  width: 64px; height: 30px; padding: 0 6px; text-align: right; border: 1px solid var(--border-2);
  border-radius: 7px; background: var(--card); color: var(--text); font: inherit; font-variant-numeric: tabular-nums;
}

.sl-tablebox { overflow-x: auto; border: 1px solid var(--border); border-radius: 10px; }
.sl-table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13.5px; }
.sl-table th, .sl-table td { padding: 7px 9px; vertical-align: top; }
.sl-table th {
  background: var(--card-2); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-2); text-align: center; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.sl-table th .dl { display: block; font-size: 10.5px; color: var(--text-3); text-transform: none; letter-spacing: 0; font-weight: 500; }
.sl-table th:first-child, .sl-table td:first-child { text-align: left; position: sticky; left: 0; background: var(--card); z-index: 1; }
.sl-table th:first-child { background: var(--card-2); }
.sl-table td { border-bottom: 1px solid var(--border); text-align: center; font-variant-numeric: tabular-nums; }
.sl-table tbody tr:last-child td { border-bottom: 0; }
.sl-rowname { white-space: nowrap; font-weight: 600; }
.sl-rowname .dl { display: block; font-size: 11.5px; font-weight: 400; color: var(--text-3); }
.sl-cell { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 72px; }
.sl-calc { font-size: 12px; color: var(--text-3); white-space: nowrap; }
.sl-calc b { font-size: 18px; color: var(--text); font-weight: 650; }
.sl-in { font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
.sl-in input, .sl-rng input {
  width: 58px; height: 28px; padding: 0 5px; text-align: right; border: 1px solid var(--border-2);
  border-radius: 6px; background: var(--card); color: var(--text); font: inherit; font-size: 12.5px;
}
.sl-rng { display: inline-flex; gap: 4px; align-items: center; font-weight: 400; color: var(--text-2); }
.sl-rng input { width: 46px; }
.sl-tag {
  display: inline-block; font-size: 10.5px; padding: 0 6px; border-radius: 999px;
  border: 1px solid var(--amber); color: var(--amber); background: var(--amber-soft);
}
.sl-rmv { border: 0; background: none; color: var(--text-3); cursor: pointer; font-size: 17px; padding: 0 4px; }
.sl-rmv:hover { color: var(--rose); }

.sl-cbox { display: flex; flex-direction: column; gap: 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--card-2); padding: 12px; }
.sl-cbox-top { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.sl-daybar { display: flex; flex: 0 1 430px; border: 1px solid var(--border-2); border-radius: 7px; overflow: hidden; background: var(--card); }
.sl-daybar button {
  flex: 1 1 0; min-width: 38px; border: 0; border-left: 1px solid var(--border-2); background: none; padding: 6px 0;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--text-2); cursor: pointer;
}
.sl-daybar button:first-child { border-left: 0; }
.sl-daybar button:hover { background: var(--card-2); }
.sl-daybar button[aria-pressed="true"] { background: var(--text); color: var(--card); }
.sl-fill { display: flex; flex-wrap: wrap; gap: 6px 20px; align-items: center; border: 0; margin: 0; padding: 0; font-size: 14.5px; }
.sl-fill legend { float: left; padding: 0; margin-right: 4px; font-style: italic; color: var(--text-2); }
.sl-fill label { display: inline-flex; gap: 7px; align-items: center; cursor: pointer; }
.sl-fill input { width: 16px; height: 16px; accent-color: var(--sky); margin: 0; }
.sl-filled {
  display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; font-size: 13px; color: var(--text-2);
  background: var(--sky-soft); border-radius: 8px; padding: 8px 12px;
}

.sl-save { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; border-top: 1px solid var(--border); padding-top: 12px; }
.sl-save .grow { flex: 1; }
.sl-daybar button.none { color: var(--text-3); font-weight: 500; }
.sl-daybar button.none[aria-pressed="true"] { color: var(--card); }
.sl-daybar button:focus-visible { outline: 2px solid var(--sky); outline-offset: -3px; }
.sl button.ghost:disabled { opacity: .5; cursor: default; }
.sl .msg { margin: 0; }
.sl.sl-busy { opacity: .6; cursor: progress; }

/* =====================================================================
   DAILY STAFFING (0047, decisions.md 122) - the layout the owner chose,
   docs/daily-staffing-mockup-b.html. Every class is ds- prefixed: on the
   mock-up a box marked plain `open` borrowed another rule's orange.
   Over is RED, short is BLUE (the owner); the text is always coloured and
   the cell shaded only for a whole person or half a shift a day. Today
   has its own colour, violet, so it never reads as a header.
   ===================================================================== */
.ds { display: flex; flex-direction: column; gap: 14px; }
.ds-top { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.ds-top h1 { font-size: 20px; margin: 0; letter-spacing: -.01em; }
.ds-sub { color: var(--text-2); font-size: 14px; }
.ds-spacer { flex: 1; }
.ds-seg, .ds-week { display: inline-flex; align-items: center; border: 1px solid var(--border-2); border-radius: 10px; overflow: hidden; background: var(--card); }
.ds-seg button, .ds-week button { border: 0; background: transparent; padding: 6px 12px; cursor: pointer; font: inherit; font-size: 13.5px; color: var(--text-2); }
.ds-seg button[aria-pressed="true"] { background: var(--sky-soft); color: var(--sky); font-weight: 650; }
.ds-week span { padding: 6px 12px; border-left: 1px solid var(--border); border-right: 1px solid var(--border); font-size: 13.5px; font-weight: 600; }
.ds-week button:disabled { color: var(--border-2); cursor: default; }
.ds-seg button:focus-visible, .ds-week button:focus-visible, .ds-morebtn:focus-visible { outline: 2px solid var(--sky); outline-offset: -2px; }
.ds-loading { color: var(--text-3); font-size: 13px; margin: 0; }
.ds-building { font-size: 16px; margin: 10px 0 0; }
.ds-alert { background: var(--amber-soft); border: 1px solid color-mix(in srgb, var(--amber) 35%, var(--border)); border-radius: 12px;
            padding: 9px 14px; font-size: 13.5px; color: var(--text); }
.ds-alert b { color: var(--amber); }
.ds-boxes { display: flex; flex-direction: column; gap: 14px; }
.ds-box { background: var(--card); border: 1px solid var(--border-2); border-radius: 12px; box-shadow: var(--shadow); overflow: clip; }
.ds-title { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; padding: 10px 16px 8px; border-left: 5px solid var(--sky); }
.ds-hoursbox .ds-title { border-left-color: var(--text-2); }
.ds-name { font-size: 16px; font-weight: 700; }
.ds-meta { color: var(--text-3); font-size: 12.5px; }
.ds-chips { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.ds-chip { font-size: 12px; padding: 1px 9px; border-radius: 999px; border: 1px solid var(--border); white-space: nowrap; }
.ds-chip.ds-short { color: var(--sky); background: var(--sky-soft); }
.ds-chip.ds-over { color: var(--rose); background: var(--rose-soft); }
.ds-chip.ds-met { color: var(--emerald); background: var(--emerald-soft); }
.ds-scroll { overflow-x: auto; }
.ds-table { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 720px; font-size: 13.5px; }
.ds-table.ds-narrow { min-width: 420px; }
.ds-table th, .ds-table td { padding: 4px 9px; white-space: nowrap; line-height: 1.3; }
.ds-table thead th { background: color-mix(in srgb, var(--border) 45%, var(--card)); color: var(--text-2); font-size: 11px; font-weight: 650; letter-spacing: .03em;
                     text-transform: uppercase; text-align: right; border-bottom: 1px solid var(--border); }
.ds-table thead tr.ds-band th { text-align: center; font-size: 11.5px; color: var(--text); padding-top: 7px; border-bottom: 0; }
.ds-table th.ds-l, .ds-table td.ds-day { text-align: left; }
.ds-table td { text-align: right; font-variant-numeric: tabular-nums; border-bottom: 1px solid var(--border); vertical-align: top; }
.ds-table .ds-sep { border-left: 2px solid var(--border); }
.ds-h { display: block; font-size: 11px; color: var(--text-3); font-weight: 400; white-space: nowrap; }
.ds-day b { font-weight: 650; }
.ds-c { display: block; font-size: 11.5px; color: var(--text-3); white-space: nowrap; }
.ds-ea { min-width: 92px; }
.ds-e { color: var(--text-2); }
.ds-sl { color: var(--text-3); margin: 0 3px; }
.ds-ea b { font-weight: 650; }
.ds-diff { font-weight: 650; min-width: 58px; }
.ds-diff.ds-short { color: var(--sky); }
.ds-diff.ds-over { color: var(--rose); }
.ds-diff.ds-short.ds-shade { background: var(--sky-soft); }
.ds-diff.ds-over.ds-shade { background: var(--rose-soft); }
.ds-diff.ds-met { color: var(--emerald); }
.ds-diff.ds-none { color: var(--text-3); font-weight: 400; }
.ds-diff .ds-br { color: inherit; font-weight: 500; font-size: 10.5px; }
.ds-short, .ds-legend .ds-short { color: var(--sky); }
.ds-over, .ds-legend .ds-over { color: var(--rose); }
.ds-why { display: inline-block; font-size: 11px; font-style: normal; color: var(--amber); background: var(--amber-soft);
          border-radius: 6px; padding: 0 6px; margin-left: 6px; font-weight: 600; }
.ds-orient { color: var(--text-2); }
.ds-noout { color: var(--amber); }
.ds-notyet { color: var(--text-3); font-size: 12px; }
.ds-table tr.ds-dim td { background: color-mix(in srgb, var(--border) 40%, var(--card)); }
.ds-table tr.ds-today td { font-style: italic; background: color-mix(in srgb, var(--violet) 8%, var(--card)); }
.ds-table tr.ds-today td.ds-day { box-shadow: inset 4px 0 0 var(--violet); }
.ds-todaytag { display: inline-block; font-style: normal; font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
               color: var(--card); background: var(--violet); border-radius: 6px; padding: 1px 7px; margin-left: 6px; vertical-align: 1px; }
.ds-table tr.ds-tot td { font-weight: 700; background: color-mix(in srgb, var(--border) 45%, var(--card)); border-top: 2px solid var(--border-2); }
/* A QUICK SNAPSHOT FIRST (the owner): today and yesterday; the week on a click. */
.ds-box:not(.ds-expanded) tr.ds-older { display: none; }
.ds-table tr.ds-more td { padding: 0; border-bottom: 0; text-align: left; background: var(--card); }
.ds-morebtn { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: transparent; cursor: pointer;
              padding: 8px 14px; font: inherit; font-size: 13px; font-weight: 600; color: var(--sky); text-align: left; }
.ds-morebtn:hover { background: var(--sky-soft); }
.ds-chev { display: inline-block; transition: transform .15s; }
.ds-box.ds-expanded .ds-chev { transform: rotate(180deg); }
.ds-legend { font-size: 13px; color: var(--text-2); line-height: 1.6; max-width: 980px; }
.ds-legend b { color: var(--text); }
@media (prefers-reduced-motion: reduce) { .ds-chev { transition: none; } }
@media (max-width: 720px) { .ds-chips { margin-left: 0; } }
