/* ─────────────────────────────────────────────────────────────
   Globosoft HRMS — theme set
   Loads AFTER app.css. Every rule is scoped to html.t so it raises
   specificity and cannot touch a page that has not opted in.

   One skeleton, four variable sets. All four keep the SAME violet
   palette (#462A8D primary, #2A1B54 sidebar) — what differs is
   radius, density, weight, border and shadow, which is what actually
   makes a theme read differently.

   Add class "t" plus one of: theme-soft | theme-sharp | theme-dense
   | theme-elevated
   ───────────────────────────────────────────────────────────── */

/* ══ Shared palette — identical across all four ══════════════ */
html.t {
  --t-primary:      #462A8D;
  --t-primary-dark: #38216F;
  --t-primary-soft: #ECE9F7;
  --t-sidebar:      #2A1B54;
  --t-accent:       #8572BF;

  --t-ink:   #221D38;
  --t-body:  #46415C;
  --t-muted: #605B73;   /* audited: >=4.5:1 on white and on ground */
  --t-faint: #6B6680;
  --t-deco:  #A9A4B8;   /* placeholders only, never read text */

  --t-success: #12A474; --t-success-soft: #E7F6F0;
  --t-warning: #C77700; --t-warning-soft: #FDF3E1;
  --t-danger:  #E5484D; --t-danger-soft:  #FDECEC;
}

/* ══ A · SOFT — friendly, rounded, generous ══════════════════ */
html.t.theme-soft {
  --t-ground: #F7F5FC; --t-surface: #FFF; --t-raised: #FAF8FE;
  --t-line: #EBE7F5; --t-line-2: #DFD9F0;
  --t-r-sm: 8px; --t-r-md: 12px; --t-r-lg: 18px;
  --t-card-pad: 22px; --t-head-pad: 18px 22px;
  --t-card-border: 1px solid var(--t-line);
  --t-card-shadow: 0 4px 18px -8px rgba(70,42,141,.13);
  --t-h1: 25px; --t-h1-w: 600; --t-h1-track: -.02em;
  --t-base: 13.5px; --t-row-pad: 15px 16px;
  --t-btn-r: 999px; --t-btn-pad: 9px 20px;
  --t-label-tf: none; --t-label-ls: 0; --t-label-size: 11.5px;
}

/* ══ B · SHARP — editorial, square, high contrast ════════════ */
html.t.theme-sharp {
  --t-ground: #FFFFFF; --t-surface: #FFF; --t-raised: #F7F6FA;
  --t-line: #E2DEEE; --t-line-2: #CFC9E2;
  --t-r-sm: 3px; --t-r-md: 4px; --t-r-lg: 4px;
  --t-card-pad: 20px; --t-head-pad: 15px 20px;
  --t-card-border: 1px solid var(--t-line-2);
  --t-card-shadow: none;
  --t-h1: 27px; --t-h1-w: 700; --t-h1-track: -.032em;
  --t-base: 13.5px; --t-row-pad: 13px 16px;
  --t-btn-r: 4px; --t-btn-pad: 9px 16px;
  --t-label-tf: uppercase; --t-label-ls: .09em; --t-label-size: 10.5px;
}

/* ══ C · DENSE — compact, data-forward ═══════════════════════ */
html.t.theme-dense {
  --t-ground: #F4F3F9; --t-surface: #FFF; --t-raised: #FAFAFD;
  --t-line: #E7E4F0; --t-line-2: #DAD5E9;
  --t-r-sm: 4px; --t-r-md: 6px; --t-r-lg: 8px;
  --t-card-pad: 14px; --t-head-pad: 11px 14px;
  --t-card-border: 1px solid var(--t-line);
  --t-card-shadow: none;
  --t-h1: 20px; --t-h1-w: 650; --t-h1-track: -.022em;
  --t-base: 12.5px; --t-row-pad: 9px 12px;
  --t-btn-r: 6px; --t-btn-pad: 6px 12px;
  --t-label-tf: uppercase; --t-label-ls: .07em; --t-label-size: 10px;
}

/* ══ D · ELEVATED — depth, layered, dimensional ══════════════ */
html.t.theme-elevated {
  --t-ground: #F3F1FA; --t-surface: #FFF; --t-raised: #F9F8FD;
  --t-line: #ECE8F7; --t-line-2: #DED8F1;
  --t-r-sm: 7px; --t-r-md: 11px; --t-r-lg: 16px;
  --t-card-pad: 20px; --t-head-pad: 17px 20px;
  --t-card-border: 1px solid rgba(255,255,255,.9);
  --t-card-shadow: 0 1px 2px rgba(34,29,56,.05), 0 12px 30px -14px rgba(70,42,141,.30);
  --t-h1: 24px; --t-h1-w: 650; --t-h1-track: -.024em;
  --t-base: 13.5px; --t-row-pad: 14px 16px;
  --t-btn-r: 11px; --t-btn-pad: 9px 18px;
  --t-label-tf: none; --t-label-ls: 0; --t-label-size: 11.5px;
}

/* ══ Skeleton — reads only from the variables above ══════════ */
html.t body { background: var(--t-ground); color: var(--t-body); font-size: var(--t-base); letter-spacing: -.006em; }
html.t h1, html.t .app-page-title { font-size: var(--t-h1); font-weight: var(--t-h1-w); letter-spacing: var(--t-h1-track); color: var(--t-ink); }
html.t h2 { font-size: 19px; font-weight: 600; color: var(--t-ink); }
html.t h3 { font-size: 15px; font-weight: 600; letter-spacing: -.012em; color: var(--t-ink); }
html.t .kpi-value, html.t .stat-value, html.t .app-table td, html.t .app-table th { font-variant-numeric: tabular-nums; }

/* Sidebar */
html.t .app-sidebar { background: var(--t-sidebar); padding: 16px 12px; }
html.t .app-sidebar .nav-section { font-size: 10px; font-weight: 600; letter-spacing: .14em; color: rgba(255,255,255,.45); padding: 18px 12px 7px; }
html.t .app-sidebar .nav-link { border-radius: var(--t-r-md); padding: 8px 12px; font-size: 13px; font-weight: 500; color: rgba(255,255,255,.76); }
html.t .app-sidebar .nav-link i { opacity: .72; }
html.t .app-sidebar .nav-link:hover { background: rgba(255,255,255,.08); color: #fff; }
html.t .app-sidebar .nav-link.active { position: relative; background: rgba(255,255,255,.11); color: #fff; font-weight: 600; }
html.t .app-sidebar .nav-link.active::before { content:""; position:absolute; left:-12px; top:50%; transform:translateY(-50%); width:3px; height:17px; border-radius:0 3px 3px 0; background: var(--t-accent); }

/* Topbar */
html.t .app-topbar { background: rgba(255,255,255,.85); backdrop-filter: saturate(150%) blur(10px); -webkit-backdrop-filter: saturate(150%) blur(10px); border-bottom: 1px solid var(--t-line); }
html.t .search-box input { background: var(--t-raised); border: 1px solid var(--t-line); border-radius: var(--t-r-md); font-size: 13px; }
html.t .search-box input:focus { background:#fff; border-color: var(--t-primary); box-shadow: 0 0 0 3px rgba(70,42,141,.10); }
html.t .topbar-icon-btn { border-radius: var(--t-r-md); color: var(--t-muted); }
html.t .topbar-icon-btn:hover { background: var(--t-primary-soft); color: var(--t-primary); }

/* Page header — the gradient banner is removed in all four, and every
   rule app.css wrote FOR that banner has to be undone. app.css is
   (0,3,0); these are (0,4,1). */
html.t .page-header:not(.page-header--plain) { background:none; box-shadow:none; border-radius:0; padding:2px 0 16px; margin-bottom:22px; border-bottom:1px solid var(--t-line); }
html.t .page-header:not(.page-header--plain) h1 { color: var(--t-ink); }
html.t .page-header:not(.page-header--plain) .lead { color: var(--t-muted); font-size: 13px; }
html.t .page-header:not(.page-header--plain) .breadcrumbs,
html.t .page-header:not(.page-header--plain) .breadcrumbs a,
html.t .page-header:not(.page-header--plain) .breadcrumbs span { color: var(--t-faint) !important; font-size: 11.5px; }
html.t .page-header:not(.page-header--plain) .btn-primary { background: var(--t-primary); border-color: var(--t-primary); color:#fff; }
html.t .page-header:not(.page-header--plain) .btn-primary:hover { background: var(--t-primary-dark); border-color: var(--t-primary-dark); color:#fff; }
html.t .page-header:not(.page-header--plain) .btn:not(.btn-primary),
html.t .page-header:not(.page-header--plain) .form-select,
html.t .page-header:not(.page-header--plain) .form-control { background:#fff; border:1px solid var(--t-line-2); color: var(--t-body); }
html.t .page-header:not(.page-header--plain) .btn:not(.btn-primary):hover { background: var(--t-primary-soft); color: var(--t-primary); }

/* Cards */
html.t .app-card { background: var(--t-surface); border: var(--t-card-border); border-radius: var(--t-r-lg); box-shadow: var(--t-card-shadow); }
html.t .app-card .card-section-header { padding: var(--t-head-pad); border-bottom: 1px solid var(--t-line); }
html.t .app-card .card-section-body { padding: var(--t-card-pad); }

/* KPI */
html.t .kpi { background: var(--t-surface); border: var(--t-card-border); border-radius: var(--t-r-lg); padding: var(--t-card-pad); box-shadow: var(--t-card-shadow); transition: transform .16s ease, box-shadow .16s ease; }
html.t .kpi:hover { transform: translateY(-1px); }
html.t .kpi .kpi-icon { width: 34px; height: 34px; border-radius: var(--t-r-md); font-size: 15px; margin-bottom: 12px; }
html.t .kpi .kpi-label { font-size: var(--t-label-size); text-transform: var(--t-label-tf); letter-spacing: var(--t-label-ls); color: var(--t-muted); font-weight: 600; }
html.t .kpi .kpi-value { font-size: calc(var(--t-h1) + 2px); font-weight: 650; color: var(--t-ink); margin: 5px 0; }
html.t .kpi .kpi-trend { font-size: 11.5px; color: var(--t-faint); }

/* Elevated gives the KPI icons a subtle brand gradient — the one place
   the four differ beyond geometry. */
html.t.theme-elevated .kpi .kpi-icon.bg-soft-primary { background: linear-gradient(135deg, #EDE9F9, #DCD3F2); color: var(--t-primary); }

/* Table */
html.t .app-table thead th { font-size: var(--t-label-size); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; color: var(--t-faint); padding: var(--t-row-pad); border-bottom: 1px solid var(--t-line); }
html.t .app-table tbody td { padding: var(--t-row-pad); font-size: var(--t-base); color: var(--t-body); border-bottom: 1px solid var(--t-line); }
html.t .app-table tbody tr:hover { background: var(--t-raised); }
html.t .app-table tbody tr:last-child td { border-bottom: none; }

/* Chips, buttons, forms, tabs, modal */
html.t .chip { border-radius: var(--t-r-sm); font-size: 11.5px; font-weight: 600; padding: 3px 9px; }
html.t .btn { border-radius: var(--t-btn-r); padding: var(--t-btn-pad); font-size: 13px; font-weight: 600; }
html.t .btn-primary { background: var(--t-primary); border-color: var(--t-primary); box-shadow: 0 6px 16px -8px rgba(70,42,141,.50); }
html.t .btn-primary:hover { background: var(--t-primary-dark); border-color: var(--t-primary-dark); }
html.t .btn-light { background:#fff; border:1px solid var(--t-line-2); color: var(--t-body); }
html.t .btn-light:hover { background: var(--t-primary-soft); color: var(--t-primary); border-color: var(--t-line-2); }
html.t .form-control, html.t .form-select { border:1px solid var(--t-line-2); border-radius: var(--t-r-md); font-size: var(--t-base); padding: 9px 12px; color: var(--t-ink); background:#fff; }
html.t .form-control::placeholder { color: var(--t-deco); }
html.t .form-control:focus, html.t .form-select:focus { border-color: var(--t-primary); box-shadow: 0 0 0 3px rgba(70,42,141,.10); }
html.t .form-label { font-size: 12.5px; font-weight: 500; color: var(--t-body); margin-bottom: 6px; }
html.t .form-check-input:checked { background-color: var(--t-primary); border-color: var(--t-primary); }
html.t .nav-tabs { border-bottom: 1px solid var(--t-line); }
html.t .nav-tabs .nav-link { border:0; border-bottom:2px solid transparent; color: var(--t-muted); font-size:13px; font-weight:500; padding:8px 12px; }
html.t .nav-tabs .nav-link.active { color: var(--t-primary); background:transparent; border-bottom-color: var(--t-primary); }
html.t .modal-content { border:1px solid var(--t-line); border-radius: var(--t-r-lg); }
html.t .modal-header, html.t .modal-footer { border-color: var(--t-line); }

@media (prefers-reduced-motion: reduce) {
  html.t .kpi { transition: none; }
  html.t .kpi:hover { transform: none; }
}

/* ══════════════════════════════════════════════════════════════
   E · BRIGHT — modelled on the Staffu reference
   Full-width coloured topbar, white sidebar sitting UNDER it, logo
   in the topbar's left block, soft tinted active pill.

   The whole shell is repositioned in CSS only — app.css fixes the
   sidebar/topbar with top/left offsets, so no page markup changes.
   Colour is Globosoft violet throughout, not the reference's indigo.
   ══════════════════════════════════════════════════════════════ */
html.t.theme-bright {
  --t-ground: #F7F7FB; --t-surface: #FFF; --t-raised: #FAFAFD;
  --t-line: #EAEAF1; --t-line-2: #E1DEEE;
  /* The reference sets a neutral UI sans, not Poppins — its 'a' is
     double-storey where Poppins' is single-storey geometric. Inter is the
     closest widely-available match. */
  --t-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --t-r-sm: 6px; --t-r-md: 10px; --t-r-lg: 12px;
  --t-card-pad: 20px; --t-head-pad: 16px 20px;
  --t-card-border: 1px solid var(--t-line);
  --t-card-shadow: 0 1px 3px rgba(34,29,56,.05);
  --t-h1: 23px; --t-h1-w: 650; --t-h1-track: -.022em;
  --t-base: 13.5px; --t-row-pad: 13px 16px;
  --t-btn-r: 8px; --t-btn-pad: 8px 16px;
  --t-label-tf: none; --t-label-ls: 0; --t-label-size: 12px;

  --t-bar: var(--t-primary);      /* the full-width top band */
  --t-rail: 248px;
}

/* ── Topbar: full width, brand violet ─────────────────────── */
html.t.theme-bright .app-topbar {
  left: 0; height: 60px;
  padding-left: calc(var(--t-rail) + 14px);
  background: var(--t-bar);
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border-bottom: 0;
}
/* The logo lives in the sidebar markup — pin it into the topbar's left
   block so the reference layout is reached without moving any HTML. */
html.t.theme-bright .app-sidebar .brand {
  position: fixed; top: 0; left: 0;
  width: var(--t-rail); height: 60px;
  display: flex; align-items: center; justify-content: flex-start;
  padding: 0 20px; margin: 0;
  z-index: 1031;
}
html.t.theme-bright .app-sidebar .brand .logo-img {
  max-width: 148px; max-height: 30px; width: auto; height: auto;
  filter: brightness(0) invert(1);
}
html.t.theme-bright .app-topbar .search-box input {
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.20);
  color: #fff; border-radius: var(--t-r-md);
}
html.t.theme-bright .app-topbar .search-box input::placeholder { color: rgba(255,255,255,.72); }
html.t.theme-bright .app-topbar .search-box input:focus {
  background: rgba(255,255,255,.24); border-color: rgba(255,255,255,.45); box-shadow: none; color:#fff;
}
html.t.theme-bright .app-topbar .search-box i { color: rgba(255,255,255,.8); }
html.t.theme-bright .topbar-icon-btn {
  width: 38px; height: 38px; border-radius: 50%;
  background: rgba(255,255,255,.14); color: #fff;
}
html.t.theme-bright .topbar-icon-btn:hover { background: rgba(255,255,255,.26); color: #fff; }
html.t.theme-bright .topbar-profile .meta strong { color: #fff; }
html.t.theme-bright .topbar-profile .meta span { color: rgba(255,255,255,.78); }
html.t.theme-bright .app-hamburger { color: #fff; }

/* ── Sidebar: white, below the topbar ─────────────────────── */
html.t.theme-bright .app-sidebar {
  top: 60px;
  background: #fff;
  border-right: 1px solid var(--t-line);
  padding: 14px 12px;
}
/* #9A95AA measured 2.9:1 on white — under the 4.5 AA floor for text this
   small. Darkened to 5.4:1. */
html.t.theme-bright .app-sidebar .nav-section {
  color: #6E6A82; font-size: 10.5px; font-weight: 700;
  letter-spacing: .1em; padding: 16px 12px 6px;
}
html.t.theme-bright .app-sidebar .nav-link {
  color: #4A4560; border-radius: var(--t-r-md);
  padding: 9px 12px; font-size: 13.5px; font-weight: 500;
}
html.t.theme-bright .app-sidebar .nav-link i { opacity: 1; color: #6E6A82; }
html.t.theme-bright .app-sidebar .nav-link:hover { background: #F4F2FA; color: var(--t-primary); }
html.t.theme-bright .app-sidebar .nav-link:hover i { color: var(--t-primary); }
/* Active: soft violet pill with a dot at the right, as in the reference */
html.t.theme-bright .app-sidebar .nav-link.active {
  background: var(--t-primary-soft); color: var(--t-primary); font-weight: 600;
}
html.t.theme-bright .app-sidebar .nav-link.active i { color: var(--t-primary); }
html.t.theme-bright .app-sidebar .nav-link.active::before { display: none; }
html.t.theme-bright .app-sidebar .nav-link.active::after {
  content: ""; margin-left: auto;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--t-primary); flex-shrink: 0;
}

/* ── Content ──────────────────────────────────────────────── */
html.t.theme-bright .app-content { padding-top: 80px; }

/* Page header: plain title left, breadcrumbs pulled to the right */
html.t.theme-bright .page-header:not(.page-header--plain) {
  position: relative; border-bottom: 0; padding: 0 0 4px; margin-bottom: 18px;
}
html.t.theme-bright .page-header:not(.page-header--plain) .breadcrumbs {
  position: absolute; right: 0; top: 7px; margin: 0;
  color: var(--t-muted) !important; font-size: 12.5px;
}
html.t.theme-bright .page-header:not(.page-header--plain) .breadcrumbs span:last-child { color: var(--t-ink) !important; font-weight: 500; }

/* KPI: trend reads as a chip, as in the reference */
/* The chip puts the status colour on its own soft tint. The standard
   --t-success / --t-danger measured 2.86:1 in that pairing, so the chip
   uses deeper variants; the tints are unchanged. */
html.t.theme-bright .kpi .kpi-trend {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px; border-radius: var(--t-r-sm);
  font-size: 11.5px; font-weight: 600;
  background: var(--t-success-soft); color: #0A6E4E;
}
html.t.theme-bright .kpi .kpi-trend.down { background: var(--t-danger-soft); color: #A32328; }

/* ── Typography ────────────────────────────────────────────
   app.css sets font-family on body and on h1–h6 only; everything else
   inherits, and Bootstrap's reboot makes form controls inherit too.
   So overriding those two selectors reaches the whole app. Icon fonts
   are set on .bi and are deliberately left alone. */
html.t.theme-bright body,
html.t.theme-bright h1, html.t.theme-bright h2, html.t.theme-bright h3,
html.t.theme-bright h4, html.t.theme-bright h5, html.t.theme-bright h6,
html.t.theme-bright .app-page-title,
html.t.theme-bright .kpi .kpi-value,
html.t.theme-bright .stat-value {
  font-family: var(--t-font);
}
html.t.theme-bright body { letter-spacing: -0.002em; }   /* Inter needs less negative tracking than Poppins */
html.t.theme-bright h1, html.t.theme-bright h2, html.t.theme-bright h3 { letter-spacing: -0.018em; }

/* ── Cards, as in the reference ────────────────────────────
   Title bold and dark, supporting line grey beneath it, generous
   internal padding, hairline border and a barely-there shadow. */
html.t.theme-bright .app-card { box-shadow: 0 1px 2px rgba(34,29,56,.04); }
html.t.theme-bright .app-card .card-section-header h3 { font-size: 15.5px; font-weight: 600; color: var(--t-ink); }
html.t.theme-bright .app-card .card-section-header { border-bottom: 0; padding-bottom: 4px; }
html.t.theme-bright .app-card .card-section-body { padding-top: 10px; }

/* KPI: bold title, big figure, chip, caption */
html.t.theme-bright .kpi { padding: 20px; }
html.t.theme-bright .kpi .kpi-label { font-size: 15px; font-weight: 600; color: var(--t-ink); }
html.t.theme-bright .kpi .kpi-value { font-size: 30px; font-weight: 700; letter-spacing: -.03em; margin: 10px 0 8px; }
html.t.theme-bright .kpi .kpi-icon { width: 38px; height: 38px; border-radius: 10px; }

/* "…" overflow buttons that sit in card headers */
html.t.theme-bright .card-section-header .btn-link,
html.t.theme-bright .card-section-header .btn-sm.btn-light {
  color: var(--t-deco); border: 0; background: transparent; padding: 2px 6px;
}
html.t.theme-bright .card-section-header .btn-link:hover { color: var(--t-primary); }

/* Progress bars — rounded track and fill, as in Team Performance */
html.t.theme-bright .progress { height: 8px; border-radius: 999px; background: #EFEDF6; overflow: hidden; }
html.t.theme-bright .progress-bar { border-radius: 999px; background: var(--t-primary); }

/* Badge/chip on a card header (78%, 156/200 in the reference) */
html.t.theme-bright .badge {
  border-radius: 999px; font-weight: 600; font-size: 11.5px;
  padding: 4px 10px; background: var(--t-primary-soft); color: var(--t-primary);
}

/* Stacked avatar group with a +N counter */
html.t.theme-bright .av-stack { display: flex; align-items: center; }
html.t.theme-bright .av-stack .av { margin-left: -8px; border: 2px solid #fff; }
html.t.theme-bright .av-stack .av:first-child { margin-left: 0; }
html.t.theme-bright .av-stack .av-more {
  margin-left: -8px; border: 2px solid #fff;
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--t-primary-soft); color: var(--t-primary);
  font-size: 11.5px; font-weight: 700;
}

/* Tinted accent panel — the lavender "Meeting with…" card */
html.t.theme-bright .app-card.card-accent,
html.t.theme-bright .card-accent {
  background: var(--t-primary-soft);
  border-color: #DCD5F0;
}

html.t.theme-bright .chip { border-radius: 999px; padding: 4px 11px; }

@media (max-width: 991.98px) {
  html.t.theme-bright .app-topbar { padding-left: 12px; }
  html.t.theme-bright .app-sidebar .brand { position: static; width: auto; height: auto; padding: 10px 12px 20px; }
  html.t.theme-bright .app-sidebar .brand .logo-img { filter: none; }
  html.t.theme-bright .app-sidebar { top: 0; }
}


/* ══════════════════════════════════════════════════════════════
   F · BENTO — modelled on the Lordbank reference
   Soft neutral ground, borderless white cards at a large radius,
   fully-rounded pill controls, a greeting-scale page title over a
   small breadcrumb, and dark accent panels mixed among the white.

   Two deliberate departures from the reference:
   · Colour stays Globosoft violet, not the reference's mint green.
     Say the word and it is a three-line change.
   · The sidebar stays. The reference carries 5 horizontal tabs; this
     app has 30+ nav items across 6 sections, which cannot fit in a
     pill bar. It gets the reference's pill treatment instead.
   ══════════════════════════════════════════════════════════════ */
html.t.theme-bento {
  --t-ground: #F4F5F6; --t-surface: #FFFFFF; --t-raised: #FAFBFB;
  --t-line: #ECEEEF; --t-line-2: #E1E4E5;
  --t-r-sm: 10px; --t-r-md: 14px; --t-r-lg: 20px;
  --t-card-pad: 22px; --t-head-pad: 20px 22px 6px;
  --t-card-border: 0;
  --t-card-shadow: 0 1px 2px rgba(22,28,34,.045), 0 8px 24px -16px rgba(22,28,34,.14);
  --t-h1: 30px; --t-h1-w: 600; --t-h1-track: -.03em;
  --t-base: 13.5px; --t-row-pad: 14px 18px;
  --t-btn-r: 999px; --t-btn-pad: 9px 18px;
  --t-label-tf: none; --t-label-ls: 0; --t-label-size: 12.5px;

  /* The reference's display face: double-storey 'a', single-storey 'g',
     geometric-humanist. Plus Jakarta Sans is the closest widely
     available match — see the note in my message about certainty. */
  --t-font: 'Plus Jakarta Sans', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --t-dark: #1F3A4D;          /* the reference's deep accent panels */
}

/* Typography — app.css sets font-family on body and h1–h6 only, and
   Bootstrap's reboot makes form controls inherit, so these two reach
   everything. Icon fonts live on .bi::before and are left alone. */
html.t.theme-bento body,
html.t.theme-bento h1, html.t.theme-bento h2, html.t.theme-bento h3,
html.t.theme-bento h4, html.t.theme-bento h5, html.t.theme-bento h6,
html.t.theme-bento .app-page-title,
html.t.theme-bento .kpi .kpi-value,
html.t.theme-bento .stat-value { font-family: var(--t-font); }
html.t.theme-bento body { letter-spacing: -.008em; }

/* ── Sidebar: white with pill rows ─────────────────────── */
html.t.theme-bento .app-sidebar {
  background: #fff; border-right: 1px solid var(--t-line); padding: 16px 14px;
}
html.t.theme-bento .app-sidebar .nav-section {
  color: #6B7479; font-size: 10.5px; font-weight: 700;
  letter-spacing: .1em; padding: 18px 14px 7px;
}
html.t.theme-bento .app-sidebar .nav-link {
  border-radius: 999px; padding: 10px 16px;
  font-size: 13.5px; font-weight: 500; color: #4A5459;
}
html.t.theme-bento .app-sidebar .nav-link i { opacity: 1; color: #5C666B; }
html.t.theme-bento .app-sidebar .nav-link:hover { background: #F2F4F4; color: var(--t-primary); }
html.t.theme-bento .app-sidebar .nav-link:hover i { color: var(--t-primary); }
/* Active reads as a solid filled pill, as in the reference's tab bar */
html.t.theme-bento .app-sidebar .nav-link.active {
  background: var(--t-primary); color: #fff; font-weight: 600;
}
html.t.theme-bento .app-sidebar .nav-link.active i { color: #fff; }
html.t.theme-bento .app-sidebar .nav-link.active::before { display: none; }

/* ── Topbar: white, pill search, circular actions ──────── */
html.t.theme-bento .app-topbar {
  background: #fff; border-bottom: 1px solid var(--t-line);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
html.t.theme-bento .search-box input {
  background: #F4F5F6; border: 1px solid transparent; border-radius: 999px;
  font-size: 13px; padding-left: 40px;
}
html.t.theme-bento .search-box input:focus {
  background: #fff; border-color: var(--t-primary); box-shadow: 0 0 0 3px rgba(70,42,141,.10);
}
html.t.theme-bento .topbar-icon-btn {
  width: 38px; height: 38px; border-radius: 50%;
  background: #F4F5F6; color: #4A5459;
}
html.t.theme-bento .topbar-icon-btn:hover { background: var(--t-primary-soft); color: var(--t-primary); }

/* ── Page header: small breadcrumb, greeting-scale title ─ */
html.t.theme-bento .page-header:not(.page-header--plain) {
  background: none; box-shadow: none; border: 0; border-radius: 0;
  padding: 4px 0 0; margin-bottom: 22px;
}
html.t.theme-bento .page-header:not(.page-header--plain) .breadcrumbs {
  color: #677075 !important; font-size: 12.5px; margin-bottom: 6px;
}
html.t.theme-bento .page-header:not(.page-header--plain) .breadcrumbs span:last-child { color: #4A5459 !important; }
html.t.theme-bento .page-header:not(.page-header--plain) h1 { color: #16212B; }
html.t.theme-bento .page-header:not(.page-header--plain) .lead { color: #5C666B; font-size: 13.5px; }
/* Header controls become pills, matching "+ Add widget" / "Add report" */
html.t.theme-bento .page-header:not(.page-header--plain) .btn:not(.btn-primary),
html.t.theme-bento .page-header:not(.page-header--plain) .form-select,
html.t.theme-bento .page-header:not(.page-header--plain) .form-control {
  background: #fff; border: 1px solid var(--t-line-2); color: #4A5459; border-radius: 999px;
}
html.t.theme-bento .page-header:not(.page-header--plain) .btn:not(.btn-primary):hover {
  background: var(--t-primary-soft); color: var(--t-primary);
}
html.t.theme-bento .page-header:not(.page-header--plain) .btn-primary {
  background: var(--t-primary); border-color: var(--t-primary); color: #fff; border-radius: 999px;
}

/* ── Cards: borderless, large radius ───────────────────── */
html.t.theme-bento .app-card { border: 0; }
html.t.theme-bento .app-card .card-section-header { border-bottom: 0; }
html.t.theme-bento .app-card .card-section-header h3 { font-size: 19px; font-weight: 600; letter-spacing: -.022em; color: #16212B; }
/* Small grey caption above a big title, as the reference cards do */
html.t.theme-bento .app-card .card-section-header .card-eyebrow { font-size: 12.5px; color: #677075; margin-bottom: 2px; }

/* KPI: caption, then a large figure */
html.t.theme-bento .kpi { border: 0; padding: 22px; }
html.t.theme-bento .kpi .kpi-label { font-size: 12.5px; font-weight: 500; color: #677075; }
html.t.theme-bento .kpi .kpi-value { font-size: 32px; font-weight: 600; letter-spacing: -.035em; color: #16212B; margin: 6px 0 8px; }
html.t.theme-bento .kpi .kpi-icon { width: 38px; height: 38px; border-radius: 12px; }
html.t.theme-bento .kpi .kpi-trend {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  background: var(--t-success-soft); color: #0A6E4E;
}
html.t.theme-bento .kpi .kpi-trend.down { background: var(--t-danger-soft); color: #A32328; }

/* ── Dark accent panel — add class "card-dark" to any app-card ── */
html.t.theme-bento .app-card.card-dark,
html.t.theme-bento .kpi.card-dark { background: var(--t-dark); color: #fff; }
html.t.theme-bento .card-dark h3,
html.t.theme-bento .card-dark .kpi-value { color: #fff; }
html.t.theme-bento .card-dark .kpi-label,
html.t.theme-bento .card-dark .lead { color: rgba(255,255,255,.74); }

/* ── Tables, chips, buttons, forms ─────────────────────── */
html.t.theme-bento .app-table thead th {
  font-size: 11.5px; font-weight: 600; text-transform: none; letter-spacing: 0;
  color: #677075; border-bottom: 1px solid var(--t-line);
}
html.t.theme-bento .app-table tbody td { color: #414C52; border-bottom: 1px solid var(--t-line); }
html.t.theme-bento .app-table tbody tr:hover { background: #F7F8F9; }

html.t.theme-bento .chip { border-radius: 999px; padding: 4px 12px; font-size: 11.5px; font-weight: 600; }
html.t.theme-bento .chip.success { background: var(--t-success-soft); color: #0A6E4E; }
html.t.theme-bento .chip.danger  { background: var(--t-danger-soft);  color: #A32328; }
html.t.theme-bento .chip.warning { background: var(--t-warning-soft); color: #8A5300; }

html.t.theme-bento .btn { border-radius: 999px; font-weight: 600; }
html.t.theme-bento .btn-primary { background: var(--t-primary); border-color: var(--t-primary); box-shadow: none; }
html.t.theme-bento .btn-primary:hover { background: var(--t-primary-dark); border-color: var(--t-primary-dark); box-shadow: none; }
html.t.theme-bento .btn-light { background: #fff; border: 1px solid var(--t-line-2); color: #4A5459; }
html.t.theme-bento .btn-light:hover { background: var(--t-primary-soft); color: var(--t-primary); }

html.t.theme-bento .form-control, html.t.theme-bento .form-select {
  border: 1px solid var(--t-line-2); border-radius: 12px; background: #fff; color: #16212B;
}
html.t.theme-bento .form-control:focus, html.t.theme-bento .form-select:focus {
  border-color: var(--t-primary); box-shadow: 0 0 0 3px rgba(70,42,141,.10);
}
html.t.theme-bento .form-label { color: #4A5459; font-size: 12.5px; font-weight: 500; }

/* Progress bars — rounded track and fill */
html.t.theme-bento .progress { height: 8px; border-radius: 999px; background: #EDEFF0; }
html.t.theme-bento .progress-bar { border-radius: 999px; background: var(--t-primary); }

html.t.theme-bento .nav-tabs { border-bottom: 1px solid var(--t-line); }
html.t.theme-bento .nav-tabs .nav-link { border: 0; border-radius: 999px; color: #5C666B; font-weight: 500; }
html.t.theme-bento .nav-tabs .nav-link.active { background: var(--t-primary-soft); color: var(--t-primary); }

html.t.theme-bento .modal-content { border: 0; border-radius: 20px; }
/* ══════════════════════════════════════════════════════════════
   Sign in — structured from the Staffu reference the client endorsed
   (staffu.mantrakshdevs.com/signin.html): split panel, FORM ON THE
   LEFT, feature showcase on the right. Palette is Globosoft violet.

   Two things in the reference are deliberately not copied:
   · the Google sign-in button — this API has no OAuth route, and a
     button that cannot work is worse than no button;
   · "Create an account" — an HRMS is invite-only, staff do not
     self-register, so that link would lead nowhere.
   ══════════════════════════════════════════════════════════════ */
html.t .signin {
  min-height: 100vh;
  display: grid; grid-template-columns: 52fr 48fr;
  background: #fff;
  font-family: var(--t-font);
  -webkit-font-smoothing: antialiased;
}

/* ── Left: the form ────────────────────────────────────── */
html.t .signin__form {
  display: flex; flex-direction: column; justify-content: center;
  padding: 48px 64px;
}
html.t .signin__inner { width: 100%; max-width: 384px; margin: 0 auto; }
/* On white, the mark keeps its own crimson */
html.t .signin__mark {
  display: block; height: 30px; width: auto; max-width: 176px;
  object-fit: contain; margin: 0 0 44px;
}
html.t .signin__title { margin: 0 0 7px; font-size: 27px; font-weight: 650; letter-spacing: -.026em; color: var(--t-ink); }
html.t .signin__meta { margin: 0 0 30px; font-size: 14px; color: var(--t-muted); }

html.t .signin__field { margin: 0 0 18px; }
html.t .signin__labelrow { display: flex; justify-content: space-between; align-items: baseline; }
html.t .signin__label { display: block; margin: 0 0 7px; font-size: 13px; font-weight: 500; color: var(--t-body); }
html.t .signin__link { font-size: 12.5px; font-weight: 500; color: var(--t-primary); text-decoration: none; }
html.t .signin__link:hover { text-decoration: underline; }
/* The reference carries a hint under the password field */
html.t .signin__hint { margin: 7px 0 0; font-size: 11.5px; color: var(--t-muted); }

html.t .signin__input {
  width: 100%; height: 48px; padding: 0 15px;
  font-family: inherit; font-size: 14px; color: var(--t-ink);
  background: #fff; border: 1px solid var(--t-line-2); border-radius: 10px;
  appearance: none;
  transition: border-color .16s ease, box-shadow .22s cubic-bezier(.16,1,.3,1);
}
html.t .signin__input::placeholder { color: var(--t-deco); }
html.t .signin__input:focus {
  outline: none; border-color: var(--t-primary); box-shadow: 0 0 0 4px rgba(70,42,141,.12);
}
html.t .signin__input:-webkit-autofill,
html.t .signin__input:-webkit-autofill:focus {
  -webkit-box-shadow: inset 0 0 0 100px #fff; -webkit-text-fill-color: var(--t-ink);
}
html.t .signin__pw { position: relative; }
html.t .signin__pw .signin__input { padding-right: 48px; }
html.t .signin__reveal {
  position: absolute; right: 7px; top: 24px; transform: translateY(-50%);
  width: 34px; height: 34px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 8px;
  color: #948FA3; cursor: pointer; line-height: 1;
  transition: color .15s ease, background-color .15s ease;
}
html.t .signin__reveal:hover { color: var(--t-primary); background: var(--t-primary-soft); }

html.t .signin__check { display: flex; align-items: center; gap: 9px; margin: 4px 0 24px; font-size: 13px; color: var(--t-body); }
html.t .signin__check input { width: 16px; height: 16px; margin: 0; flex-shrink: 0; accent-color: var(--t-primary); cursor: pointer; }

html.t .signin__submit {
  position: relative; overflow: hidden;
  width: 100%; height: 48px;
  font-family: inherit; font-size: 14.5px; font-weight: 600;
  color: #fff; background: var(--t-primary);
  border: 0; border-radius: 10px; cursor: pointer;
  box-shadow: 0 8px 20px -8px rgba(70,42,141,.55);
  transition: background-color .16s ease, box-shadow .22s ease, transform .16s cubic-bezier(.16,1,.3,1);
}
html.t .signin__submit::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 28%, rgba(255,255,255,.26) 50%, transparent 72%);
  transform: translateX(-120%);
}
html.t .signin__submit:hover:not(:disabled) { background: var(--t-primary-dark); box-shadow: 0 12px 26px -8px rgba(70,42,141,.62); transform: translateY(-1px); }
html.t .signin__submit:hover:not(:disabled)::after { animation: sgnSheen .75s ease-out; }
@keyframes sgnSheen { to { transform: translateX(120%); } }
html.t .signin__submit:active:not(:disabled) { transform: translateY(0) scale(.995); }
html.t .signin__submit:disabled { opacity: .62; cursor: default; box-shadow: none; }

html.t .sgn-spin {
  display: inline-block; width: 15px; height: 15px; vertical-align: -2px;
  margin-right: 8px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
  animation: sgnSpin .6s linear infinite;
}
@keyframes sgnSpin { to { transform: rotate(360deg); } }

html.t .signin__error {
  margin: 0 0 18px; padding: 11px 13px;
  font-size: 12.5px; line-height: 1.5;
  color: #A32328; background: var(--t-danger-soft);
  border-left: 2px solid #C1272D; border-radius: 8px;
}
html.t .signin__foot { margin: 26px 0 0; font-size: 11.5px; color: var(--t-muted); }
html.t .signin__foot a { color: var(--t-body); text-decoration: none; }
html.t .signin__foot a:hover { color: var(--t-primary); text-decoration: underline; }

/* ── Right: the showcase ───────────────────────────────── */
html.t .signin__show {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center; gap: 14px;
  padding: 48px 56px;
  background: var(--t-sidebar);
}
/* One light source, upper right, so the field has form */
html.t .signin__show::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(110% 80% at 85% 10%, rgba(148,126,214,.48) 0%, rgba(148,126,214,0) 62%);
  pointer-events: none;
}
/* Concentric arcs echoing the opening in the Globosoft G */
html.t .signin__show::after {
  content: ""; position: absolute;
  left: -200px; bottom: -210px; width: 440px; height: 440px;
  border-radius: 50%; border: 1.5px solid rgba(255,255,255,.12);
  box-shadow: 0 0 0 48px rgba(255,255,255,.05), 0 0 0 98px rgba(255,255,255,.032);
  pointer-events: none;
}
html.t .signin__showhead {
  position: relative; z-index: 1;
  margin: 0 0 8px; max-width: 340px;
  font-size: 21px; font-weight: 600; line-height: 1.4; letter-spacing: -.02em; color: #fff;
}
html.t .signin__showcard {
  position: relative; z-index: 1;
  display: flex; align-items: flex-start; gap: 13px;
  padding: 15px 17px;
  background: rgba(255,255,255,.075);
  border: 1px solid rgba(255,255,255,.115);
  border-radius: 13px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
html.t .signin__showicon {
  flex-shrink: 0; width: 36px; height: 36px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.14); color: #fff; font-size: 16px;
}
html.t .signin__showtitle { margin: 0 0 3px; font-size: 13.5px; font-weight: 600; color: #fff; }
html.t .signin__showtext  { margin: 0; font-size: 12px; line-height: 1.55; color: rgba(255,255,255,.72); }

/* ── Motion ────────────────────────────────────────────────
   Gated behind html.anim-ready, added by the page only when the tab is
   visible. These animate from opacity 0 and a background tab has a
   frozen timeline — ungated, the form would render invisible. */
@keyframes sgnFadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes sgnSlideL { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }

html.anim-ready.t .signin__mark  { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .06s both; }
html.anim-ready.t .signin__title { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .14s both; }
html.anim-ready.t .signin__meta  { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .20s both; }
html.anim-ready.t .signin__form form > .signin__field:nth-of-type(1) { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .26s both; }
html.anim-ready.t .signin__form form > .signin__field:nth-of-type(2) { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .32s both; }
html.anim-ready.t .signin__form form > .signin__check  { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .38s both; }
html.anim-ready.t .signin__form form > .signin__submit { animation: sgnFadeUp .5s cubic-bezier(.16,1,.3,1) .44s both; }
html.anim-ready.t .signin__foot { animation: sgnFadeUp .5s ease-out .50s both; }
html.anim-ready.t .signin__showhead { animation: sgnSlideL .55s cubic-bezier(.16,1,.3,1) .18s both; }
html.anim-ready.t .signin__showcard:nth-of-type(2) { animation: sgnSlideL .55s cubic-bezier(.16,1,.3,1) .26s both; }
html.anim-ready.t .signin__showcard:nth-of-type(3) { animation: sgnSlideL .55s cubic-bezier(.16,1,.3,1) .34s both; }
html.anim-ready.t .signin__showcard:nth-of-type(4) { animation: sgnSlideL .55s cubic-bezier(.16,1,.3,1) .42s both; }
html.anim-ready.t .signin__showcard:nth-of-type(5) { animation: sgnSlideL .55s cubic-bezier(.16,1,.3,1) .50s both; }

/* Slide only, never opacity — a running animation pins its first frame
   while the timeline is stalled, which could leave the message present
   but invisible. An unreadable error is the one failure to avoid. */
@keyframes sgnErrIn { from { transform: translateY(-7px); } to { transform: none; } }
@keyframes sgnNudge { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-4px)} 75%{transform:translateX(4px)} }
html.anim-ready.t .signin__error:not(.d-none) {
  animation: sgnErrIn .32s cubic-bezier(.16,1,.3,1), sgnNudge .34s ease-in-out .3s;
}

@media (max-width: 980px) {
  html.t .signin { grid-template-columns: 1fr; }
  html.t .signin__show { display: none; }
  html.t .signin__form { padding: 48px 32px; }
}
@media (max-width: 480px) {
  html.t .signin__form { padding: 34px 22px; }
  html.t .signin__mark { margin-bottom: 32px; height: 27px; }
  html.t .signin__title { font-size: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  html.anim-ready.t .signin__mark,
  html.anim-ready.t .signin__title,
  html.anim-ready.t .signin__meta,
  html.anim-ready.t .signin__form form > .signin__field,
  html.anim-ready.t .signin__form form > .signin__check,
  html.anim-ready.t .signin__form form > .signin__submit,
  html.anim-ready.t .signin__foot,
  html.anim-ready.t .signin__showhead,
  html.anim-ready.t .signin__showcard,
  html.anim-ready.t .signin__error:not(.d-none) { animation: none !important; }
  html.t .signin__submit:hover:not(:disabled) { transform: none; }
  html.t .sgn-spin { animation-duration: 1.4s; }
}

/* ══════════════════════════════════════════════════════════════
   Bento hero — the three-card band from the Lordbank reference
   Profile card, an averages card with a dot-matrix, and a dark
   accent panel. Violet throughout, not the reference's green.
   ══════════════════════════════════════════════════════════════ */
html.t.theme-bento .bento-profile {
  background: #EDE9F9; border-radius: 20px; padding: 20px;
  display: flex; flex-direction: column; justify-content: space-between;
  min-height: 240px; position: relative; overflow: hidden;
}
html.t.theme-bento .bento-avatar {
  width: 92px; height: 92px; border-radius: 50%;
  background: #8572BF; color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; font-weight: 600; letter-spacing: -.02em;
  margin: 6px auto 0;
}
html.t.theme-bento .bento-idcard {
  background: #fff; border-radius: 14px; padding: 11px 14px;
  display: flex; align-items: center; gap: 10px;
}
html.t.theme-bento .bento-idname { font-size: 13.5px; font-weight: 600; color: #16212B; line-height: 1.25; }
html.t.theme-bento .bento-idrole { font-size: 11.5px; color: #677075; }
html.t.theme-bento .bento-idbtn {
  width: 32px; height: 32px; border-radius: 50%; border: 0; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #F1EEFA; color: var(--t-primary); font-size: 14px; cursor: pointer;
}
html.t.theme-bento .bento-idbtn:last-child { background: var(--t-primary); color: #fff; }

html.t.theme-bento .bento-figure { font-size: 40px; font-weight: 600; letter-spacing: -.04em; color: #16212B; line-height: 1; }
html.t.theme-bento .bento-caption { font-size: 12.5px; color: #677075; margin: 8px 0 0; }
html.t.theme-bento .bento-legend { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #677075; }
html.t.theme-bento .bento-legend i { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }

/* Dot matrix — one column per day, dots shaded by that day's density */
html.t.theme-bento .bento-dots { display: flex; align-items: flex-end; gap: 7px; }
html.t.theme-bento .bento-dotcol { display: flex; flex-direction: column-reverse; gap: 5px; flex: 1; }
html.t.theme-bento .bento-dot { width: 100%; aspect-ratio: 1; border-radius: 50%; background: #E7E3F5; }
html.t.theme-bento .bento-dot.on { background: var(--t-primary); }
html.t.theme-bento .bento-dot.mid { background: #A08FD6; }

html.t.theme-bento .bento-dark {
  background: var(--t-primary); border-radius: 20px; padding: 20px; color: #fff;
  display: flex; flex-direction: column; justify-content: space-between; min-height: 240px;
}
html.t.theme-bento .bento-dark .bento-figure { color: #fff; }
html.t.theme-bento .bento-dark .bento-caption { color: rgba(255,255,255,.78); }
html.t.theme-bento .bento-inset {
  background: rgba(255,255,255,.13); border-radius: 15px; padding: 15px;
  border: 1px solid rgba(255,255,255,.14);
}
html.t.theme-bento .bento-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600;
  background: var(--t-success-soft); color: #0A6E4E;
}
html.t.theme-bento .bento-dark .bento-pill { background: rgba(255,255,255,.18); color: #fff; }
html.t.theme-bento .bento-chipicon {
  width: 34px; height: 34px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.16); color: #fff; font-size: 15px;
}

/* ══════════════════════════════════════════════════════════════
   DESIGN SYSTEM — Phase 1 primitives
   Spacing/radius/shadow tokens, plus the components the audit found
   missing entirely: skeletons (0 files), empty states (0 files), and
   a unified toast. Everything here is reusable — no page-specific CSS.
   ══════════════════════════════════════════════════════════════ */
html.t {
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;
  --shadow-sm: 0 1px 2px rgba(22,28,34,.05);
  --shadow-md: 0 4px 14px -6px rgba(22,28,34,.14);
  --shadow-lg: 0 18px 44px -20px rgba(22,28,34,.28);
  --dur-fast: 150ms; --dur: 220ms; --ease: cubic-bezier(.16,1,.3,1);
}

/* ── Accessibility: a visible focus ring on every interactive thing.
      §28 asks for keyboard navigation; Bootstrap's default ring is
      easy to lose against tinted backgrounds. ─────────────────── */
html.t a:focus-visible,
html.t button:focus-visible,
html.t [tabindex]:focus-visible,
html.t .form-control:focus-visible,
html.t .form-select:focus-visible {
  outline: 2px solid var(--t-primary);
  outline-offset: 2px;
  border-radius: var(--t-r-sm);
}

/* ── Skeleton loaders ──────────────────────────────────── */
html.t .sk {
  position: relative; overflow: hidden;
  background: #E9EBEC; border-radius: var(--t-r-sm);
}
html.t .sk::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.65), transparent);
  transform: translateX(-100%);
  animation: skShimmer 1.25s infinite;
}
@keyframes skShimmer { to { transform: translateX(100%); } }
html.t .sk-line   { height: 12px; margin-bottom: var(--sp-2); }
html.t .sk-line.w40{ width: 40%; } html.t .sk-line.w60{ width: 60%; } html.t .sk-line.w80{ width: 80%; }
html.t .sk-title  { height: 20px; width: 45%; margin-bottom: var(--sp-3); }
html.t .sk-figure { height: 34px; width: 55%; margin-bottom: var(--sp-3); }
html.t .sk-avatar { width: 36px; height: 36px; border-radius: 50%; }
html.t .sk-card   { padding: var(--t-card-pad); background: var(--t-surface); border-radius: var(--t-r-lg); box-shadow: var(--shadow-sm); }
html.t .sk-row    { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) 0; border-bottom: 1px solid var(--t-line); }
html.t .sk-row .sk-line { margin: 0; }

/* ── Empty states ──────────────────────────────────────── */
html.t .empty { text-align: center; padding: var(--sp-10) var(--sp-6); }
html.t .empty__icon {
  width: 56px; height: 56px; margin: 0 auto var(--sp-4);
  border-radius: 18px; display: flex; align-items: center; justify-content: center;
  background: var(--t-primary-soft); color: var(--t-primary); font-size: 24px;
}
html.t .empty__title { font-size: 15.5px; font-weight: 600; color: var(--t-ink); margin: 0 0 var(--sp-2); }
html.t .empty__text  { font-size: 13px; color: var(--t-muted); margin: 0 auto var(--sp-5); max-width: 320px; line-height: 1.6; }

/* ── Toasts ────────────────────────────────────────────── */
html.t .toast-stack {
  position: fixed; right: 20px; bottom: 20px; z-index: 2200;
  display: flex; flex-direction: column; gap: var(--sp-2);
  max-width: min(380px, calc(100vw - 40px));
}
html.t .toast-item {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: 13px 15px;
  background: #fff; border-radius: var(--t-r-md);
  box-shadow: var(--shadow-lg);
  border-left: 3px solid var(--t-primary);
  font-size: 13px; color: var(--t-ink);
  animation: toastIn var(--dur) var(--ease) both;
}
@keyframes toastIn { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
html.t .toast-item.is-out { animation: toastOut 180ms ease-in both; }
@keyframes toastOut { to { opacity: 0; transform: translateY(6px); } }
html.t .toast-item i { font-size: 16px; line-height: 1.3; flex-shrink: 0; }
html.t .toast-item.success { border-left-color: var(--t-success); }
html.t .toast-item.success i { color: #0A6E4E; }
html.t .toast-item.warning { border-left-color: var(--t-warning); }
html.t .toast-item.warning i { color: #8A5300; }
html.t .toast-item.danger  { border-left-color: var(--t-danger); }
html.t .toast-item.danger  i { color: #A32328; }

@media (prefers-reduced-motion: reduce) {
  html.t .sk::after, html.t .toast-item { animation: none; }
}

/* ── Collapsed sidebar rail (§6) ────────────────────────────
   shell.js toggles .is-collapsed and persists it. Labels hide, the
   rail narrows to icons, and the native title="" tooltip carries the
   label — shell.js sets title on every link for exactly this. */
html.t .app-sidebar { transition: width var(--dur) var(--ease); }
html.t .app-sidebar.is-collapsed { width: 76px; }
html.t .app-sidebar.is-collapsed .nav-link { justify-content: center; padding-left: 0; padding-right: 0; }
html.t .app-sidebar.is-collapsed .nav-link span { display: none; }
html.t .app-sidebar.is-collapsed .nav-link i { margin: 0; font-size: 17px; }
html.t .app-sidebar.is-collapsed .nav-link::after { display: none; }   /* the active dot */
html.t .app-sidebar.is-collapsed .nav-section {
  font-size: 0; padding: 14px 0 6px; text-align: center;
}
html.t .app-sidebar.is-collapsed .nav-section::before {
  content: ""; display: inline-block; width: 18px; height: 1px; background: var(--t-line-2);
}
html.t .app-sidebar.is-collapsed .brand { justify-content: center; padding-left: 0; padding-right: 0; }
html.t .app-sidebar.is-collapsed .brand .logo-img { max-width: 40px; }
html.sidebar-collapsed .app-topbar { left: 76px; }
html.sidebar-collapsed .app-content { margin-left: 76px; }
@media (max-width: 991.98px) {
  html.sidebar-collapsed .app-topbar { left: 0; }
  html.sidebar-collapsed .app-content { margin-left: 0; }
  html.t .app-sidebar.is-collapsed { width: 248px; }   /* off-canvas on mobile — never a rail */
}

/* ── Sidebar logo on a LIGHT sidebar ────────────────────────
   app.css forces `filter: brightness(0) invert(1)` on the sidebar mark,
   which was right when the sidebar was deep violet. theme-bright and
   theme-bento make it white, so a white asset + invert = invisible.

   The mark is then painted in the brand violet rather than its native
   crimson. Done with a MASK, not a filter chain: masking gives the exact
   token colour, whereas hue-rotate/sepia stacks only approximate a
   target hex and drift per browser. The element's own bitmap is replaced
   with a 1x1 transparent GIF so only the masked background shows.
   Specificity beats app.css's (0,3,0) rule. */
html.t.theme-bento .app-sidebar .brand .logo-img,
html.t.theme-bright .app-sidebar .brand .logo-img {
  content: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
  width: 150px; height: 34px; max-width: 150px; max-height: 34px;
  background-color: var(--t-primary);
  -webkit-mask: url('../../images/logo.png') no-repeat center / contain;
          mask: url('../../images/logo.png') no-repeat center / contain;
  filter: none;
}
/* A tenant's uploaded logo keeps its own artwork and colours — masking it
   to a flat violet would destroy their branding. */
html.t.theme-bento.hrms-logo-custom .app-sidebar .brand .logo-img,
html.t.theme-bright.hrms-logo-custom .app-sidebar .brand .logo-img {
  -webkit-mask: none !important; mask: none !important;
  background-color: transparent !important;
  filter: none !important;
}

/* ══════════════════════════════════════════════════════════════
   MOTION — §16. Durations 150–300ms, entrances play once, nothing
   loops in peripheral vision. Everything here is gated behind
   html.anim-ready (set only when the tab is visible) because these
   animate from opacity 0 — a frozen timeline in a background tab
   would otherwise leave content permanently invisible.
   ══════════════════════════════════════════════════════════════ */
@keyframes uiRise  { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes uiFade  { from { opacity: 0; } to { opacity: 1; } }
@keyframes uiPop   { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }

/* Cards and KPIs rise in, staggered by position within their row */
html.anim-ready.t .app-content .kpi,
html.anim-ready.t .app-content .app-card,
html.anim-ready.t .bento .card,
html.anim-ready.t .bento .profile { animation: uiRise .28s var(--ease, cubic-bezier(.16,1,.3,1)) both; }
html.anim-ready.t .app-content [class*="col-"]:nth-child(1) .kpi,
html.anim-ready.t .app-content [class*="col-"]:nth-child(1) .app-card { animation-delay: .02s; }
html.anim-ready.t .app-content [class*="col-"]:nth-child(2) .kpi,
html.anim-ready.t .app-content [class*="col-"]:nth-child(2) .app-card { animation-delay: .07s; }
html.anim-ready.t .app-content [class*="col-"]:nth-child(3) .kpi,
html.anim-ready.t .app-content [class*="col-"]:nth-child(3) .app-card { animation-delay: .12s; }
html.anim-ready.t .app-content [class*="col-"]:nth-child(4) .kpi,
html.anim-ready.t .app-content [class*="col-"]:nth-child(4) .app-card { animation-delay: .17s; }

/* Page header fades in ahead of the content */
html.anim-ready.t .page-header { animation: uiFade .24s ease-out both; }
/* Modals scale in rather than snapping */
html.anim-ready.t .modal.show .modal-dialog { animation: uiPop .22s cubic-bezier(.16,1,.3,1) both; }
/* Table rows fade as they arrive */
html.anim-ready.t .app-table tbody tr { animation: uiFade .2s ease-out both; }

/* ── Interaction ─────────────────────────────────────────── */
html.t .kpi, html.t .app-card, html.t .bento .card {
  transition: transform .18s var(--ease, cubic-bezier(.16,1,.3,1)), box-shadow .18s ease;
}
html.t .kpi:hover, html.t .bento .card:hover { transform: translateY(-2px); }
html.t .btn { transition: transform .14s ease, background-color .16s ease, box-shadow .16s ease; }
html.t .btn:active:not(:disabled) { transform: translateY(1px) scale(.99); }
html.t .app-sidebar .nav-link { transition: background-color .15s ease, color .15s ease; }
html.t .app-table tbody tr { transition: background-color .14s ease; }

/* Figures animating up look wrong mid-count if they reflow, so pin them
   to tabular figures while counting. */
html.t .is-counting { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  html.anim-ready.t .app-content .kpi,
  html.anim-ready.t .app-content .app-card,
  html.anim-ready.t .bento .card,
  html.anim-ready.t .bento .profile,
  html.anim-ready.t .page-header,
  html.anim-ready.t .modal.show .modal-dialog,
  html.anim-ready.t .app-table tbody tr { animation: none !important; }
  html.t .kpi:hover, html.t .bento .card:hover { transform: none; }
}

