/* ============================================================
   Webronic HRMS — Design System
   ------------------------------------------------------------
   Light and dark are both first-class: every colour below is a
   token, and nothing hard-codes a hex outside the two :root
   blocks. The theme is set by data-theme on <html>, written by
   the toggle in includes/footer.php.

   The component half (card, btn, badge, tabs, data-row, form,
   table, id-block, auth) keeps the SAME class names the older
   dossier stylesheet used, because employees/*.php and leave/*.php
   render against them. Renaming would have meant touching seven
   pages to change a colour scheme.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap');

:root {
  /* Blue sampled from the reference dashboard — a brighter, more saturated
     royal blue than the earlier #2362BD set. Applied everywhere: rail, primary
     buttons, links, active states, chart strokes. */
  --blue-900: #0A3D91;
  --blue-700: #0F5FD9;
  --blue-600: #1A6FE8;
  --blue-500: #4A90FF;
  --green-700: #087A35;
  --green-600: #07B022;
  --green-500: #3CB371;
  --gold-500: #F7931E;
  --purple-500: #7C6FD9;
  --radius: 10px;

  /* ── Type system (2026-09-17) ───────────────────────────────────────────
     ONE family for every word in the portal — headings, body, labels, figures.
     Plus Jakarta Sans: geometric, very legible at 13px, confident at 800.
     JetBrains Mono only for identifiers (employee codes, keys, references).
     Sizes come from this scale; weights are 400 body · 500 UI · 600 labels ·
     700 headings · 800 display. Nothing else. */
  --font-sans: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  --fs-xs: 12px; --fs-sm: 13px; --fs-base: 14px; --fs-md: 15px; --fs-lg: 17px;
  --fs-xl: 20px; --fs-2xl: 24px; --fs-3xl: 30px;
  --fs-display: clamp(38px, 4.2vw, 58px);

  /* Brand colours, sampled from the logo artwork: the W's ocean and continents. */
  --brand-ocean-900: #002474;
  --brand-ocean-700: #1561C2;
  --brand-ocean-600: #1B77D7;
  --brand-ocean-500: #2F8CF0;
  --brand-green-600: #5DA52A;
  --brand-green-500: #7CC242;
}

/* -------- Light (default) -------- */
html, html[data-theme="light"] {
  --bg: #F3F7FD;
  --surface: #FFFFFF;
  --surface-alt: #F7FAFF;
  --text: #16233D;
  --text-muted: #64748B;
  --text-faint: #94A3B8;
  --border: #E4EAF5;
  --shadow: 0 1px 2px rgba(16,42,90,.04), 0 10px 30px rgba(16,42,90,.06);
  --rail-w: 256px;             /* one source of truth: rail width and its backdrop */
  --sidebar-bg: linear-gradient(180deg, #1568E6 0%, #0D51C4 100%);
  --sidebar-text: rgba(255,255,255,.82);
  --sidebar-text-strong: #FFFFFF;
  --sidebar-hover: rgba(255,255,255,.12);
  --sidebar-active-bg: rgba(255,255,255,.18);
  --sidebar-border: rgba(255,255,255,.14);
  --sidebar-active: #E8F1FF;   /* soft blue tint used by tiles in the content area */
  --danger-bg: #FDECEC;
  --danger: #C6362E;
  --success-bg: #E6F7EC;
  --success: #087A35;
  --warn-bg: #FDF1DF;
  --warn: #B4700C;

  /* Workspace palette — the sign-in page's look, shared with the shell.
     Ocean blue and continent green are the logo's own colours. */
  --ws-page: radial-gradient(700px 520px at 100% 0%, rgba(47,140,240,.10), transparent 65%),
             radial-gradient(640px 520px at 40% 108%, rgba(124,194,66,.07), transparent 64%),
             radial-gradient(900px 700px at 104% 110%, rgba(47,140,240,.10), transparent 62%),
             linear-gradient(180deg, #F8FBFF 0%, #EEF4FC 100%);
  --ws-app: radial-gradient(1100px 620px at 72% -12%, rgba(27,119,215,.08), transparent 70%),
            radial-gradient(800px 600px at -6% 110%, rgba(124,194,66,.06), transparent 64%),
            linear-gradient(180deg, #F8FBFF 0%, #EEF4FC 100%);
  --ws-heading: #0B1A33;
  --ws-subheading: #334155;
  --ws-label: #1F2A3D;
  --ws-muted: #5B6B82;
  --ws-muted-strong: #3E4C63;
  --ws-placeholder: #97A3B6;
  --ws-accent: #1561C2;
  --ws-pill-bg: rgba(27,119,215,.07);
  --ws-pill-border: rgba(27,119,215,.16);
  --ws-card: #FFFFFF;
  --ws-card-border: #E5ECF5;
  --ws-card-shadow: 0 1px 2px rgba(11,26,51,.04), 0 28px 64px -18px rgba(11,40,90,.20);
  --ws-input: #FFFFFF;
  --ws-input-focus: #FFFFFF;
  --ws-input-border: #DCE4EF;
  --ws-input-hover: #C3D0E2;
  --ws-icon: #7C8BA1;
  --ws-ring: rgba(27,119,215,.16);
  --ws-button: #1568E6;   /* the rail's blue */
  --ws-side: #F5F8FC;
  --ws-grad-text: linear-gradient(92deg, #1561C2 0%, #1B77D7 48%, #4E9A24 100%);
  --ws-logo-filter: drop-shadow(0 1px 1px rgba(11,26,51,.28)) drop-shadow(0 6px 14px rgba(11,40,90,.10)) contrast(1.06);
  --ws-tagline: var(--ws-subheading);
  --ws-os: var(--ws-muted-strong);
  --ws-blue-bg: #DDEBFF;   --ws-blue-fg: #1A6FE8;
  --ws-purple-bg: #E5E2FF; --ws-purple-fg: #6558E0;
  --ws-green-bg: #D6F5E5;  --ws-green-fg: #0F9D58;
  --ws-amber-bg: #FFF0C9;  --ws-amber-fg: #E8930A;
}

/* -------- Dark -------- */
html[data-theme="dark"] {
  /* The logo's ocean blue, a shade deeper than the sign-in page so charts and
     links keep their contrast (was a neutral near-black #0B1220). */
  --bg: #011439;
  --surface: #072452;
  --surface-alt: #0A2C62;
  --text: #EDF3FC;
  --text-muted: #A3B6D4;
  --text-faint: #6F8AB3;
  --border: #173D75;
  --shadow: 0 1px 2px rgba(0,0,0,.25), 0 14px 36px rgba(0,0,0,.28);
  --sidebar-bg: linear-gradient(180deg, #06265A 0%, #011439 100%);
  --sidebar-text: rgba(226,235,250,.72);
  --sidebar-text-strong: #FFFFFF;
  --sidebar-hover: rgba(255,255,255,.07);
  --sidebar-active-bg: #2362BD;
  --sidebar-border: rgba(255,255,255,.09);
  --sidebar-active: #0E3470;
  --danger-bg: #3A1B1B;
  --danger: #F17A72;
  --success-bg: #10301D;
  --success: #4FD98B;
  --warn-bg: #3A2C12;
  --warn: #E0A64A;
  --blue-500: #5B9BFF;
  --blue-600: #5AA8F7;   /* links and accents: readable on the ocean-blue surfaces */
  --green-500: #4FD98B;

  --ws-page: radial-gradient(700px 520px at 100% 0%, rgba(47,140,240,.18), transparent 65%),
             radial-gradient(640px 520px at 40% 108%, rgba(124,194,66,.06), transparent 64%),
             radial-gradient(900px 700px at 104% 110%, rgba(47,140,240,.16), transparent 62%),
             linear-gradient(180deg, #032560 0%, #011237 100%);
  --ws-app: radial-gradient(1100px 620px at 72% -12%, rgba(27,119,215,.20), transparent 70%),
            radial-gradient(800px 600px at -6% 110%, rgba(124,194,66,.05), transparent 64%),
            linear-gradient(180deg, #02205A 0%, #011237 100%);
  --ws-heading: #F5F8FE;
  --ws-subheading: #D3DEEE;
  --ws-label: #DCE6F5;
  --ws-muted: #A3B6D4;
  --ws-muted-strong: #C9D7EC;
  --ws-placeholder: #6F8AB3;
  --ws-accent: #5AA8F7;
  --ws-pill-bg: rgba(90,168,247,.10);
  --ws-pill-border: rgba(90,168,247,.24);
  --ws-card: rgba(5,36,90,.62);
  --ws-card-border: rgba(90,168,247,.20);
  --ws-card-shadow: 0 30px 70px -20px rgba(0,0,0,.6);
  --ws-input: rgba(1,18,56,.55);
  --ws-input-focus: rgba(1,18,56,.78);
  --ws-input-border: rgba(120,170,235,.24);
  --ws-input-hover: rgba(120,170,235,.42);
  --ws-icon: #93AED6;
  --ws-ring: rgba(47,140,240,.28);
  --ws-button: #1F6FE0;
  --ws-side: #071A3C;
  --ws-grad-text: linear-gradient(92deg, #5AA8F7 0%, #7FC0FF 45%, #8FD354 100%);
  --ws-logo-filter: none;
  --ws-tagline: var(--ws-subheading);
  --ws-os: var(--ws-muted-strong);
  --ws-blue-bg: #1A63D6;   --ws-blue-fg: #FFFFFF;
  --ws-purple-bg: #5A4ED0; --ws-purple-fg: #FFFFFF;
  --ws-green-bg: #12A15A;  --ws-green-fg: #FFFFFF;
  --ws-amber-bg: #F2A516;  --ws-amber-fg: #FFFFFF;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 500;   /* Jakarta at 400 reads thin on screen — 500 is the body weight */
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  word-spacing: .025em;   /* Jakarta's native word space is tight at 13-15px */
  /* The sign-in page's soft blue field (--ws-page), behind every page. */
  background-color: var(--bg);
  background-image: var(--ws-app);
  background-attachment: fixed;
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  transition: background .2s, color .2s;
}

/* Headings: same family as everything else, set apart by weight and tighter
   tracking — not by a second typeface. (Lora + Inter read as two products;
   Velraj, 2026-09-17: "each has different fonts, no uniformity".) */
h1, h2, h3, .display,
.list-title, .welcome-hi h1, .id-name, .empty-title,
.card-header h2, .panel2-head h3, .panel-head h3, .auth-title {
  font-family: var(--font-sans);
  margin: 0;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -.02em;
}
a { text-decoration: none; color: var(--blue-600); }

/* Identifiers read as data, not prose: employee codes, asset tags, field keys,
   reference numbers. Tabular figures keep columns aligned. */
.mono, .fb-key, .id-code, .import-output, code {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
/* Figures: tabular so columns and KPI tiles line up. */
.kpi2-num, .donut2-mid .n, .tile .n, .leave-stats .stat .n, .stat-tile .value,
.dir-table td, table td, table th { font-family: var(--font-sans); font-variant-numeric: tabular-nums; }
.kpi2-num, .donut2-mid .n, .tile .n { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }

/* ============================================================
   Top bar
   ============================================================ */
/* Lives inside .main, so it spans the content column only and never crosses the
   blue rail. The masthead therefore sits level with, and to the right of, the
   wordmark — which is the whole point of the reference's L-shaped shell. */
.topbar {
  height: 72px;
  background: var(--surface);   /* solid: a see-through bar let scrolled content show behind it */
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 22px;
  padding: 0 26px;
  position: sticky; top: 0; z-index: 10;
}
.brand-lockup { display: flex; align-items: center; gap: 12px; flex-shrink: 0; min-width: 0; }
.brand-text .tagline { font-size: 9px; letter-spacing: .14em; color: var(--text-faint); font-weight: 700; text-transform: uppercase; }
.brand-text .company { font-size: 12.5px; font-weight: 800; color: var(--green-700); line-height: 1.3; }
html[data-theme="dark"] .brand-text .company { color: var(--green-500); }

/* Pill field with a trailing search control, per the reference. */
.searchbar {
  flex: 1; max-width: 560px;
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
  padding: 6px 6px 6px 20px;
}
.searchbar:focus-within { border-color: var(--blue-500); box-shadow: 0 0 0 3px rgba(21,104,230,.12); }
.searchbar input { border: none; outline: none; background: transparent; font-family: inherit; font-size: 13.5px; color: var(--text); flex: 1; min-width: 0; }
.searchbar input::placeholder { color: var(--text-faint); }
.search-go {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: 50%; border: none; cursor: pointer;
  background: transparent; color: var(--text-muted);
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.search-go svg { width: 17px; height: 17px; stroke: currentColor; fill: none; }
.search-go:hover { background: var(--sidebar-active); color: var(--blue-600); }

.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 18px; }
.icon-btn { position: relative; display: flex; }
.icon-btn svg { width: 20px; height: 20px; stroke: var(--text-muted); fill: none; }
.icon-dot {
  position: absolute; top: -6px; right: -8px; min-width: 15px; height: 15px; border-radius: 50%;
  font-size: 9.5px; font-weight: 700; color: #fff; display: flex; align-items: center; justify-content: center;
  padding: 0 3px; background: var(--danger);
}
.theme-toggle {
  width: 40px; height: 22px; border-radius: 20px; background: var(--surface-alt); border: 1px solid var(--border);
  display: flex; align-items: center; padding: 2px; cursor: pointer; flex-shrink: 0;
}
.theme-toggle .knob {
  width: 16px; height: 16px; border-radius: 50%; background: var(--blue-600);
  display: flex; align-items: center; justify-content: center; transition: transform .2s;
}
html[data-theme="dark"] .theme-toggle .knob { transform: translateX(18px); background: var(--gold-500); }
.theme-toggle svg { width: 10px; height: 10px; stroke: #fff; fill: none; }

/* Identity block: avatar · name/role · caret, then a disclosure panel.
   Built on <details>/<summary> so it needs no JavaScript and Log out is
   reachable by keyboard, which a hover-only menu would not be. */
.user-menu { position: relative; }
.user-menu > summary { list-style: none; cursor: pointer; }
.user-menu > summary::-webkit-details-marker { display: none; }
.user-chip { display: flex; align-items: center; gap: 10px; padding: 4px 6px 4px 4px; border-radius: 999px; }
.user-chip:hover { background: var(--surface-alt); }
.user-chip .avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--blue-700); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; flex-shrink: 0; }
.user-chip .name { font-size: 13.5px; font-weight: 700; color: var(--text); line-height: 1.25; }
.user-chip .role { font-size: 11.5px; color: var(--text-muted); line-height: 1.25; }
.uc-caret { width: 15px; height: 15px; stroke: var(--text-muted); fill: none; flex-shrink: 0; transition: transform .18s; }
.user-menu[open] .uc-caret { transform: rotate(180deg); }

.user-pop {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 40; min-width: 200px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 14px 40px rgba(9,16,30,.16); padding: 6px; overflow: hidden;
}
.user-pop .up-head { padding: 10px 12px 12px; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.user-pop .up-head .name { font-size: 13.5px; font-weight: 700; color: var(--text); }
.user-pop .up-head .role { font-size: 11.5px; color: var(--text-muted); }
.user-pop a { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--text); }
.user-pop a:hover { background: var(--surface-alt); }
.user-pop a svg { width: 16px; height: 16px; stroke: var(--text-muted); fill: none; }

/* ============================================================
   Shell + sidebar
   ============================================================ */
/* The rail is the full-height first column and the top bar lives inside .main,
   so the bar starts where the rail ends. Getting this wrong is what put the
   company masthead *above* the logo instead of beside it. */
.app-shell { display: flex; min-height: 100vh; position: relative; }

/* The rail is sticky at 100vh, so on a page taller than the viewport its own box
   stops partway down. This paints the rail's column for the full document height
   behind it, so the blue never runs out — visible when printing, and in any
   full-page render where sticky does not apply. */
.app-shell::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: var(--rail-w);
  background: var(--sidebar-bg); z-index: 0; pointer-events: none;
}

.sidebar {
  width: var(--rail-w); flex-shrink: 0; background: var(--sidebar-bg); border-right: none;
  padding: 0 12px 14px; display: flex; flex-direction: column; gap: 2px;
  position: sticky; top: 0; height: 100vh; z-index: 20;
}
/* Brand sits at the very top of the blue rail, level with the top bar, so the
   rail reads as one object from logo to footer — the reference's strongest
   structural move. No rule under it: the reference separates the wordmark from
   the nav with space, not a hairline. */
.sidebar-brand { padding: 18px 8px 20px; }
.sidebar-brand .wbr-mark { height: 34px; }
.sidebar-brand .sb-sub { margin-top: 9px; font-size: 12px; font-weight: 600; color: rgba(255,255,255,.78); letter-spacing: .01em; }

/* Only the nav scrolls, so the wordmark and the rail footer stay put on a short
   viewport instead of the whole rail scrolling away. */
.sidebar-nav { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; min-height: 0; }
.sidebar-nav::-webkit-scrollbar { width: 0; }

.sidebar a {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px;
  font-size: 13.5px; font-weight: 600; color: var(--sidebar-text);
}
.sidebar a svg { width: 18px; height: 18px; stroke: currentColor; fill: none; flex-shrink: 0; opacity: .9; }
.sidebar a:hover { background: var(--sidebar-hover); color: var(--sidebar-text-strong); }
.sidebar a.active { background: var(--sidebar-active-bg); color: #fff; font-weight: 700; box-shadow: inset 0 0 0 1px rgba(255,255,255,.10); }
.sidebar a.active svg { stroke: #fff; opacity: 1; }

/* Modules on the roadmap but not built yet. Shown so the shape of the
   product is visible, dimmed and inert so nobody clicks into a 404. */
.sidebar a.soon { opacity: .45; cursor: not-allowed; }
.sidebar a.soon:hover { background: none; color: var(--sidebar-text); }
.sidebar a.soon::after {
  content: "soon"; margin-left: auto; font-size: 8.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; border: 1px solid var(--sidebar-border); border-radius: 4px; padding: 1px 4px;
  color: rgba(255,255,255,.55);
}
.sidebar-sep { margin: 12px 12px 4px; font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.5); }

/* Dotted world map at the foot of the rail. Decorative and inert: it sits under
   the rail footer, is aria-hidden, and never takes pointer events. */
.rail-map { margin-top: auto; position: relative; height: 92px; pointer-events: none; overflow: hidden; }
.rail-map svg { position: absolute; inset: 0; width: 100%; height: 100%; fill: rgba(255,255,255,.17); }

.sidebar-foot { padding: 10px 12px 0; border-top: 1px solid var(--sidebar-border); font-size: 10.5px; color: rgba(255,255,255,.6); line-height: 1.6; }

/* Rail collapse, pinned to the rail's bottom-right edge as in the reference. */
.rail-collapse {
  position: absolute; right: -15px; bottom: 26px; z-index: 2;
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  background: var(--blue-600); color: #fff; border: 3px solid var(--bg);
  display: flex; align-items: center; justify-content: center; padding: 0;
  transition: transform .2s;
}
.rail-collapse svg { width: 13px; height: 13px; }
.rail-collapse:hover { background: var(--blue-700); }
html.rail-collapsed .rail-collapse { transform: rotate(180deg); }

/* Collapsed rail: icons only. Labels and the wordmark's text are clipped rather
   than removed, so nothing reflows and expanding is instant. */
html.rail-collapsed { --rail-w: 76px; }
html.rail-collapsed .sidebar { padding-left: 8px; padding-right: 8px; }
html.rail-collapsed .sidebar-nav a { justify-content: center; padding-left: 0; padding-right: 0; }
html.rail-collapsed .sidebar-nav a span,
html.rail-collapsed .sidebar-nav a.soon::after,
html.rail-collapsed .sidebar-sep,
html.rail-collapsed .sb-sub,
html.rail-collapsed .sidebar-foot,
html.rail-collapsed .rail-map { display: none; }
/* Expanded shows the wordmark; collapsed swaps in the W glyph. Scaling the
   wordmark down instead left 4px letterforms that read as a smudge. */
.wbr-glyph { display: none; width: auto; height: 28px; }
html.rail-collapsed .sidebar-brand { padding: 18px 0 20px; }
html.rail-collapsed .sidebar-brand .wbr-mark { display: none; }
html.rail-collapsed .sidebar-brand .wbr-glyph { display: block; margin: 0 auto; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.content { flex: 1; padding: 26px 28px 0; }
.content-inner { max-width: 1320px; }

.page-title { font-size: 15px; font-weight: 700; }

/* ============================================================
   Greeting row
   ============================================================ */
.greet-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 22px; flex-wrap: wrap; }
.greeting h1 { font-size: 22px; font-weight: 800; margin: 0 0 4px; }
.greeting p { margin: 0; color: var(--text-muted); font-size: 13.5px; }
.today-chip { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-muted); background: var(--surface); border: 1px solid var(--border); border-radius: 20px; padding: 7px 14px; }
.today-chip svg { width: 15px; height: 15px; stroke: currentColor; fill: none; }

/* ============================================================
   Cards / panels
   ============================================================ */
/* No padding on .card itself. The roominess lives on the children that own
   their own edges (.card-header, .card-body), because .card-header carries a
   border-bottom and a table dropped straight into a card is meant to run to
   the card's sides. Padding on the parent insets both, leaving dividers that
   stop short at each end. .kpi2 and .panel2 set their own padding below and
   are unaffected either way. */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); margin-bottom: 16px; }
.card-header { padding: 17px 20px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-header h2 { font-size: 14.5px; font-weight: 700; }
.card-body { padding: 20px; }

.panel { padding: 18px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 10px; }
.panel-head h3 { font-size: 14.5px; font-weight: 700; }
.panel-head select { font-size: 12px; border: 1px solid var(--border); border-radius: 7px; padding: 5px 9px; background: var(--surface-alt); color: var(--text-muted); font-family: inherit; }
.panel-link { font-size: 12px; color: var(--blue-600); font-weight: 600; cursor: pointer; }

/* ============================================================
   Dashboard — KPIs, charts, lists
   ============================================================ */
.grid-main { display: grid; grid-template-columns: 2.4fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 1100px) { .grid-main { grid-template-columns: 1fr; } }

.kpis { display: grid; grid-template-columns: repeat(4,1fr); gap: 16px; margin-bottom: 18px; }
@media (max-width: 900px) { .kpis { grid-template-columns: repeat(2,1fr); } }
.kpi { padding: 16px; display: flex; align-items: center; gap: 12px; margin-bottom: 0; }
.kpi-icon { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.kpi-icon svg { width: 20px; height: 20px; stroke: #fff; fill: none; }
.kpi .num { font-size: 19px; font-weight: 800; line-height: 1.1; }
.kpi .lbl { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.kpi .delta { font-size: 10.5px; font-weight: 700; margin-top: 3px; }
.delta.up { color: var(--green-600); }
.delta.down { color: var(--danger); }
.delta.flat { color: var(--text-faint); }

.charts-row { display: grid; grid-template-columns: 1.5fr 1fr; gap: 16px; margin-bottom: 16px; }
@media (max-width: 900px) { .charts-row { grid-template-columns: 1fr; } }
.charts-row .card { margin-bottom: 0; }

.donut-wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.donut { width: 128px; height: 128px; border-radius: 50%; position: relative; flex-shrink: 0; }
.donut::after { content: ""; position: absolute; inset: 18px; border-radius: 50%; background: var(--surface); }
.donut-total { position: absolute; inset: 18px; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 1; }
.donut-total .n { font-size: 19px; font-weight: 800; }
.donut-total .t { font-size: 10px; color: var(--text-muted); }
.legend { display: flex; flex-direction: column; gap: 9px; font-size: 12.5px; flex: 1; min-width: 150px; }
.legend .row { display: flex; align-items: center; gap: 8px; }
.legend .dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.legend .name { flex: 1; color: var(--text-muted); }
.legend .val { font-weight: 700; }

.leave-stats { display: flex; gap: 22px; margin-bottom: 16px; flex-wrap: wrap; }
.leave-stats .stat .n { font-size: 19px; font-weight: 800; }
.leave-stats .stat .l { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
/* Scoped to .bar-row itself, not to a .leave-bars wrapper: the dashboard renders
   these rows directly and the label ran into the value without it. */
.bar-row { margin-bottom: 12px; }
.bar-row:last-child { margin-bottom: 0; }
.bar-row .top { display: flex; justify-content: space-between; gap: 12px; font-size: 12px; margin-bottom: 5px; color: var(--text-muted); }
.bar-row .top span:last-child { font-weight: 700; color: var(--text); white-space: nowrap; }
.bar-track { height: 6px; border-radius: 4px; background: var(--surface-alt); overflow: hidden; }
.bar-fill { height: 100%; border-radius: 4px; }

.activity-item { display: flex; gap: 11px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.activity-item:last-child { border-bottom: none; }
.act-icon { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; background: var(--sidebar-active); }
.act-icon svg { width: 16px; height: 16px; fill: none; }
.act-text .title { font-size: 13px; font-weight: 600; }
.act-text .meta { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }

.side-col { display: flex; flex-direction: column; gap: 16px; }
.side-col .card { margin-bottom: 0; }
.people-item { display: flex; align-items: center; gap: 10px; padding: 9px 0; }
.people-item .mini-avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--blue-500); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; flex-shrink: 0; }
.people-item .name { font-size: 12.5px; font-weight: 700; }
.people-item .role { font-size: 11px; color: var(--text-muted); }
.people-item .date { margin-left: auto; font-size: 11.5px; color: var(--text-muted); font-weight: 600; }

.holiday-item { display: flex; align-items: center; gap: 11px; padding: 8px 0; }
.holiday-date { width: 40px; height: 40px; border-radius: 9px; background: var(--green-600); color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; flex-shrink: 0; }
.holiday-date .m { font-size: 9px; font-weight: 700; text-transform: uppercase; }
.holiday-date .d { font-size: 14px; font-weight: 800; line-height: 1.1; }
.holiday-item .name { font-size: 12.5px; font-weight: 700; }
.holiday-item .day { font-size: 11px; color: var(--text-muted); }

.quick-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 10px; }
.quick-item { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 12px 6px; border-radius: 10px; }
.quick-item:hover { background: var(--surface-alt); }
.quick-item .qi-icon { width: 34px; height: 34px; border-radius: 9px; display: flex; align-items: center; justify-content: center; background: var(--sidebar-active); }
.quick-item .qi-icon svg { width: 16px; height: 16px; fill: none; }
.quick-item .lbl { font-size: 11px; font-weight: 600; text-align: center; color: var(--text-muted); }

/* An empty state that says WHY it is empty. A dashboard panel with no
   data source must never fall back to plausible-looking numbers. */
.no-source { font-size: 12px; color: var(--text-faint); padding: 14px 0; text-align: center; line-height: 1.6; }
.no-source b { color: var(--text-muted); font-weight: 600; }

/* Light footer with per-badge colour, matching the reference. Each badge keeps
   its own hue so the row reads as a set of marks, not one tinted block. */
.footer-bar {
  margin-top: 22px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 16px 26px;
  display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap;
  color: var(--text-muted); font-size: 12.5px;
}
.fb-copy { display: flex; align-items: center; gap: 8px; }
.fb-copy svg { width: 14px; height: 14px; stroke: var(--text-faint); fill: none; flex-shrink: 0; }

.footer-features { display: flex; gap: 26px; flex-wrap: wrap; }
.footer-features .f { display: flex; align-items: center; gap: 7px; font-weight: 600; color: var(--text); }
.footer-features svg { width: 15px; height: 15px; fill: none; }
.f-secure   svg { stroke: var(--green-600); }
.f-reliable svg { stroke: var(--blue-600); }
.f-compliant svg { stroke: var(--green-600); }
.f-friendly svg { stroke: var(--text-faint); }

/* JV lockup — the partner's own artwork, not a CSS approximation of it. */
.footer-jv { display: flex; align-items: center; gap: 10px; }
.footer-jv .lbl { font-size: 11.5px; color: var(--text-faint); }
.footer-jv .jv-img { display: block; height: 26px; width: auto; flex-shrink: 0; }

/* ============================================================
   Components carried over — same class names, new skin
   ============================================================ */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; margin-bottom: 18px; }
.stat-tile { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; box-shadow: var(--shadow); padding: 16px; }
.stat-tile .label { font-size: 11.5px; color: var(--text-muted); }
.stat-tile .value { font-size: 22px; font-weight: 800; }

.data-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 28px; }
.data-row { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; border-bottom: 1px solid var(--border); }
.data-row:last-child { border-bottom: none; }
.data-row .label { color: var(--text-muted); font-size: 12.5px; }
.data-row .value { font-weight: 600; font-size: 13px; text-align: right; }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { padding: 11px 18px; text-align: left; border-bottom: 1px solid var(--border); }
th { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); font-weight: 700; background: var(--surface-alt); }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-alt); }
.text-right { text-align: right; }

.btn {
  display: inline-flex; align-items: center; gap: 7px; padding: 8px 15px; border-radius: 9px;
  font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface); color: var(--text); transition: .15s;
}
.btn:hover { background: var(--surface-alt); }
.btn-primary { background: var(--ws-button); border-color: transparent; color: #fff; box-shadow: 0 4px 12px rgba(24,119,242,.22); }
.btn-primary:hover { background: var(--ws-button); filter: brightness(1.06); }
.btn-secondary { background: var(--surface-alt); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }

/* Badge classes are generated by statusBadgeClass(): lowercase, spaces stripped.
   Every employment_status ENUM value needs a rule here or it renders unstyled —
   the set below covers all ten from migration 003, grouped by meaning:
   green = present and working, amber = temporarily away or provisional,
   blue = a defined engagement, red = gone. */
.badge { display: inline-flex; align-items: center; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 20px; }
.badge-active, .badge-approved { background: var(--success-bg); color: var(--success); }
.badge-probation, .badge-noticeperiod, .badge-pending, .badge-holiday { background: var(--warn-bg); color: var(--warn); }
.badge-rejected, .badge-terminated, .badge-cancelled, .badge-resigned { background: var(--danger-bg); color: var(--danger); }
.badge-onleave, .badge-interns, .badge-contractualbasis { background: var(--sidebar-active); color: var(--blue-600); }
.badge-inactive, .badge-suspended { background: var(--surface-alt); color: var(--text-muted); border: 1px solid var(--border); }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); padding: 0 18px; flex-wrap: wrap; }
.tab { padding: 11px 14px; font-size: 13px; font-weight: 600; color: var(--text-muted); border-bottom: 2px solid transparent; cursor: pointer; }
.tab:hover { color: var(--text); }
.tab.active { color: var(--blue-600); border-bottom-color: var(--blue-600); }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }   /* minmax(0,…): a 1fr track will not shrink below an input's default width, which overflowed phones */
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field label { font-size: 11.5px; font-weight: 600; color: var(--text-muted); }
.field input, .field select, .field textarea {
  font-family: inherit; font-size: 13.5px; padding: 9px 12px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--surface-alt); color: var(--text); outline: none;
  width: 100%; max-width: 100%; box-sizing: border-box;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--blue-500); background: var(--surface); }
.field-hint, .helper-text { font-size: 12.5px; color: var(--text-muted); }   /* --text-faint is 2.6:1 on white — below WCAG AA for body text */
.field.full { grid-column: 1 / -1; }

.flash { padding: 11px 16px; border-radius: 10px; font-size: 13px; font-weight: 500; margin-bottom: 16px; }
.flash-success { background: var(--success-bg); color: var(--success); }
.flash-error { background: var(--danger-bg); color: var(--danger); }

/* Record header.
   The old markup put the status stamp FIRST with margin-left:auto, which shoved
   the stamp *and everything after it* to the right edge and left a dead gap on
   the left. Reading order is now avatar → who they are → actions, with the
   status as a badge beside the name where it is actually noticed. */
.back-link { display: inline-block; font-size: 12.5px; font-weight: 600; color: var(--text-muted); margin-bottom: 12px; }
.back-link:hover { color: var(--blue-600); }

.id-block { display: flex; align-items: center; gap: 18px; padding: 20px; }
.id-photo {
  width: 60px; height: 60px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, var(--blue-700), var(--blue-500));
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 21px; font-weight: 800; letter-spacing: .02em;
}
.id-main { min-width: 0; flex: 1; }
.id-name-row { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 3px; }
.id-name { font-size: 19px; font-weight: 800; letter-spacing: -.01em; }
.badge-type { background: var(--surface-alt); color: var(--text-muted); border: 1px solid var(--border); }
.id-role { font-size: 13px; color: var(--text-muted); }
.id-role .sep { margin: 0 7px; opacity: .5; }
.id-meta { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 7px; font-size: 12px; color: var(--text-faint); }
.id-meta a { color: var(--text-muted); }
.id-meta a:hover { color: var(--blue-600); }
.id-code { font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.id-actions { margin-left: auto; flex-shrink: 0; }
@media (max-width: 700px) {
  .id-block { flex-wrap: wrap; }
  .id-actions { margin-left: 0; width: 100%; }
  .id-actions .btn { width: 100%; justify-content: center; }
}

.mt-8  { margin-top: 8px; }
.mt-16 { margin-top: 16px; }

/* Expandable JSON context in the audit log. Monospace comes from .fb-key; this
   only undoes that class's inline-chip sizing so a multi-line block reads.
   Cells align to the top so an expanded Detail block does not leave the
   timestamp floating in the middle of a tall row. */
.audit-table td { vertical-align: top; }
.audit-detail { display: block; white-space: pre-wrap; word-break: break-word; font-size: 11px; line-height: 1.5; padding: 8px 10px; margin: 6px 0 0; max-width: 460px; }

/* ---------- Public form (apply.php) ----------
   Standalone: no sidebar, no topbar. It carries the same tokens as the rest of
   the app so it looks like Webronic, but nothing that assumes the shell — the
   page has to sit inside somebody else's layout without fighting it. */
.public-form-body { background-color: var(--bg); background-image: var(--ws-app); background-attachment: fixed; }
.public-form { max-width: 1280px; margin: 0 auto; padding: 0 clamp(16px, 4vw, 40px) 64px; }

/* Full-bleed banner in the brand blue, so an embedded form still reads as
   Webronic's. The container inside keeps the text at a readable measure. */
.pf-banner { /* edge to edge, whatever the container's width */
  margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); margin-bottom: clamp(22px, 3vw, 36px);
  padding: clamp(28px, 5vw, 56px) clamp(16px, 4vw, 40px); color: #fff; background: var(--sidebar-bg); }
.pf-banner-in { max-width: 1200px; margin: 0 auto; }
.pf-org { margin: 0 0 8px; font-size: var(--fs-sm); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: rgba(255,255,255,.86); }
.pf-banner h1 { margin: 0; color: #fff; font-size: clamp(26px, 3.2vw, 40px); font-weight: 800; letter-spacing: -.02em; line-height: 1.15; }
.pf-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; padding: 0; list-style: none; }
.pf-chips li { padding: 5px 13px; border-radius: 999px; font-size: var(--fs-sm); font-weight: 600;
  background: rgba(255,255,255,.16); color: #fff; }
.pf-closes { margin: 14px 0 0; font-size: var(--fs-sm); color: rgba(255,255,255,.9); }

.pf-about h2 { font-size: var(--fs-lg); margin: 0 0 8px; }
.pf-desc { font-size: var(--fs-md); line-height: 1.65; color: var(--text); }

/* The form card. Two columns on a wide screen, one on a phone or at 400% zoom
   (WCAG 1.4.10 reflow) — the grid rule in the shared form-grid does that. */
.public-form .card { max-width: 1200px; margin: 0 auto 18px; }
.public-form .card-body { padding: clamp(20px, 2.6vw, 34px); }
.public-form .form-grid { gap: 20px 28px; }
.public-form .field label, .public-form .field legend { font-size: var(--fs-md); font-weight: 600; margin-bottom: 7px; }
.public-form .field input, .public-form .field select, .public-form .field textarea {
  min-height: 46px; font-size: var(--fs-md); }
.public-form .field label, .public-form .field legend { color: var(--text); }
.public-form input[type="file"] { padding: 10px 12px; cursor: pointer; }
.public-form input[type="file"]::file-selector-button { margin-right: 12px; padding: 8px 14px; min-height: 32px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface); color: var(--text);
  font: inherit; font-size: var(--fs-sm); font-weight: 600; cursor: pointer; }
.public-form input[type="file"]::file-selector-button:hover { border-color: var(--blue-600); color: var(--blue-600); }
/* A choice reads as one phrase: "Team Project" must not break across lines. */
.public-form .choice { white-space: nowrap; }
.public-form .field textarea { min-height: 104px; }
.public-form fieldset.field { border: 0; margin: 0; padding: 0; }
.public-form fieldset.field legend { padding: 0; }

.pf-errors { display: block; }
.pf-errors h2 { font-size: var(--fs-md); margin: 0 0 6px; color: inherit; }
.pf-errors ul { margin: 0; padding-left: 20px; font-size: var(--fs-sm); }
.pf-errors li + li { margin-top: 4px; }
.pf-errors a { color: inherit; font-weight: 700; }
.pf-errors:focus-visible { outline: 3px solid var(--danger); outline-offset: 3px; }

.pf-privacy { display: block; margin: 26px 0 18px; font-size: var(--fs-sm); line-height: 1.6; color: var(--text-muted); }
.pf-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  padding-top: 18px; border-top: 1px solid var(--border); }
.pf-submit { min-height: 48px; padding: 0 28px; font-size: var(--fs-md); }

/* Visible focus on everything interactive (WCAG 2.4.7), including when a
   browser would otherwise drop it on a clicked choice chip. */
.public-form a:focus-visible, .public-form button:focus-visible,
.public-form input:focus-visible, .public-form select:focus-visible, .public-form textarea:focus-visible {
  outline: 3px solid var(--blue-600); outline-offset: 2px; }
.public-form .choice:focus-within { outline: 3px solid var(--blue-600); outline-offset: 2px; }

/* For screen readers only — the word behind the required asterisk. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (max-width: 760px) {
  .pf-banner { padding-top: 24px; padding-bottom: 24px; }
  .public-form .card-body { padding: 18px 16px; }
}

/* Required marker and per-field errors. Colour is never the only signal —
   the message is text, and aria-invalid carries it to a screen reader. */
.req { color: var(--danger); font-weight: 700; }
.field-error { display: block; margin-top: 4px; font-size: 12px; color: var(--danger); }
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: var(--danger); }

/* Radio / checkbox / rating groups. Whole-label hit area, because half of
   these applications arrive on a phone. */
.choice-set { display: flex; flex-wrap: wrap; gap: 8px; }
.choice { display: inline-flex; align-items: center; gap: 7px; padding: 9px 13px;
          border: 1px solid var(--border); border-radius: 10px; background: var(--surface-alt);
          font-size: 13.5px; cursor: pointer; min-height: 42px; }
.choice:hover { border-color: var(--blue-500); }
.choice input { accent-color: var(--blue-600); margin: 0; }
.choice-set.rating .choice { min-width: 56px; justify-content: center; }

/* The honeypot. Off-screen rather than display:none — a bot that skips hidden
   fields is exactly the bot this is meant to catch. */
.hp { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ---------- Work suite ---------- */
/* All colour comes from the existing tokens — the suite adds shapes, not a
   second palette, so light and dark follow the theme for free. */

.timer-strip { display: flex; align-items: center; gap: 16px; padding: 14px 16px; flex-wrap: wrap;
               border-left: 3px solid var(--success); }
.timer-strip.idle { border-left-color: var(--border); }
.timer-strip.runaway { border-left-color: var(--warn); }
.timer-what { flex: 1 1 240px; min-width: 0; }
.timer-label { font-size: 11.5px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .04em; }
.timer-title { font-weight: 700; font-size: 15px; margin-top: 2px; }
.timer-note { font-size: 12px; color: var(--text-faint); margin-top: 2px; }
.timer-elapsed { font-family: var(--font-mono); font-size: 22px; font-weight: 700;
                 font-variant-numeric: tabular-nums; }
.timer-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.timer-actions input { font-family: inherit; font-size: 13px; padding: 8px 11px; border-radius: 9px;
                       border: 1px solid var(--border); background: var(--surface-alt); color: var(--text); min-width: 190px; }

/* Provenance chip. Every source reads as a chip so "where did this come from"
   is answerable at a glance and never inferred from the absence of a link. */
.src-chip { display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
            padding: 2px 7px; border-radius: 999px; background: var(--surface-alt);
            color: var(--text-faint); border: 1px solid var(--border); }
.src-notion { background: var(--sidebar-active); color: var(--blue-600); border-color: transparent; }
.src-gchat  { background: var(--success-bg); color: var(--success); border-color: transparent; }

/* Source cards size themselves rather than sitting in a fixed two-up grid,
   where a short card leaves a hole beside a tall one. */
.source-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
               gap: 14px; align-items: start; margin-bottom: 16px; }

.week-strip { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.week-day { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 4px;
            border: 1px solid var(--border); border-radius: 12px; text-decoration: none; color: inherit; }
.week-day:hover { background: var(--surface-alt); }
.week-day.today { border-color: var(--blue-600); }
.wd-name { font-size: 11.5px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .04em; }
.wd-bar { width: 26px; height: 90px; background: var(--surface-alt); border-radius: 6px;
          display: flex; align-items: flex-end; overflow: hidden; }
.wd-bar span { display: block; width: 100%; background: var(--blue-600); border-radius: 6px 6px 0 0; }
.wd-num { font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.wd-date { font-size: 11px; color: var(--text-faint); }

@media (max-width: 700px) {
  .week-strip { grid-template-columns: repeat(4, 1fr); }
  .timer-elapsed { font-size: 18px; }
  .timer-actions input { min-width: 0; flex: 1; }
}

/* ---------- Login ---------- */
.auth-shell { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--bg); padding: 24px; }
.auth-card { width: 100%; max-width: 390px; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow); padding: 30px; }
.auth-mark { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; }
.auth-mark svg { width: 40px; height: 40px; }
.auth-title { font-size: 19px; font-weight: 800; margin-bottom: 6px; }

/* ============================================================
   Directory — list header, group tabs, filter bar, table
   ============================================================ */
.list-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.list-title { font-size: 21px; font-weight: 800; letter-spacing: -.01em; }
.list-sub { margin: 3px 0 0; font-size: 13px; color: var(--text-muted); }
.list-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-sm { padding: 5px 11px; font-size: 12px; }

/* Group tabs sit above the filter bar: they answer "which population", the bar
   answers "which of them". Keeping them apart stops the bar becoming a wall. */
.group-tabs { display: flex; gap: 4px; margin-bottom: 14px; flex-wrap: wrap; }
.group-tab {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 15px; border-radius: 999px; font-size: 13px; font-weight: 600;
  color: var(--text-muted); background: var(--surface); border: 1px solid var(--border);
}
.group-tab:hover { color: var(--text); border-color: var(--text-faint); }
.group-tab.active { background: var(--blue-700); border-color: var(--blue-700); color: #fff; }
.group-tab .n { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--surface-alt); color: var(--text-muted); }
.group-tab.active .n { background: rgba(255,255,255,.22); color: #fff; }

.filter-bar { display: flex; gap: 8px; padding: 12px; align-items: center; flex-wrap: wrap; }
.filter-search { flex: 1; min-width: 240px; display: flex; align-items: center; gap: 9px; background: var(--surface-alt); border: 1px solid var(--border); border-radius: 9px; padding: 8px 12px; }
.filter-search svg { width: 15px; height: 15px; color: var(--text-faint); flex-shrink: 0; }
.filter-search input { flex: 1; border: none; outline: none; background: transparent; font-family: inherit; font-size: 13.5px; color: var(--text); }
.filter-bar select { font-family: inherit; font-size: 13px; padding: 8px 11px; border-radius: 9px; border: 1px solid var(--border); background: var(--surface-alt); color: var(--text); }

.table-scroll { overflow-x: auto; }
.dir-table { min-width: 760px; }
.dir-table td { vertical-align: middle; }
.dir-person { display: flex; align-items: center; gap: 11px; color: inherit; }
.dir-avatar { width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0; background: linear-gradient(135deg, var(--blue-700), var(--blue-500)); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; }
.dir-who { display: flex; flex-direction: column; min-width: 0; }
.dir-name { font-weight: 700; font-size: 13.5px; }
.dir-person:hover .dir-name { color: var(--blue-600); }
.dir-sub { font-size: 11.5px; color: var(--text-faint); margin-top: 1px; }

.empty-state { padding: 46px 20px; text-align: center; }
.empty-title { font-size: 15px; font-weight: 700; }
.empty-sub { font-size: 13px; color: var(--text-muted); margin-top: 5px; }

/* ============================================================
   Import
   ============================================================ */
.import-form { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }
.file-drop {
  width: 100%; display: flex; flex-direction: column; gap: 5px; cursor: pointer;
  border: 1.5px dashed var(--border); border-radius: 12px; padding: 20px; background: var(--surface-alt);
}
.file-drop:hover { border-color: var(--blue-500); }
.file-drop input { margin-bottom: 8px; font-family: inherit; font-size: 13px; }
.fd-title { font-size: 13.5px; font-weight: 700; }
.fd-sub { font-size: 11.5px; color: var(--text-faint); line-height: 1.6; }

.check-row { display: flex; gap: 11px; align-items: flex-start; font-size: 13px; cursor: pointer; }
.check-row input { margin-top: 3px; flex-shrink: 0; }
.check-row small { display: block; font-size: 11.5px; color: var(--text-faint); margin-top: 3px; line-height: 1.6; }

.import-legend { display: flex; gap: 18px; flex-wrap: wrap; font-size: 11.5px; color: var(--text-muted); margin-bottom: 12px; }
.import-legend b { font-family: var(--font-mono); margin-right: 4px; }
.mk-new { color: var(--green-600); } .mk-upd { color: var(--text-muted); }
.mk-recode { color: var(--blue-600); } .mk-warn { color: var(--warn); }
.import-output {
  margin: 0; padding: 14px; border-radius: 10px; background: var(--surface-alt);
  border: 1px solid var(--border); font-family: var(--font-mono);
  font-size: 11.5px; line-height: 1.65; color: var(--text); max-height: 460px; overflow: auto;
  white-space: pre; -webkit-overflow-scrolling: touch;
}

/* ============================================================
   Mobile shell — drawer nav, compact topbar, stacked tables
   ------------------------------------------------------------
   Everything above this block is the desktop layout and is left
   alone. The sidebar was a fixed 232px with no breakpoint, so on
   a 390px phone the browser shrank the whole page to ~60% to make
   it fit: a third of the screen was permanently nav and the text
   needed pinch-zoom. Below 900px the sidebar becomes off-canvas.
   ============================================================ */

/* Hidden on desktop — the sidebar is already on screen there. */
.nav-toggle, .search-toggle { display: none; }
.nav-toggle, .search-toggle {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--text-muted); align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 9px; flex-shrink: 0;
}
.nav-toggle svg, .search-toggle svg { width: 21px; height: 21px; }
.nav-toggle:hover, .search-toggle:hover { background: var(--surface-alt); color: var(--text); }
.scrim { display: none; }

@media (max-width: 900px) {
  .topbar { height: 58px; padding: 0 12px; gap: 10px; }
  .nav-toggle, .search-toggle { display: inline-flex; }

  /* Logo only. The company name is white-space:nowrap, so leaving it in forced
     the whole document to ~510px and the browser zoomed the app out again — the
     exact bug the mobile shell exists to prevent. */
  .brand-text, .topbar-title { display: none; }
  /* The rail carries its own brand block; it must not stretch the drawer. */
  .sidebar-brand .wbr-mark { height: 26px; }

  /* Search drops out of the bar and opens as its own full-width row. */
  .searchbar {
    position: absolute; top: 58px; left: 0; right: 0; z-index: 9;
    max-width: none; border-radius: 0; border-left: none; border-right: none;
    display: none; background: var(--surface); padding: 11px 14px;
  }
  body.search-open .searchbar { display: flex; }

  .topbar-actions { gap: 10px; margin-left: auto; }
  .user-chip .uc-text, .uc-caret { display: none; }   /* avatar only */
  .icon-btn { display: none; }                        /* bell is not a phone job */

  /* ---- The drawer ---- */
  .app-shell { min-height: 100vh; }
  /* The rail is off-canvas here, so its backdrop would be a stray blue stripe. */
  .app-shell::before { display: none; }
  /* The rail is off-canvas here, so its edge-mounted collapse control has no
     edge to hang off — the hamburger is the affordance on a phone. */
  .rail-collapse { display: none; }
  html.rail-collapsed .sidebar { width: 270px; padding-left: 12px; padding-right: 12px; }
  html.rail-collapsed .sidebar-nav a span,
  html.rail-collapsed .sidebar-sep,
  html.rail-collapsed .sb-sub,
  html.rail-collapsed .rail-map,
  html.rail-collapsed .sidebar-foot { display: revert; }
  html.rail-collapsed .sidebar-nav a { justify-content: flex-start; padding-left: 14px; padding-right: 14px; }
  html.rail-collapsed .sidebar-brand { padding: 18px 8px 20px; }
  html.rail-collapsed .sidebar-brand .wbr-mark  { display: block; }
  html.rail-collapsed .sidebar-brand .wbr-glyph { display: none; }
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
    width: 270px; max-width: 84vw;
    transform: translateX(-100%);
    transition: transform .24s ease;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    box-shadow: 0 0 40px rgba(0,0,0,.18);
    padding-top: 14px;
  }
  .sidebar.is-open { transform: translateX(0); }

  .scrim {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(9,16,30,.5); backdrop-filter: blur(1px);
  }
  .scrim[hidden] { display: none; }

  /* Locking the body stops the page scrolling under the open drawer. */
  body.nav-open { overflow: hidden; }

  /* Comfortable touch targets — 9px padding is a mouse size. */
  /* 44px is the accepted minimum tap target; padding alone left the <button>
     elements at 38px because their line-height differs from the <a> buttons. */
  .sidebar a { padding: 12px 14px; font-size: 14.5px; min-height: 44px; }
  .btn, button.btn, .group-tab { min-height: 44px; padding: 10px 16px; }
  .filter-bar select, .filter-search { min-height: 44px; }

  .content { padding: 18px 14px 0; }

  /* ---- Page furniture ---- */
  .list-head { gap: 12px; }
  .list-actions { width: 100%; }
  .list-actions .btn { flex: 1; justify-content: center; }
  .filter-bar { flex-direction: column; align-items: stretch; }
  .filter-bar select, .filter-bar .btn { width: 100%; }
  .filter-search { min-width: 0; }
  .greet-row { flex-direction: column; align-items: flex-start; }
  .footer-bar { border-radius: 12px 12px 0 0; padding: 14px 16px; }
  .footer-features { gap: 14px; font-size: 11.5px; }

  /* ---- Directory: table -> stacked cards ----
     A 5-column table inside a horizontal scroller is still unreadable on a
     phone. Each row becomes its own card with the column name as a label. */
  .table-scroll { overflow-x: visible; }
  .dir-table { min-width: 0; display: block; }
  .dir-table thead { display: none; }
  .dir-table tbody, .dir-table tr, .dir-table td { display: block; width: 100%; }
  .dir-table tr {
    border: 1px solid var(--border); border-radius: 12px;
    padding: 12px; margin-bottom: 10px; background: var(--surface);
  }
  .dir-table tr:hover { background: var(--surface); }
  .dir-table td { border: none; padding: 4px 0; }
  .dir-table td:first-child { padding-bottom: 10px; }
  /* Label every stacked cell except the person and the trailing action. */
  .dir-table td[data-label]:not(:first-child)::before {
    content: attr(data-label);
    display: block; font-size: 10px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-faint); margin-bottom: 2px;
  }
  .dir-table td.text-right { text-align: left; padding-top: 10px; }
  .dir-table td.text-right .btn { width: 100%; justify-content: center; }

  /* Profile header stacks; the avatar stays with the name. */
  .id-block { padding: 16px; gap: 14px; }
  .id-photo { width: 50px; height: 50px; font-size: 18px; }
  .id-name { font-size: 17px; }
  .tabs { padding: 0 4px; overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .tab { white-space: nowrap; }
  .data-grid { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .import-output { font-size: 10.5px; }
}

@media (max-width: 420px) {
  .list-actions { flex-direction: column; }
  .list-actions .btn { width: 100%; }
  .group-tabs { display: grid; grid-template-columns: repeat(3, 1fr); }
  .group-tab { justify-content: center; padding: 10px 6px; font-size: 12.5px; }
}

@media (max-width: 900px) {
  /* Catch-all for tables written before the mobile pass (leave/, attendance/).
     Making the table itself the scroll container keeps the page at viewport
     width — otherwise a six-column report stretches the document and the
     browser zooms the whole app out to compensate. Row/cell display types are
     untouched, so column alignment survives. */
  .card > table,
  .card > form > table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* Several older pages hand-rolled flex rows without a wrap, which forced a
     minimum width on small screens. */
  .card-body [style*="display:flex"],
  .card-header { flex-wrap: wrap; }

  .stat-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   Dashboard v2 — compact cards, tinted icon tiles, sparklines
   Colour and density follow the blue-rail reference; the soft
   tinted tiles, sparklines and relative-time chips follow the
   glassy one.
   ============================================================ */
/* Company name as the reference renders it: caps, heavy, brand blue, tracked
   out slightly so it reads as a masthead rather than a page title. */
.topbar-title {
  font-family: var(--font-sans);
  font-size: 18px; font-weight: 800; letter-spacing: .005em;
  color: var(--blue-900); white-space: nowrap;
}
html[data-theme="dark"] .topbar-title { color: var(--text); }

/* The wordmark is raster artwork generated from the design master; height drives
   it and width follows, so the aspect never distorts. */
.wbr-mark { display: block; width: auto; height: 34px; }
.icon-btn { width: 38px; height: 38px; border-radius: 10px; align-items: center; justify-content: center; }
.icon-btn:hover { background: var(--surface-alt); }

/* ---- Welcome strip: greeting + quick actions on one row ---- */
.welcome { display: flex; align-items: center; gap: 26px; padding: 18px 20px; flex-wrap: wrap; margin-bottom: 16px; }
.welcome-hi h1 { font-size: 23px; font-weight: 800; letter-spacing: -.015em; }
.welcome-when { display: flex; align-items: center; gap: 14px; margin-top: 8px; font-size: 13px; color: var(--text-muted); }
.welcome-when .sep { width: 1px; height: 14px; background: var(--border); }
.welcome-when svg { width: 14px; height: 14px; stroke: currentColor; fill: none; margin-right: 6px; vertical-align: -2px; }
.welcome-when .dot-live { width: 8px; height: 8px; border-radius: 50%; background: var(--green-600); display: inline-block; margin-right: 7px; }
/* Quick actions: a labelled group, per the reference, rather than a bare row of
   buttons hanging off the greeting. */
/* The reference rules a line between the greeting and the actions, which is
   what stops the two halves reading as one run-on row. */
.qa-wrap { margin-left: auto; padding-left: 26px; border-left: 1px solid var(--border); }
.qa-cap { font-size: 13px; font-weight: 600; color: var(--text-muted); margin-bottom: 10px; }
.qa-strip { display: flex; gap: 10px; flex-wrap: wrap; }
.qa-btn {
  display: flex; align-items: center; gap: 10px; padding: 11px 17px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface); font-size: 13px; font-weight: 600; color: var(--text);
}
.qa-btn:hover { border-color: var(--blue-500); background: var(--sidebar-active); }
/* Glyph only — no tile. Five filled squares in a row read as a toolbar of
   buttons-within-buttons and pull focus off the labels. */
.qa-btn .ic { background: none; width: auto; height: auto; display: flex; align-items: center; flex-shrink: 0; }
.qa-btn .ic svg { width: 17px; height: 17px; fill: none; stroke-width: 2; }

/* ---- KPI row ---- */
.kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 16px; }
.kpi2 { padding: 17px 18px; display: flex; flex-direction: column; gap: 9px; margin-bottom: 0; position: relative; overflow: hidden; }
.kpi2-top { display: flex; align-items: center; gap: 14px; position: relative; z-index: 1; }
.kpi2-ic { width: 52px; height: 52px; border-radius: 14px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.kpi2-ic svg { width: 25px; height: 25px; fill: none; stroke-width: 2; }
.kpi2-lbl { font-size: 13px; color: var(--text-muted); font-weight: 600; }
.kpi2-num { font-size: 30px; font-weight: 800; letter-spacing: -.02em; line-height: 1.2; margin-top: 1px; }
.kpi2-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; position: relative; z-index: 1; }
/* Two-tone, as the reference sets it: the figure carries the colour, the
   qualifier stays muted. One saturated run of text reads as a warning. */
.kpi2-delta { font-size: 12px; font-weight: 600; color: var(--text-muted); }
.kpi2-delta b { font-weight: 800; }
.kpi2-delta b.up   { color: var(--green-600); }
.kpi2-delta b.warn { color: var(--gold-500); }
.kpi2-spark { flex-shrink: 0; opacity: .95; }

/* Watermark art, centre-right of each KPI card, as the reference draws it —
   large enough to read as an illustration rather than a smudge. Decorative and
   inert: aria-hidden, no pointer events, and pinned under the figures via
   z-index so it can never sit on top of a number. */
.kpi2-art {
  position: absolute; right: 12px; top: 50%; transform: translateY(-46%); z-index: 0;
  width: 132px; height: 74px; pointer-events: none; overflow: hidden;
}
.kpi2-art svg { width: 100%; height: 100%; display: block; }

/* Solid tiles — the KPI treatment from the reference: a filled brand-coloured
   square with a white glyph. The tinted set below stays for the denser lists,
   where four saturated blocks in a row would shout over the numbers. */
.s-blue   { background: var(--ws-blue-bg);   color: var(--ws-blue-fg); }
.s-green  { background: var(--ws-green-bg);  color: var(--ws-green-fg); }
.s-amber  { background: var(--ws-amber-bg);  color: var(--ws-amber-fg); }
.s-violet { background: var(--ws-purple-bg); color: var(--ws-purple-fg); }
.s-teal   { background: #D4F2F4; color: #0B8793; }
html[data-theme="dark"] .s-teal { background: #0E8E9A; color: #fff; }

/* Bare glyph colours, for icons that carry no tile. */
.c-blue  { color: #2F6FE4; }
.c-green { color: #16A34A; }
html[data-theme="dark"] .c-blue  { color: #7FB0FF; }
html[data-theme="dark"] .c-green { color: #64DE96; }

/* Tinted tiles — one hue per metric, reused by the quick actions. */
.t-blue   { background: #E8F0FE; color: #1B5FD9; }
.t-green  { background: #E3F8EA; color: #0A8A38; }
.t-amber  { background: #FEF1DE; color: #B4700C; }
.t-violet { background: #EEEBFB; color: #6558C9; }
.t-rose   { background: #FDE8EA; color: #C6362E; }
.t-teal   { background: #DEF4F5; color: #0E7C86; }
html[data-theme="dark"] .t-blue   { background: rgba(35,98,189,.20);  color: #7FB0FF; }
html[data-theme="dark"] .t-green  { background: rgba(10,138,56,.20);  color: #64DE96; }
html[data-theme="dark"] .t-amber  { background: rgba(180,112,12,.22); color: #E9B45F; }
html[data-theme="dark"] .t-violet { background: rgba(101,88,201,.24); color: #A79AF5; }
html[data-theme="dark"] .t-rose   { background: rgba(198,54,46,.22);  color: #F3908A; }
html[data-theme="dark"] .t-teal   { background: rgba(14,124,134,.24); color: #6BD3DC; }

/* ---- Grid below the KPIs ---- */
.dash-grid { display: grid; grid-template-columns: 1.35fr 1fr 1fr; gap: 14px; align-items: start; }
.dash-grid .card, .dash-row .card { margin-bottom: 0; }
/* Three since the holidays panel landed: leave summary, birthdays, holidays.
   Collapses the same way .dash-grid does — see the 1250px rule below. */
.dash-row { display: grid; grid-template-columns: 1.2fr 1fr 1fr; gap: 14px; margin-top: 14px; }
.panel2 { padding: 15px; }
.panel2-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 11px; }
.panel2-head h3 { font-size: 13.5px; font-weight: 700; }
.panel2-head .lnk { font-size: 11.5px; font-weight: 700; color: var(--blue-600); }
.pill-select { font-size: 11.5px; border: 1px solid var(--border); border-radius: 7px; padding: 4px 9px; background: var(--surface-alt); color: var(--text-muted); font-weight: 600; }

/* Chart key, under the plot as the reference places it. */
.chart-key { display: flex; gap: 18px; justify-content: center; margin-top: 4px; }
.chart-key .k { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--text-muted); font-weight: 600; }
.chart-key .ln { width: 18px; height: 2.5px; border-radius: 2px; background: #2D6FD2; }
/* States the basis of a partial series, so a low line is not read as a low
   headcount. Muted, because it is a footnote and not a finding. */
.chart-caveat { margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--border); font-size: 11.5px; line-height: 1.5; color: var(--text-faint); }

/* ---- Donut with a legend that carries counts ---- */
.donut2-wrap { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.donut2 { width: 158px; height: 158px; border-radius: 50%; position: relative; flex-shrink: 0; }
.donut2::after { content: ""; position: absolute; inset: 30px; border-radius: 50%; background: var(--surface); }
.donut2-mid { position: absolute; inset: 30px; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 1; }
.donut2-mid .n { font-size: 25px; font-weight: 800; letter-spacing: -.02em; }
.donut2-mid .t { font-size: 11px; color: var(--text-muted); }
.legend2 { flex: 1; min-width: 160px; display: flex; flex-direction: column; gap: 9px; }
.legend2 .r { display: flex; align-items: center; gap: 9px; font-size: 12.5px; }
/* Square swatches, and the two number columns right-aligned to their own widths
   so percentages and counts line up down the list instead of ragging. */
.legend2 .d { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.legend2 .nm { flex: 1; color: var(--text); }
.legend2 .pc { font-weight: 700; min-width: 34px; text-align: right; }
.legend2 .ct { color: var(--text-faint); font-size: 12px; min-width: 38px; text-align: right; }

/* ---- Approvals / counted list rows ---- */
/* No tiles and no pills here, matching the reference: a plain coloured outline
   glyph, the label, and the count as bare figures. Four filled tiles stacked
   vertically fought with the KPI row directly above them. */
.count-row { display: flex; align-items: center; gap: 13px; padding: 11px 0; }
.count-row + .count-row { border-top: 1px solid var(--border); }
.count-row .ic { background: none; width: 22px; height: 22px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.count-row .ic svg { width: 19px; height: 19px; fill: none; stroke-width: 1.9; }
.count-row .nm { flex: 1; font-size: 13px; font-weight: 600; }
.count-row .n { font-size: 14px; font-weight: 800; min-width: 20px; text-align: right; }
.count-row .n.zero { color: var(--text-faint); }
.count-row .n.some { color: var(--danger); }

/* ---- Stat tiles (Leave summary) ---- */
/* Label / figure / unit, divided by rules rather than sat in grey boxes — the
   reference's arrangement. The unit line is what lets the figure lose its
   "Days" suffix and still be unambiguous. */
.tile-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin-bottom: 14px; }
.tile { padding: 4px 8px; text-align: center; }
.tile + .tile { border-left: 1px solid var(--border); }
.tile .l { font-size: 11.5px; color: var(--text-muted); font-weight: 600; }
.tile .n { font-size: 23px; font-weight: 800; letter-spacing: -.02em; line-height: 1.25; }
.tile .u { font-size: 11px; color: var(--text-faint); }

/* Utilisation bar under the stat row. */
/* ------------------------------------------------------------------
   Payslip — the one document in this app laid out to match a piece of
   paper. Tokens only, so it reads in both themes on screen; the print
   block at the end of this file forces it to ink-on-white regardless.
   ------------------------------------------------------------------ */
.payslip-sheet {
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 26px 28px; max-width: 900px; box-shadow: var(--shadow);
}
.ps-letterhead { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.ps-title {
  background: var(--blue-700); color: #fff; font-weight: 800; text-align: center;
  padding: 10px 12px; font-size: 14px; letter-spacing: .3px;
}
.ps-period {
  background: var(--success-bg); color: var(--text); font-weight: 700;
  padding: 8px 12px; font-size: 13px; border: 1px solid var(--border); border-top: none;
}
.ps-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.ps-table th, .ps-table td { border: 1px solid var(--border); padding: 7px 9px; text-align: left; vertical-align: top; }
/* The global `th` rule uppercases and greys every table heading, which suits a
   data grid but not a document: the approved template prints "Employee Name",
   not "EMPLOYEE NAME". Reset all three properties here. */
.ps-table th {
  font-weight: 600; color: var(--text); background: var(--surface-alt);
  text-transform: none; letter-spacing: normal; font-size: 12.5px;
}
.ps-identity td { width: 26%; }
.ps-money { margin-top: 14px; }
.ps-money .ps-head th { background: var(--blue-700); color: #fff; text-align: center; font-weight: 700; }
.ps-money .ps-sub th { background: var(--blue-600); color: #fff; font-weight: 700; }
.ps-money .ps-cols th { background: var(--surface-alt); font-weight: 600; }
.ps-table .ps-total th, .ps-table .ps-total td { font-weight: 800; background: var(--surface-alt); }
.ps-summary { margin-top: 14px; }
.ps-summary .ps-head-right th { background: var(--blue-700); color: #fff; text-align: right; font-weight: 700; }
.ps-summary .ps-section th { background: var(--surface-alt); font-weight: 800; }
.ps-note { text-align: center; font-size: 11px; color: var(--text-muted); margin: 16px 0 0; }
.ps-footer { margin-top: 14px; padding-top: 12px; border-top: 2px solid var(--blue-700); text-align: center; font-size: 11px; color: var(--text-muted); line-height: 1.7; }
.ps-footer-name { font-weight: 800; color: var(--text); font-size: 12px; }
.ps-footer-meta { font-size: 10.5px; }

@media (max-width: 640px) {
  .payslip-sheet { padding: 14px; }
  /* The payslip is a fixed grid of four columns; on a phone it scrolls
     inside its own box rather than collapsing into stacked cards, because
     a payslip that reflows is no longer the document people recognise. */
  .ps-table { display: block; overflow-x: auto; white-space: nowrap; }
}

/* Printing.
   Two things have to happen, and the second is the one that is easy to miss.

   1. Remove the application shell. Note .app-shell::before — the painted rail
      backdrop, whose own comment says it is "visible when printing". Hiding
      .sidebar alone leaves that dark column on the page.

   2. **Neutralise the theme tokens, not individual rules.** A dark-theme user
      printing a payslip would otherwise get dark fills inside the table and
      white-on-white text in the footer, because every component here draws
      from var(--surface-alt) / var(--text). Redefining the tokens for print
      fixes all of them at once and keeps working as components are added. */
@media print {
  html, html[data-theme="dark"], html[data-theme="light"] {
    --bg: #FFFFFF;
    --surface: #FFFFFF;
    --surface-alt: #F2F2F2;
    --text: #000000;
    --text-muted: #333333;
    --text-faint: #555555;
    --border: #999999;
    --shadow: none;
  }

  .topbar, .sidebar, .scrim, .footer-bar, .no-print, .flash,
  .rail-map, .rail-collapse, .sidebar-foot { display: none !important; }
  .app-shell::before { display: none !important; content: none !important; }

  .app-shell { display: block !important; min-height: 0 !important; }
  .main, .content, .content-inner {
    display: block !important; margin: 0 !important; padding: 0 !important;
    width: auto !important; max-width: none !important;
  }

  html, body { background: #fff !important; color: #000 !important; margin: 0 !important; }

  .payslip-sheet {
    max-width: none; border: none; box-shadow: none; border-radius: 0;
    padding: 0; background: #fff !important;
  }

  /* The blue and green fills are part of the approved document, so they are
     forced through rather than dropped — browsers strip backgrounds when
     printing unless told otherwise. */
  .ps-title, .ps-money .ps-head th, .ps-money .ps-sub th, .ps-summary .ps-head-right th {
    background: #2f6fc0 !important; color: #fff !important;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .ps-period {
    background: #dff0d8 !important; color: #000 !important;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .ps-table .ps-total th, .ps-table .ps-total td, .ps-summary .ps-section th {
    background: #f2f2f2 !important; color: #000 !important;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }

  .ps-table { page-break-inside: avoid; }
  .ps-footer { page-break-inside: avoid; }
  @page { margin: 12mm; }
}

/* The download → sign → upload sequence. Numbered because it is a procedure
   people follow once and must not have to guess at; tokens only, both themes. */
.signflow { margin: 0; padding-left: 20px; }
.signflow li { margin-bottom: 14px; font-size: 13.5px; line-height: 1.7; color: var(--text); }
.signflow li:last-child { margin-bottom: 0; }
.signflow strong { font-weight: 700; }

/* ------------------------------------------------------------------
   The shell shed too late.
   The topbar is brand + masthead + search + actions. .topbar-title is the
   registered company name at 19px/800 with white-space:nowrap — roughly 430px
   that cannot shrink or wrap — and the user chip carries a full email address.
   Together with the 256px rail that gives the shell a minimum width near
   1400px, so EVERY page scrolled sideways between about 900px and 1400px:
   197px of horizontal overflow at 1200, which is an ordinary laptop.

   The ≤900px rules already hide both, they just started too late. These two
   steps shed the same things earlier, in the same order.
   ------------------------------------------------------------------ */
@media (max-width: 1400px) {
  /* The masthead is the first to go: the company name is still in the rail. */
  .topbar-title { display: none; }
}
@media (max-width: 1150px) {
  /* Then the username text, keeping the avatar and the caret. */
  .user-chip .uc-text { display: none; }
}

/* Six tiles on the asset list. A class rather than an inline grid-template,
   because an inline style cannot be overridden by the media queries below —
   at 1100px six columns are unreadable and at phone width they are unusable. */
.kpi-row-4 { grid-template-columns: repeat(4, 1fr); }
.kpi-row-3 { grid-template-columns: repeat(3, 1fr); }
.kpi-row-6 { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 1100px) { .kpi-row-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 1400px) { .kpi-row-6 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px)  { .kpi-row-6 { grid-template-columns: repeat(2, 1fr); } }
/* The label must be allowed two lines without shoving the number out of line
   with its neighbours — "Expiring soon" does exactly that at three columns. */
.kpi-row-6 .kpi2-top { align-items: flex-start; }
.kpi-row-6 .kpi2-lbl { line-height: 1.25; }

/* Expiry pills on the asset list. Three states, and the colours carry the same
   meaning as the badges elsewhere: green fine, amber act soon, red already past.
   Tokens only, so both themes follow. */
.expiry-pill { display: inline-block; font-size: 12px; font-weight: 700; padding: 3px 9px;
               border-radius: 999px; white-space: nowrap;
               background: var(--surface-alt); color: var(--text-muted); }
.expiry-pill.is-ok      { background: var(--success-bg); color: var(--success); }
.expiry-pill.is-soon    { background: var(--warn-bg);    color: var(--warn); }
.expiry-pill.is-expired { background: var(--danger-bg);  color: var(--danger); }

/* The KPI tile you are currently filtered by. Without this the tiles are links
   that appear to do nothing — the list changes but nothing says which one is on. */
.kpi2.is-on { outline: 2px solid var(--blue-600); outline-offset: -2px; }

/* ------------------------------------------------------------------
   My policies — the employee's half of the module.
   Cards rather than a table, because an employee is answering "what do I have
   to do?" and a row of version numbers and coverage counts does not answer it.
   One column on a phone: signing and uploading from mobile is the point.
   ------------------------------------------------------------------ */
.policy-cards { display: grid; gap: 14px; max-width: 760px; }
.policy-card { margin-bottom: 0; }
/* The ones needing action carry a left edge, so the eye finds them before
   reading a single word. */
.policy-card.is-todo { border-left: 3px solid var(--blue-600); }

.pc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.pc-title { font-family: var(--font-sans); font-size: 16px; font-weight: 700;
            color: var(--text); text-decoration: none; line-height: 1.35; }
.pc-title:hover { color: var(--blue-700); }
.pc-meta { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.pc-summary { font-size: 13.5px; color: var(--text-muted); line-height: 1.6; margin: 12px 0 0; }
.pc-note { font-size: 13px; color: var(--text-muted); margin: 10px 0 0;
           padding: 8px 10px; border-radius: 8px; background: var(--surface-alt); }
.pc-note.is-bad { background: var(--danger-bg); color: var(--danger); }
.pc-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

/* Pill tabs, as links rather than a JS control — the state is in the URL, so a
   bookmark and the back button both behave.
   A DISTINCT class, not .tabs: that one is the underlined component
   employees/profile.php already uses, and `.tabs .tab` here would have out-
   specificity'd it and silently restyled that page. See design-system.md —
   shared component classes are not redefined. */
.pill-tabs { display: flex; gap: 4px; margin-bottom: 14px; flex-wrap: wrap; }
.pill-tabs a { padding: 7px 14px; border-radius: 999px; font-size: 13px; font-weight: 600;
               color: var(--text-muted); text-decoration: none; background: var(--surface); }
.pill-tabs a:hover { color: var(--text); }
.pill-tabs a.is-on { background: var(--blue-700); color: #fff; }

@media (max-width: 640px) {
  .pc-head { flex-direction: column; }
  .pc-actions .btn { flex: 1; text-align: center; }
}

/* The audience picker. A scrolling column of checkboxes rather than a
   multi-select: with 45 staff a multi-select hides most of them and loses the
   ticks on a mis-click, and this has to be right — publishing to the wrong
   people is silent. */
.audience-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
                 gap: 6px; max-height: 340px; overflow-y: auto;
                 border: 1px solid var(--border); border-radius: 10px; padding: 12px; }
.audience-person { display: flex; align-items: flex-start; gap: 8px; font-size: 13.5px;
                   padding: 5px 6px; border-radius: 7px; cursor: pointer; }
.audience-person:hover { background: var(--surface-alt); }
.audience-role { display: block; font-size: 11.5px; color: var(--text-muted); }
.audience-actions { font-size: 13px; font-weight: 600; }
.audience-person.is-locked { opacity: .75; cursor: default; }
.audience-tag { display: inline-block; font-size: 10.5px; font-weight: 700; margin-left: 6px;
                padding: 1px 7px; border-radius: 999px;
                background: var(--surface-alt); color: var(--text-muted); }

/* Policy prose. Measure is capped because a policy read edge-to-edge on a wide
   monitor is a policy nobody finishes; tokens only, so it follows both themes. */
.policy-body { max-width: 72ch; }
.policy-body p { margin: 0 0 14px; font-size: 14px; line-height: 1.75; color: var(--text); }
.policy-body p:last-child { margin-bottom: 0; }

.util-bar { height: 8px; border-radius: 999px; background: var(--surface-alt); overflow: hidden; margin-top: 4px; }
.util-bar i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--blue-600), var(--green-600)); }
.util-cap { text-align: center; font-size: 12px; font-weight: 700; color: var(--blue-600); margin-top: 9px; }

/* ---- People / holiday rows with relative chips ---- */
.row-item { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.row-item:last-child { border-bottom: none; }
.row-av { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; background: linear-gradient(135deg, var(--blue-700), var(--blue-500)); color: #fff; }
.row-date { width: 38px; height: 38px; border-radius: 10px; flex-shrink: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.row-date .m { font-size: 8.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.row-date .d { font-size: 13px; font-weight: 800; line-height: 1.05; }
.row-body { flex: 1; min-width: 0; }
.row-name { font-size: 12.5px; font-weight: 700; }
.row-sub { font-size: 11px; color: var(--text-muted); margin-top: 1px; }
.when-chip { flex-shrink: 0; font-size: 10.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; background: var(--surface-alt); color: var(--text-muted); white-space: nowrap; }
.when-chip.soon { background: var(--warn-bg); color: var(--warn); }
.when-chip.today { background: var(--success-bg); color: var(--success); }

/* ---- Activity feed ---- */
/* Recent activity runs across, divided into columns, as the reference lays it
   out — not as a stacked list. Each cell is icon + text + a relative time. */
.act-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.act-cell { display: flex; gap: 11px; padding: 2px 16px; }
.act-cell + .act-cell { border-left: 1px solid var(--border); }
.act-cell:first-child { padding-left: 0; }
.act-cell .ic { width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.act-cell .ic svg { width: 16px; height: 16px; fill: none; }
.act-cell .b { min-width: 0; }
.act-cell .t { font-size: 12.5px; font-weight: 700; line-height: 1.35; }
.act-cell .s { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; line-height: 1.35; }
.act-cell .ago { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-faint); margin-top: 5px; }
.act-cell .ago::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--green-600); flex-shrink: 0; }

/* Bottom band: the wide activity strip beside the action tiles. */
.dash-bottom { display: grid; grid-template-columns: 1.7fr 1fr; gap: 14px; margin-top: 14px; align-items: start; }
.dash-bottom .card { margin-bottom: 0; }
.dash-bottom-solo { grid-template-columns: 1fr; }
@media (max-width: 1100px) { .dash-bottom { grid-template-columns: 1fr; } }

/* ---- Notice banner ---- */
/* Quick-action tile grid, as the reference places it at the foot of the board.
   Pure navigation — no figures — so it carries no risk of showing a number the
   database did not produce. */
.qtile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }   /* fills the row whatever the number of shortcuts */
.qtile {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 8px; border-radius: 12px; border: 1px solid var(--border);
  background: var(--surface); text-align: center; font-size: 11.5px; font-weight: 700; color: var(--text);
}
.qtile:hover { border-color: var(--blue-500); background: var(--sidebar-active); }
/* Bare blue glyph, no tinted tile — the reference's bottom row is a set of
   plain icons over two-line labels. */
.qtile .ic { background: none; width: auto; height: auto; color: #2F6FE4; display: flex; }
.qtile .ic svg { width: 26px; height: 26px; fill: none; stroke-width: 1.9; }
html[data-theme="dark"] .qtile .ic { color: #7FB0FF; }
@media (max-width: 900px) { .qtile-grid { grid-template-columns: repeat(2, 1fr); } }

.notice { display: flex; align-items: center; gap: 14px; padding: 14px 18px; margin-top: 14px; border-left: 3px solid var(--blue-600); }
.notice .ic { width: 38px; height: 38px; border-radius: 11px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.notice .ic svg { width: 18px; height: 18px; fill: none; }
.notice .t { font-size: 13.5px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.notice .s { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.tag-new { font-size: 9.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; padding: 2px 7px; border-radius: 999px; background: var(--success-bg); color: var(--success); }

@media (max-width: 1250px) { .dash-grid { grid-template-columns: 1fr 1fr; } .dash-grid > :nth-child(3) { grid-column: 1 / -1; }
                             .dash-row  { grid-template-columns: 1fr 1fr; } .dash-row  > :nth-child(3) { grid-column: 1 / -1; } }
@media (max-width: 1000px) { .kpi-row { grid-template-columns: repeat(2, 1fr); } .dash-row { grid-template-columns: 1fr; } }
@media (max-width: 760px)  { .dash-grid { grid-template-columns: 1fr; } .dash-grid > :nth-child(3) { grid-column: auto; } .kpi-row { grid-template-columns: 1fr; } .qa-strip { width: 100%; margin-left: 0; } .qa-btn { flex: 1; justify-content: center; } .tile-row { grid-template-columns: repeat(2, 1fr); } }

/* ============================================================
   Form builder
   ============================================================ */
.fb-grid { display: grid; grid-template-columns: 1fr 320px; gap: 16px; align-items: start; }
.fb-grid .card { margin-bottom: 16px; }
.fb-list { padding: 10px; }
.fb-row {
  display: flex; align-items: center; gap: 12px; padding: 11px 13px; margin-bottom: 6px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface-alt); cursor: default;
}
.fb-row:last-child { margin-bottom: 0; }
.fb-row.is-retired { opacity: .55; }
.fb-row.is-dragging { opacity: .35; border-style: dashed; }
.fb-handle { color: var(--text-faint); cursor: grab; font-size: 15px; user-select: none; flex-shrink: 0; }
.fb-handle:active { cursor: grabbing; }
.fb-main { flex: 1; min-width: 0; }
.fb-label { font-size: 13.5px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fb-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; font-size: 11.5px; color: var(--text-muted); }
.fb-key { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-faint); background: var(--surface); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; }
.fb-opts { color: var(--text-faint); }
.fb-used { color: var(--warn); font-weight: 600; }
.pill-req { font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; padding: 2px 7px; border-radius: 999px; background: var(--danger-bg); color: var(--danger); }
.pill-ret { font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; padding: 2px 7px; border-radius: 999px; background: var(--surface); color: var(--text-faint); border: 1px solid var(--border); }
.pill-type { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--sidebar-active); color: var(--blue-700); }
html[data-theme="dark"] .pill-type { background: rgba(35,98,189,.22); color: #7FB0FF; }
.fb-actions { display: flex; gap: 6px; flex-shrink: 0; }
.fb-actions form { margin: 0; }
.fb-ico { width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface); color: var(--text-faint); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.fb-ico svg { width: 15px; height: 15px; }
.fb-ico:hover { border-color: var(--text-faint); color: var(--text); }
.fb-ico.on { color: var(--danger); border-color: var(--danger); background: var(--danger-bg); }
.fb-ico.danger:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); }
.fb-ico.restore { color: var(--green-600); border-color: var(--green-600); }
.fb-add .field { margin-bottom: 12px; }
.fb-add textarea { font-family: inherit; font-size: 13px; resize: vertical; }
.fb-notes { margin: 0; padding-left: 17px; font-size: 12px; color: var(--text-muted); line-height: 1.7; }
.fb-notes li { margin-bottom: 8px; }
.fb-notes li:last-child { margin-bottom: 0; }
.fb-notes code { font-size: 11px; background: var(--surface-alt); border: 1px solid var(--border); border-radius: 4px; padding: 0 4px; }
@media (max-width: 900px) { .fb-grid { grid-template-columns: 1fr; } }

/* ============================================================
   Assets — grouped kit on the employee profile
   ============================================================ */
.asset-tab { display: flex; flex-direction: column; gap: 16px; padding: 4px 0 8px; }
.asset-group { border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.asset-group-head {
  display: flex; align-items: center; gap: 8px; padding: 9px 14px;
  background: var(--surface-alt); border-bottom: 1px solid var(--border);
  font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
}
.asset-group-head .n { font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--surface); color: var(--text-faint); border: 1px solid var(--border); }
.asset-line { display: flex; align-items: center; gap: 12px; padding: 11px 14px; border-bottom: 1px solid var(--border); }
.asset-line:last-child { border-bottom: none; }
.asset-line-main { flex: 1; min-width: 0; }
.asset-name { font-size: 13.5px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.asset-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.spec-chip { font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 999px; background: var(--sidebar-active); color: var(--blue-700); }
html[data-theme="dark"] .spec-chip { background: rgba(35,98,189,.22); color: #7FB0FF; }

/* Previous-month payslip panel (payslips/edit.php).
   Its own block rather than a .flash: a flash is something that happened, and
   this is standing context about the month being prepared — it is equally
   present when the answer is "nothing to carry forward". Tokens only, so it
   follows the theme in both directions. */
.prev-slip { border: 1px solid var(--border); background: var(--surface-alt); border-radius: var(--radius); padding: 12px 14px; }
.prev-slip-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.prev-slip-lbl { font-size: 12px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .03em; }
.prev-slip-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.prev-slip-actions:empty { display: none; }

/* A field the system fills in and the reader cannot type into (Days in month on
   payslips/edit.php). Styled so it reads as an answer rather than an empty box
   asking to be filled — a readonly input that looks editable is a field people
   click into and then wonder why nothing happens. */
.field input[readonly] { background: var(--surface-alt); color: var(--text-muted); cursor: default; font-weight: 600; }

/* Live totals on the payslip editor. Net salary and Monthly CTC are the two
   figures people actually look for, so they carry the weight. */
.ps-live th { font-weight: 600; color: var(--text-muted); text-align: left; }
.ps-live-strong th, .ps-live-strong td { font-weight: 700; color: var(--text); }

/* Authenticator QR on /mfa.php. White background in BOTH themes: a QR drawn dark
   on a dark card is unscannable by most phone cameras. */
/* 280px: about 5.5px per module on screen — large enough for a phone held at a
   comfortable distance. No padding: the four-module quiet zone is drawn inside the
   SVG itself, so its width is exact at any size. */
.mfa-qr { width: 280px; max-width: 100%; margin: 16px 0; background: #fff; border-radius: var(--radius); border: 1px solid var(--border); }
.mfa-qr svg { display: block; width: 100%; height: auto; }

/* ─────────────────────────────────────────────────────────────────────────────
   Workplace sign-in (login.php) — "Webronians Workspace" (Velraj's mockup,
   2026-09-17). Welcome side on the page background, sign-in card on the right;
   the same composition in both themes. The logo is the official metallic lockup
   (assets/img/webronic-lockup.png, from Pictures/Webronic-Logo-Brand-New.png) —
   never the mockup's redrawn one.
   Its tokens (--ws-*) are the portal-wide "workspace" palette: the shell uses the
   same background, card and tile colours so signing in and working look alike.
   ───────────────────────────────────────────────────────────────────────────── */
.wa-body { margin: 0; min-height: 100vh; color: var(--text); background-image: var(--ws-page); font-family: var(--font-sans); font-weight: 500; word-spacing: .025em; }
.wa-shell { position: relative; height: 100vh; height: 100dvh; min-height: 560px; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); }

/* Welcome side: one calm brand blue in both themes (the logo's ocean), two soft
   circles, nothing else — the clean look Velraj pointed at in Support Center's
   sign-in, in this portal's own colours and with its own layout. */
.wa-hero { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start;
  padding: clamp(22px, 5vh, 60px) clamp(28px, 5.5vw, 88px); color: #fff;
  /* EXACTLY the portal's rail (--sidebar-bg), in each theme — signing in and the
     page you land on are one blue, not two (Velraj, 2026-09-17). */
  background: var(--sidebar-bg);
  --ws-heading: #FFFFFF; --ws-subheading: rgba(255,255,255,.92); --ws-muted: rgba(255,255,255,.86); --ws-muted-strong: rgba(255,255,255,.9); }
.wa-hero::before, .wa-hero::after { content: ""; position: absolute; border-radius: 50%; background: rgba(255,255,255,.07); pointer-events: none; }
.wa-hero::before { width: 620px; height: 620px; right: -230px; top: -210px; }
.wa-hero::after  { width: 440px; height: 440px; left: -170px; bottom: -200px; }
.wa-hero > * { position: relative; z-index: 1; max-width: 640px; }
html[data-theme="dark"] .wa-hero { box-shadow: inset -1px 0 0 rgba(255,255,255,.08); }
.wa-hero-main { margin: auto 0; padding: clamp(10px, 3vh, 36px) 0; }
.wa-logo { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.wa-logo .wbr-mark { display: block; height: 44px; width: auto; filter: drop-shadow(0 0 1px rgba(255,255,255,.55)) drop-shadow(0 2px 6px rgba(0,0,0,.18)); }   /* keeps the blue W from melting into the blue */
.wa-os { margin-left: 2px; font-size: var(--fs-xs); font-weight: 600; letter-spacing: .3em; text-transform: uppercase; color: rgba(255,255,255,.85); }
.wa-headline { margin: 0; font-family: var(--font-sans); font-weight: 800; letter-spacing: -.03em;
  font-size: min(clamp(28px, 3.1vw, 50px), 7vh); line-height: 1.05; color: #fff; white-space: nowrap; }   /* one line, always */
.wa-tagline { margin: clamp(8px, 1.6vh, 16px) 0 8px; font-size: clamp(18px, 1.5vw, 21px); font-weight: 700; letter-spacing: -.01em; color: var(--ws-subheading); }
.wa-lead { margin: 0 0 clamp(16px, 3.6vh, 36px); max-width: 30em; font-size: var(--fs-md); font-weight: 500; line-height: 1.6; color: var(--ws-muted); }
.wa-features { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(12px, 2.6vh, 26px) 30px; }
.wa-feature { display: flex; gap: 15px; align-items: flex-start; }
.wa-feature-ic { flex: none; width: 46px; height: 46px; border-radius: 13px; display: grid; place-items: center;
  background: rgba(255,255,255,.14); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.16); }
.wa-feature-ic svg { width: 22px; height: 22px; }
.wa-feature strong { display: block; font-size: var(--fs-md); font-weight: 800; letter-spacing: -.01em; color: #fff; margin: 2px 0 3px; }
.wa-feature strong + span { display: block; font-size: var(--fs-sm); font-weight: 500; line-height: 1.5; color: var(--ws-muted); }
.wa-legal { margin: 0; font-size: var(--fs-sm); font-weight: 500; color: rgba(255,255,255,.78); }

.wa-panel { display: flex; align-items: center; justify-content: center; min-height: 0; overflow-y: auto; padding: clamp(20px, 4vh, 56px) clamp(20px, 4vw, 64px); background: var(--ws-side); }
/* No floating card: the form sits straight on the page, centred. */
.wa-card { width: 100%; max-width: 440px; box-sizing: border-box; }
.wa-glyph { display: flex; justify-content: center; margin-bottom: clamp(10px, 2vh, 20px); }
.wa-glyph .wbr-glyph { display: block; height: 52px; width: auto; }
.wa-title { margin: 0; text-align: center; font-family: var(--font-sans); font-size: 30px; font-weight: 800; letter-spacing: -.025em; line-height: 1.15; color: var(--ws-heading); }
.wa-sub { margin: 8px 0 clamp(18px, 3.2vh, 30px); text-align: center; color: var(--ws-muted); font-size: var(--fs-md); font-weight: 500; }
.wa-continue { display: flex; align-items: center; gap: 8px; margin: -12px 0 22px; padding: 10px 12px; border-radius: 12px;
  font-size: var(--fs-sm); color: var(--ws-heading); background: var(--ws-pill-bg); border: 1px solid var(--ws-pill-border); }
.wa-continue svg { width: 16px; height: 16px; color: var(--ws-accent); flex: none; }
.wa-alert { margin-bottom: 18px; }
.wa-form { display: grid; }
.wa-label { font-size: var(--fs-sm); font-weight: 700; margin: 0 0 8px; color: var(--ws-label); }
.wa-input { position: relative; display: flex; align-items: center; margin-bottom: clamp(12px, 2vh, 18px); }
.wa-input > svg { position: absolute; left: 16px; width: 19px; height: 19px; color: var(--ws-icon); pointer-events: none; z-index: 1; }
.wa-input input { width: 100%; box-sizing: border-box; height: 50px; padding: 0 48px 0 48px; font-family: var(--font-sans); font-size: var(--fs-md); font-weight: 500;
  color: var(--ws-heading); background: var(--ws-input); border: 1.5px solid var(--ws-input-border); border-radius: 12px;
  transition: border-color .15s, box-shadow .15s, background .15s; }
.wa-input input::placeholder { color: var(--ws-placeholder); font-weight: 500; }
.wa-input input:hover { border-color: var(--ws-input-hover); }
.wa-input input:focus { outline: none; border-color: var(--brand-ocean-600); background: var(--ws-input-focus); box-shadow: 0 0 0 4px var(--ws-ring); }
/* Browser autofill paints its own pale blue: repaint it in the field's own colours. */
.wa-input input:-webkit-autofill, .wa-input input:-webkit-autofill:hover, .wa-input input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ws-heading); caret-color: var(--ws-heading);
  -webkit-box-shadow: 0 0 0 1000px var(--ws-input) inset; transition: background-color 9999s ease-out 0s; }
.wa-code { letter-spacing: .32em; font-variant-numeric: tabular-nums; font-size: 19px !important; font-weight: 700 !important; }
.wa-eye { position: absolute; right: 6px; width: 38px; height: 38px; display: grid; place-items: center;
  border: 0; border-radius: 9px; background: transparent; color: var(--ws-icon); cursor: pointer; }
.wa-eye:hover { color: var(--ws-accent); background: var(--ws-pill-bg); }
.wa-eye[aria-pressed="true"] { color: var(--ws-accent); }
.wa-eye svg { width: 20px; height: 20px; }
.wa-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: -2px 0 clamp(14px, 2.4vh, 22px); }
.wa-check { display: inline-flex; align-items: center; gap: 9px; font-size: var(--fs-sm); font-weight: 600; color: var(--ws-label); cursor: pointer; user-select: none; }
.wa-check input { width: 17px; height: 17px; margin: 0; accent-color: var(--brand-ocean-600); cursor: pointer; }
.wa-link { border: 0; background: none; padding: 0; font-family: var(--font-sans); font-size: var(--fs-sm); font-weight: 600; color: var(--ws-accent); cursor: pointer; }
.wa-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.wa-note { margin: -10px 0 20px; padding: 11px 13px; border-radius: 12px; font-size: var(--fs-sm); line-height: 1.55; color: var(--ws-label);
  background: var(--ws-pill-bg); border: 1px solid var(--ws-pill-border); }
.wa-note[hidden] { display: none; }
.wa-btn { height: 52px; width: 100%; display: flex; align-items: center; justify-content: center; gap: 10px;
  border: 0; border-radius: 12px; font-family: var(--font-sans); font-size: var(--fs-md); font-weight: 700; letter-spacing: .005em; color: #fff; cursor: pointer;
  background: var(--ws-button); box-shadow: 0 8px 18px -8px rgba(21,97,194,.55);
  transition: transform .12s, box-shadow .15s, filter .15s; }
.wa-btn:hover { filter: brightness(1.07); box-shadow: 0 10px 22px -8px rgba(21,97,194,.65); }
.wa-btn:active { transform: translateY(1px); }
.wa-btn svg { width: 18px; height: 18px; transition: transform .15s; }
.wa-btn:hover svg { transform: translateX(3px); }
.wa-btn-alt { width: 100%; margin-top: 0; color: var(--ws-heading); background: transparent; border: 1.5px solid var(--ws-input-border); box-shadow: none; }
.wa-btn-alt:hover { box-shadow: none; filter: none; border-color: var(--brand-ocean-600); }
.wa-btn:disabled { opacity: .6; cursor: progress; }
.wa-or { display: flex; align-items: center; gap: 12px; margin: 16px 0; font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--ws-placeholder); }
.wa-or::before, .wa-or::after { content: ""; flex: 1; height: 1px; background: var(--ws-card-border); }
.wa-or[hidden], .wa-btn[hidden] { display: none; }
.wa-help { margin: 18px 0 0; text-align: center; font-size: var(--fs-sm); color: var(--ws-muted); }
.wa-help a { color: var(--ws-accent); font-weight: 600; text-decoration: none; }
.wa-help a:hover { text-decoration: underline; text-underline-offset: 3px; }
.wa-secure { display: flex; align-items: center; justify-content: center; gap: 8px; margin: clamp(16px, 2.6vh, 26px) 0 0;
  padding-top: clamp(12px, 2vh, 20px); border-top: 1px solid var(--ws-card-border); font-size: var(--fs-sm); font-weight: 600; color: var(--ws-muted); }
.wa-secure svg { width: 17px; height: 17px; color: var(--brand-green-600); }

@media (min-width: 861px) and (max-height: 780px) {
  .wa-lead { display: none; }
  .wa-tagline { margin-bottom: clamp(14px, 3vh, 26px); }
  .wa-feature-ic { width: 40px; height: 40px; border-radius: 11px; }
  .wa-feature-ic svg { width: 19px; height: 19px; }
}
@media (min-width: 861px) and (max-height: 660px) {
  .wa-features, .wa-glyph { display: none; }
}
@media (max-width: 1180px) {
  .wa-features { grid-template-columns: 1fr; gap: 18px; }
}
@media (max-width: 860px) {
  .wa-shell { grid-template-columns: 1fr; grid-template-rows: auto 1fr; height: auto; min-height: 100vh; min-height: 100dvh; overflow: visible; }
  .wa-hero { padding: 18px 18px 20px; }
  .wa-hero::after { display: none; }
  .wa-hero-main { padding: 12px 0 0; }
  .wa-logo { gap: 8px; }
  .wa-logo .wbr-mark { height: 30px; }
  .wa-headline { font-size: min(7.4vw, 30px); }
  .wa-tagline { font-size: 16px; margin: 6px 0 0; }
  .wa-lead, .wa-features, .wa-legal { display: none; }
  .wa-panel { align-items: flex-start; overflow: visible; padding: 22px 16px 24px; }
  .wa-glyph { display: none; }
  .wa-title { font-size: 24px; }
  .wa-sub { margin-bottom: 18px; }
}
@media (max-width: 860px) and (max-height: 700px) {
  .wa-tagline, .wa-os { display: none; }
  .wa-hero-main { padding-top: 8px; }
  .wa-headline { font-size: min(7vw, 26px); }
  .wa-sub { display: none; }
  .wa-title { margin-bottom: 16px; }
  .wa-secure { margin-top: 12px; padding-top: 10px; }
}

/* ── My account (account.php + mfa.php), 2026-09-18 ─────────────────────── */
.acct-hero { display: flex; align-items: center; gap: 18px; padding: 20px 22px; margin-bottom: 14px; }
.acct-av { flex: none; width: 60px; height: 60px; border-radius: 50%; display: grid; place-items: center;
  font-size: 21px; font-weight: 800; color: #fff; background: var(--ws-button); }
.acct-name { font-size: var(--fs-2xl); font-weight: 800; margin: 0 0 6px; }
.acct-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; font-size: var(--fs-sm); color: var(--text-muted); }
.acct-chip { padding: 3px 10px; border-radius: 999px; font-size: var(--fs-xs); font-weight: 700; background: var(--sidebar-active); color: var(--blue-600); }
.acct-chip.is-on  { background: var(--success-bg); color: var(--success); }
.acct-chip.is-off { background: var(--warn-bg); color: var(--warn); }
.acct-tabs { margin: 0 0 16px; }
.acct-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
.acct-grid .card { margin-bottom: 0; }
.acct-form { display: grid; gap: 14px; max-width: 420px; }
.acct-form .field { margin: 0; }
.acct-sub { padding-top: 16px; border-top: 1px solid var(--border); }
.acct-sub h3 { font-size: var(--fs-md); margin: 0 0 4px; }
.acct-inline { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 10px; }
.acct-inline input { width: 190px; height: 40px; padding: 0 12px; font: inherit; font-size: var(--fs-md); font-weight: 600;
  letter-spacing: .18em; color: var(--text); background: var(--surface-alt); border: 1px solid var(--border); border-radius: 9px; }
.acct-inline input::placeholder { letter-spacing: 0; font-weight: 500; color: var(--text-faint); }
.acct-inline input:focus { outline: none; border-color: var(--blue-600); box-shadow: 0 0 0 3px var(--ws-ring); }
/* One label/value pair per line inside the account cards — two columns of pairs
   in a half-width card wrapped every label. */
.acct-grid .data-grid { display: block; }
.acct-grid .data-row { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.acct-grid .data-row:last-child { border-bottom: 0; }
.acct-grid .data-row > span:first-child { color: var(--text-muted); flex: none; }
.acct-grid .data-row > span:last-child { text-align: right; font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.acct-events { list-style: none; margin: 0; padding: 0; }
.acct-events li { display: grid; grid-template-columns: 10px 1fr auto; gap: 10px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--border); }
.acct-events li:last-child { border-bottom: 0; }
.acct-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); }
.acct-dot.is-warn { background: var(--gold-500); }
.acct-dot.is-bad  { background: var(--danger); }
.acct-ev { font-weight: 600; font-size: var(--fs-sm); }
.acct-when { font-size: var(--fs-xs); color: var(--text-muted); white-space: nowrap; }
@media (max-width: 860px) {
  .acct-grid { grid-template-columns: 1fr; }
  .acct-hero { padding: 16px; }
  .acct-events li { grid-template-columns: 10px 1fr; }
  .acct-when { grid-column: 2; }
}

/* A section heading inside a public form (field_type 'section', migration 029). */
.form-section { grid-column: 1 / -1; margin: 18px 0 2px; padding-top: 14px; border-top: 1px solid var(--border);
  font-size: var(--fs-lg); font-weight: 800; letter-spacing: -.01em; color: var(--ws-heading, var(--text)); }
.form-grid > .form-section:first-child, .form-section:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* One pair per line — the application screen reads as a transcript, not a grid. */
.data-grid-1 { grid-template-columns: 1fr; }
.data-grid-1 .data-row { align-items: flex-start; gap: 24px; }
.data-grid-1 .data-row .label { flex: 0 0 38%; }
.data-grid-1 .data-row .value { text-align: left; }

