/* Kiwi application styles.
 * Extracted from views/partials/header.ejs, where this block was inlined into
 * every HTML response and could not be cached. Served fingerprinted from
 * public/ - see assetUrl() in src/app.js.
 */

:root {
  color-scheme: light;
  --bg: #f4f6f8;
  --panel: #ffffff;
  --ink: #1f2937;
  /* Measured with axe on every authenticated route: #6b7280 on --bg #f4f6f8 is
     4.46:1, below the 4.5:1 that WCAG 2.1 AA asks of body text, and 4.38:1 on the
     attention tile's warm tint. The token itself was the failure, so the token
     moved. #636a78 keeps the same hue and measures 5.02:1 on --bg, 4.79:1 on the
     darkest surface muted text ever sits on. */
  --muted: #636a78;
  --accent: #1f7a52;
  --accent-strong: #176543;
  --accent-soft: rgba(31, 122, 82, 0.08);
  --border: #d8dee6;
  --border-strong: #c3ccd7;
  --surface: #f8fafc;
  --danger: #9b2c2c;
  --danger-strong: #b42318;
  --warning: #c27a00;
  --danger-soft: rgba(155, 44, 44, 0.08);
  --danger-border: rgba(155, 44, 44, 0.2);
  --warning-soft: rgba(194, 122, 0, 0.09);
  --warning-border: rgba(194, 122, 0, 0.38);
  --state-active-bg: #e6f4ec;
  --state-active-border: #cce7d8;
  --state-inactive-bg: #eef2f6;
  --state-inactive-color: #475467;
  --state-terminated-bg: #fef0f0;
  --state-terminated-border: #f6d0d2;
  --state-pass-bg: #f6fbf8;
  --state-fail-bg: #fff7f7;
  --state-fail-border: #f0c9cc;
  --review-danger-bg: #fff4f3;
  --review-danger-border: #f1c3c0;
  --review-danger-color: #8f1d18;
}
* { box-sizing: border-box; }
/* Always reserve the vertical scrollbar gutter so page width is identical whether
   or not a page is tall enough to scroll (prevents a few-px content shift between
   pages on systems with classic, space-taking scrollbars). */
html { overflow-x: hidden; overflow-y: scroll; }
body {
  margin: 0;
  font-family: 'Plus Jakarta Sans', Arial, Helvetica, sans-serif;
  color: var(--ink);
  background: var(--bg);
  font-size: 0.875rem;
  overflow-x: hidden;
}
a { color: var(--accent); text-decoration: none; }
.app-shell {
  display: grid;
  grid-template-columns: 250px 1fr;
  min-height: 100vh;
}
.sidebar {
  border-right: 1px solid var(--border);
  background: var(--surface);
  padding: 1rem 0.9rem;
  position: sticky;
  top: 0;
  height: 100vh;
  box-shadow: none;
}
.content {
  min-width: 0;
}
.shell { max-width: 1240px; margin: 0 auto; padding: 1.25rem 1.25rem 2.5rem; }
.brand {
  font-size: 0.975rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.brand-mark {
  width: 1.8rem;
  height: 1.8rem;
  border-radius: 0.55rem;
  background: var(--accent);
  color: white;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  box-shadow: none;
}
.nav-stack {
  display: grid;
  gap: 0.35rem;
  margin-top: 1.25rem;
}
.nav-link-app {
  padding: 0.65rem 0.75rem;
  border-radius: 10px;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.9rem;
  font-weight: 500;
}
.nav-link-app.active, .nav-link-app:hover {
  background: var(--accent-soft);
  color: var(--accent);
}
.profile-chip {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.4rem 0.7rem;
  background: var(--panel);
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.sidebar-footer {
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}
.panel, .card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  box-shadow: none;
}
.panel { padding: 1rem; }
.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.card { padding: 0.95rem; }
.metric-label {
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.metric-value {
  font-size: 1.35rem;
  margin-top: 0.2rem;
  font-weight: 700;
}
h1, h2, h3 { margin: 0 0 0.75rem; font-weight: 700; letter-spacing: -0.02em; }
h1 { font-size: 1.65rem; }
h2 { font-size: 1rem; }
h3 { font-size: 0.95rem; }
p, li { line-height: 1.45; }
form.stack { display: grid; gap: 0.8rem; }
label { font-size: 0.875rem; display: grid; gap: 0.35rem; }
input, select, textarea, button {
  font: inherit;
  padding: 0.6rem 0.7rem;
  border-radius: 0.5rem;
  border: 1px solid var(--border);
  background: var(--panel);
}
textarea { min-height: 90px; resize: vertical; }
button {
  background: var(--accent);
  color: white;
  cursor: pointer;
  border-color: var(--accent);
}
/* Bootstrap draws every button state through its own --bs-btn-* variables, and
   .btn:disabled (specificity 0,2,0) out-specifies a plain property override
   (0,1,0). Overriding background-color alone therefore left a disabled primary
   painting itself Bootstrap blue #0d6efd - measured on the Settings page's
   "Add Admin" button, a colour that appears nowhere else in Kiwi. Assign the
   variables instead so every state resolves to a Kiwi token. */
.btn-primary, button.btn-primary {
  --bs-btn-bg: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent-strong);
  --bs-btn-hover-border-color: var(--accent-strong);
  --bs-btn-active-bg: var(--accent-strong);
  --bs-btn-active-border-color: var(--accent-strong);
  --bs-btn-disabled-bg: var(--accent);
  --bs-btn-disabled-border-color: var(--accent);
  background-color: var(--accent);
  border-color: var(--accent);
}
.btn-primary:hover, button.btn-primary:hover,
button:hover {
  background-color: var(--accent-strong);
  border-color: var(--accent-strong);
}
.btn-outline-primary {
  color: var(--accent);
  border-color: var(--accent);
}
.btn-outline-primary:hover {
  background-color: var(--accent);
  border-color: var(--accent);
  color: white;
}
button.secondary {
  background: transparent;
  color: var(--ink);
}
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}
th, td {
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  text-align: left;
}
th {
  color: var(--muted);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
}
.muted { color: var(--muted); }
.error {
  border: 1px solid var(--danger-border);
  background: var(--danger-soft);
  color: var(--danger);
  padding: 0.85rem 1rem;
  border-radius: 12px;
  margin-bottom: 1rem;
}
.split-layout {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1.3fr 1fr;
}
.pill {
  display: inline-block;
  padding: 0.18rem 0.48rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 0.68rem;
  font-weight: 600;
  background: var(--surface);
  color: var(--state-inactive-color);
}
.mono { font-family: "SFMono-Regular", Consolas, monospace; font-size: 0.9em; }
details summary { cursor: pointer; color: var(--accent); }
.table-light th {
  background: var(--surface);
  color: var(--muted);
  font-weight: 600;
  font-size: 0.68rem;
}
tr.table-danger-subtle > * {
  background: var(--review-danger-bg);
}
.card-header {
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  padding: 0.8rem 0.95rem;
}
.card-body {
  padding: 0.95rem;
}
.card-footer {
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.page-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.page-intro {
  margin-bottom: 1.15rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}
.page-kicker {
  color: var(--muted);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 0.25rem;
  font-weight: 700;
}
.page-title {
  margin: 0;
  font-size: 1.65rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}
.page-subtitle {
  margin-top: 0.25rem;
  color: var(--muted);
  max-width: 72ch;
  font-size: 0.875rem;
}
.filter-card {
  border-bottom: 1px solid var(--border);
  padding: 0.85rem 0.95rem;
  background: var(--surface);
}
.badge-soft-active {
  background: var(--state-active-bg);
  color: var(--accent-strong);
  border: 1px solid var(--state-active-border);
}
.badge-soft-inactive {
  background: var(--state-inactive-bg);
  color: var(--state-inactive-color);
  border: 1px solid var(--border);
}
.badge-soft-terminated {
  background: var(--state-terminated-bg);
  color: var(--danger-strong);
  border: 1px solid var(--state-terminated-border);
}
.id-copy-input {
  background: var(--surface);
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.875rem;
}
.border-left-primary { border-left: 0.2rem solid var(--accent-strong) !important; }
.border-left-success { border-left: 0.2rem solid var(--accent-strong) !important; }
.border-left-warning { border-left: 0.2rem solid var(--warning) !important; }
.border-left-danger { border-left: 0.2rem solid var(--danger-strong) !important; }
.badge {
  font-size: 0.72rem;
  font-weight: 600;
  border-radius: 999px;
  padding: 0.25rem 0.55rem;
}
.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.section-title {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.section-meta {
  color: var(--muted);
  font-size: 0.75rem;
}
.detail-meta {
  display: grid;
  gap: 0.8rem;
}
.meta-row {
  display: grid;
  gap: 0.2rem;
}
.meta-label {
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.meta-value {
  font-size: 0.84rem;
  line-height: 1.35;
}
.metric-strip {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.metric-tile {
  border: 1px solid var(--border);
  border-radius: 0.55rem;
  background: var(--surface);
  padding: 0.75rem 0.8rem;
}
.metric-tile .metric-label {
  margin-bottom: 0.18rem;
}
.metric-tile .metric-value {
  font-size: 1.05rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.table-compact th,
.table-compact td {
  padding-top: 0.58rem;
  padding-bottom: 0.58rem;
}
.table-compact td {
  line-height: 1.35;
}
.table-responsive {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table-scroll-hint {
  display: none;
  color: var(--muted);
  font-size: 0.72rem;
  line-height: 1.35;
  margin-top: 0.2rem;
}
/* Import previews live inside constrained review columns even on desktop. Their
   wide, fixed readability contracts can still overflow after the global
   breakpoint hides ordinary table guidance. Keep their explicit guidance
   visible at every viewport size. */
.table-scroll-hint-constrained {
  display: block;
}
@media (max-width: 1280px) {
  .table-scroll-hint {
    display: block;
  }
}
@media (min-width: 1281px) and (max-width: 1399px) {
  .table-scroll-hint-detail {
    display: block;
  }
}
.table-data {
  min-width: 100%;
}
.chart-shell {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.chart-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  padding: 0.95rem;
}
.chart-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.chart-title {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.chart-subtitle {
  margin-top: 0.2rem;
  color: var(--muted);
  font-size: 0.75rem;
}
.chart-stage {
  position: relative;
  min-height: 260px;
}
.chart-stage canvas {
  width: 100% !important;
  height: 260px !important;
}
.chart-note {
  margin-top: 0.65rem;
  color: var(--muted);
  font-size: 0.73rem;
}
.table-employees {
  min-width: 820px;
}
/* Nine columns now: adding "Kept by employee" and "Returned to pool" is what
   makes a termination outcome readable from the register, but five 144px nowrap
   numeric columns squeezed the employee name to ~85px and wrapped it over three
   lines. The headers wrap instead, and the figures keep one line. */
.table-grants {
  min-width: 1000px;
}
.table-grants .col-number-wide {
  width: 116px;
}
.table-grants th.col-number-wide {
  white-space: normal;
}
.table-activity {
  min-width: 680px;
}
/* Employee activity mixes effective dates, descriptive events, grant references,
   amounts and optional notes. Auto layout let whichever row happened to contain
   the longest grant ID consume the table, leaving Event at roughly 100px. A fixed
   semantic colgroup keeps the narrative readable and uses the full detail card. */
.table-activity-employee {
  min-width: 44rem;
  table-layout: fixed;
}
.table-activity-employee .col-timeline-date { width: 7rem; }
.table-activity-employee .col-timeline-event { width: 29%; }
.table-activity-employee .col-timeline-grant { width: 22%; }
.table-activity-employee .col-timeline-amount { width: 5.5rem; }
.table-activity-employee .col-timeline-notes { width: auto; }
.table-activity-employee .timeline-date-cell > :first-child,
.table-activity-employee .timeline-amount-cell {
  white-space: nowrap;
}
.table-activity-employee .timeline-grant-cell,
.table-activity-employee .timeline-notes-cell {
  overflow-wrap: anywhere;
  word-break: break-word;
}
/* The grant ledger carries seven columns, five of them fixed-width numbers, and
   gave its Event column whatever they left over. At 1440px that was 69px, which
   wrapped the explanatory note to one or two words per line while the numeric
   columns kept large empty margins. Scoped to the ledger: the employee activity
   timeline shares .table-activity but has five columns and fits at 680px. */
.table-activity-ledger {
  min-width: 820px;
}
.table-activity-ledger th:nth-child(2),
.table-activity-ledger td:nth-child(2) {
  min-width: 240px;
}
.table-activity-ledger .col-number {
  width: 96px;
}
/* 960px could not fit its own container: the Recent Actions panel is one half of
   .dashboard-columns inside a 1240px shell, so 400-505px of the table - the
   Shares and Reference columns - was off-screen at every desktop width from 1280
   to 1920. The panel is now full width, and 760px fits from 1024px up. */
.table-activity-dashboard {
  min-width: 760px;
  table-layout: fixed;
}
.table-activity-dashboard .col-activity-action {
  width: 200px;
}
.table-activity-dashboard .col-activity-employee {
  width: 180px;
}
.table-activity-dashboard .col-activity-date {
  width: 140px;
}
.table-activity-dashboard .col-activity-shares {
  width: 110px;
}
.table-activity-dashboard .activity-action-cell .pill {
  display: inline-flex;
  max-width: 100%;
  white-space: normal;
  line-height: 1.2;
  text-align: left;
}
.table-activity-dashboard .activity-reference {
  display: inline-block;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.8rem;
  line-height: 1.35;
}
.table-pool {
  /* The right-hand pool panel measures 718px at the 1440px desktop shell. A
     720px floor created a meaningless two-pixel scrollbar on every desktop. */
  min-width: 712px;
}
.table-audit-issues {
  min-width: 100%;
  table-layout: fixed;
}
.table-audit-issues .col-issue-type {
  width: 8rem;
}
.table-audit-issues .issue-message {
  overflow-wrap: anywhere;
  word-break: break-word;
}
.table-tenant-admins {
  min-width: 44rem;
  table-layout: fixed;
}
.table-tenant-admins .col-admin-email { width: 16rem; }
.table-tenant-admins .col-admin-role { width: 6rem; }
.table-tenant-admins .col-admin-status { width: 7rem; }
.table-tenant-admins .col-admin-updated { width: 7.5rem; }
.table-tenant-admins .col-admin-action { width: 7.5rem; }
.table-tenant-admins .admin-identifier,
.table-admin-activity .activity-identifier {
  overflow-wrap: anywhere;
  word-break: break-word;
}
.table-tenant-admins .admin-updated,
.table-tenant-admins .admin-action {
  white-space: nowrap;
}
.table-admin-activity {
  min-width: 56rem;
  table-layout: fixed;
}
.table-admin-activity .col-activity-when { width: 11rem; }
.table-admin-activity .col-activity-admin { width: 15rem; }
.table-admin-activity .col-activity-change { width: 10rem; }
.table-admin-activity .col-activity-record { width: 10rem; }
.table-admin-activity .col-activity-details { width: auto; }
.table-admin-activity .activity-when {
  white-space: nowrap;
}
.table-source-errors {
  min-width: 34rem;
  table-layout: fixed;
}
.table-source-errors .col-source-row {
  width: 5rem;
}
.table-source-errors .col-source-reference {
  width: 34%;
}
.table-source-errors th:first-child,
.table-source-errors td:first-child {
  text-align: right;
  white-space: nowrap;
}
.table-import-preview-employees {
  min-width: 56rem;
}
.table-import-preview-grants {
  min-width: 68rem;
}
.table-import-preview-generic {
  min-width: 44rem;
  table-layout: fixed;
}
.table-import-preview-generic .col-import-row {
  width: 5rem;
}
.table-import-preview-generic .col-import-data {
  width: 52%;
}
.table-import-preview-generic .serialized-data,
.table-import-preview .import-wrap {
  overflow-wrap: anywhere;
  word-break: break-word;
}
.table-import-preview .col-import-row {
  width: 5rem;
  text-align: right;
  white-space: nowrap;
}
.table-import-preview .col-import-date {
  width: 8rem;
  white-space: nowrap;
}
.table-import-preview .col-import-shares {
  width: 10rem;
  text-align: right;
  white-space: nowrap;
}
.table-import-preview .col-import-email { min-width: 14rem; }
.table-import-preview .col-import-plan { min-width: 17rem; }
.table-import-preview .col-import-id { min-width: 12rem; }
.table-import-preview .col-import-notes,
.table-import-preview .col-import-validation { min-width: 12rem; }
.table-employee-holdings {
  min-width: 44rem;
}
.table-employee-holdings th.col-number-wide {
  white-space: normal;
}
.col-actions {
  width: 72px;
  white-space: nowrap;
}
.col-status {
  width: 120px;
}
.col-date {
  width: 120px;
  white-space: nowrap;
}
.col-number {
  width: 120px;
  white-space: nowrap;
}
.col-number-wide {
  width: 144px;
  white-space: nowrap;
}
.list-shell {
  display: grid;
  gap: 1rem;
  min-width: 0;
}
.list-toolbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.list-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.filter-grid {
  display: grid;
  grid-template-columns: minmax(260px, 1.5fr) minmax(150px, 0.7fr) auto;
  gap: 0.65rem;
  align-items: center;
}
.results-meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6rem;
  flex-wrap: wrap;
  color: var(--muted);
  font-size: 0.78rem;
}
.table-title-cell {
  display: grid;
  gap: 0.12rem;
}
.table-title-cell .primary {
  font-weight: 600;
  font-size: 0.84rem;
  color: var(--ink);
}
.table-title-cell .secondary {
  color: var(--muted);
  font-size: 0.74rem;
  line-height: 1.35;
}
.empty-state {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.84rem;
  line-height: 1.45;
}
.page-flash {
  margin-bottom: 1rem;
}
.page-flash .alert {
  border: 1px solid var(--border);
  margin-bottom: 0;
}
.report-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}
.report-card {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
.report-card .card-body {
  display: grid;
  gap: 0.75rem;
  align-content: start;
}
.report-card-list {
  margin: 0;
  padding-left: 1rem;
  color: var(--muted);
  font-size: 0.8rem;
}
.report-card-list li + li {
  margin-top: 0.2rem;
}
.report-card .card-footer {
  background: var(--panel);
  padding: 0.85rem 0.95rem;
}
.status-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.85rem;
}
.status-panel {
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  background: var(--panel);
  padding: 0.85rem 0.95rem;
}
.status-panel .metric-value,
.metric-tile .metric-value.metric-value-numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.status-panel .section-meta {
  text-align: right;
}
.status-panel.pass {
  background: var(--state-pass-bg);
  border-color: var(--state-active-border);
}
.status-panel.fail {
  background: var(--state-fail-bg);
  border-color: var(--state-fail-border);
}
.form-shell {
  display: grid;
  gap: 1rem;
}
.form-page {
  max-width: 820px;
  margin: 0 auto;
}
.dropdown-scroll {
  max-height: 280px;
  overflow-y: auto;
}
.form-grid {
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.form-grid.single {
  grid-template-columns: 1fr;
}
.form-panel {
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  background: var(--panel);
}
.form-panel-header {
  padding: 0.85rem 0.95rem;
  border-bottom: 1px solid var(--border);
}
.form-panel-body {
  padding: 0.95rem;
}
.helper-list {
  margin: 0;
  padding-left: 1rem;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.45;
}
.helper-list li + li {
  margin-top: 0.2rem;
}
.compact-banner {
  border: 1px solid var(--border);
  border-radius: 0.55rem;
  background: var(--surface);
  padding: 0.8rem 0.9rem;
  font-size: 0.82rem;
  color: var(--ink);
}
.preview-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.85rem 0.95rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.preview-meta {
  color: var(--muted);
  font-size: 0.8rem;
}
.review-alert {
  border: 1px solid var(--review-danger-border);
  border-radius: 0.6rem;
  background: var(--review-danger-bg);
  padding: 0.9rem 0.95rem;
  display: grid;
  gap: 0.7rem;
  margin-bottom: 1rem;
}
.review-alert-title {
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--review-danger-color);
}
.review-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  margin-bottom: 1rem;
}
.import-layout {
  display: grid;
  gap: 1rem;
  grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr);
  align-items: start;
}
.import-layout > * { min-width: 0; }
.review-card {
  border: 1px solid var(--border);
  border-radius: 0.6rem;
  background: var(--panel);
  overflow: hidden;
}
.review-card-header {
  padding: 0.8rem 0.95rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.review-card-body {
  padding: 0.9rem 0.95rem;
}
.review-list {
  margin: 0;
  padding-left: 1rem;
  display: grid;
  gap: 0.4rem;
}
.review-list li {
  font-size: 0.8rem;
  color: var(--ink);
}
.review-error-list {
  margin: 0;
  padding-left: 1rem;
  display: grid;
  gap: 0.35rem;
}
.review-error-list li {
  font-size: 0.77rem;
  line-height: 1.4;
  color: var(--ink);
}
.review-error-list strong {
  color: var(--review-danger-color);
}
.review-row-ref {
  font-size: 0.76rem;
  color: var(--muted);
  line-height: 1.35;
}
.login-shell {
  max-width: 430px;
  margin: 3.5rem auto;
}
.login-shell-wide {
  max-width: 640px;
}
.modal-content {
  border: 1px solid var(--border);
  border-radius: 0.65rem;
  box-shadow: none;
}
.modal-header,
.modal-footer {
  border-color: var(--border);
  padding: 0.8rem 0.95rem;
}
.modal-body {
  padding: 0.95rem;
}
.modal-title {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.modal form {
  display: grid;
  gap: 0.75rem;
}
.modal .alert {
  margin-bottom: 0;
}
.modal .table {
  font-size: 0.78rem;
}
.modal-feedback {
  display: none;
}
.modal-feedback.show {
  display: block;
}
.kv-table th,
.kv-table td {
  padding-top: 0.7rem;
  padding-bottom: 0.7rem;
}
.kv-table th {
  width: 58%;
  background: var(--panel);
  color: var(--muted);
  font-size: 0.76rem;
  text-transform: none;
  letter-spacing: 0;
}
.kv-table td {
  text-align: right;
  font-weight: 600;
  color: var(--ink);
}
.timeline-list {
  display: grid;
}
.timeline-item {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: 0.85rem;
  padding: 0.8rem 0.95rem;
  border-bottom: 1px solid var(--border);
}
.timeline-item:last-child {
  border-bottom: 0;
}
.timeline-icon {
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  background: var(--state-active-bg);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
}
.note-fine {
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.35;
}
.dashboard-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  align-items: start;
  min-width: 0;
}
.dashboard-columns > * { min-width: 0; }
.detail-columns {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 1.5rem;
  align-items: start;
  min-width: 0;
}
.detail-columns-grant {
  /* At the 1440px shell this reserves about 830px for the 820px ledger while
     keeping a usable 264px grant-record panel. Narrower layouts may still use
     the contained table scroller until the grid stacks at 860px. */
  grid-template-columns: minmax(16.5rem, 0.72fr) minmax(0, 2.28fr);
}
.detail-columns > * { min-width: 0; }
.card-split {
  display: grid;
  grid-template-columns: 5fr 7fr;
  align-items: start;
  min-width: 0;
}
.card-split > * { min-width: 0; }
.card-split-left {
  border-right: 1px solid var(--border);
}
.mobile-nav-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.mobile-nav-toggle {
  display: none;
  background: none;
  border: none;
  padding: 0.4rem 0.45rem;
  color: var(--ink);
  font-size: 1.35rem;
  cursor: pointer;
  border-radius: 6px;
  line-height: 1;
}
.mobile-nav-toggle:hover {
  background: var(--accent-soft);
  color: var(--accent);
}
@media (max-width: 1100px) {
  .shell {
    padding: 1rem 1rem 2rem;
  }
  .status-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .metric-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .chart-stage {
    min-height: 230px;
  }
  .chart-stage canvas {
    height: 230px !important;
  }
}
@media (max-width: 860px) {
  .mobile-nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
  }
  .sidebar.nav-closed .nav-collapsible { display: none; }
  .app-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: static;
    height: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
  .shell {
    padding: 0.9rem 0.9rem 1.6rem;
  }
  .page-intro {
    margin-bottom: 1rem;
    padding-bottom: 0.65rem;
  }
  .page-title {
    font-size: 1.45rem;
  }
  .page-subtitle {
    max-width: none;
  }
  .split-layout { grid-template-columns: 1fr; }
  /* Row 2 now carries the status select plus its Apply button, so the select
     needs a floor or it collapses to two characters ("Ac") next to the result
     count - measured at 390px. */
  .filter-grid { grid-template-columns: minmax(12rem, auto) 1fr; }
  .filter-grid > div:nth-of-type(1) { grid-column: 1 / -1; }
  .form-grid { grid-template-columns: 1fr; }
  .status-summary,
  .metric-strip {
    grid-template-columns: repeat(2, 1fr);
  }
  .chart-shell {
    grid-template-columns: 1fr;
  }
  .review-grid {
    grid-template-columns: 1fr;
  }
  .import-layout {
    grid-template-columns: 1fr;
  }
  .timeline-item {
    grid-template-columns: 1fr;
    gap: 0.55rem;
  }
  .timeline-icon {
    display: none;
  }
  .modal-dialog {
    margin: 0.7rem;
  }
  .results-meta { justify-content: flex-start; }
  .dashboard-columns { grid-template-columns: 1fr; }
  .detail-columns { grid-template-columns: 1fr; }
  .card-split { grid-template-columns: 1fr; }
  .card-split-left { border-right: none; border-bottom: 1px solid var(--border); }
  .table-activity-dashboard { min-width: 560px; }
  .table-activity-dashboard .col-activity-action { width: 160px; }
  .table-activity-dashboard .col-activity-employee { width: 140px; }
  .table-activity-dashboard .col-activity-date { width: 100px; }
  .table-activity-dashboard .col-activity-shares { width: 90px; }
  .nav-link-app { min-height: 44px; }
  input:not([type="hidden"]),
  select,
  textarea { min-height: 44px; }
  /* design.md asks for a 44px touch target on every control. The previous
     exclusions carved out exactly the controls that need it most: every row
     action is a .btn-sm (measured 32.0 x 31.0px), pagination links were exempt,
     and the hamburger - the only route to navigation on a phone - measured
     35.1 x 36.4px. .btn-sm keeps its type scale and grows through padding, so
     the visual density of a dense row does not change. */
  .btn,
  button,
  .page-link { min-height: 44px; }
  .btn-sm,
  .btn-group-sm > .btn {
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
    min-width: 44px;
  }
}
@media (max-width: 640px) {
  body {
    font-size: 0.84rem;
  }
  .sidebar {
    padding: 0.85rem 0.75rem;
  }
  .nav-link-app {
    padding: 0.58rem 0.65rem;
    font-size: 0.86rem;
  }
  th,
  .table-light th {
    font-size: 0.68rem;
  }
  th,
  td {
    padding-left: 0.6rem;
    padding-right: 0.6rem;
  }
  .empty-state {
    padding: 1.4rem 0.8rem;
  }
  .compact-banner,
  .status-panel,
  .metric-tile,
  .card-body,
  .card-header {
    padding-left: 0.8rem;
    padding-right: 0.8rem;
  }
  .login-shell { margin-top: 1.5rem; }
  /* Below 640px even 12rem plus the result count does not fit one row. */
  .filter-grid { grid-template-columns: 1fr; }
  .chart-stage { min-height: 180px; }
  .chart-stage canvas { height: 180px !important; }
}
@media (max-width: 480px) {
  .status-panel .metric-value,
  .status-panel .section-meta {
    text-align: left;
  }
}

/* ---------------------------------------------------------------------------
 * Focus visibility.
 *
 * There was no focus rule anywhere in this stylesheet. Bootstrap's own outline is
 * suppressed by the button styles below, so a keyboard user tabbing through a
 * lifecycle modal could not tell whether focus sat on "Cancel" or on the button
 * that writes an irreversible fact to the ledger. Measured on "Apply Termination":
 * outline: none 0px, and a fully transparent box-shadow.
 *
 * One global rule, using :focus-visible so a pointer click does not draw a ring.
 * ------------------------------------------------------------------------- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
.btn:focus-visible,
.page-link:focus-visible,
.dropdown-item:focus-visible,
.btn-close:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.form-check-input:focus-visible {
  outline: 3px solid var(--accent, #1f7a52);
  outline-offset: 2px;
  border-radius: 3px;
  box-shadow: none;
}

/* On a destructive control the ring must read as destructive, not as brand. */
.btn-danger:focus-visible,
.dropdown-item.text-danger:focus-visible,
.btn[data-destructive]:focus-visible,
[data-destructive]:focus-visible {
  outline-color: var(--danger, #9b2c2c);
}

/* Bootstrap's own field focus is #86b7fe with a blue glow. Pointer focus keeps
   a Kiwi glow; keyboard focus also receives the explicit 3px ring above. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 0.2rem var(--accent-soft);
}

/* Tabular figures. design.md mandates these; no table had them, so digits in a
 * column did not line up and a mis-keyed amount was harder to spot. */
table td,
table th,
.metric-value,
.metric-value-numeric,
input[type="number"],
input[name="share_amount"] {
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * Irreversible-action modals.
 * ------------------------------------------------------------------------- */
.consequence {
  border: 1px solid var(--border, #d8dee6);
  border-left: 3px solid var(--danger, #9b2c2c);
  background: var(--surface, #f8fafc);
  border-radius: 4px;
  padding: 12px 14px;
  margin: 12px 0;
}

.consequence-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 3px 0;
  font-variant-numeric: tabular-nums;
}

.consequence-label { color: var(--muted, #636a78); }
.consequence-value { font-weight: 600; color: var(--ink, #1f2937); }
.consequence-note { margin: 8px 0 0; font-size: 13px; color: var(--muted, #636a78); }

/* ---------------------------------------------------------------------------
 * Bootstrap variants mapped onto Kiwi tokens.
 *
 * .btn-danger, .btn-success and the .alert-* variants were never mapped, so
 * Bootstrap's palette arrived through the side door: destructive red existed as
 * both #dc3545 and --danger #9b2c2c, and the buyback confirm button (#198754)
 * sat four hue units from the brand green --accent #1f7a52, reading as "the same
 * green that did not quite load". Assign the --bs-* variables so a variant keeps
 * its Bootstrap semantics and Kiwi's colour.
 * ------------------------------------------------------------------------- */
.btn-danger {
  --bs-btn-bg: var(--danger);
  --bs-btn-border-color: var(--danger);
  --bs-btn-hover-bg: var(--danger-strong);
  --bs-btn-hover-border-color: var(--danger-strong);
  --bs-btn-active-bg: var(--danger-strong);
  --bs-btn-active-border-color: var(--danger-strong);
  --bs-btn-disabled-bg: var(--danger);
  --bs-btn-disabled-border-color: var(--danger);
}
.btn-success {
  --bs-btn-bg: var(--accent);
  --bs-btn-border-color: var(--accent);
  --bs-btn-hover-bg: var(--accent-strong);
  --bs-btn-hover-border-color: var(--accent-strong);
  --bs-btn-active-bg: var(--accent-strong);
  --bs-btn-active-border-color: var(--accent-strong);
  --bs-btn-disabled-bg: var(--accent);
  --bs-btn-disabled-border-color: var(--accent);
}
.alert-danger {
  --bs-alert-bg: var(--danger-soft);
  --bs-alert-border-color: var(--danger-border);
  --bs-alert-color: var(--danger);
}
.alert-warning {
  --bs-alert-bg: var(--warning-soft);
  --bs-alert-border-color: var(--warning-border);
  --bs-alert-color: var(--ink);
}
.alert-info {
  --bs-alert-bg: var(--surface);
  --bs-alert-border-color: var(--border);
  --bs-alert-color: var(--ink);
}
/* Bootstrap's #ffc107 measured 1.56:1 on --surface and #198754 is not the brand
   green. Both are used as standalone text colours, so both need a token. */
.text-warning { color: var(--warning) !important; }
.text-success { color: var(--accent-strong) !important; }
.text-danger { color: var(--danger) !important; }

/* ---------------------------------------------------------------------------
 * Attention tile.
 *
 * "Kept by employee" on the employee detail page carried its meaning in hue
 * alone: .text-warning, measured rgb(255,193,7) on rgb(248,250,252) - a contrast
 * ratio of 1.56:1 against the 4.5:1 that 16.8px/700 text needs, and nothing at
 * all for a greyscale or colourblind reader. The Kiwi token --warning only
 * reaches 3.30:1, so hue cannot carry this meaning at any value.
 *
 * The signal now lives in the border, the tint and a sentence. The number itself
 * stays --ink so it is the most readable thing in the tile.
 * ------------------------------------------------------------------------- */
.metric-tile-attention {
  border-color: var(--warning-border);
  background: var(--warning-soft);
}
.metric-tile-attention .metric-value {
  color: var(--ink);
}
.metric-tile-note {
  margin-top: 0.35rem;
  font-size: 0.72rem;
  line-height: 1.35;
  color: var(--ink);
}

/* A count and a share balance were rendered in the same 1.05rem bold face, so
   "Total grants 1" and "Granted 1200.000" read as the same kind of number. */
.metric-value.metric-value-count {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: normal;
}

/* ---------------------------------------------------------------------------
 * Skip link.
 *
 * Measured tab order on every authenticated page: brand, seven nav links, then
 * the Logout submit button, and only then the first page control - ten stops
 * before content, with an irreversible-looking control adjacent to the first.
 * ------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.skip-link:focus {
  position: fixed;
  left: 1rem;
  top: 1rem;
  z-index: 2000;
  width: auto;
  height: auto;
  background: var(--panel);
  color: var(--ink);
  border: 1px solid var(--accent);
  border-radius: 0.5rem;
  padding: 0.6rem 0.9rem;
}

/* A totals row must never be mistakable for a record. */
tfoot th,
tfoot td {
  border-top: 2px solid var(--border-strong);
  background: var(--surface);
  font-weight: 700;
  color: var(--ink);
}

/* The status filter submits on change for pointer users. A keyboard user moving
   through the options fires change on every arrow press, so the explicit submit
   below is their path through the list. It stays visible for everyone. */
.filter-apply {
  white-space: nowrap;
}

/* Bootstrap paints <code> in #d63384, a pink that appears nowhere else in Kiwi
   and reads as an error on a grant or employee ID. */
code {
  color: var(--ink);
}

/* The ledger's numeric columns are fixed and .col-number sets nowrap, so a
   two-word header such as "Kept by employee" could not wrap and pushed the last
   column past the panel. Headers wrap; the figures themselves stay on one line. */
.table-activity-ledger th.col-number {
  white-space: normal;
}

/* ---------------------------------------------------------------------------
 * Accessibility pass.
 *
 * Every rule below closes a defect measured with axe-core 4.13 in Chromium at
 * 1280x900 against the seeded local tenant. The measured numbers are quoted
 * beside the rule that fixes them.
 * ------------------------------------------------------------------------- */

/* .btn-outline-secondary was the last unmapped Bootstrap variant. Its own
   #6c757d measured 4.32:1 on --bg (Refresh Snapshot) and 4.48:1 on --surface
   (the list filters' Apply button) - both under 4.5:1. Mapped onto Kiwi tokens
   it measures 5.02:1 and 5.72:1 on the same two surfaces. */
.btn-outline-secondary {
  --bs-btn-color: var(--muted);
  --bs-btn-border-color: var(--border-strong);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-hover-bg: var(--muted);
  --bs-btn-hover-border-color: var(--muted);
  --bs-btn-active-color: #ffffff;
  --bs-btn-active-bg: var(--muted);
  --bs-btn-active-border-color: var(--muted);
  --bs-btn-disabled-color: var(--muted);
  --bs-btn-disabled-border-color: var(--border-strong);
}

/* link-in-text-block: the "Show all" link inside the muted results line measured
   1.09:1 against its surrounding text (3:1 required), so hue alone identified it.
   Links that sit inside a run of text are underlined; standalone links, buttons
   and table cell links keep .text-decoration-none and are unaffected. */
.muted a,
.section-meta a,
.page-subtitle a,
.note-fine a,
.empty-state a,
.helper-list a,
.results-meta a,
.metric-tile-note a,
.chart-note a {
  text-decoration: underline;
}

/* A field block that cannot wrap its control in a <label>, because the control
   is a combobox whose listbox and help text must stay outside the label's
   accessible name. Mirrors the bare `label` grid so form spacing is identical. */
.field {
  display: grid;
  gap: 0.35rem;
  font-size: 0.875rem;
}
.field > label {
  display: block;
}

/* Required fields must be visually obvious (design.md, Form rules). The marker
   is decorative: the `required` attribute already exposes the state, so the
   asterisk is aria-hidden and never read twice. */
.required-marker {
  color: var(--danger);
  font-weight: 700;
  margin-left: 0.15rem;
}
.form-required-note {
  margin: 0;
  font-size: 0.72rem;
  color: var(--muted);
}

/* Metric hint. The tooltip trigger was an <i> with a Bootstrap-injected
   aria-label - axe aria-prohibited-attr, 9 nodes on the employee page - and no
   tab stop, so the explanation was unreachable by keyboard. It is a real button
   now, carrying the same sentence as visually hidden text so the name survives
   even if Chart/Bootstrap JS never loads. */
.metric-hint {
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
  color: var(--muted);
  font-size: inherit;
  line-height: 1;
  cursor: help;
  position: relative;
}
.metric-hint:hover {
  background: none;
  color: var(--accent);
}

/* Chart text alternative. A <canvas> exposes nothing, so every chart carries a
   disclosure holding the same numbers the chart draws. */
.chart-data-details {
  margin-top: 0.65rem;
  border-top: 1px solid var(--border);
  padding-top: 0.55rem;
}
.chart-data-details > summary {
  font-size: 0.73rem;
  color: var(--muted);
  cursor: pointer;
}
.chart-data-details > summary:hover {
  color: var(--accent);
}
.chart-data-details .table-responsive {
  margin-top: 0.55rem;
}

/* A live region that reports search results and submit progress. It is read, not
   seen, so it carries no box of its own. */
.status-live {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Combobox option rows. Bootstrap's .dropdown-item is styled for links and
   buttons; the listbox now uses role="option" divs, which need the same paint. */
.dropdown-menu [role="option"] {
  display: block;
  width: 100%;
  padding: 0.35rem 1rem;
  clear: both;
  font-weight: 400;
  color: var(--ink);
  text-align: inherit;
  background-color: transparent;
  border: 0;
  cursor: pointer;
}
.dropdown-menu [role="option"]:hover,
.dropdown-menu [role="option"][aria-selected="true"] {
  background-color: var(--accent-soft);
  color: var(--accent-strong);
}

/* Bootstrap keeps a .visually-hidden caption in flow on purpose - its own
   :not(caption) guard skips the absolute positioning, because an out-of-flow
   caption stops naming its table. What it does not skip is white-space: nowrap,
   and a caption feeds the table wrapper a min-content width. Adding captions
   therefore made five previously static tables scroll sideways: measured as five
   new axe scrollable-region-focusable nodes on the import and settings pages. The
   caption stays in flow, stays 1px by 1px and clipped, and is allowed to wrap. */
caption.visually-hidden {
  white-space: normal !important;
  /* Bootstrap's margin: -1px pulls the caption above the scroll container's own
     origin, which Chrome counts as one pixel of vertical overflow. axe then reads
     .table-responsive as a scrollable region with no focusable content: eight
     nodes across the import, chronology and settings pages, on tables that do not
     scroll at all. Zero margin keeps the 1px clipped box inside the container. */
  margin: 0 !important;
}

/* The owner-reauth banner grew a readonly account field beside the password, so
   its row is one control wider and squeezed the submit button onto three lines at
   1280px. It wraps instead, and the button keeps its label on one line. */
.owner-reauth-form {
  flex-wrap: wrap;
}
.owner-reauth-form button[type="submit"] {
  white-space: nowrap;
}

/* label is display: grid, so a bare text node and a following <span> land in two
   rows: the required asterisk sat on its own line under every label it was added
   to. The label text and its marker share one grid item. */
.field-label {
  display: block;
}
