/* ==========================================================================
   Haris Embroidery -- Factory Management System
   One stylesheet, no framework. Built to stay quick on the office machines.
   ========================================================================== */

:root {
  --ground:      #F0F3F7;
  --surface:     #FFFFFF;
  --surface-2:   #E3E9F0;
  --surface-3:   #D5E0E9;
  --ink:         #151C2C;
  --ink-2:       #3D4A5F;
  --muted:       #6C7889;
  --line:        #D2DBE6;
  --line-strong: #AEBECF;

  --accent:      #1D4E6B;
  --accent-ink:  #FFFFFF;
  --accent-soft: #DCE7ED;

  --ok:          #227059;
  --ok-soft:     #DFEEE8;
  --warn:        #A9720F;
  --warn-soft:   #F2E7D3;
  --bad:         #A83E44;
  --bad-soft:    #F2E0E1;

  --sidebar:     #0F1826;
  --sidebar-2:   #1A2537;
  --sidebar-ink: #E7ECF3;
  --sidebar-mut: #8593A8;

  --shadow-sm: 0 1px 2px rgba(10,16,28,.07);
  --shadow:    0 1px 2px rgba(10,16,28,.07), 0 8px 24px -18px rgba(10,16,28,.35);

  --display: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --sans: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Spline Sans Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --radius: 5px;
  --sidebar-w: 218px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:      #0E1420;
    --surface:     #161D2C;
    --surface-2:   #1E2738;
    --surface-3:   #283248;
    --ink:         #EAF0F6;
    --ink-2:       #C3CEDC;
    --muted:       #8D9BAF;
    --line:        #2A3448;
    --line-strong: #3C4A63;

    --accent:      #6FA8CB;
    --accent-ink:  #0B1622;
    --accent-soft: #1C3346;

    --ok:          #5FBE9E;  --ok-soft:   #173B30;
    --warn:        #D9A353;  --warn-soft: #3A2C12;
    --bad:         #E1878C;  --bad-soft:  #3A1E20;

    --sidebar:     #090E17;
    --sidebar-2:   #141C2A;
    --sidebar-ink: #E6ECF2;
    --sidebar-mut: #8595AC;

    --shadow-sm: 0 1px 2px rgba(0,0,0,.5);
    --shadow:    0 1px 2px rgba(0,0,0,.5), 0 8px 24px -18px rgba(0,0,0,.9);
  }
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 16.5px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .brand-name, .login-card h1, .doc-head .co {
  font-family: var(--display);
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

@media (prefers-reduced-motion: no-preference) {
  .btn, .nav a, .card, table.data tbody tr, .pill, .tabs a, .sidebar {
    transition: background-color .15s ease, border-color .15s ease,
                color .15s ease, box-shadow .15s ease, transform .22s ease;
  }
}

/* ==========================================================================
   Shell
   ========================================================================== */

.app { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); min-height: 100vh; }

.sidebar {
  background: var(--sidebar);
  color: var(--sidebar-ink);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--sidebar-mut) var(--sidebar);
}
.sidebar::-webkit-scrollbar { width: 8px; }
.sidebar::-webkit-scrollbar-track { background: var(--sidebar); }
.sidebar::-webkit-scrollbar-thumb {
  background: var(--sidebar-mut); border-radius: 4px;
  border: 2px solid var(--sidebar);
}
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--sidebar-ink); }

.brand {
  padding: 18px 18px 16px;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.brand-name {
  font-size: 20px; font-weight: 650; letter-spacing: -.01em;
  display: block; line-height: 1.25;
}
.brand-sub {
  font-family: var(--mono); font-size: 12px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--sidebar-mut); margin-top: 4px; display: block;
}

.nav { padding: 12px 10px 24px; flex: 1; }
.nav-group { margin-bottom: 16px; }
.nav-title {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--sidebar-mut);
  padding: 0 10px; margin: 0 0 6px;
}
.nav a {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; margin-bottom: 1px;
  color: var(--sidebar-ink); border-radius: 4px;
  font-size: 17.5px; text-decoration: none;
  border-left: 2px solid transparent;
}
.nav a:hover { background: var(--sidebar-2); text-decoration: none; }
.nav a.is-active {
  background: var(--sidebar-2);
  border-left-color: var(--accent);
  font-weight: 600;
}
.nav a .ico { width: 15px; text-align: center; opacity: .75; flex: none; }
.nav a.is-active .ico { opacity: 1; }

.sidebar-foot {
  padding: 12px 18px 16px;
  border-top: 1px solid rgba(255,255,255,.08);
  font-family: var(--mono); font-size: 13px; color: var(--sidebar-mut);
}

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 0 22px;
  height: 54px;
  display: flex; align-items: center; gap: 16px;
  position: sticky; top: 0; z-index: 20;
}
.topbar h1 { font-size: 22.5px; font-weight: 650; letter-spacing: -.015em; margin: 0; flex: none; }
.topbar .spacer { flex: 1; }

.quick-search { position: relative; }
.quick-search input[type="search"] {
  width: 250px; padding: 6px 10px 6px 32px;
  border: 1px solid var(--line); border-radius: 4px;
  background: var(--ground); color: var(--ink); font: inherit; font-size: 16px;
}
.quick-search::before {
  content: ""; position: absolute; left: 10px; top: 50%;
  width: 13px; height: 13px; transform: translateY(-50%);
  pointer-events: none;
  background-color: var(--muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.2' y2='16.2'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.2' y2='16.2'/%3E%3C/svg%3E") center / contain no-repeat;
}

.usermenu { position: relative; }
.usermenu > summary {
  display: flex; align-items: center; gap: 8px;
  font-size: 16px; color: var(--ink-2);
  list-style: none; cursor: pointer; user-select: none;
  padding: 4px 8px; border-radius: var(--radius);
  border: 1px solid transparent;
}
.usermenu > summary::-webkit-details-marker { display: none; }
.usermenu > summary:hover { background: var(--surface-2); }
.usermenu[open] > summary { background: var(--surface-2); border-color: var(--line); }
.usermenu .who { font-weight: 600; color: var(--ink); }
.usermenu .role {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 3px;
  padding: 1px 6px; color: var(--muted);
}
.usermenu[open] .role { background: var(--surface); }
.usermenu .caret { font-size: 11px; color: var(--muted); }
.usermenu-pop {
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 190px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 6px; z-index: 30;
  display: flex; flex-direction: column;
}
.usermenu-pop a {
  padding: 9px 12px; border-radius: 4px; color: var(--ink);
  text-decoration: none; font-size: 15px; white-space: nowrap;
}
.usermenu-pop a:hover { background: var(--surface-2); text-decoration: none; }

.content { padding: 22px; flex: 1; }
.content > *:first-child { margin-top: 0; }

/* ==========================================================================
   Page head, cards
   ========================================================================== */

.page-head {
  display: flex; align-items: flex-start; gap: 16px;
  flex-wrap: wrap; margin-bottom: 18px;
}
.page-head .titles { flex: 1; min-width: 220px; }
.page-head h2 { margin: 0 0 3px; font-size: 28px; font-weight: 650; letter-spacing: -.015em; }
.page-head p { margin: 0; color: var(--muted); font-size: 16.5px; }
.page-head .actions { display: flex; gap: 8px; flex-wrap: wrap; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  margin-bottom: 18px;
}
.card-head {
  padding: 13px 16px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.card-head h3 { margin: 0; font-size: 19.5px; font-weight: 650; }
.card-head .spacer { flex: 1; }
.card-body { padding: 16px; }
.card-body.tight { padding: 0; }
.card-foot {
  padding: 12px 12px 24px; border-top: 1px solid var(--line);
  background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius);
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}

/* ==========================================================================
   Stat tiles
   ========================================================================== */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px; margin-bottom: 18px;
}
.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 14px 16px; box-shadow: var(--shadow-sm);
}
.stat .k {
  font-family: var(--mono); font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); display: block; margin-bottom: 7px;
}
.stat .v {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 29.5px; font-weight: 600; letter-spacing: -.02em; line-height: 1.1;
  display: block; color: var(--ink);
}
.stat .n { font-size: 15px; color: var(--muted); display: block; margin-top: 6px; }
.stat.accent { border-color: var(--accent); }
.stat.accent .v { color: var(--accent); }
.stat.good .v { color: var(--ok); }
.stat.warn .v { color: var(--warn); }
.stat.bad  .v { color: var(--bad); }
.stat a { color: inherit; }

/* ==========================================================================
   Tables
   ========================================================================== */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.data {
  width: 100%; border-collapse: collapse; font-size: 17px;
}
table.data th {
  font-family: var(--mono); font-size: 12px; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted); font-weight: 500; text-align: left;
  padding: 10px 14px; border-bottom: 1px solid var(--line-strong);
  white-space: nowrap; background: var(--surface);
  position: sticky; top: 0; z-index: 1;
}
table.data td {
  padding: 9px 14px; border-bottom: 1px solid var(--line); vertical-align: sub;
}
table.data tbody tr:hover { background: var(--surface-2); }
table.data tbody tr.is-cancelled td { opacity: .55; text-decoration: line-through; }
table.data tfoot td {
  padding: 11px 14px; border-top: 2px solid var(--line-strong);
  font-weight: 650; background: var(--surface-2);
}
table.data .num, table.data td.num, table.data th.num {
  text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
table.data .mono { font-family: var(--mono); font-size: 15px; }
table.data .row-actions { text-align: right; white-space: nowrap; }
table.data .row-actions a { margin-left: 10px; font-size: 15px; }
table.data .row-actions a.act-danger { color: var(--bad); }

.empty {
  padding: 40px 20px; text-align: center; color: var(--muted); font-size: 16.5px;
}
.empty strong { display: block; color: var(--ink); font-size: 18.5px; margin-bottom: 5px; }

/* ==========================================================================
   Pills
   ========================================================================== */

.pill {
  display: inline-block; font-family: var(--mono);
  font-size: 11.5px; letter-spacing: .09em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 3px; white-space: nowrap;
  border: 1px solid transparent; font-weight: 500;
}
.pill.ok    { background: var(--ok-soft);    color: var(--ok);    border-color: var(--ok); }
.pill.warn  { background: var(--warn-soft);  color: var(--warn);  border-color: var(--warn); }
.pill.bad   { background: var(--bad-soft);   color: var(--bad);   border-color: var(--bad); }
.pill.muted { background: var(--surface-2);  color: var(--muted); border-color: var(--line-strong); }
.pill.dr    { background: var(--accent-soft);color: var(--accent);border-color: var(--accent); }
.pill.cr    { background: var(--ok-soft);    color: var(--ok);    border-color: var(--ok); }

.tag-manual {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--warn); border: 1px solid var(--warn); border-radius: 3px;
  padding: 0 4px; margin-left: 5px;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 15px; border-radius: 4px; font: inherit; font-size: 16.5px; font-weight: 600;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  cursor: pointer; text-decoration: none; white-space: nowrap;
}
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
}
.btn-primary:hover { background: var(--accent); filter: brightness(1.08); }
.btn-danger { border-color: var(--bad); color: var(--bad); }
.btn-danger:hover { background: var(--bad-soft); }
.btn-sm { padding: 4px 9px; font-size: 14.5px; }
.btn[disabled], .btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-group { display: inline-flex; gap: 6px; flex-wrap: wrap; }

/* ==========================================================================
   Forms
   ========================================================================== */

.form-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px 16px;
}
.form-grid.two  { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field.span-2 { grid-column: span 2; }
.field.span-all { grid-column: 1 / -1; }

label, .field > span.lbl {
  font-family: var(--mono); font-size: 12px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
}
label .req { color: var(--accent); }

input[type=text], input[type=number], input[type=date], input[type=password],
input[type=search], input[type=tel], select, textarea {
  width: 100%; padding: 7px 10px;
  border: 1px solid var(--line-strong); border-radius: 4px;
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: 17px;
}
input[type=number], input.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; }
input:disabled, select:disabled, input[readonly] {
  background: var(--surface-2); color: var(--muted); cursor: not-allowed;
}
textarea { min-height: 68px; resize: vertical; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: right 13px center, right 8px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 26px; }
.hint { font-size: 14px; color: var(--muted); }
.in-words { display: block; font-size: 13.5px; color: var(--muted); margin-top: 4px; font-style: italic; }
.in-words:empty { display: none; }
/* in a card-foot the fields share one flex-end row; let the compact reading
   float below the input instead of growing the field and breaking alignment */
.card-foot .field { position: relative; }
.card-foot .field > .in-words { position: absolute; top: 100%; left: 0; margin-top: 2px; }
/* inside a data grid the reading sits tight under the box so rows stay compact */
.data td > .in-words { font-size: 11px; margin-top: 1px; font-style: normal; letter-spacing: .01em; }
.checkline { display: flex; align-items: center; gap: 8px; }
.checkline label { text-transform: none; letter-spacing: 0; font-size: 16.5px; font-family: var(--sans); color: var(--ink); }
.checkline input { width: auto; }

fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; margin: 0 0 16px; }
legend { font-family: var(--mono); font-size: 12px; letter-spacing: .13em; text-transform: uppercase; color: var(--muted); padding: 0 6px; }

/* ==========================================================================
   Filter bar
   ========================================================================== */

.filters {
  display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
  padding: 12px 16px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); margin-bottom: 16px;
}
.filters .field { min-width: 140px; }
.filters .field.wide { min-width: 220px; }

/* ==========================================================================
   Flash + alerts
   ========================================================================== */

.flashes { margin-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }
.alert {
  padding: 10px 14px; border-radius: 4px; font-size: 16.5px;
  border: 1px solid var(--line); background: var(--surface); border-left-width: 3px;
}
.alert.success { border-left-color: var(--ok);   background: var(--ok-soft);   color: var(--ok); }
.alert.error   { border-left-color: var(--bad);  background: var(--bad-soft);  color: var(--bad); }
.alert.warning { border-left-color: var(--warn); background: var(--warn-soft); color: var(--warn); }
.alert.info    { border-left-color: var(--accent); }

.callout {
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  background: var(--surface); border-radius: 4px; padding: 12px 16px; margin-bottom: 16px;
}
.callout .lbl {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--accent); display: block; margin-bottom: 5px;
}
.callout p { margin: 0; font-size: 16.5px; }
.callout.warn { border-left-color: var(--warn); }
.callout.warn .lbl { color: var(--warn); }

/* ==========================================================================
   Bill entry grid
   ========================================================================== */

.bill-grid { width: 100%; border-collapse: collapse; font-size: 16px; }
.bill-grid th {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); font-weight: 500; text-align: left;
  padding: 8px 6px; border-bottom: 1px solid var(--line-strong); white-space: nowrap;
}
.bill-grid td { padding: 3px 4px; border-bottom: 1px solid var(--line); vertical-align: sub; }
.bill-grid .in-words { font-size: 11px; margin-top: 1px; font-style: normal; letter-spacing: .01em; }
.bill-grid input, .bill-grid select {
  padding: 5px 7px; font-size: 16px; border-radius: 3px; border-color: var(--line);
}
.bill-grid .out {
  font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right;
  padding-right: 8px; color: var(--ink-2); white-space: nowrap;
}
.bill-grid .out.amount { font-weight: 600; color: var(--ink); }
.bill-grid tr.is-empty .out { color: var(--muted); }
.bill-grid .sr { color: var(--muted); font-family: var(--mono); font-size: 13.5px; text-align: center; width: 30px; }
.bill-grid .del {
  border: none; background: none; color: var(--muted); cursor: pointer;
  font-size: 18.5px; line-height: 1; padding: 2px 5px; border-radius: 3px;
}
.bill-grid .del:hover { color: var(--bad); background: var(--bad-soft); }

.col-w-sm  { width: 78px; }
.col-w-md  { width: 104px; }
.col-w-lg  { width: 132px; }

.bill-totals {
  display: grid; grid-template-columns: 1fr auto; gap: 6px 24px;
  margin-left: auto; max-width: 360px; font-size: 16.5px;
}
.bill-totals dt { color: var(--muted); }
.bill-totals dd {
  margin: 0; font-family: var(--mono); font-variant-numeric: tabular-nums;
  text-align: right; font-weight: 600;
}
.bill-totals .grand dt, .bill-totals .grand dd {
  border-top: 1px solid var(--line-strong); padding-top: 7px; margin-top: 3px;
  font-size: 19.5px; color: var(--accent);
}

/* Short K/M form shown under a full amount (bill lines + totals, salary). */
.amt-k {
  display: block; font-size: 11px; font-weight: 400; line-height: 1;
  color: var(--muted); margin-top: 2px; letter-spacing: .01em;
}
.bill-totals .grand dd .amt-k { font-size: 12px; }
table.data td.num .amt-k { text-align: right; }

/* ==========================================================================
   Ledger / statement
   ========================================================================== */

table.ledger td.debit  { color: var(--accent); }
table.ledger td.credit { color: var(--ok); }
table.ledger tr.opening td { background: var(--surface-2); font-weight: 600; }
table.ledger tr.closing td { border-top: 2px solid var(--line-strong); font-weight: 650; background: var(--surface-2); }

.balance-big {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 31.5px; font-weight: 600; letter-spacing: -.02em;
}
.balance-big.dr { color: var(--accent); }
.balance-big.cr { color: var(--ok); }

/* ==========================================================================
   Aging bar
   ========================================================================== */

.aging { display: flex; height: 26px; border-radius: 4px; overflow: hidden; border: 1px solid var(--line); }
.aging span { display: block; height: 100%; }
.aging .b0 { background: var(--ok); }
.aging .b1 { background: #7FA05A; }
.aging .b2 { background: var(--warn); }
.aging .b3 { background: var(--accent); }
.aging-key { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 9px; font-size: 14.5px; color: var(--muted); }
.aging-key i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }

/* ==========================================================================
   Pagination + misc
   ========================================================================== */

.pager { display: flex; gap: 5px; align-items: center; justify-content: flex-end; padding: 12px 16px; flex-wrap: wrap; }
.pager a, .pager span {
  padding: 4px 9px; border: 1px solid var(--line); border-radius: 3px;
  font-family: var(--mono); font-size: 14.5px; color: var(--ink-2); text-decoration: none;
}
.pager .is-current { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.pager .count { border: none; color: var(--muted); margin-right: auto; padding-left: 0; }

.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: 16px; flex-wrap: wrap; }
.tabs a {
  padding: 8px 14px; font-size: 16.5px; color: var(--ink-2); text-decoration: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs a:hover { color: var(--accent); text-decoration: none; }
.tabs a.is-active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

.kv { display: grid; grid-template-columns: auto 1fr; gap: 7px 18px; font-size: 16.5px; }
.kv dt { font-family: var(--mono); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); align-self: center; }
.kv dd { margin: 0; }

.muted { color: var(--muted); }
.right { text-align: right; }
.mono  { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.stack { display: flex; flex-direction: column; gap: 3px; }
.stack small { color: var(--muted); font-size: 14px; }
.inline-form { display: inline; }

/* ==========================================================================
   Login
   ========================================================================== */

.login-wrap {
  min-height: 100vh; display: grid; place-items: center; padding: 24px;
  background: var(--sidebar);
}
.login-card {
  width: 100%; max-width: 370px; background: var(--surface);
  border-radius: 7px; padding: 30px 30px 26px; box-shadow: 0 20px 60px -20px rgba(0,0,0,.6);
}
.login-card h1 { margin: 0 0 3px; font-size: 28px; font-weight: 650; letter-spacing: -.015em; }
.login-card .sub {
  font-family: var(--mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 22px;
}
.login-card .field { margin-bottom: 14px; }
.login-card .btn { width: 100%; margin-top: 6px; padding: 9px; }

/* Salary grid rows just filled in from an uploaded sheet -- tinted so the
   operator can see at a glance which days the upload touched before saving. */
tr.salary-day.is-imported > td { background: var(--ok-soft); }
tr.salary-day.is-imported > td:first-child { box-shadow: inset 3px 0 0 var(--ok); }

/* A locked row reopened with the Edit button. It is the one row on the page
   whose saved figures will be replaced on Save, so it is marked clearly. */
tr.salary-day.is-editing > td { background: var(--warn-soft, var(--accent-soft)); }
tr.salary-day.is-editing > td:first-child { box-shadow: inset 3px 0 0 var(--warn, var(--accent)); }
tr.salary-day .s-actions { text-align: right; }
tr.salary-day .s-actions .btn { padding: 2px 8px; font-size: 12px; }

/* ==========================================================================
   Print
   ========================================================================== */

.print-only { display: none; }

@media print {
  /* One margin, not two: .doc's own border and 26px/30px padding are zeroed
     below, so this is the only margin a printed page gets. Top is 0 and the
     other three sides keep their normal amount (top right bottom left). */
  @page { size: A4; margin: 0 10mm 0 10mm; }

  .sidebar, .topbar, .no-print, .filters, .pager, .btn, .tabs { display: none !important; }
  .app { display: block; }
  .content { padding: 0; }
  .print-only { display: block; }

  body { background: #fff; color: #000; font-size: 11px; }
  .card { border: none; box-shadow: none; margin: 0; }
  .card-head, .card-foot { display: none; }
  .card-body { padding: 0; }

  table.data, table.ledger { font-size: 10.5px; }
  /* .print-doc is excluded from the flat 10.5px above and scaled instead:
     it is the one table that appears inside a .doc, where the A-/A+ buttons
     have to reach it on paper exactly as they do on screen. 3/4 of the
     default --doc-fs is the same 10.5px it printed at before. */
  table.print-doc { font-size: calc(var(--doc-fs) * 3 / 4); }
  table.data th, table.print-doc th {
    background: #f0f0f0 !important; color: #000; position: static;
    border-bottom: 1px solid #000; -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  table.data td, table.print-doc td { border-bottom: 1px solid #ddd; }
  thead { display: table-header-group; }
  tr { page-break-inside: avoid; }

  a { color: #000; text-decoration: none; }
  .pill { border: 1px solid #666; color: #000; background: none; }
}

/* ---- Printed documents (bill, receipt, gate pass, statement) ------------- */

/* Text size on a printed document. The A-/A+ buttons in the print toolbar
   write this back onto .doc as an inline style, and every size below is a
   multiple of it, so the whole document scales as one piece instead of the
   text outgrowing a layout measured in fixed pixels.

   The multipliers are exact fractions of 14 rather than rounded decimals, so
   at the default each one lands on precisely the size it always was -- 29/28
   is 14.5px, not 14.4998px. Bills, ledger and lender statements share these
   rules, so "unchanged at the default" has to hold for them too.

   Multiples of --doc-fs and NOT nested `em`: several of these blocks sit
   inside .doc-meta, which sets its own 15px, and an em there would compound
   into 15px * 1.036 rather than the 14.5px intended. */
.doc {
  --doc-fs: 14px;

  background: var(--surface); color: var(--ink);
  max-width: 800px; margin: 0 auto 18px; padding: 26px 30px;
  border: 1px solid var(--line); border-radius: var(--radius);
}

/* Nothing on a document may run past its content box at any text size: a
   value with nowhere left to wrap breaks rather than overflowing, and every
   grid and flex child is told it may shrink. A grid item defaults to
   min-width:auto, and that default is what normally pushes wide content out
   through the side of the page.

   `break-word` and not `anywhere`: both break a word that genuinely cannot
   fit, but `anywhere` also lets a column claim it can be one character wide,
   which stacks a name up letter by letter long before the space has actually
   run out. `word-wrap` is the same property under its old name, and is the
   spelling Dompdf acts on -- harmless here, and it keeps the screen rule and
   the PDF rule reading alike. */
.doc, .doc * { min-width: 0; overflow-wrap: break-word; word-wrap: break-word; }

.doc-head { text-align: center; border-bottom: 2px solid var(--ink); padding-bottom: 12px; margin-bottom: 14px; }
.doc-head .co { font-size: calc(var(--doc-fs) * 27 / 14); font-weight: 700; letter-spacing: .03em; margin: 0; }
.doc-head .city { font-size: calc(var(--doc-fs) * 29 / 28); color: var(--muted); letter-spacing: .18em; text-transform: uppercase; margin: 3px 0 0; }
.doc-head .sub  { font-size: calc(var(--doc-fs) * 27 / 28); color: var(--muted); margin: 4px 0 0; }
.doc-head .title2 { font-size: calc(var(--doc-fs) * 33 / 28); font-weight: 700; margin: 8px 0 0; }
.doc-head .kind {
  display: inline-block; font-family: var(--mono);
  font-size: calc(var(--doc-fs) * 6 / 7); letter-spacing: .18em; text-transform: uppercase;
  border: 1px solid var(--ink); padding: 2px 10px; border-radius: 3px; margin-top: 8px;
}

.doc-meta {
  display: grid; grid-template-columns: 1fr auto; gap: 6px 26px;
  font-size: calc(var(--doc-fs) * 15 / 14); margin-bottom: 14px;
}
.doc-meta .row { display: flex; gap: 8px; line-height: 1.4; }
.doc-meta .k { color: var(--muted); min-width: 68px; }
.doc-meta .v { font-weight: 600; }

/* Fixed layout over the percentage widths stated on each table's header cells
   in the print views. This is what keeps a document on the paper as the text
   size goes up: the columns are shares of the sheet, so a row can only ever
   grow taller. An auto-layout table does the opposite -- it widens to fit its
   widest cell, and there is no width it will not take. */
table.print-doc { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: calc(var(--doc-fs) * 29 / 28); }
table.print-doc th {
  font-size: calc(var(--doc-fs) * 23 / 28); letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
  text-align: left; padding: 6px 7px; border-bottom: 1px solid var(--ink); background: var(--surface-2);
}
table.print-doc td { padding: 2px 7px; border-bottom: 1px solid var(--line); }
/* No `nowrap` on the figures. It reads better when it fits, but inside a fixed
   column it is the one thing that can still shove content out through the side
   of the page: a number that may not wrap has nowhere to go but out. The
   columns are sized so nothing wraps at ordinary sizes anyway -- this only
   comes into play once the text has been made genuinely large, and there a
   wrapped figure beats half a figure. */
table.print-doc .num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }

.doc-totals { margin-top: 14px; margin-left: auto; width: 290px; max-width: 100%; font-size: calc(var(--doc-fs) * 8 / 7); }
.doc-totals .line { display: flex; justify-content: space-between; gap: 12px; }
.doc-totals .line .v { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }
.doc-totals .line.total { border-top: 2px solid var(--ink); margin-top: 5px; padding-top: 2px; font-size: calc(var(--doc-fs) * 31 / 28); }

/* Two small pieces of document furniture that used to be inline `style=`
   attributes on the views. They are classes now because those views are also
   rendered by Dompdf for the PDF, and Dompdf cannot resolve a custom property
   -- an inline calc(var(--doc-fs) ...) silently collapsed to the inherited
   size there, so the ledger and lender statements came out subtly different
   from the printed page. Stated once per stylesheet, each engine gets a value
   it can actually read. */
.doc-note { margin-top: 18px; font-size: calc(var(--doc-fs) * 6 / 7); }
.doc-sub  { text-align: center; font-size: calc(var(--doc-fs) * 15 / 14); margin: 0 0 16px; }

.doc-sign { display: flex; justify-content: space-between; gap: 16px; margin-top: 46px; font-size: var(--doc-fs); color: var(--muted); }
.doc-sign span { border-top: 1px solid var(--line-strong); padding-top: 5px; min-width: 170px; text-align: center; }

/* ---- Salary slips ------------------------------------------------------- */

/* Explicit, not left to inherit body's 1.65: a paragraph's line-height is far
   more generous than a dense, many-row grid needs, and -- because nothing on
   the slip set its own -- Dompdf's PDF was filling in its own guess for
   "normal" instead, a different number from whatever the browser assumed.
   That per-element gap between "whatever each engine defaults to" is what let
   a slip that printed on one page from the browser come back as two pages
   from "Save as PDF" at the very same chosen text size. One explicit number,
   read by both stylesheets, is what makes the two agree on how tall a row is
   and therefore how many pages a given size needs.

   Scoped to .doc-slip/.doc-slip-fixed -- the two classes the salary slip
   alone carries -- rather than put on .doc itself, which bills, ledger and
   lender statements share: touching that would have shrunk the line spacing
   on documents nobody asked to change here. */
.doc-slip, .doc-slip-fixed { line-height: 1.3; }

/* Variable slip: full day-by-day table, kept compact so a month fits one A4. */
.doc-slip .doc-meta { margin-bottom: 10px; gap: 4px 26px; }
/* Fixed layout over the percentage widths stated on the header cells in
   views/salary/print_combined.php. This is what makes the "never cut off"
   promise hold for the widest thing on the slip: the columns are shares of
   the sheet, so raising the text size makes rows taller, never wider. */
.slip-day-table { margin-top: 10px; table-layout: fixed; }
.slip-day-table td, .slip-day-table th { padding: 3px 7px; font-size: calc(var(--doc-fs) * 27 / 28); }
.slip-day-table tr.slip-off td, .slip-day-table tr.slip-off td { color: var(--muted); }
/* Zebra striping: every second data row gets a light background so a long
   month's worth of rows stays easy to track across eleven columns. Kept off
   thead/tfoot (nth-child counts tbody's own rows, not the table's) and given
   the print-color-adjust pair so it survives to paper without the reader
   having to turn on the browser's own "background graphics" print option. */
.slip-day-table tbody tr:nth-child(even) td {
  background: var(--surface-2);
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.slip-day-table tfoot td { border-top: 2px solid var(--ink); }
.slip-day-table .doc-pill { font-size: calc(var(--doc-fs) * 19 / 28); padding: 0 4px; letter-spacing: .04em; }
.doc-slip .doc-totals { margin-top: 10px; }
/* Inside a fixed column, a value that may not wrap is the one thing that can
   still shove content out through the side of the page -- so the money
   columns, and the date/shift/bonus cells marked .nowrap, give up nowrap here
   and are allowed to break. A wrapped figure is ugly; half a figure is wrong. */
.slip-day-table .num, .slip-day-table .nowrap { white-space: normal; }
/* The 2.5x / Hol 2.5x badge shares the Day column with the weekday, and at the
   largest sizes it no longer fits beside it. Letting it wrap puts it on the
   next line; keeping it nowrap would hang it off the edge of the page. */
.slip-day-table .doc-pill { white-space: normal; }

/* Fixed slip: centred, one-row-per-line table, sized to sit in the top half
   of an A4 with the lower half left blank. */
.doc.doc-slip-fixed { max-width: 560px; }
.doc.doc-slip-fixed .doc-meta { margin-bottom: 12px; }
/* The one .print-doc table left on auto layout: two columns of short label /
   figure pairs inside a 560px sheet, with no header row to hang widths on.
   It has room to spare at every size the buttons offer. */
.slip-table { width: 100%; table-layout: auto; margin: 16px 0 6px; border: 1px solid var(--ink); }
.slip-table td { padding: 8px 12px; border-bottom: 1px solid var(--line); font-size: calc(var(--doc-fs) * 29 / 28); }
.slip-table tr:last-child td { border-bottom: none; }
.slip-table td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.slip-table tr.slip-table-final td {
  border-top: 2px solid var(--ink); font-weight: 700; font-size: calc(var(--doc-fs) * 8 / 7);
}
.slip-adv-note { text-align: center; color: var(--muted); font-size: calc(var(--doc-fs) * 25 / 28); margin: 10px 0 0; }

/* Variable slip footer: the advance outstanding box on the left, the money
   totals on the right. Laid out with a table rather than flexbox so the
   browser, the printer and dompdf (PDF) all render it the same way. */
/* Trimmed from 12px: the footer is a single, unsplittable row (it holds the
   advance box and the totals side by side), so if it doesn't fit in whatever
   is left at the bottom of the day grid's page, the whole thing moves to a
   fresh page rather than being allowed to break -- exactly the gap that was
   turning a slip which printed on one page into two from "Save as PDF" at
   small text sizes, where the grid itself easily fit but this margin alone
   was enough to push the footer over the edge. */
.slip-foot { width: 100%; table-layout: fixed; border-collapse: collapse; margin-top: 8px; }
.slip-foot > tbody > tr > td { padding: 0; border: none; vertical-align: top; }
/* Shares of the sheet rather than a pair of fixed pixel widths: both halves
   grow with the text, and two fixed widths would sooner or later add up to
   more than the slip and push the totals off the edge. */
.slip-foot .slip-foot-adv { width: 44.5%; padding-right: 26px; }
.slip-foot .doc-totals { margin: 0 0 0 auto; width: 82%; }
/* FINAL TO PAY gets a rule under it to match the one above, then breathing
   room before whatever follows. */
.slip-foot .doc-totals .line.total {
  border-bottom: 2px solid var(--ink); padding-bottom: 2px; margin-bottom: 20px;
}

.slip-adv-box { width: 100%; border-collapse: collapse; border: 1px solid var(--ink); }
.slip-adv-box th {
  font-size: calc(var(--doc-fs) * 23 / 28); letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
  text-align: left; padding: 5px 8px; border-bottom: 1px solid var(--ink);
  background: var(--surface-2);
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.slip-adv-box td { padding: 5px 8px; font-size: calc(var(--doc-fs) * 29 / 28); }
.slip-adv-box tr.sep td { border-top: 1px solid var(--line); }
.slip-adv-box td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 600; }

@media print {
  /* `@page` above already gives the page its one margin, so .doc's own card
     border and 26px/30px padding are removed here rather than kept -- kept,
     they used to stack a second margin on top of @page's and draw a border
     around the printed page, neither of which belongs on paper. Removing them
     doesn't narrow anything a column depends on: every width in this
     stylesheet is a percentage of .doc's own content box, so less padding
     only ever hands the table more room, never less. */
  .doc {
    max-width: 100%; margin: 0; padding: 0;
    border: none; border-radius: 0; box-shadow: none;
  }
  .doc.doc-slip-fixed { max-width: 560px; margin: 0 auto; border: none; min-height: 140mm; page-break-after: avoid; }
  /* Tighter on paper than on screen, but still driven by --doc-fs: these
     used to be flat 11px/12px, which quietly cancelled the chosen text size
     the moment the slip was actually printed. The fractions land on those
     same two sizes at the default. */
  .slip-day-table td, .slip-day-table th { padding: 2px 5px; font-size: calc(var(--doc-fs) * 11 / 14); }
  .slip-table td { padding: 6px 10px; font-size: calc(var(--doc-fs) * 6 / 7); }
  .slip-foot { page-break-inside: avoid; }
}

/* A badge just like .pill, but its own class so the @media print rule that
   flattens .pill to grayscale (for the app's regular list pages) doesn't
   also grey out the ledger/bill documents -- those should stay colourful,
   on screen, on paper, and in the generated PDF. */
.doc-pill {
  display: inline-block; font-family: var(--mono);
  font-size: calc(var(--doc-fs) * 3 / 4); letter-spacing: .08em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 3px; white-space: nowrap;
  border: 1px solid transparent; font-weight: 600;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.doc-pill.dr    { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.doc-pill.cr    { background: var(--ok-soft);     color: var(--ok);     border-color: var(--ok); }
.doc-pill.bad   { background: var(--bad-soft);    color: var(--bad);    border-color: var(--bad); }
.doc-pill.muted { background: var(--surface-2);   color: var(--muted);  border-color: var(--line-strong); }

table.print-doc td.debit  { color: var(--accent); }
table.print-doc td.credit { color: var(--ok); }
.bal-dr { color: var(--accent); }
.bal-cr { color: var(--ok); }

/* ==========================================================================
   Mobile nav (hamburger + off-canvas drawer)
   ========================================================================== */

.nav-toggle {
  display: none;
  align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  border: 1px solid var(--line-strong); border-radius: 4px;
  background: var(--surface); color: var(--ink);
  cursor: pointer; padding: 0;
}
.nav-toggle:hover { background: var(--surface-2); }
.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  display: block; width: 16px; height: 2px; border-radius: 1px;
  background: currentColor; position: relative;
}
.nav-toggle-bars::before { content: ""; position: absolute; top: -5px; }
.nav-toggle-bars::after  { content: ""; position: absolute; top: 5px; }

/* ==========================================================================
   Topbar "back" button
   ========================================================================== */

.topbar-back {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  border: 1px solid var(--line-strong); border-radius: 4px;
  background: var(--surface); color: var(--ink);
  cursor: pointer; padding: 0; font-size: 18px; line-height: 1;
}
.topbar-back > span { padding: 0 0 2px; }
.topbar-back:hover { background: var(--surface-2); }

/* ==========================================================================
   Desktop sidebar collapse (persisted in localStorage, see app.js)
   ========================================================================== */

/* A slim vertical tab clinging to the sidebar's outer (right) edge, near the
   bottom. Sits outside the sidebar so it stays put when the sidebar collapses. */
.sidebar-collapse-btn {
  position: fixed;
  bottom: 24px;
  left: var(--sidebar-w);
  z-index: 40;
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 18px; height: 60px; flex: none;
  border: 1px solid rgba(255,255,255,.18); border-left: 0;
  border-radius: 0 6px 6px 0;
  background: var(--sidebar-2); color: var(--sidebar-ink);
  cursor: pointer; padding: 0; font-size: 15px; line-height: 1;
  transition: left .15s ease, background .15s ease;
}
.sidebar-collapse-btn:hover { background: var(--sidebar); }

@media (min-width: 901px) {
  html.sidebar-collapsed .app { grid-template-columns: 0 minmax(0, 1fr); }
  html.sidebar-collapsed .sidebar {
    width: 0; min-width: 0; padding: 0; border: 0; overflow: hidden; visibility: hidden;
  }
  html.sidebar-collapsed .sidebar-collapse-btn { left: 0; }
}

.sidebar-backdrop {
  position: fixed; inset: 0; z-index: 29;
  background: rgba(15, 10, 12, .5);
  opacity: 0; visibility: hidden;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.app.nav-open .sidebar-backdrop {
  opacity: 1; visibility: visible;
  transition: opacity .2s ease, visibility 0s linear 0s;
}

/* ==========================================================================
   Narrow screens (tablet and below -- sidebar becomes a drawer)
   ========================================================================== */

@media (max-width: 900px) {
  .app { grid-template-columns: minmax(0, 1fr); }
  .nav-toggle { display: inline-flex; }
  .sidebar-collapse-btn { display: none; }

  .sidebar {
    position: fixed; top: 0; left: 0; z-index: 30;
    width: min(260px, 84vw); height: 100vh;
    transform: translateX(-100%);
    box-shadow: var(--shadow);
  }
  .app.nav-open .sidebar { transform: translateX(0); }
  body.nav-open { overflow: hidden; }

  .nav { display: block; padding-top: 14px; }
  .nav-group { margin-bottom: 14px; }
  .nav a { padding: 10px 12px; font-size: 17px; }

  .topbar { flex-wrap: wrap; height: auto; min-height: 54px; padding: 10px 14px; row-gap: 8px; }
  .quick-search { order: 3; flex: 1 1 100%; }
  .quick-search input { width: 100%; }
  .content { padding: 14px; }
}

/* ==========================================================================
   Phones
   ========================================================================== */

@media (max-width: 560px) {
  .topbar h1 { font-size: 19px; }
  .usermenu .role { display: none; }

  .page-head { flex-direction: column; align-items: stretch; }
  .page-head .actions { width: 100%; }
  .page-head .actions .btn { flex: 1; }

  .filters { flex-direction: column; align-items: stretch; padding: 12px; }
  .filters .field, .filters .field.wide { min-width: 0; width: 100%; }
  .filters > .btn, .filters > a.btn { width: 100%; }

  .stats { grid-template-columns: 1fr 1fr; }
  .stat { padding: 12px 14px; }
  .stat .v { font-size: 23px; }

  .card-head { padding: 12px 14px; }
  .card-body { padding: 14px; }
  .card-foot { padding: 12px 14px; }
  .card-foot .btn { flex: 1; }

  table.data th, table.data td { padding: 8px 10px; }

  .doc { padding: 18px 16px; }
  .doc-meta { grid-template-columns: 1fr; }
  .doc-sign { flex-direction: column; gap: 20px; }
  .doc-sign span { min-width: 0; }

  .btn { min-height: 38px; }
  input[type=text], input[type=number], input[type=date], input[type=password],
  input[type=search], input[type=tel], select, textarea {
    font-size: 19.5px; /* keeps iOS from zooming in on focus */
  }
}
