/* ==========================================================================
   Getfive HR Recruitment Dashboard — Design System
   Modern SaaS look: soft neutrals, the logo's blue as the accent, generous spacing,
   card-based layout, consistent stepper/timeline components.
   ========================================================================== */

:root {
  --brand-ink:      #0f172a;   /* sidebar / headings */
  --brand-ink-2:    #1e293b;
  --brand-logo:     #1b2a88;   /* the blue of the Getfive wordmark itself */
  --brand-logo-d:   #142063;   /* one step down, for hover on filled controls */
  /* The primary action colour IS the logo's blue. Buttons, links, active
     states and focus rings all resolve through these three, so the whole
     interface reads as one brand rather than as a navy logo sitting above an
     unrelated indigo UI. It is also the more legible choice: white on
     #1b2a88 is 12.12:1 against 6.29:1 for the indigo it replaced. */
  --brand-primary:  #1b2a88;   /* the Getfive wordmark blue */
  --brand-primary-d:#142063;   /* one step down, for hover on filled controls */
  --brand-primary-l:#e9edf8;   /* the same blue at tint strength */
  --brand-accent:   #0ea5e9;   /* sky-500 */
  --brand-accent-2: #f0762a;   /* orange — active-state accent */
  --brand-success:  #16a34a;
  --brand-warning:  #d97706;
  --brand-danger:   #dc2626;
  --brand-bg:       #f6f7fb;
  --surface:        #ffffff;
  --border:         #e6e8f0;
  --text:           #1f2430;
  --text-muted:     #6b7280;
  --text-faint:     #9aa1b1;
  --radius-sm:      .5rem;
  --radius:         .85rem;
  --radius-lg:      1.1rem;
  --shadow-xs:      0 1px 2px rgba(16,24,40,.05);
  --shadow-sm:      0 1px 3px rgba(16,24,40,.08), 0 1px 2px rgba(16,24,40,.04);
  --shadow-md:      0 4px 14px rgba(16,24,40,.08);
  --shadow-lg:      0 12px 32px rgba(16,24,40,.12);
  /* Every header band in the system resolves here: data-table headers, the
     card header strips and the activity footer. A blue-leaning tint rather
     than a neutral grey, so the headers read as part of the brand. */
  --thead-bg:       #eef1f9;
  --trow-hover:     #fafbff;
  --wf-done-bg:     #f7f9ff;
  --kanban-col-bg:  #eef1f8;
}

* { box-sizing: border-box; }

/*
 * The one lever for overall scale.
 *
 * Every size in this file is expressed in rem, so the whole interface —
 * type, padding, gaps, icon tiles, radii — resolves from this single value.
 * Dropping the root from the browser default of 16px to 14.5px makes the
 * system about 9% denser everywhere at once, in proportion, rather than
 * shrinking a hundred rules by hand and drifting out of step.
 *
 * Borders and hairlines stay in px on purpose: a 1px rule should stay 1px.
 */
html { font-size: 14.5px; }

body {
  background: var(--brand-bg);
  font-family: 'Inter', 'Segoe UI', Roboto, Arial, sans-serif;
  color: var(--text);
  font-size: .925rem;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 { color: var(--brand-ink); font-weight: 650; letter-spacing: -.01em; }
a { color: var(--brand-primary); }
a:hover { color: var(--brand-primary-d); }

/* ---------------------------------------------------------------------
   Top bar
   ------------------------------------------------------------------- */
/* The full-width navy bar is gone: the logo moved into the sidebar and the top
   bar became part of the content column (.app-topbar). What is left here is the
   avatar chip, which several pages still use outside the top bar. */
.avatar-chip {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--brand-primary); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .82rem;
}
/* A photo fills the circle and is cropped to it, so a portrait and a landscape
   snapshot both come out as the same round chip. overflow:hidden does the
   clipping; object-fit stops the face being squashed to fit. */
.avatar-chip { overflow: hidden; flex-shrink: 0; }
.avatar-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The larger version on My Profile, beside the file picker. */
.avatar-chip-lg {
  width: 68px; height: 68px; border-radius: 50%;
  background: var(--brand-primary); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 1.5rem;
}
.avatar-edit { display: flex; align-items: center; gap: 1rem; }
.avatar-edit-fields { min-width: 0; flex: 1; }
/* The small grey line under a form control that explains accepted formats or
   limits. Shared, so a hint reads the same wherever it appears. */
.form-hint,
.avatar-edit-hint { font-size: .72rem; color: var(--text-faint); margin-top: .3rem; }

/* Icon button in the top bar (notifications). The bar is white now, so the
   icon is ink on a pale hover fill — it was white-on-white and invisible when
   this style was inherited from the old navy bar. */
.nav-icon-btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border: 1px solid var(--border); background: var(--surface);
  border-radius: 50%;
  color: var(--text-muted);
  font-size: 1.05rem;
  transition: background .15s, color .15s, border-color .15s;
}
.nav-icon-btn:hover, .nav-icon-btn:focus { background: var(--brand-bg); color: var(--brand-ink); border-color: #d7dbe7; text-decoration: none; }
.nav-icon-btn i { color: inherit !important; }
.nav-icon-btn .badge {
  position: absolute; top: -1px; right: -1px;
  min-width: 16px; height: 16px; padding: 0 4px;
  font-size: .625rem; line-height: 16px;
  border-radius: 999px;
  background: var(--brand-danger) !important; color: #fff;
}

/* ---------------------------------------------------------------------
   Sidebar
   ------------------------------------------------------------------- */
/* The shell is two columns, both full height: the sidebar carries the logo and
   the menu, and the content column carries its own top bar. Nothing spans
   across the two, so the logo sits above the menu it belongs to. */
.app-shell { display: flex; min-height: 100vh; }
.app-content { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* The top bar belongs to the content column, so it starts where the sidebar
   ends. It is sticky on its own, which keeps the account menu reachable while
   a long table scrolls underneath. */
/* One content track, shared by the top bar, the page and the footer. The bar's
   own background and bottom rule still run edge to edge; only what sits inside
   is constrained, which is what keeps the menu button above the page title and
   the account chip above the right edge of the cards. --app-gutter is the single
   place the side padding is set, so the three can never drift apart. */
:root { --app-track: 1440px; --app-gutter: 1.5rem; }

.app-topbar {
  position: sticky; top: 0; z-index: 30;
  padding: .6rem 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.app-topbar-inner {
  width: 100%;
  max-width: var(--app-track);
  margin: 0 auto;
  padding: 0 var(--app-gutter);
  display: flex; align-items: center; gap: .6rem;
}
.app-topbar-spacer { flex: 1 1 auto; }

/* Avatar, then name over role. The role is the half people actually scan for
   when several colleagues share a first name. */
.user-chip {
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .25rem .6rem .25rem .3rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  transition: background .14s ease, border-color .14s ease;
}
.user-chip:hover, .user-chip:focus { background: var(--brand-bg); border-color: #d7dbe7; color: var(--text); }
.user-chip::after { margin-left: .1rem; color: var(--text-faint); }
.user-chip-text { flex-direction: column; line-height: 1.15; min-width: 0; }
.user-chip-name { font-size: .8125rem; font-weight: 650; color: var(--brand-ink); }
.user-chip-role { font-size: .7rem; color: var(--text-muted); }

.app-sidebar {
  width: 224px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  min-height: 100vh;
  padding: 0 .75rem 1.1rem;
}
/* The logo block lines up with the top bar next to it, so the two rules across
   the top of the page read as one line rather than two near-misses. */
/* The head matches the top bar height exactly, so the two hairlines meet and
   read as one rule across the page rather than two that nearly line up. */
.app-sidebar-head {
  display: flex; align-items: center; justify-content: space-between;
  height: 62px;
  margin: 0 -.75rem 1rem;
  padding: 0 1rem;
  border-bottom: 1px solid var(--border);
}
.app-brand { display: inline-flex; align-items: center; text-decoration: none; min-width: 0; }
/* The logo was capped at 30px in a 62px head, so it read as a caption rather
   than the mark it is. The sidebar is ~215px wide inside its padding, so a
   40px-tall logo at a 3:1 ratio lands near 125px and still leaves room for the
   close button on mobile. */
.app-brand img { display: block; height: 40px; width: auto; max-width: 180px; object-fit: contain; }
.app-brand-text { font-size: 1.3rem; font-weight: 800; letter-spacing: -.02em; color: var(--brand-ink); }
.app-brand-text .accent { color: var(--brand-accent-2); }
/* A hairline between groups instead of an uppercase caption. It carries the
   same grouping with none of the shouting, and gives the eye less to step
   over on the way down the list. */
.app-sidebar .nav-divider {
  height: 1px;
  background: var(--border);
  margin: .7rem .7rem .6rem;
}
.app-sidebar .nav-link {
  position: relative;
  color: var(--text-muted);
  padding: .6rem .75rem;
  font-size: .875rem;
  font-weight: 500;
  border-radius: .55rem;
  margin-bottom: .12rem;
  display: flex;
  align-items: center;
  transition: background .14s ease, color .14s ease;
}
.app-sidebar .nav-link i {
  font-size: 1rem;
  opacity: .65;
  width: 1.35rem;
  transition: opacity .14s ease, color .14s ease;
}
.app-sidebar .nav-link:hover { color: var(--brand-ink); background: var(--brand-bg); }
.app-sidebar .nav-link:hover i { opacity: .9; }
/* The active row is a solid pill in the logo's own blue. On a light sidebar
   that is the strongest available signal for "you are here", and it needs no
   accent bar propping it up — the fill alone carries it. */
.app-sidebar .nav-link.active,
.app-sidebar .nav-link.active:hover {
  color: #fff;
  background: var(--brand-logo);
  font-weight: 600;
}
.app-sidebar .nav-link.active i { opacity: 1; color: #fff; }
.app-sidebar .nav-link .badge {
  margin-left: auto;
  background: var(--brand-bg) !important;
  color: var(--text-muted) !important;
  font-weight: 700; font-size: .68rem;
  border-radius: 999px; padding: .15rem .45rem;
}
/* On the blue pill the count sits in a translucent white rather than a second
   blue, which read as two unrelated accents stacked on each other. */
.app-sidebar .nav-link.active .badge { background: rgba(255,255,255,.22) !important; color: #fff !important; }
.app-sidebar hr { border-color: var(--border); margin: .75rem .5rem; }

.app-main { flex: 1 0 auto; min-width: 0; }

/* ---------------------------------------------------------------------
   KPI cards — the headline row
   ------------------------------------------------------------------- */
/* auto-fit rather than a fixed five columns, so the row reflows to 3, 2 and 1
   on narrower screens without a media query per breakpoint. */
.kpi-row {
  display: grid;
  /* 190px each meant the five tiles needed ~1005px and wrapped to 4 + 1 on a
     scaled-up display, leaving one stranded on its own row. 150px lets all
     five sit on one line in about 800px and they still share the space
     equally, so nothing looks cramped on a wide screen. */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: .7rem;
  margin-bottom: 1rem;
}
.kpi-card {
  display: flex; flex-direction: column; gap: .45rem;
  padding: .8rem .85rem;
  border: 1px solid var(--border);
  border-top: 3px solid var(--kpi-ink, var(--brand-primary));
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  color: inherit; text-decoration: none;
  transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
a.kpi-card:hover, a.kpi-card:focus-visible {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
  color: inherit; text-decoration: none;
}
a.kpi-card:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
.kpi-card-top { display: flex; align-items: center; gap: .55rem; }
.kpi-card-icon {
  width: 28px; height: 28px; border-radius: .5rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .95rem; flex-shrink: 0;
}
.kpi-card-label { font-size: .82rem; font-weight: 600; color: var(--text-muted); min-width: 0; }
.kpi-card-value {
  font-size: 1.6rem; font-weight: 750; color: var(--brand-ink);
  line-height: 1.05; font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------
   Stat list — label / value rows inside a panel
   ------------------------------------------------------------------- */
.stat-list { padding: .5rem .6rem .7rem; display: flex; flex-direction: column; }
.stat-list-row {
  display: flex; align-items: center; gap: .7rem;
  padding: .5rem .55rem;
  border-radius: .5rem;
  color: inherit; text-decoration: none;
  transition: background .14s ease;
}
.stat-list-row:hover { background: var(--brand-bg); color: inherit; text-decoration: none; }
.stat-list-row:hover .stat-list-label { color: var(--brand-primary); }
.stat-list-row:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 1px; }
.stat-list-icon {
  width: 30px; height: 30px; border-radius: .5rem; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .9rem;
}
.stat-list-label { flex: 1; min-width: 0; font-size: .85rem; font-weight: 600; color: var(--text); }
.stat-list-value {
  font-size: 1.05rem; font-weight: 750; color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------
   Current vacancies
   ------------------------------------------------------------------- */
.vacancy-list { padding: .4rem .6rem .5rem; display: flex; flex-direction: column; }
.vacancy-row {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem;
  border-radius: .5rem;
  color: inherit; text-decoration: none;
  transition: background .14s ease;
}
.vacancy-row + .vacancy-row { border-top: 1px solid var(--border); border-radius: .5rem; }
.vacancy-row:hover { background: var(--brand-bg); color: inherit; text-decoration: none; }
.vacancy-row:hover .vacancy-title { color: var(--brand-primary); }
.vacancy-row:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 1px; }
.vacancy-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand-primary-l); color: var(--brand-primary);
  font-size: .75rem; font-weight: 700;
}
.vacancy-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.vacancy-title {
  font-size: .85rem; font-weight: 650; color: var(--brand-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vacancy-meta { font-size: .73rem; color: var(--text-muted); }
.vacancy-side { text-align: right; flex-shrink: 0; display: flex; flex-direction: column; }
.vacancy-date { font-size: .78rem; font-weight: 600; color: var(--text); white-space: nowrap; }
.vacancy-days { font-size: .7rem; font-weight: 600; white-space: nowrap; }
.vacancy-days-muted { color: var(--text-faint); }
.vacancy-days-soon  { color: var(--brand-warning); }
.vacancy-days-over  { color: var(--brand-danger); }

/* The link on the bottom edge of a panel, under a truncated list. */
.panel-soft-foot-link {
  display: block; text-align: center;
  padding: .6rem;
  margin-top: auto;
  border-top: 1px solid var(--border);
  font-size: .78rem; font-weight: 650;
  color: var(--brand-accent-2);
  text-decoration: none;
}
.panel-soft-foot-link:hover { background: var(--brand-bg); color: var(--brand-accent-2); }
/* The content area sets its own breathing room. Without this the page header
   sits flush against the top bar and hard against the sidebar, so the two navy
   bars read as one block. */
.app-main .container-fluid {
  max-width: var(--app-track);
  padding: 1.25rem var(--app-gutter) 2.25rem;
}

/* ---------------------------------------------------------------------
   Cards, stats
   ------------------------------------------------------------------- */
.stat-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  background: var(--surface);
}
.card { background: var(--surface); border-color: var(--border); color: var(--text); }
.stat-card .stat-value { font-size: 1.9rem; font-weight: 750; color: var(--brand-ink); line-height: 1.1; }
.stat-card .stat-label { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); font-weight: 600; }

.kpi-tile {
  position: relative;
  border: 1px solid var(--border);
  border-top: 3px solid var(--kpi-accent, var(--brand-primary));
  border-radius: var(--radius);
  background: var(--surface);
  padding: .75rem .85rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: .35rem;
  height: 84px;
  box-sizing: border-box;
}
.kpi-tile .kpi-icon {
  width: 30px; height: 30px; border-radius: .5rem;
  display: flex; align-items: center; justify-content: center;
  font-size: .84rem; flex-shrink: 0;
  align-self: flex-end;
  order: 2;
  position: relative;
  box-shadow:
    0 1px 1px rgba(255,255,255,.6) inset,
    0 -3px 5px rgba(0,0,0,.10) inset,
    0 3px 6px rgba(16,24,40,.16),
    0 1px 2px rgba(16,24,40,.10);
  border: 1px solid rgba(255,255,255,.5);
  overflow: hidden;
}
.kpi-tile .kpi-icon::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(155deg, rgba(255,255,255,.75) 0%, rgba(255,255,255,.15) 40%, rgba(255,255,255,0) 65%);
  pointer-events: none;
}
.kpi-tile .kpi-icon i { position: relative; filter: drop-shadow(0 1px 0.5px rgba(0,0,0,.12)); }
.kpi-tile .kpi-value { font-size: 1.35rem; font-weight: 800; color: var(--brand-ink); line-height: 1.1; }
.kpi-tile .kpi-label { font-size: .7rem; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.kpi-tile .kpi-trend { font-size: .68rem; font-weight: 600; color: var(--text-faint); }
/* Horizontal tile: icon beside the figure rather than above it. Named
   `.kpi-tile-h`, not `.kpi-row` — `.kpi-row` is the dashboard's grid
   container, and having both on one element made a tile inherit
   `display: grid` and a stray bottom margin from its own container class. */
.kpi-tile.kpi-tile-h { flex-direction: row; align-items: center; gap: .65rem; }
.kpi-tile.kpi-tile-h .kpi-icon { order: 0; align-self: center; }
.kpi-tile { transition: transform .15s ease, box-shadow .15s ease; }
.kpi-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.kpi-tile:hover .kpi-icon { transform: translateY(-1px); }
a.kpi-tile { text-decoration: none; color: inherit; cursor: pointer; }
a.kpi-tile:hover .kpi-value { color: var(--kpi-accent, var(--brand-primary)); }

/* Overview tiles that sit above the Workforce cards borrow that card's
   anatomy — caption on top, figure below, pushed to the same baseline — so
   the two rows read the same way instead of inverting on the reader. */
.kpi-tile.kpi-stat {
  height: auto;
  min-height: 92px;
  padding: .95rem 1rem 1rem;
  gap: .35rem;
  justify-content: flex-start;
}
.kpi-tile.kpi-stat .kpi-label {
  font-size: .72rem;
  letter-spacing: .05em;
  line-height: 1.35;
}
.kpi-tile.kpi-stat .kpi-value {
  font-size: 1.75rem;
  font-weight: 750;
  font-variant-numeric: tabular-nums;
  margin-top: auto;
}

.ageing-item { text-decoration: none; color: inherit; display: flex; cursor: pointer; }
.ageing-item:hover { background: var(--surface-alt, rgba(0,0,0,.02)); }

/* Empty states (used inside tables / lists / panels) */
.empty-state {
  text-align: center;
  padding: 2.75rem 1.5rem;
  color: var(--text-muted);
  font-size: .85rem;
}
.empty-state i {
  display: block;
  font-size: 1.9rem;
  color: var(--text-faint);
  margin-bottom: .6rem;
}
.empty-state h6,
.empty-state .empty-state-title {
  font-weight: 700;
  color: var(--text);
  font-size: .95rem;
  margin-bottom: .25rem;
}
.empty-state p { max-width: 48ch; margin-left: auto; margin-right: auto; }
.empty-state .btn { margin-top: 1rem; }

.section-heading {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: .9rem; flex-wrap: wrap; gap: .5rem;
}
.section-heading h4 { margin: 0; font-size: 1.15rem; }
.section-heading small { color: var(--text-muted); font-weight: 500; }

/* ---------------------------------------------------------------------
   Page banner (dark navy header card)
   ------------------------------------------------------------------- */
/* Page header. Plain type on the page ground rather than a filled navy bar:
   the bar belonged to the old dark-chrome design, and beside the white top bar
   and the light sidebar it read as a third, unrelated block of colour. The icon
   tile is the same shape and tint used on the KPI cards and panel headers, so
   the whole app speaks one language. */
.page-banner {
  background: none;
  padding: 0;
  color: inherit;
  display: flex; align-items: center; gap: .75rem;
  margin-bottom: 1.15rem;
}
.page-banner .page-banner-icon {
  width: 38px; height: 38px; border-radius: .6rem;
  background: var(--brand-primary-l); color: var(--brand-primary);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.05rem; flex-shrink: 0;
}
.page-banner h4 {
  color: var(--brand-ink); margin: 0;
  font-size: 1.35rem; font-weight: 750;
  letter-spacing: -.02em; line-height: 1.2;
}
.page-banner .page-banner-meta {
  color: var(--text-muted); font-size: .8rem; margin-top: .1rem;
  line-height: 1.4;
}
/* These buttons were white-on-navy. The bar is no longer navy, so white would
   be invisible; they are restyled here rather than in each page that uses one. */
.page-banner .btn-outline-light,
.page-banner .btn-light {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 600;
}
.page-banner .btn-outline-light:hover,
.page-banner .btn-light:hover {
  background: var(--brand-bg);
  border-color: #d7dbe7;
  color: var(--brand-ink);
}
/* Keep the header to a single line of description — a long sentence that wraps
   is what makes these bars grow tall. */
.page-banner > div:not(.page-banner-icon):not(.page-banner-actions) { min-width: 0; }
.page-banner .page-banner-actions {
  margin-left: auto;
  display: flex; align-items: center; gap: .4rem;
  flex-shrink: 0;
}
.page-banner .page-banner-actions .btn { white-space: nowrap; }
.page-banner .page-banner-actions .btn-sm { padding: .25rem .6rem; font-size: .8rem; }
/* A picker sat in the header (the candidate requisition select) is capped so it
   cannot stretch the bar. */
.page-banner .page-banner-actions .form-select,
.page-banner .page-banner-actions .form-control { max-width: 260px; }

/* Thin variant: smaller icon and heading, for a preview or a nested screen. */
.page-banner.page-banner-sm { gap: .65rem; }
.page-banner.page-banner-sm .page-banner-icon { width: 32px; height: 32px; border-radius: .5rem; font-size: .92rem; }
.page-banner.page-banner-sm h4 { font-size: 1.1rem; }
.page-banner.page-banner-sm .page-banner-meta { font-size: .76rem; }

/* Small caps section label used above a row of KPI tiles */
.section-label-bar {
  display: flex; align-items: center; gap: .4rem;
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted);
  margin: 1.5rem 0 .6rem;
}
.section-label-bar:first-child { margin-top: 0; }
.section-label-bar i { font-size: .85rem; }

/* Settings page: icon-badged card headers */
.settings-card { border-radius: var(--radius-lg); }
.settings-card-header { display: flex; align-items: center; gap: .7rem; margin-bottom: 1.1rem; }
.settings-card-icon {
  width: 40px; height: 40px; border-radius: .65rem; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 1.05rem;
  position: relative; overflow: hidden;
  border: 1px solid rgba(255,255,255,.5);
  box-shadow:
    0 1px 1px rgba(255,255,255,.6) inset,
    0 -3px 5px rgba(0,0,0,.10) inset,
    0 3px 6px rgba(16,24,40,.16),
    0 1px 2px rgba(16,24,40,.10);
}
.settings-card-icon::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(155deg, rgba(255,255,255,.75) 0%, rgba(255,255,255,.15) 40%, rgba(255,255,255,0) 65%);
  pointer-events: none;
}
.settings-card-icon i { position: relative; filter: drop-shadow(0 1px 0.5px rgba(0,0,0,.12)); }
.settings-card-header h5 { margin: 0; }
.settings-card-header .settings-card-sub { font-size: .78rem; color: var(--text-muted); margin-top: .1rem; }

/* Secondary links inside a settings card — related screens that belong to the
   thing this card configures. Quieter than a button row so the card keeps one
   obvious primary action. */
.settings-links {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1.15rem;
  margin-top: .9rem;
  padding-top: .8rem;
  border-top: 1px solid var(--border);
}
.settings-links a {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .82rem;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
}
.settings-links a i { font-size: .95rem; color: var(--text-faint); }
.settings-links a:hover { color: var(--brand-primary); }
.settings-links a:hover i { color: var(--brand-primary); }


/* Dark navy panel header used on list-style cards */
.panel-dark {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.panel-dark-header {
  background: linear-gradient(120deg, var(--brand-ink), #1f4d78 130%);
  color: #fff;
  padding: .7rem 1.1rem;
  font-weight: 700;
  font-size: .88rem;
  display: flex; align-items: center; gap: .5rem;
}
.panel-dark-header i { opacity: .9; }
.panel-dark-body { padding: .6rem 1.1rem; }

/* ---------------------------------------------------------------------
   Today's Activity feed (dashboard)
   ------------------------------------------------------------------- */
.panel-dark-header .activity-count {
  background: rgba(255,255,255,.18);
  border-radius: 999px;
  padding: .05rem .5rem;
  font-size: .72rem;
  font-weight: 700;
}
.activity-scope-note {
  padding: .5rem 1.1rem;
  background: var(--brand-primary-l);
  color: var(--text-muted);
  font-size: .76rem;
  border-bottom: 1px solid var(--border);
}
.wf-kpi-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1rem; /* matches the Bootstrap g-3 gutter on the row above */
  margin-bottom: .25rem;
}
.wf-kpi {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: .95rem 1rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 3px solid var(--wf-ink, var(--brand-primary));
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: inherit;
  transition: box-shadow .15s, transform .15s;
}
a.wf-kpi:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); color: inherit; }
.wf-kpi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.wf-kpi-label {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-muted);
  line-height: 1.35;
}
.wf-kpi-icon {
  width: 30px; height: 30px;
  border-radius: .5rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .85rem;
  flex-shrink: 0;
}
.wf-kpi-value {
  font-size: 1.75rem;
  font-weight: 750;
  line-height: 1.1;
  color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
  margin-top: auto;
}
.wf-kpi-note { font-size: .72rem; color: var(--text-faint); line-height: 1.4; }
.wf-kpi-spark { margin: .15rem 0 .1rem; line-height: 0; height: 26px; }
.wf-kpi-spark .spark { width: 100%; height: 26px; display: block; }

/* Panels: a light header with a coloured icon. The navy is reserved for the
   top bar and the sidebar, so the page has one dark anchor instead of five. */
/* Panels in a .row-stretch all reach the height of the tallest one, so a row
   of side-by-side cards has one baseline along the bottom instead of three
   ragged edges. The column is the flex parent; the panel fills it. */
.row-stretch > [class*="col-"] { display: flex; }
.row-stretch > [class*="col-"] > .panel-soft {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  width: 100%;
}
/* ...and inside the panel the body takes the slack while the footnote sits on
   the bottom edge, so a card reads as full rather than as content that stopped
   halfway down with dead space underneath. */
.row-stretch > [class*="col-"] > .panel-soft > .funnel,
.row-stretch > [class*="col-"] > .panel-soft > .metric-bars,
.row-stretch > [class*="col-"] > .panel-soft > .activity-list {
  flex: 1 1 auto;
}
/* The rows start straight under the panel header and stay at their natural
   pitch. Spreading them to fill the card pushed 38px between rows only 22px
   tall, and centring the group left an 87px void above the first row — both
   read as a fault. Starting at the top puts the leftover height at the bottom
   edge, where it looks like padding rather than a hole. */
.row-stretch > [class*="col-"] > .panel-soft > .funnel,
.row-stretch > [class*="col-"] > .panel-soft > .metric-bars {
  justify-content: flex-start;
}

.panel-soft {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
/* Header bands are the logo's blue, filled — the strongest way to carry the
   brand through the interface. White type sits on it at 12.12:1, and the
   action link uses a light orange (5.62:1) so the one interactive thing in
   the band is still distinguishable from the label beside it. */
.panel-soft-header {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .7rem 1.1rem;
  background: var(--brand-logo);
  border-bottom: 1px solid var(--brand-logo);
  font-weight: 700;
  font-size: .88rem;
  color: #fff;
}
.panel-soft-icon {
  width: 26px; height: 26px;
  border-radius: .45rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .8rem;
  flex-shrink: 0;
}
.panel-soft-action {
  margin-left: auto; font-size: .78rem; font-weight: 600; text-decoration: none;
  color: #f79a5e;
  /* The link is short and fixed; a long panel title should shrink before this
     breaks onto a second line and makes one header band taller than its
     neighbours. */
  white-space: nowrap; flex: none;
}
.panel-soft-action:hover { text-decoration: underline; color: #ffb37a; }
.panel-soft-body { padding: .6rem 1.1rem; }
.panel-soft-header .activity-heading-link { color: #fff; text-decoration: none; }
.panel-soft-header .activity-heading-link:hover { color: #f79a5e; }
.panel-soft-header .activity-count {
  background: rgba(255,255,255,.18);
  color: #fff;
  border-radius: 999px;
  padding: .05rem .5rem;
  font-size: .72rem;
  font-weight: 700;
}

/* Hiring funnel */
.funnel { padding: .9rem 1.1rem .4rem; display: flex; flex-direction: column; gap: .55rem; }
.funnel-row { display: flex; align-items: center; gap: .75rem; }
/* Funnel and source rows are links to the candidates behind them. They keep
   their own colours rather than turning link-blue — the bar is the affordance,
   and a row of blue labels would read as five separate calls to action. The
   hover pad is pulled out into the panel's padding so the bars stay aligned. */
a.funnel-row, a.metric-row {
  color: inherit;
  text-decoration: none;
  margin: 0 -.5rem;
  padding: .15rem .5rem;
  border-radius: .4rem;
  transition: background-color .12s ease;
}
a.funnel-row:hover, a.metric-row:hover { background: var(--brand-bg); }
a.funnel-row:hover .funnel-label, a.metric-row:hover .metric-label { color: var(--brand-primary); }
a.funnel-row:focus-visible, a.metric-row:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: 1px;
  background: var(--brand-bg);
}
.funnel-label {
  width: 120px; flex-shrink: 0;
  font-size: .8rem; font-weight: 600; color: var(--text);
  display: flex; align-items: center; gap: .4rem;
}
.funnel-label i { color: var(--text-faint); font-size: .85rem; }
.funnel-track {
  flex: 1; min-width: 0;
  height: 22px;
  background: var(--brand-bg);
  border-radius: .35rem;
  overflow: hidden;
}
.funnel-bar {
  height: 100%;
  border-radius: .35rem;
  background: linear-gradient(90deg, var(--brand-primary), var(--brand-accent));
  min-width: 4px;
}
.funnel-count {
  width: 38px; flex-shrink: 0; text-align: right;
  font-size: .9rem; font-weight: 750; color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}
.funnel-conv {
  width: 48px; flex-shrink: 0; text-align: right;
  font-size: .78rem; font-weight: 600; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.funnel-foot {
  padding: .5rem 1.1rem .75rem;
  font-size: .72rem;
  color: var(--text-faint);
}

/* Needs attention */
.attention {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand-warning);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: .75rem .9rem .85rem;
  margin-bottom: .85rem;
}
.attention-head {
  display: flex; align-items: center; gap: .4rem;
  font-size: .74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted);
  margin-bottom: .6rem;
}
.attention-head i { color: var(--brand-warning); }
.attention-items {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: .5rem;
}
.attention-item {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  text-decoration: none; color: inherit;
  transition: background .12s, border-color .12s;
}
.attention-item:hover { background: var(--trow-hover); border-color: var(--brand-primary); color: inherit; }
.attention-icon {
  width: 28px; height: 28px;
  border-radius: .4rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .8rem; flex-shrink: 0;
}
.attention-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.attention-label { font-size: .8rem; font-weight: 600; line-height: 1.3; }
.attention-note { font-size: .71rem; color: var(--text-faint); line-height: 1.35; }
.attention-count {
  font-size: 1.05rem; font-weight: 750;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.attention-warn   .attention-icon { background: #fef3c7; color: var(--brand-warning); }
.attention-warn   .attention-count { color: var(--brand-warning); }
.attention-danger .attention-icon { background: #fee2e2; color: var(--brand-danger); }
.attention-danger .attention-count { color: var(--brand-danger); }
.attention-info   .attention-icon { background: #e0f2fe; color: var(--brand-accent); }
.attention-info   .attention-count { color: var(--brand-accent); }

@media (max-width: 575.98px) {
  .funnel-label { width: 92px; font-size: .74rem; }
  .funnel-conv { width: 40px; }
}
@media (max-width: 1200px) { .wf-kpi-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 767.98px) { .wf-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px) { .wf-kpi-grid { grid-template-columns: minmax(0, 1fr); } }
.activity-heading-link { color: #fff; text-decoration: none; }
.activity-heading-link:hover { color: #fff; text-decoration: underline; }
.activity-list { list-style: none; margin: 0; padding: 0; }
.activity-list li + li { border-top: 1px solid var(--border); }

.activity-item {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .6rem 1.1rem;
  text-decoration: none;
  color: inherit;
}
a.activity-item:hover { background: var(--trow-hover); }

.activity-icon {
  width: 28px; height: 28px;
  border-radius: .45rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .8rem;
  flex-shrink: 0;
  margin-top: .1rem;
}
.activity-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.activity-title { font-size: .84rem; font-weight: 600; color: var(--text); line-height: 1.35; }
.activity-meta  { font-size: .74rem; color: var(--text-muted); margin-top: .05rem; }
.activity-detail {
  font-size: .74rem;
  color: var(--text-faint);
  margin-top: .15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.activity-time {
  font-size: .74rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  margin-top: .15rem;
}
.activity-more {
  padding: .55rem 1.1rem;
  border-top: 1px solid var(--border);
  background: var(--thead-bg);
  font-size: .78rem;
}
.activity-more a { text-decoration: none; }

/* ---------------------------------------------------------------------
   Tables
   ------------------------------------------------------------------- */
.table { color: var(--text); border-color: var(--border); }
.table > :not(caption) > * > * { background-color: transparent; color: inherit; }
.table-modern { margin-bottom: 0; }
.table-modern thead th {
  background: var(--brand-logo);
  color: #fff;
  /* Held a step above the .72rem micro-label tier: column headers are read
     on every scan of a table, so they keep ~11px after the root drop. */
  font-size: .76rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  font-weight: 700;
  border-bottom: 1px solid var(--brand-logo);
  padding: .7rem .9rem;
  white-space: nowrap;
}
.table-modern tbody td { padding: .7rem .9rem; vertical-align: middle; border-bottom: 1px solid var(--border); }
.table-modern tbody tr:last-child td { border-bottom: none; }
.table-modern tbody tr { transition: background .1s; }
.table-modern tbody tr:hover { background: var(--trow-hover); }

/* A row that opens a page. The pointer says the whole row is the target; the
   first cell still holds a real link, so this only widens the hit area. */
tr[data-row-href], tr[data-row-toggle] { cursor: pointer; }
/* The link in the first cell carries no link styling — the row is the control,
   and a blue underline on one cell would suggest only that cell was clickable. */
.row-link { color: inherit; text-decoration: none; }
tr[data-row-href]:hover .row-link { color: var(--brand-primary); }
.row-link:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; border-radius: .25rem; }
.table-hover > tbody > tr:hover > * { background: var(--trow-hover); color: inherit; }
.table-sticky thead th { position: sticky; top: 0; background: var(--thead-bg); z-index: 1; }

/* ---------------------------------------------------------------------
   Buttons & form controls
   ------------------------------------------------------------------- */
.btn { border-radius: .55rem; font-weight: 600; font-size: .87rem; }
.btn-primary { background: var(--brand-primary); border-color: var(--brand-primary); }
.btn-primary:hover, .btn-primary:focus { background: var(--brand-primary-d); border-color: var(--brand-primary-d); }
.btn-outline-primary { color: var(--brand-primary); border-color: var(--brand-primary); }
.btn-outline-primary:hover { background: var(--brand-primary); border-color: var(--brand-primary); }
.btn-outline-secondary { color: var(--text-muted); border-color: var(--border); background: var(--surface); }
.btn-outline-secondary:hover { background: var(--brand-bg); color: var(--brand-ink); border-color: var(--border); }

.form-control, .form-select {
  border-radius: .55rem;
  border-color: var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: .87rem;
}
.form-control:focus, .form-select:focus {
  border-color: var(--brand-primary);
  box-shadow: 0 0 0 .18rem rgba(79,70,229,.14);
  background: var(--surface);
  color: var(--text);
}
.form-control::placeholder { color: var(--text-faint); }
.form-control:disabled, .form-select:disabled, .form-control[readonly] { background: var(--brand-bg); color: var(--text-muted); }
.form-label { font-weight: 600; font-size: .8rem; color: var(--brand-ink-2); margin-bottom: .3rem; }
/* Compact label used beside a field inside a dense panel. */
.form-label-sm { display: block; font-size: .74rem; font-weight: 600; color: var(--text-muted); margin-bottom: .2rem; }
.form-check-input:checked { background-color: var(--brand-primary); border-color: var(--brand-primary); }
.input-group-text { background: var(--brand-bg); border-color: var(--border); color: var(--text-muted); }

.badge { font-weight: 600; letter-spacing: .01em; }
.badge-stage { font-weight: 600; }

.dropdown-menu { background: var(--surface); border-color: var(--border); }
.dropdown-item { color: var(--text); }
.dropdown-item:hover, .dropdown-item:focus { background: var(--brand-bg); color: var(--brand-ink); }
.dropdown-divider { border-color: var(--border); }
.modal-content { background: var(--surface); border-color: var(--border); }
.modal-header, .modal-footer { border-color: var(--border); }
.list-group-item { background: var(--surface); border-color: var(--border); color: var(--text); }
hr { border-color: var(--border); }

/* ---------------------------------------------------------------------
   Stepper (requisition / candidate stage progress)
   ------------------------------------------------------------------- */
.stepper {
  display: flex;
  align-items: flex-start;
  overflow-x: auto;
  padding: .4rem .1rem 1rem;
  gap: 0;
}
.stepper .step {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 92px;
  flex: 1;
  position: relative;
  text-align: center;
}
.stepper .step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 15px;
  left: 55%;
  width: 90%;
  height: 2px;
  background: var(--border);
  z-index: 0;
}
.stepper .step.done:not(:last-child)::after { background: var(--brand-primary); }
.stepper .step .dot {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; font-weight: 700; color: var(--text-faint);
  position: relative; z-index: 1;
  flex-shrink: 0;
}
.stepper .step.done .dot { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.stepper .step.active .dot { border-color: var(--brand-primary); color: var(--brand-primary); box-shadow: 0 0 0 4px var(--brand-primary-l); }
.stepper .step .label {
  font-size: .68rem; font-weight: 600; color: var(--text-faint);
  margin-top: .4rem; line-height: 1.2; max-width: 92px;
}
.stepper .step.done .label, .stepper .step.active .label { color: var(--brand-ink); }
.stepper .step.cancelled .dot { border-color: var(--brand-danger); color: var(--brand-danger); }

/* ---------------------------------------------------------------------
   Workflow step cards (collapsed / active states)
   ------------------------------------------------------------------- */
.wf-step {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  margin-bottom: .9rem;
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.wf-step.wf-active { border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--brand-primary-l); }
.wf-step.wf-done .wf-step-header { background: var(--wf-done-bg); }
.wf-step-header {
  display: flex; align-items: center; gap: .7rem;
  padding: .9rem 1.1rem;
  cursor: default;
}
.wf-step-badge {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .78rem; font-weight: 700; flex-shrink: 0;
  background: var(--border); color: var(--text-muted);
}
.wf-step.wf-done .wf-step-badge { background: var(--brand-success); color: #fff; }
.wf-step.wf-active .wf-step-badge { background: var(--brand-primary); color: #fff; }
.wf-step-title { font-weight: 700; font-size: .95rem; color: var(--brand-ink); flex: 1; }
.wf-step-meta { font-size: .78rem; color: var(--text-muted); }
.wf-step-body { padding: 0 1.1rem 1.1rem; }
.wf-step-summary { padding: 0 1.1rem 1rem; font-size: .82rem; color: var(--text-muted); }
.wf-step-summary .kv { display: inline-block; margin-right: 1.25rem; }
.wf-step-summary .kv b { color: var(--brand-ink-2); font-weight: 600; }

/* ---------------------------------------------------------------------
   Timeline (candidate evaluation history)
   ------------------------------------------------------------------- */
.timeline { position: relative; padding-left: 1.7rem; }
.timeline::before {
  content: '';
  position: absolute; left: .55rem; top: .3rem; bottom: .3rem;
  width: 2px; background: var(--border);
}
.timeline-item { position: relative; margin-bottom: 1rem; }
.timeline-item::before {
  content: '';
  position: absolute; left: -1.7rem; top: .25rem;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--brand-primary);
}
.timeline-item.tl-pending::before { border-color: var(--border); }
.timeline-item.tl-rejected::before { border-color: var(--brand-danger); background: var(--brand-danger); }
/* A reversal of a rejection. Hollow, so it reads as a correction to the entry
   above it rather than as another decision in its own right. */
.timeline-item.tl-reinstated::before { border-color: var(--brand-warning, #b45309); background: var(--surface); }

/* ---------------------------------------------------------------------
   Score ring / scorecard bars
   ------------------------------------------------------------------- */
.score-bar-track { background: var(--border); border-radius: 999px; height: 8px; overflow: hidden; }
.score-bar-fill { height: 100%; border-radius: 999px; background: var(--brand-primary); }
.progress { background: var(--border); }
.progress-bar { background-color: var(--brand-primary); }
.progress-bar.bg-success { background-color: var(--brand-success) !important; }
.progress-bar.bg-primary { background-color: var(--brand-primary) !important; }

/* ---------------------------------------------------------------------
   Misc
   ------------------------------------------------------------------- */
.kanban-board { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: 1rem; }
.kanban-col { min-width: 260px; background: var(--kanban-col-bg); border-radius: .7rem; padding: .75rem; flex-shrink: 0; }
.kanban-col-header { font-weight: 700; font-size: .82rem; text-transform: uppercase; letter-spacing: .03em; color: var(--text-muted); margin-bottom: .6rem; display:flex; justify-content: space-between; }
.kanban-card { background: var(--surface); border-radius: .6rem; padding: .65rem .8rem; margin-bottom: .6rem; box-shadow: var(--shadow-xs); font-size: .84rem; border: 1px solid var(--border); }
.kanban-card .badge { font-size: .68rem; }

.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: radial-gradient(circle at top left, #312e81, var(--brand-ink) 70%); }
.login-card { max-width: 410px; width: 100%; border: none; border-radius: 1.1rem; box-shadow: var(--shadow-lg); }

.pill-filter { border-radius: 999px !important; }

/* ---------------------------------------------------------------------
   Zoho Recruit-inspired components: colour pills, source chips,
   initials avatars, list toolbar, refreshed Kanban board.
   ------------------------------------------------------------------- */

/* Colour tokens: bg tint / text / dot-or-solid, per semantic colour name.
   Reused by .pill (stage/status), .chip (source tag) and .avatar (initials). */
.pill-slate  { --c-bg:#f1f5f9; --c-text:#475569; --c-dot:#64748b; }
.pill-blue   { --c-bg:#eff6ff; --c-text:#1d4ed8; --c-dot:#3b82f6; }
.pill-violet { --c-bg:#f5f3ff; --c-text:#6d28d9; --c-dot:#8b5cf6; }
.pill-teal   { --c-bg:#f0fdfa; --c-text:#0f766e; --c-dot:#14b8a6; }
.pill-indigo { --c-bg:#eef2ff; --c-text:#4338ca; --c-dot:#6366f1; }
.pill-pink   { --c-bg:#fdf2f8; --c-text:#be185d; --c-dot:#ec4899; }
.pill-amber  { --c-bg:#fffbeb; --c-text:#b45309; --c-dot:#f59e0b; }
.pill-orange { --c-bg:#fff7ed; --c-text:#c2410c; --c-dot:#f97316; }
.pill-cyan   { --c-bg:#ecfeff; --c-text:#0e7490; --c-dot:#06b6d4; }
.pill-green  { --c-bg:#f0fdf4; --c-text:#15803d; --c-dot:#22c55e; }
.pill-red    { --c-bg:#fef2f2; --c-text:#b91c1c; --c-dot:#ef4444; }
.pill-gray   { --c-bg:#f4f4f5; --c-text:#52525b; --c-dot:#71717a; }

.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  background: var(--c-bg); color: var(--c-text);
  padding: .22rem .6rem .22rem .5rem;
  border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .01em;
  white-space: nowrap; line-height: 1.4;
}
.pill-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--c-dot); flex-shrink: 0; }

.chip {
  display: inline-flex; align-items: center; gap: .2rem;
  background: var(--c-bg); color: var(--c-text);
  border: 1px solid color-mix(in srgb, var(--c-dot) 30%, transparent);
  padding: .18rem .55rem;
  border-radius: .4rem;
  font-size: .7rem; font-weight: 600;
  white-space: nowrap; line-height: 1.4;
}
.chip-slate  { --c-bg:#f1f5f9; --c-text:#475569; --c-dot:#64748b; }
.chip-blue   { --c-bg:#eff6ff; --c-text:#1d4ed8; --c-dot:#3b82f6; }
.chip-violet { --c-bg:#f5f3ff; --c-text:#6d28d9; --c-dot:#8b5cf6; }
.chip-teal   { --c-bg:#f0fdfa; --c-text:#0f766e; --c-dot:#14b8a6; }
.chip-indigo { --c-bg:#eef2ff; --c-text:#4338ca; --c-dot:#6366f1; }
.chip-amber  { --c-bg:#fffbeb; --c-text:#b45309; --c-dot:#f59e0b; }
.chip-green  { --c-bg:#f0fdf4; --c-text:#15803d; --c-dot:#22c55e; }
.chip-red    { --c-bg:#fef2f2; --c-text:#b91c1c; --c-dot:#ef4444; }
/* Archive, on a row that still counts as a hire. Bootstrap's own
   btn-outline-warning is #ffc107 — about 1.6:1 on white, so the icon all but
   vanishes on the one button that most needs a second look. */
.btn-archive-caution {
  color: #b45309;
  border: 1px solid #e3b273;
  background: #fff;
}
.btn-archive-caution:hover,
.btn-archive-caution:focus {
  color: #fff;
  background: #b45309;
  border-color: #b45309;
}

.chip-cyan   { --c-bg:#ecfeff; --c-text:#0e7490; --c-dot:#06b6d4; }
.chip-gray   { --c-bg:#f4f4f5; --c-text:#52525b; --c-dot:#71717a; }

/* Sourcing-channel mark. Stands in for the channel name in Source
   Effectiveness, where seven text labels cost more width than they earn.
   Colour arrives inline from SOURCE_MARKS so one rule serves every channel. */
.source-mark {
  width: 30px; height: 30px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: .5rem;
  font-size: .95rem; line-height: 1;
}
.source-mark-text { font-size: .82rem; font-weight: 800; letter-spacing: -.02em; }
/* A channel with nothing in it yet is still worth listing — dimmed, so the
   eye lands on the channels that are actually producing. */
.source-mark-dim { opacity: .45; filter: saturate(.45); }

/* Initials avatar, colour deterministically derived from the candidate's name */
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; font-weight: 700; color: #fff; flex-shrink: 0;
  background: var(--a-solid, var(--brand-primary));
}
.avatar-md { width: 34px; height: 34px; font-size: .78rem; }
.avatar-lg { width: 52px; height: 52px; font-size: 1.1rem; }
.avatar-sm { width: 26px; height: 26px; font-size: .66rem; }
.avatar-blue   { --a-solid: #3b82f6; }
.avatar-violet { --a-solid: #8b5cf6; }
.avatar-teal   { --a-solid: #14b8a6; }
.avatar-indigo { --a-solid: #6366f1; }
.avatar-pink   { --a-solid: #ec4899; }
.avatar-amber  { --a-solid: #f59e0b; }
.avatar-orange { --a-solid: #f97316; }
.avatar-cyan   { --a-solid: #06b6d4; }
.avatar-green  { --a-solid: #22c55e; }
.avatar-slate  { --a-solid: #64748b; }

/* Candidate identity cell: avatar + name + meta, used in tables & kanban cards */
.candidate-id { display: flex; align-items: center; gap: .65rem; min-width: 0; }
.candidate-id .cid-text { min-width: 0; }
.candidate-id .cid-name { font-weight: 650; color: var(--brand-ink); display: flex; align-items: center; gap: .35rem; }
.candidate-id .cid-meta { font-size: .75rem; color: var(--text-muted); }

/* List/Kanban toolbar: search + filters + view toggle */
.list-toolbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: .6rem;
  margin-bottom: 1rem;
}
.list-toolbar .search-box { position: relative; flex: 1 1 220px; max-width: 320px; }
.list-toolbar .search-box i {
  position: absolute; left: .7rem; top: 50%; transform: translateY(-50%);
  color: var(--text-faint); font-size: .85rem;
}
.list-toolbar .search-box input { padding-left: 2rem; }
.list-toolbar .spacer { flex: 1 1 auto; }

/* Buttons in a table's last column. They live in this wrapper rather than on the
   <td> itself: making the cell the flex container takes it out of the table
   layout, so its width stops agreeing with the header and the column drifts.
   The buttons stay on one line and the cell reserves the width they need, so
   the column agrees with its header; a table too wide for the viewport scrolls
   inside its own `.table-responsive` rather than wrapping into ragged rows. */
.row-actions {
  display: flex; align-items: center; gap: .35rem;
  justify-content: flex-end; flex-wrap: nowrap;
}
.row-actions form { margin: 0; }
.row-actions .btn { white-space: nowrap; }
td:has(> .row-actions) { white-space: nowrap; width: 1%; }

/* Segmented control: the `.view-toggle` shape reused for a pair of in-form
   tabs. Bootstrap's own `.nav-pills` paints the selected tab in its stock
   blue, which is the one colour on the page belonging to no palette. */
.segmented {
  display: inline-flex; width: 100%;
  background: var(--brand-bg); border: 1px solid var(--border);
  border-radius: .55rem; padding: .2rem; gap: .2rem;
}
.segmented a {
  flex: 1 1 0; text-align: center;
  padding: .34rem .75rem; border-radius: .4rem;
  font-size: .8rem; font-weight: 600; color: var(--text-muted);
  text-decoration: none; transition: background .12s, color .12s;
}
.segmented a.active { background: var(--surface); color: var(--brand-ink); box-shadow: var(--shadow-xs); }
.segmented a:hover:not(.active) { color: var(--brand-ink); }

.view-toggle {
  display: inline-flex; background: var(--brand-bg); border: 1px solid var(--border);
  border-radius: .55rem; padding: .2rem;
}
.view-toggle a {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .32rem .75rem; border-radius: .4rem;
  font-size: .8rem; font-weight: 600; color: var(--text-muted);
  text-decoration: none; transition: background .12s, color .12s;
}
.view-toggle a.active { background: var(--surface); color: var(--brand-ink); box-shadow: var(--shadow-xs); }
.view-toggle a:hover:not(.active) { color: var(--brand-ink); }

/* Refreshed Kanban board: colour-accented column headers, richer candidate cards */
.kanban-board { align-items: flex-start; }
.kanban-col {
  background: var(--brand-bg);
  border: 1px solid var(--border);
  border-top: 3px solid var(--col-accent, var(--brand-primary));
  border-radius: var(--radius);
  padding: 0;
  overflow: hidden;
}
.kanban-col-header {
  text-transform: none; letter-spacing: 0; font-size: .82rem;
  color: var(--brand-ink); padding: .75rem .85rem .6rem;
  margin-bottom: 0;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.kanban-col-header .badge { background: var(--col-accent, var(--brand-primary)) !important; color: #fff; font-weight: 700; }
.kanban-col-body { padding: .7rem; }
.kanban-card {
  border-radius: .7rem;
  padding: .75rem .85rem;
  box-shadow: var(--shadow-xs);
  border: 1px solid var(--border);
  transition: box-shadow .15s, transform .15s;
}
.kanban-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.kanban-card .kc-tags { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .55rem; }

/* ---------------------------------------------------------------------
   Small general-purpose utilities
   ------------------------------------------------------------------- */
.text-faint { color: var(--text-faint) !important; }
.text-body { color: var(--text) !important; }
.tabular { font-variant-numeric: tabular-nums; }
.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .85em;
  font-variant-numeric: tabular-nums;
}

.link-with-icon {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .85rem; font-weight: 600;
}
.link-with-icon i { font-size: .78rem; }

.linkedin-icon-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: #e8f1fb; color: #0a66c2;
  font-size: 1rem; transition: background .12s, color .12s, transform .12s;
}
.linkedin-icon-link:hover { background: #0a66c2; color: #fff; transform: translateY(-1px); }

/* Let a dropdown menu inside a scrollable table actually show above the
   table instead of being clipped by the wrapper's overflow-x:auto. */
.table-responsive.dropdown-open-overflow { overflow: visible; }

/* Clickable KPI tile used as a filter (e.g. Website Applications status tiles) */
.wa-kpi-tile {
  cursor: pointer;
  transition: box-shadow .15s, transform .15s, border-color .15s;
}
.wa-kpi-tile:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.wa-kpi-active {
  border-color: var(--kpi-accent, var(--brand-primary));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--kpi-accent, var(--brand-primary)) 16%, transparent);
}

/* Lightweight rich-text editor used by the Email Templates and Compose Email
   screens — a contenteditable surface styled to match .form-control. */
.email-editor-toolbar {
  flex-wrap: wrap;
}
.email-editor-toolbar .btn {
  border-color: var(--border);
  color: var(--text-muted);
}
.email-editor-toolbar .btn:hover {
  background: var(--brand-primary-l);
  color: var(--brand-primary-d);
  border-color: var(--brand-primary-l);
}
.email-editor-surface {
  min-height: 220px;
  max-height: 480px;
  overflow-y: auto;
  padding: .85rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: .92rem;
  line-height: 1.55;
}
.email-editor-surface:focus {
  outline: none;
  border-color: var(--brand-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary) 14%, transparent);
}
.email-editor-surface p { margin-bottom: .75rem; }
.email-editor-surface a { color: var(--brand-primary); }
.email-editor-surface ul, .email-editor-surface ol { padding-left: 1.4rem; margin-bottom: .75rem; }

/* =====================================================================
   Components added alongside the newer features — duplicate review, seat
   tracking, pagination, the dashboard worklist. Drawn in the same language
   as everything above: indigo accent, .85rem radius, soft shadow.
   ===================================================================== */

/* Inline notice — a message that means something, sat in the page flow. */
.notice {
  display: flex; align-items: flex-start; gap: .75rem;
  padding: .75rem 1rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-faint);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  font-size: .85rem;
  color: var(--text);
}
.notice > i { font-size: 1rem; line-height: 1.4; flex-shrink: 0; color: var(--text-muted); }
.notice > div { flex: 1; min-width: 0; }
.notice strong { color: var(--brand-ink); font-weight: 700; }
.notice .btn { flex-shrink: 0; align-self: center; }
.notice-info    { border-left-color: var(--brand-primary); background: var(--brand-primary-l); }
.notice-info > i { color: var(--brand-primary); }
.notice-success { border-left-color: var(--brand-success); background: #f0fdf4; }
.notice-success > i { color: var(--brand-success); }
.notice-warning { border-left-color: var(--brand-warning); background: #fffbeb; }
.notice-warning > i { color: var(--brand-warning); }
.notice-danger  { border-left-color: var(--brand-danger); background: #fef2f2; }
.notice-danger > i { color: var(--brand-danger); }

/* A thin header strip inside a card, grouping the rows beneath it. */
.card-strip {
  display: flex; align-items: center; gap: .5rem;
  padding: .7rem 1.1rem;
  border-bottom: 1px solid var(--border);
  background: var(--thead-bg);
  border-radius: var(--radius) var(--radius) 0 0;
  font-size: .82rem;
}

/* Pagination, shown under a long list. */
.list-pager {
  display: flex; align-items: center; flex-wrap: wrap; gap: .75rem;
  padding: .7rem 1.1rem;
  border-top: 1px solid var(--border);
  font-size: .82rem;
  color: var(--text-muted);
}
.list-pager-count strong { color: var(--brand-ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.list-pager-controls { display: flex; align-items: center; gap: .25rem; margin-left: auto; }
.list-pager-btn,
.list-pager-num {
  display: inline-flex; align-items: center; gap: .25rem;
  min-width: 32px; height: 32px;
  padding: 0 .5rem;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: .45rem;
  background: var(--surface);
  color: var(--text-muted);
  font-size: .82rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: background .12s, border-color .12s, color .12s;
}
a.list-pager-btn:hover,
a.list-pager-num:hover { background: var(--brand-bg); color: var(--brand-ink); text-decoration: none; }
.list-pager-num.current { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.list-pager-btn.disabled { opacity: .45; pointer-events: none; }
.list-pager-gap { color: var(--text-faint); padding: 0 2px; }
@media (max-width: 575.98px) { .list-pager-btn span { display: none; } }

/* Seat meter — filled versus approved headcount on a requisition. */
.seat-meter { display: block; }
.seat-track { display: block; height: 5px; background: var(--border); border-radius: 999px; overflow: hidden; }
.seat-track > span { display: block; height: 100%; background: var(--text-faint); border-radius: 999px; }
.seat-ok   .seat-track > span { background: var(--brand-success); }
.seat-warn .seat-track > span { background: var(--brand-warning); }
.seat-idle .seat-track > span { background: var(--border); }
.seat-label { font-size: .75rem; color: var(--text-muted); margin-top: .25rem; font-variant-numeric: tabular-nums; }
.seat-label strong { color: var(--brand-ink); font-weight: 700; }

/* Dashboard worklist grid. */
.bento { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: .75rem; }
.bento-cell {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 1rem 1.1rem;
  grid-column: span 12;
  min-width: 0;
}
.bento-3, .bento-4, .bento-6, .bento-8 { grid-column: span 12; }
@media (min-width: 768px) {
  .bento-3 { grid-column: span 6; }
  .bento-4 { grid-column: span 6; }
  .bento-6 { grid-column: span 6; }
}
@media (min-width: 1200px) {
  .bento-3 { grid-column: span 3; }
  .bento-4 { grid-column: span 4; }
  .bento-6 { grid-column: span 6; }
  .bento-8 { grid-column: span 8; }
}
.cell-head { display: flex; align-items: baseline; gap: .5rem; margin-bottom: .7rem; }
.cell-head h6 { margin: 0; font-size: .9rem; font-weight: 700; }
.cell-link { margin-left: auto; font-size: .8rem; font-weight: 600; }
.cell-empty { margin: 0; font-size: .82rem; color: var(--text-muted); }
.cell-figure {
  font-size: 2rem; font-weight: 800; color: var(--brand-ink);
  line-height: 1; margin: 0 0 .4rem;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.bento-cell .btn { margin-top: .75rem; }

.work-list { list-style: none; margin: 0; padding: 0; }
.work-list li {
  display: flex; align-items: center; gap: .75rem;
  padding: .5rem 0;
  border-bottom: 1px solid var(--border);
}
.work-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.work-list li > a { flex: 1; min-width: 0; color: inherit; text-decoration: none; }
.work-list li > a:hover .work-name { color: var(--brand-primary); }
.work-name { display: block; font-weight: 650; color: var(--brand-ink); font-size: .87rem; }
.work-meta { display: block; font-size: .75rem; color: var(--text-muted); }
.work-when { font-size: .75rem; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Segmented view filter (All / In progress / Onboarded). */
.btn-seg { background: var(--surface); border: 1px solid var(--border); color: var(--text-muted); }
.btn-seg:hover { background: var(--brand-bg); color: var(--brand-ink); }
.btn-seg.active { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.btn-seg.active:hover { background: var(--brand-primary-d); border-color: var(--brand-primary-d); color: #fff; }

/* ---------------------------------------------------------------------
   Mobile navigation: hamburger button + off-canvas sidebar drawer
   ------------------------------------------------------------------- */
/* Ink on the white top bar. It was white, inherited from the old navy bar, and
   became invisible the moment the bar turned light. */
.sidebar-toggle-btn {
  background: transparent;
  border: none;
  color: var(--brand-ink);
  font-size: 1.35rem;
  line-height: 1;
  padding: .3rem .55rem;
  margin-right: .5rem;
  border-radius: .4rem;
}
.sidebar-toggle-btn:hover, .sidebar-toggle-btn:focus { background: var(--brand-bg); }

/* The close button now lives in .app-sidebar-head beside the logo, so the
   separate mobile-only header block it used to sit in has gone. */
.sidebar-close-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 1.1rem;
  padding: .25rem .5rem;
  border-radius: .4rem;
}
.sidebar-close-btn:hover { background: var(--brand-bg); color: var(--brand-ink); }

.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15,23,42,.5);
  z-index: 1040;
  opacity: 0;
  transition: opacity .2s ease;
}

@media (max-width: 991.98px) {
  .app-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: 82vw;
    max-width: 300px;
    height: 100vh;
    z-index: 1050;
    transform: translateX(-100%);
    transition: transform .25s ease;
    box-shadow: var(--shadow-lg);
    overflow-y: auto;
  }
  body.sidebar-open .app-sidebar { transform: translateX(0); }
  body.sidebar-open .sidebar-backdrop { display: block; opacity: 1; }
  body.sidebar-open { overflow: hidden; }

  /* Comfortable tap targets on touch devices */
  .app-sidebar .nav-link { padding: .7rem .75rem; font-size: .92rem; }

  /* Narrower screens want the space back for content. */
  /* Setting the gutter rather than the padding keeps the top bar and footer in
     step with the page: all three read the same variable. */
  :root { --app-gutter: 1.1rem; }
  .app-main .container-fluid { padding-top: 1rem; padding-bottom: 1.75rem; }

  /* Let page banners wrap their action buttons onto a new line instead
     of overflowing horizontally on narrow screens. */
  .page-banner { flex-wrap: wrap; row-gap: .6rem; }
  .page-banner .page-banner-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }
  .page-banner .page-banner-actions .btn { flex: 1 1 auto; }
}

@media (min-width: 992px) {
  /* The backdrop belongs to the off-canvas drawer, which only exists below this
     width. The toggle button itself stays: here it hides and shows the menu
     column rather than sliding a drawer over the page. */
  .sidebar-backdrop { display: none !important; }

  /* Collapsed by choice: the column narrows to a rail of icons rather than
     disappearing altogether. Removing it gave back the width but took the menu
     with it, so every jump to another section began by opening the menu again.
     The rail returns most of the space and still keeps every destination one
     click away, which is the point of collapsing it at all.

     What the rail looks like is at the foot of this file, kept in one piece so
     the collapsed state can be read as a whole. */
  body.sidebar-hidden .app-sidebar {
    width: 64px;
  }
}

/* Below the breakpoint the sidebar is a drawer, so the desktop collapsed state
   must not apply — otherwise the drawer could never be opened on a phone. */
@media (max-width: 991.98px) {
  body.sidebar-hidden .app-sidebar { display: block; }
}

/* Extra-small phones: tighten padding and font sizes a touch further */
@media (max-width: 420px) {
  :root { --app-gutter: .85rem; }
  .kpi-tile { padding: .65rem .7rem; height: 78px; }
  .kpi-tile .kpi-value { font-size: 1.15rem; }
  .kpi-tile .kpi-label { font-size: .62rem; }
  .kpi-tile.kpi-stat { padding: .7rem .75rem .75rem; min-height: 78px; }
  .kpi-tile.kpi-stat .kpi-value { font-size: 1.35rem; }
  .kpi-tile.kpi-stat .kpi-label { font-size: .64rem; }
  .page-banner { padding: 1rem; }
  .page-banner h4 { font-size: 1.1rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

@media print {
  .app-topbar, .app-sidebar, .sidebar-backdrop, .list-toolbar, .list-pager,
  .btn, .page-banner-actions { display: none !important; }
  .app-shell, .app-content { display: block; }
  .app-main .container-fluid { max-width: none; padding: 0; }
  .stat-card, .bento-cell { break-inside: avoid; }
  body { background: #fff; font-size: 11pt; }
}

/* Hiring performance: horizontal bars shared by Source Effectiveness and
   Average Days per Stage. Same rhythm as the funnel above, but the figure
   sits in its own column so it stays readable whatever the bar does. */
.metric-bars { padding: .9rem 1.1rem .4rem; display: flex; flex-direction: column; gap: .55rem; }
.metric-row { display: flex; align-items: center; gap: .75rem; }
.metric-label {
  width: 132px; flex-shrink: 0;
  font-size: .8rem; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.metric-label-wide { width: 178px; }
.metric-count {
  width: 42px; flex-shrink: 0; text-align: right;
  font-size: .9rem; font-weight: 750; color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}
.metric-track {
  flex: 1; min-width: 0;
  height: 22px;
  background: var(--brand-bg);
  border-radius: .35rem;
  overflow: hidden;
}
.metric-bar {
  height: 100%;
  border-radius: .35rem;
  background: linear-gradient(90deg, var(--brand-primary), var(--brand-accent));
  min-width: 4px;
  display: flex; align-items: stretch;
}
/* The darker inner segment is the share that actually joined. */
.metric-bar-strong {
  height: 100%;
  border-radius: .35rem;
  background: var(--brand-success);
  min-width: 4px;
}
.metric-bar-warn { background: linear-gradient(90deg, var(--brand-warning), var(--brand-danger)); }
.metric-side {
  width: 66px; flex-shrink: 0; text-align: right;
  font-size: .74rem; font-weight: 600; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.metric-row-flag .metric-label { color: var(--brand-danger); }

/* Source Effectiveness rows lead with the channel mark rather than a name, so
   the bar gets the width the label used to take. */
.metric-row-source { gap: .65rem; }
.metric-row-source .metric-track { height: 20px; }
/* An idle channel keeps its place in the list but recedes: hairline track, no
   figure weight, so seven rows still read as one producing channel. */
.metric-row-idle .metric-count { color: var(--text-faint); font-weight: 600; }
.metric-row-idle .metric-side { color: var(--text-faint); font-weight: 500; }
.metric-row-idle .metric-track { background: var(--brand-bg); opacity: .6; }
.metric-note { font-size: .72rem; color: var(--text-faint); line-height: 1.35; margin-top: .15rem; }
.metric-value-empty { color: var(--text-faint); font-weight: 600; }
.metric-key { display: inline-flex; align-items: center; gap: .3rem; margin-right: .9rem; }
.metric-key-swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.metric-key-light { background: linear-gradient(90deg, var(--brand-primary), var(--brand-accent)); }
.metric-key-dark { background: var(--brand-success); }
/* Source Effectiveness gives every channel its own hue, so the green is named
   inline in its footnote rather than keyed against a colour the bars share. */
.metric-key-inline { display: inline-flex; align-items: center; gap: .25rem; }
/* The joined segment butts straight against the channel colour, and cyan or
   teal against green is a soft edge. A hairline keeps the split readable on
   every hue; the track clips it when the bar is entirely joined. */
.metric-row-source .metric-bar-strong { box-shadow: 2px 0 0 var(--surface); }

@media (max-width: 640px) {
  .metric-label, .metric-label-wide { width: 104px; font-size: .74rem; }
  .metric-side { width: 52px; font-size: .68rem; }
}

/* =====================================================================
   CALENDAR — the dashboard's Today's Schedule panel and the Calendar page.
   One tone per event type, used by the rail, the chiplet and the pill so a
   colour means the same thing wherever it appears.
   ===================================================================== */
.cal-blue,   .cal-rail-blue   { --cal-c:#2563eb; --cal-bg:#eff6ff; --cal-ink:#1d4ed8; }
.cal-purple, .cal-rail-purple { --cal-c:#7c3aed; --cal-bg:#f5f3ff; --cal-ink:#6d28d9; }
.cal-green,  .cal-rail-green  { --cal-c:#059669; --cal-bg:#ecfdf5; --cal-ink:#047857; }
.cal-amber,  .cal-rail-amber  { --cal-c:#d97706; --cal-bg:#fffbeb; --cal-ink:#b45309; }
.cal-rail-slate               { --cal-c:#64748b; --cal-bg:#f1f5f9; --cal-ink:#475569; }

/* --- the strip under the panel header ------------------------------- */
.cal-today-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; flex-wrap: wrap;
  padding: .55rem .9rem; border-bottom: 1px solid var(--border);
  background: var(--brand-bg);
}
.cal-today-date { font-size: .78rem; font-weight: 600; color: var(--text-muted); }
.cal-today-counts { display: flex; gap: .35rem; flex-wrap: wrap; }
.cal-count {
  font-size: .68rem; font-weight: 700; padding: .16rem .45rem; border-radius: 999px;
  background: var(--cal-bg); color: var(--cal-ink); white-space: nowrap;
}
.cal-count-blue   { --cal-bg:#eff6ff; --cal-ink:#1d4ed8; }
.cal-count-purple { --cal-bg:#f5f3ff; --cal-ink:#6d28d9; }
.cal-count-green  { --cal-bg:#ecfdf5; --cal-ink:#047857; }
.cal-count-amber  { --cal-bg:#fffbeb; --cal-ink:#b45309; }

/* --- agenda rows (shared by the panel and the day column) ------------ */
.cal-agenda { display: flex; flex-direction: column; }
.cal-agenda-row {
  display: grid; grid-template-columns: 68px 3px 1fr auto;
  align-items: center; gap: .6rem;
  padding: .6rem .9rem; border-bottom: 1px solid var(--border);
  text-decoration: none; color: inherit; transition: background .12s ease;
}
.cal-agenda-row:last-child { border-bottom: 0; }
.cal-agenda-row:hover { background: var(--brand-bg); }
.cal-agenda-time {
  font-size: .74rem; font-weight: 700; color: var(--brand-ink);
  font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap;
}
.cal-agenda-time-allday { font-weight: 600; color: var(--text-muted); font-size: .68rem; }
.cal-agenda-rail { align-self: stretch; border-radius: 2px; background: var(--cal-c); min-height: 30px; }
.cal-agenda-body { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cal-agenda-title  { font-size: .82rem; font-weight: 600; color: var(--brand-ink);
                     overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-agenda-detail { font-size: .74rem; color: var(--text-muted);
                     overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-agenda-meta   { font-size: .69rem; color: var(--text-faint);
                     overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-agenda-side { white-space: nowrap; }

.cal-pill {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .66rem; font-weight: 700; padding: .17rem .45rem; border-radius: 999px;
  background: var(--cal-bg); color: var(--cal-ink);
}
.cal-pill i { font-size: .72rem; }
.cal-pill-blue   { --cal-bg:#eff6ff; --cal-ink:#1d4ed8; }
.cal-pill-purple { --cal-bg:#f5f3ff; --cal-ink:#6d28d9; }
.cal-pill-green  { --cal-bg:#ecfdf5; --cal-ink:#047857; }
.cal-pill-amber  { --cal-bg:#fffbeb; --cal-ink:#b45309; }

/* --- filter chips ---------------------------------------------------- */
.cal-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .74rem; font-weight: 600; padding: .28rem .6rem;
  border: 1px solid var(--border); border-radius: 999px;
  background: #fff; color: var(--text-muted); text-decoration: none;
  transition: all .12s ease;
}
.cal-chip:hover { border-color: var(--cal-c); color: var(--cal-ink); }
.cal-chip.is-on { background: var(--cal-bg); border-color: var(--cal-c); color: var(--cal-ink); }
.cal-chip-count {
  font-size: .66rem; font-weight: 700; padding: 0 .3rem; border-radius: 999px;
  background: var(--brand-bg); color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.cal-chip.is-on .cal-chip-count { background: rgba(255,255,255,.7); color: var(--cal-ink); }
.cal-chip-blue   { --cal-c:#2563eb; --cal-bg:#eff6ff; --cal-ink:#1d4ed8; }
.cal-chip-purple { --cal-c:#7c3aed; --cal-bg:#f5f3ff; --cal-ink:#6d28d9; }
.cal-chip-green  { --cal-c:#059669; --cal-bg:#ecfdf5; --cal-ink:#047857; }
.cal-chip-amber  { --cal-c:#d97706; --cal-bg:#fffbeb; --cal-ink:#b45309; }

/* --- month grid ------------------------------------------------------ */
.cal-month-head {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  padding: .7rem .9rem; border-bottom: 1px solid var(--border);
}
.cal-month-title { font-size: .95rem; font-weight: 700; color: var(--brand-ink); }
.cal-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 8px;
  border: 1px solid var(--border); color: var(--text-muted); text-decoration: none;
}
.cal-nav:hover { background: var(--brand-bg); color: var(--brand-primary); }

.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-dow {
  padding: .4rem .5rem; font-size: .68rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-muted); text-align: center;
  border-bottom: 1px solid var(--border); background: var(--brand-bg);
}
.cal-day {
  min-height: 96px; padding: .35rem .4rem;
  border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  display: flex; flex-direction: column; gap: .2rem;
  text-decoration: none; color: inherit; overflow: hidden;
  transition: background .12s ease;
}
.cal-day:nth-child(7n+7) { border-right: 0; }   /* the +7 offsets past the day-name row */
.cal-day:hover { background: var(--brand-bg); }
.cal-day-out { background: #fafbfc; }
.cal-day-out .cal-day-num { color: var(--text-faint); }
.cal-day-num {
  font-size: .74rem; font-weight: 700; color: var(--brand-ink);
  font-variant-numeric: tabular-nums; line-height: 1.4;
}
.cal-day-today .cal-day-num {
  display: inline-flex; align-items: center; justify-content: center; align-self: flex-start;
  min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px;
  background: var(--brand-primary); color: #fff;
}
.cal-day-sel { box-shadow: inset 0 0 0 2px var(--brand-primary); background: #fff; }
.cal-day-events { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cal-chiplet {
  font-size: .64rem; line-height: 1.35; padding: .1rem .3rem; border-radius: 4px;
  background: var(--cal-bg); color: var(--cal-ink);
  border-left: 2px solid var(--cal-c);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal-chiplet b { font-variant-numeric: tabular-nums; }
.cal-more { font-size: .62rem; font-weight: 600; color: var(--text-muted); padding-left: .3rem; }

@media (max-width: 991px) {
  .cal-day { min-height: 78px; }
  .cal-chiplet { font-size: .6rem; }
}
@media (max-width: 640px) {
  /* Below this width a chiplet cannot hold a readable name, so each day
     reduces to its number and a row of dots — one per event, colour-coded. */
  .cal-day { min-height: 54px; align-items: center; }
  .cal-day-events { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 3px; }
  .cal-chiplet {
    width: 6px; height: 6px; padding: 0; border-radius: 999px; border-left: 0;
    background: var(--cal-c); color: transparent; overflow: hidden;
  }
  /* The dots summarise, so the overflow count has to stay — otherwise nine
     events on a day read as three. */
  .cal-more { font-size: .58rem; padding: 0; align-self: center; }
  .cal-agenda-row { grid-template-columns: 58px 3px 1fr; }
  .cal-agenda-side { display: none; }
}

/* =====================================================================
   AUDIT LOG — a forensic table. The work here is scannability: a day's
   entries read as one block, and destructive actions are findable in a
   wall of rows without reading a word.
   ===================================================================== */
.audit-toolbar { flex-direction: column; align-items: stretch; gap: .55rem; }
.audit-filters {
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
}
.audit-filters .form-select, .audit-filters .form-control { width: auto; }

.audit-search { position: relative; flex: 1 1 260px; max-width: 380px; }
.audit-search i {
  position: absolute; left: .7rem; top: 50%; transform: translateY(-50%);
  color: var(--text-faint); font-size: .85rem; pointer-events: none;
}
.audit-search input {
  width: 100%; padding: .32rem .7rem .32rem 2rem;
  font-size: .8rem; line-height: 1.5;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: #fff; color: var(--text);
}
.audit-search input:focus {
  outline: none; border-color: var(--brand-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary) 14%, transparent);
}

.audit-dates { display: inline-flex; align-items: center; gap: .35rem; }
.audit-dates-sep { font-size: .74rem; color: var(--text-muted); }

/* Saved questions, not filters — they set the fields below and stay lit. */
.audit-quick { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.audit-quick-link {
  font-size: .72rem; font-weight: 600; padding: .2rem .55rem;
  border-radius: 999px; text-decoration: none;
  color: var(--text-muted); background: var(--brand-bg);
  border: 1px solid transparent; transition: all .12s ease;
}
.audit-quick-link:hover { color: var(--brand-primary); border-color: var(--border); }
.audit-quick-link.is-on {
  background: var(--brand-primary-l); color: var(--brand-primary);
  border-color: color-mix(in srgb, var(--brand-primary) 25%, transparent);
}

/* --- the table ------------------------------------------------------- */
.audit-table { font-size: .8rem; }
.audit-table thead th {
  position: sticky; top: 0; z-index: 2;
}
.audit-table td { padding-top: .45rem; padding-bottom: .45rem; vertical-align: middle; }

/* The date, lifted out of every row and stated once per day. */
.audit-day-row td {
  background: var(--brand-bg);
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  padding: .3rem .75rem !important;
}
.audit-day {
  font-size: .7rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--brand-ink);
}
.audit-day-date { font-size: .7rem; color: var(--text-faint); margin-left: .5rem; }

.audit-time {
  font-size: .74rem; color: var(--text-muted); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.audit-entity { display: inline-flex; align-items: center; gap: .35rem; min-width: 0; }
.audit-entity i { color: var(--text-faint); font-size: .85rem; flex: none; }
.audit-entity a { color: var(--brand-primary); text-decoration: none; font-weight: 600; }
.audit-entity a:hover { text-decoration: underline; }
.audit-id { color: var(--text-faint); font-variant-numeric: tabular-nums; }

.audit-action i { font-size: .78rem; }

/* One line, always — "System Admin" was wrapping to two and doubling row height. */
.audit-actor { display: inline-flex; align-items: center; gap: .4rem; min-width: 0; }
.audit-actor-name {
  font-weight: 600; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.audit-avatar {
  flex: none; width: 22px; height: 22px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand-primary-l); color: var(--brand-primary);
  font-size: .62rem; font-weight: 700; letter-spacing: .02em;
}
.audit-avatar-system { background: #f1f5f9; color: #64748b; font-size: .6rem; }

.audit-details {
  font-size: .76rem; color: var(--text-muted);
  min-width: 220px; max-width: 460px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* A hairline in the row's own colour, so deletions and permission changes are
   findable by eye without reading the action column. */
.audit-row-flag > td:first-child { position: relative; }
.audit-row-flag > td:first-child::before {
  content: ''; position: absolute; left: 0; top: 4px; bottom: 4px;
  width: 3px; border-radius: 0 2px 2px 0; background: var(--audit-flag, transparent);
}
.audit-flag-red    { --audit-flag: #dc2626; }
.audit-flag-amber  { --audit-flag: #d97706; }
.audit-flag-violet { --audit-flag: #8b5cf6; }

@media (max-width: 991px) {
  .audit-search { max-width: none; }
  .audit-details { min-width: 160px; }
}
@media (max-width: 640px) {
  .audit-filters > * { flex: 1 1 100%; }
  .audit-filters .form-select, .audit-filters .form-control { width: 100%; }
  .audit-dates { flex-wrap: nowrap; }
  .audit-dates .form-control { flex: 1 1 0; min-width: 0; }
}

/* =====================================================================
   PHONES
   ---------------------------------------------------------------------
   Everything below this line only applies at phone and small-tablet
   widths. It is one block rather than a media query per component so the
   phone layout can be read, and changed, as a single design rather than
   as twenty afterthoughts scattered through the file.

   Three things were actually wrong on a phone, and the rest follows from
   them: a card would not shrink below the width of a wide table inside
   it and dragged the whole page sideways; a data table showed two of its
   eight columns with nothing to say the other six existed; and controls
   sized for a mouse were 27px tall, well under what a thumb can hit.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Nothing may make the page wider than the screen
   ------------------------------------------------------------------- */
/* A flex or grid item will not shrink below its content's intrinsic
   width unless it is told it may, and a 1014px table is exactly that
   content. Without this the card grew to the table's width and took the
   document with it — Role Permissions rendered 780px wide on a 390px
   screen, so half of every row sat off the right edge with no scrollbar
   anywhere to reach it. */
@media (max-width: 991.98px) {
  .app-content, .app-main, .app-main .container-fluid,
  .card, .stat-card, .panel-soft, .bento-cell { min-width: 0; }
  .table-responsive { max-width: 100%; }
}

/* A card in a stretched row was never given its width, only its height.
   `.panel-soft` had the rule and `.card` did not, so a card in one of
   these rows shrank to fit its contents: the Calendar month grid was
   273px wide inside a 380px column, squeezing seven day cells into 39px
   each. This is wrong at every width — it is simply invisible on a
   desktop, where the contents are wide enough to fill the column. */
.row-stretch > [class*="col-"] > .card {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
}

/* ---------------------------------------------------------------------
   2. Data tables become cards
   ------------------------------------------------------------------- */
/* A table is a grid because a wide screen can hold one. At 390px it
   cannot, so each row becomes a card of label/value pairs. The labels
   are the table's own column headings, copied onto the cells by the
   script in footer.php — which is why no template had to be touched and
   a column added later is labelled here without anyone remembering.

   Above this breakpoint none of it applies and the table is a table. */
@media (max-width: 767.98px) {
  /* The wrapper scrolled sideways to reveal the columns. There is
     nothing left to reveal, so it stops scrolling and stops clipping
     the dropdown menus that sit in the last column. */
  .table-responsive.table-stacked { overflow: visible; }

  table.tbl-stack,
  table.tbl-stack > tbody,
  table.tbl-stack > tbody > tr,
  table.tbl-stack > tbody > tr > td { display: block; width: auto; }

  table.tbl-stack > thead { display: none; }

  table.tbl-stack { border-collapse: separate; border-spacing: 0; }

  table.tbl-stack > tbody > tr {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    box-shadow: var(--shadow-xs);
    margin: 0 0 .55rem;
    padding: .15rem 0 .35rem;
    overflow: hidden;
  }
  table.tbl-stack > tbody > tr:last-child { margin-bottom: 0; }
  /* The row-level hover and zebra treatments belong to a grid of rows.
     On a card they read as an accidental colour. */
  table.tbl-stack > tbody > tr:hover { background: var(--surface); }

  table.tbl-stack > tbody > tr > td {
    border: 0;
    padding: .3rem .8rem;
    display: flex;
    align-items: flex-start;
    gap: .8rem;
    font-size: .84rem;
    /* Both utilities land on these cells with !important, and both are
       column properties that stop making sense once the column is gone:
       a value that may not wrap simply runs off a 366px card, and a
       right-aligned "Actions" column becomes a right-aligned label with
       its buttons stranded under the next row's value. */
    white-space: normal !important;
    text-align: left !important;
    max-width: none;
  }

  /* The label sits in a fixed column so the values line up down the card
     instead of stepping in and out with the length of each heading. */
  table.tbl-stack > tbody > tr > td::before {
    content: attr(data-label);
    flex: 0 0 7.5rem;
    min-width: 0;
    font-size: .66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .045em;
    color: var(--text-muted);
    line-height: 1.6;
    word-break: break-word;
  }
  table.tbl-stack > tbody > tr > td > * { min-width: 0; }

  /* The cell's own contents, gathered into one box. Without it every
     element in the cell became a flex item beside the label — a name and
     the department under it ended up side by side rather than stacked. */
  table.tbl-stack > tbody > tr > td > .tbl-val {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
  }

  /* The first column identifies the record, so it becomes the card's
     heading: full width, no label, a rule under it. A table whose first
     column is not an identity (the Audit Log opens with a clock time)
     opts out with data-stack-lead="0" and keeps its label. */
  table.tbl-stack > tbody > tr > td.tbl-lead {
    display: block;
    padding: .6rem .8rem .55rem;
    margin-bottom: .2rem;
    border-bottom: 1px solid var(--border);
    font-size: .9rem;
  }
  table.tbl-stack > tbody > tr > td.tbl-lead::before { content: none; }

  /* An unnamed column is the row's actions. There is no label to show,
     so the buttons take the full width of the card. */
  table.tbl-stack > tbody > tr > td.tbl-nolabel { display: block; padding: .45rem .8rem .25rem; }
  table.tbl-stack > tbody > tr > td.tbl-nolabel::before { content: none; }

  /* A cell spanning the table is a day heading or an empty state. It was
     already full width and needs no label. */
  table.tbl-stack > tbody > tr > td.tbl-full { display: block; padding: .5rem .8rem; }
  table.tbl-stack > tbody > tr > td.tbl-full::before { content: none; }
  /* …and the row around it is not a record, so it is not a card. */
  table.tbl-stack > tbody > tr:has(> td.tbl-full) {
    border: 0; box-shadow: none; background: transparent; padding: 0;
  }

  /* An empty cell is a blank line on a phone rather than a tidy gap in a
     grid, so it leaves the card. */
  table.tbl-stack > tbody > tr > td.tbl-empty { display: none; }

  /* Cell contents that were sized for a table column. */
  /* A right-aligned actions column put its buttons against the right edge
     of a card whose labels start at the left — so the row read as two
     unrelated things. Alignment set anywhere inside a cell is unwound,
     not just on the cell itself, because most of these tables set it on a
     wrapper div rather than on the <td>. */
  table.tbl-stack > tbody > tr > td .row-actions,
  table.tbl-stack > tbody > tr > td .justify-content-end,
  table.tbl-stack > tbody > tr > td .justify-content-center {
    justify-content: flex-start !important;
    flex-wrap: wrap;
    gap: .4rem;
  }
  table.tbl-stack > tbody > tr > td .text-end,
  table.tbl-stack > tbody > tr > td .text-center { text-align: left !important; }
  /* Truncation is what you do when a column has a fixed width. */
  table.tbl-stack .text-truncate { white-space: normal; overflow: visible; text-overflow: clip; }


  /* The Audit Log's day separators and flagged rows keep their meaning:
     the heading is a heading, and a destructive entry keeps its stripe
     down the left edge of the card. */
  table.tbl-stack > tbody > tr.audit-day-row { margin: .9rem 0 .35rem; }
  table.tbl-stack > tbody > tr.audit-row-flag { border-left-width: 3px; }

  /* Role Permissions is a matrix, not a list: each card is one module and
     each labelled row is one role's tick. That is exactly the stacked
     shape, so it needs nothing beyond room for the checkbox. */
  table.tbl-stack.perm-matrix > tbody > tr > td { align-items: center; }

  /* Every one of these tables sits inside a panel, which was the frame
     around the grid. The rows are their own frames now, so a card of
     cards is one border too many. */
  .card:has(> .table-responsive.table-stacked),
  .card:has(> .table-responsive.table-stacked) {
    border: 0; background: transparent; box-shadow: none;
  }
  .card > .table-responsive.table-stacked { padding: 0; }
  /* …but the pager under it still needs its own line. */
  .card:has(> .table-responsive.table-stacked) > .list-pager { border-top: 0; padding-inline: 0; }
}

/* Above the breakpoint the wrapper is not a box at all: `display: contents`
   hoists its children back into the cell, so a table on a desktop lays out
   exactly as it did before any of this existed. */
.tbl-val { display: contents; }
/* One rule above does read the cell's direct child — `td:has(> .row-actions)`,
   which shrinks an actions column to its buttons. The wrapper is added at
   every width, so that selector would quietly stop matching and the column
   would go back to claiming its share of the table. This says the same thing
   through the wrapper. */
td:has(> .tbl-val > .row-actions) { white-space: nowrap; width: 1%; }

/* ---------------------------------------------------------------------
   3. Controls a thumb can hit
   ------------------------------------------------------------------- */
/* Buttons were 27px and selects 28px — fine under a cursor, too small
   under a finger, where about 44px is the target and 42px is as low as
   is comfortable. The 16px font on fields is not a style choice: below
   16px iOS zooms the whole page in when a field takes focus, and then
   leaves it zoomed. */
@media (max-width: 767.98px) {
  .btn,
  .list-pager-btn, .list-pager-num {
    min-height: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .btn-sm, .btn-group-sm > .btn { padding: .45rem .85rem; font-size: .85rem; }

  .form-control, .form-select,
  input[type="text"], input[type="email"], input[type="tel"],
  input[type="number"], input[type="search"], input[type="password"],
  input[type="date"], input[type="time"], input[type="url"] {
    min-height: 42px;
    font-size: 16px;
  }
  .form-control-sm, .form-select-sm { min-height: 42px; font-size: 16px; }
  textarea.form-control { min-height: 96px; }

  /* Checkboxes and radios are square by definition — a minimum height
     would stretch them into rectangles, so they are simply made bigger. */
  .form-check-input { width: 1.15rem; height: 1.15rem; margin-top: .15rem; }

  /* Links that act as controls: filter chips, quick links, tabs. */
  .audit-quick-link, .cal-chip, .filter-pill, .seg-btn, .tab-link {
    min-height: 38px;
    display: inline-flex;
    align-items: center;
  }
  /* These pills are tinted with the page's own background, which reads as
     a pill on a white toolbar and as nothing at all once the toolbar
     stacks onto the page. On a phone they have to look pressable. */
  .audit-quick-link {
    padding: .4rem .8rem;
    background: var(--surface);
    border-color: var(--border);
  }

  /* The pager's page numbers are the densest row of targets in the app. */
  .list-pager { justify-content: center; }
  .list-pager-controls { margin-left: 0; gap: .35rem; flex-wrap: wrap; justify-content: center; }
  .list-pager-count { width: 100%; text-align: center; }
  .list-pager-btn, .list-pager-num { min-width: 42px; }
}

/* ---------------------------------------------------------------------
   4. Toolbars, filters and page headers stack
   ------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  .list-toolbar { flex-direction: column; align-items: stretch; gap: .5rem; }
  .list-toolbar > form { display: flex; flex-wrap: wrap; gap: .5rem; width: 100%; }
  .list-toolbar > form > *,
  .list-toolbar > .btn, .list-toolbar > a.btn { flex: 1 1 100%; width: 100%; }
  .list-toolbar .search-box { flex: 1 1 100%; max-width: none; }
  .list-toolbar .spacer { display: none; }
  /* A row of filter pills scrolls rather than wrapping into four lines. */
  .list-toolbar .filter-pills, .seg-group {
    display: flex; gap: .4rem; overflow-x: auto; width: 100%;
    padding-bottom: .2rem; -webkit-overflow-scrolling: touch;
  }
  .list-toolbar .filter-pills > *, .seg-group > * { flex: 0 0 auto; }

  .page-banner { padding: .95rem 1rem; }
  .page-banner h4 { font-size: 1.15rem; }
  .page-banner-meta { font-size: .78rem; }

  /* Modals are sheets: full width, and never taller than the screen. */
  .modal-dialog { margin: .5rem; max-width: none; }
  .modal-body { max-height: calc(100vh - 11rem); overflow-y: auto; }
  .modal-footer { flex-wrap: wrap; gap: .5rem; }
  .modal-footer > .btn { flex: 1 1 auto; margin: 0; }
}

/* ---------------------------------------------------------------------
   5. Dashboard tiles
   ------------------------------------------------------------------- */
/* The figures sit on a shared baseline whatever their captions do. With
   the value packed straight under the label, "Active Employees" wrapping
   to two lines pushed its number a line below "Exits" beside it, and the
   pair read as two different sizes of card. */
.kpi-card-value { margin-top: auto; }

@media (max-width: 575.98px) {
  /* Two columns, fixed. auto-fit chose two at this width anyway, but the
     fifth tile then sat alone against a column of empty space — so the
     odd one out spans the row and lays itself out sideways instead. */
  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .55rem; }
  .kpi-row > :last-child:nth-child(odd) {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
  .kpi-row > :last-child:nth-child(odd) .kpi-card-value { margin-top: 0; }
  .kpi-card-label { font-size: .76rem; }
  .kpi-card-value { font-size: 1.45rem; }
}

/* ---------------------------------------------------------------------
   6. Measured rows: funnel, sources, days per stage
   ------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  /* 178px of label out of 366px of page left the bar no room to say
     anything. The label takes what it needs and the bar takes the rest. */
  .metric-label, .metric-label-wide { width: auto; flex: 1 1 5.5rem; min-width: 0; font-size: .76rem; }
  .metric-count { width: 34px; font-size: .82rem; }
  .metric-side { font-size: .68rem; }
  .metric-track { min-width: 48px; }

}

/* Source Effectiveness identifies its channels by a coloured mark and a
   tooltip. A phone has no hover, so four unnamed squares was the whole
   panel — the name is spelled out at that width instead. The base rule
   has to come after the media query above it, or it would simply undo
   it: same specificity, and the later rule wins. */
.metric-src-name { display: none; }
@media (max-width: 767.98px) {
  .metric-src-name {
    display: block;
    flex: 1 1 5rem;
    min-width: 0;
    font-size: .76rem;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* The mark and the figure give the name the rest of the row. */
  .metric-row-source .metric-count { flex: 0 0 auto; width: auto; min-width: 22px; }
  .metric-row-source .metric-track { flex: 1 1 40px; }
  .metric-row-source .metric-side { flex: 0 0 auto; }
}

/* ---------------------------------------------------------------------
   7. Things that are meant to scroll sideways
   ------------------------------------------------------------------- */
/* A pipeline board and a stage tracker are horizontal by nature — the
   fix is not to stop them scrolling but to make the scrolling obvious
   and to stop each panel taking the whole screen. */
@media (max-width: 767.98px) {
  .kanban-board {
    scroll-snap-type: x mandatory;
    gap: .6rem;
    padding-inline: .1rem;
  }
  .kanban-col { min-width: 78vw; scroll-snap-align: start; }

  .stepper {
    scroll-snap-type: x proximity;
    padding-bottom: .6rem;
    /* The tracker runs past the right edge; the fade says so. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
  }
  .stepper .step { min-width: 78px; scroll-snap-align: center; }
  .stepper .step .label { font-size: .66rem; }
}

/* ---------------------------------------------------------------------
   8. Calendar
   ------------------------------------------------------------------- */
@media (max-width: 575.98px) {
  /* Seven columns in 366px is 52px a day. The cells lose their padding
     before they lose their gridlines. */
  .cal-day { min-height: 74px; padding: .25rem .2rem; }
  .cal-dow { padding: .35rem .1rem; font-size: .6rem; }
  .cal-month-head { gap: .6rem; }
  .cal-chip { min-height: 38px; }
}

/* ---------------------------------------------------------------------
   9. The top bar and the drawer
   ------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  /* The menu button is the only way to the navigation on a phone, so it
     gets a full target rather than the 31px it had. */
  .sidebar-toggle-btn, .nav-icon-btn {
    min-width: 42px; min-height: 42px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .user-chip { min-height: 42px; }
  /* The drawer covers the page, so it must not also be scrolled behind. */
  body.sidebar-open { position: relative; }
  .app-sidebar .sidebar-brand { min-height: 44px; }
}


/* ===========================================================================
   THE WAY ACROSS TO THE OTHER SYSTEM
   ---------------------------------------------------------------------------
   "Getfive Home" sits below the menu, not in it: every entry above navigates
   within the HR dashboard, and this one leaves it altogether.

   Pinning it needs the column bounded to the viewport. Left alone, .app-sidebar
   stretches to the height of the PAGE, so on a long list the foot of the column
   lands well below the bottom of the screen and the link can only be reached by
   scrolling to the end of the page. Bounding it lets the menu scroll inside
   itself while the foot stays where it is.

   Desktop only. Below 992px the sidebar is already a fixed, full-height,
   scrolling drawer, where the link sits at the end of the menu and is reached
   by scrolling the drawer — which is correct there.
   =========================================================================== */
@media (min-width: 992px) {
  .app-sidebar {
    position: sticky;
    top: 0;
    height: 100vh;
    min-height: 0;
    align-self: flex-start;
    display: flex;
    flex-direction: column;
  }
  /* min-height:0 is what actually lets a flex child scroll rather than grow.
     flex-wrap:nowrap matters just as much: the menu carries Bootstrap's .nav,
     which wraps by default, so the moment the column's height is bounded the
     items that no longer fit wrap into a SECOND COLUMN rather than scrolling —
     HR Policies and Settings ended up as two loose icons beside the menu. */
  .app-sidebar > nav {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    flex-wrap: nowrap;
  }
}


/*
 * The menu scrolls inside itself, and the browser's default bar is a wide grey
 * slab down the edge that competes with the items beside it. A thin bar that
 * darkens on hover keeps the affordance without the furniture. Both syntaxes
 * are given because Firefox understands only the first and WebKit only the
 * second; neither hides the bar outright, so the menu never loses its scroll.
 */
.app-sidebar > nav { scrollbar-width: thin; scrollbar-color: #d8dce8 transparent; }
.app-sidebar > nav:hover { scrollbar-color: #b9c0d4 transparent; }
.app-sidebar > nav::-webkit-scrollbar { width: 6px; }
.app-sidebar > nav::-webkit-scrollbar-track { background: transparent; }
.app-sidebar > nav::-webkit-scrollbar-thumb { background: #d8dce8; border-radius: 3px; }
.app-sidebar > nav:hover::-webkit-scrollbar-thumb { background: #b9c0d4; }

/* ===========================================================================
   THE COLLAPSED SIDEBAR — a rail of icons
   ---------------------------------------------------------------------------
   Desktop only. Below 992px the sidebar is an off-canvas drawer and the same
   button opens and closes it, which is the right behaviour on a phone; nothing
   here applies there.

   The labels are bare text nodes inside each link, not elements, so there is
   nothing to hide directly. Collapsing the row's font-size removes them and the
   icon takes its own size back explicitly — which is also why Bootstrap's me-2
   has to be beaten with !important on the way out.
   =========================================================================== */
@media (min-width: 992px) {
  /* Animated so the change reads as the column narrowing rather than the page
     jumping. Declared on the sidebar itself so it runs in both directions. */
  .app-sidebar { transition: width .16s ease, padding .16s ease; }

  body.sidebar-hidden .app-sidebar {
    padding-left: .5rem;
    padding-right: .5rem;
    overflow-x: hidden;
  }

  /* The head keeps its 62px so the hairline beneath it still meets the one
     beneath the top bar and the two read as a single rule across the page. The
     wordmark itself goes: at 48px wide it would be a smudge rather than a logo,
     and it is still on the sign-in page and the chooser where it does its work. */
  body.sidebar-hidden .app-sidebar-head {
    margin-left: -.5rem;
    margin-right: -.5rem;
    padding: 0;
    justify-content: center;
  }
  body.sidebar-hidden .app-brand { display: none; }

  body.sidebar-hidden .app-sidebar .nav-link {
    justify-content: center;
    padding: .6rem 0;
    margin-bottom: .2rem;
    font-size: 0;
  }
  body.sidebar-hidden .app-sidebar .nav-link i {
    font-size: 1.05rem;
    width: auto;
    margin-right: 0 !important;
  }

  /* A waiting count still has to show, but there is no room for it beside the
     icon, so it becomes a marker in the corner of the row: enough to say
     something needs attention here, without pretending to be readable at this
     width. The number is back in full the moment the menu is opened. */
  body.sidebar-hidden .app-sidebar .nav-link .badge {
    position: absolute;
    top: .2rem;
    right: .5rem;
    margin-left: 0;
    min-width: 15px;
    padding: .05rem .22rem;
    font-size: .58rem;
    line-height: 1.15;
  }

  body.sidebar-hidden .app-sidebar .nav-divider {
    margin-left: .3rem;
    margin-right: .3rem;
  }
}
