/* @import must be the very first thing in the file (a stylesheet's @import rules are only valid
   before any other rule - a comment doesn't count, but the :root block below does) - see
   https://developer.mozilla.org/en-US/docs/Web/CSS/@import. Loads the same two Google Fonts
   (Inter for body text, Poppins for headings/buttons/brand marks) that the reference app at
   D:\Java\jira-data-portal loads, for the same reason it does: kabs.de (that theme's own model)
   pairs a bold rounded display face for headings with a plain highly-legible sans for body copy. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@600;700;800&display=swap');

/* ---- Theme tokens ----

   Copied from the sibling internal tool at D:\Java\jira-data-portal (its own
   src/main/resources/static/css/app.css :root block, the "Kabs" theme - see that file's own
   comment for the kabs.de reference it was modeled after) so this app's colors actually match
   rather than just resembling the SNAKPulse/reference screenshots by eye. Every color below is
   that file's own value, copied verbatim rather than re-guessed from a screenshot; the variable
   names are kept identical too, so anyone who already knows that app's theme recognizes this one
   immediately, and a future re-sync is a straight diff instead of a re-derivation.

   Everything in this file that used to be a literal hex color has been switched to reference one
   of these variables (or left as a one-off rgba() shadow/overlay where jira-data-portal's own
   file does the same) - see each rule below for which token it now uses. Anything genuinely
   specific to this app (the login page's own dark-navy gradient art, for instance) keeps its own
   literal values rather than being forced onto a token that doesn't quite fit. */
:root {
    --bg: #f4f6fa;
    --surface: #ffffff;
    --surface-2: #eaf1f8;
    --border: #dde4ed;
    --border-hover: #b9c6d6;
    --text: #0b2a4a;
    --text-muted: #64748b;

    /* Superseded from the jira-data-portal cyan (#1ea7e1) to this blue - the Attendance History
       "Top Nav + Tabs" redesign decided in the Design-canvas prototype (see the project doc
       claude/attendance-history-ui-design.md and its linked Artifact) uses this app's own
       original blue throughout (nav/tab active states, filter chip, Filters button, buttons), and
       that prototype is the newer, explicit decision - so the shared --accent token follows it
       rather than leaving two different blues fighting across the app. */
    --accent: #2563eb;
    --accent-hover: #1d4ed8;
    --accent-soft: rgba(37, 99, 235, 0.12);
    --accent-soft-strong: rgba(37, 99, 235, 0.32);

    --danger: #dc2626;
    --danger-soft: rgba(220, 38, 38, 0.10);
    --danger-soft-strong: rgba(220, 38, 38, 0.30);
    --danger-text: #b91c1c;

    --warn-soft: rgba(217, 119, 6, 0.12);
    --warn-text: #b45309;

    --ok: #059669;
    --ok-soft: rgba(5, 150, 105, 0.10);
    --ok-text: #047857;

    --neutral-soft: rgba(100, 116, 139, 0.10);
    --neutral-text: #475569;

    /* The icon sidebar's own background (fragments/appshell.html - see .app-sidebar below), and
       also the login page's dark marketing-panel gradient (.login-left) - both want the same deep
       navy. --sidebar-hover/--sidebar-active/--sidebar-text are copied from the same source
       (D:\Java\jira-data-portal's app.css), except --sidebar-active, which uses this app's own
       --accent blue rather than jira's cyan so the active-link highlight matches the rest of this
       app's palette instead of introducing a second, unrelated blue. */
    --sidebar-bg: #0b2340;
    --sidebar-hover: rgba(255, 255, 255, 0.08);
    --sidebar-active: rgba(37, 99, 235, 0.28);
    --sidebar-text: #9fb3c8;
    --topbar-bg: #2b57ab;

    --shadow-card: 0 1px 2px rgba(15, 35, 60, 0.04), 0 8px 20px rgba(15, 35, 60, 0.07);

    --radius-card: 14px;
    --radius-btn: 9px;
    --radius-pill: 999px;

    --font-body: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    --font-heading: 'Poppins', var(--font-body);

    color-scheme: light;
}

body {
    margin: 0;
    font-family: var(--font-body);
    background: var(--bg);
    color: var(--text);
}

/* ---- Login page (split marketing-panel + sign-in-panel layout) ---- */

.login-split {
    min-height: 100vh;
    display: flex;
}

/* ---- Left: brand / value-prop panel ---- */

.login-left {
    flex: 1 1 46%;
    max-width: 46%;
    background: linear-gradient(160deg, var(--sidebar-bg) 0%, #14304f 65%, #1a4270 100%);
    color: #ffffff;
    display: flex;
    align-items: center;
    padding: 56px;
    box-sizing: border-box;
}

.login-left-inner {
    max-width: 480px;
}

.brand-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.18);
    padding: 6px 14px;
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 28px;
}

/* No white backing chip, per explicit ask - instead the navy/orange PNG is recolored to a flat
   white silhouette (brightness(0) turns every visible pixel black while keeping the image's own
   transparency, then invert(1) flips that black to white), so it reads directly against this
   panel's dark background the same way the reference screenshot's mark does. This does lose the
   logo's orange arc color; the right panel's sign-in card still shows the real navy+orange
   version, since that panel's background is white and doesn't need this treatment. */
.brand-pill-logo {
    display: block;
    height: 18px;
    width: auto;
    filter: brightness(0) invert(1);
}

.brand-pill-name {
    color: #ffffff;
    font-weight: 700;
}

.login-headline {
    font-family: var(--font-heading);
    font-size: 38px;
    line-height: 1.2;
    margin: 0 0 16px 0;
    font-weight: 800;
}

.login-headline .accent {
    color: var(--accent);
}

.login-sub {
    color: #cbd5e1;
    font-size: 15px;
    line-height: 1.6;
    margin: 0 0 28px 0;
}

.feature-list {
    list-style: none;
    margin: 0 0 32px 0;
    padding: 0;
}

.feature-list li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 14px;
    color: #e2e8f0;
    margin-bottom: 14px;
}

.feature-check {
    flex: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--accent);
    color: #ffffff;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
}

.preview-card {
    background: rgba(15, 35, 60, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);
}

.preview-titlebar {
    display: flex;
    gap: 6px;
    padding: 10px 12px;
    background: rgba(255, 255, 255, 0.05);
}

.preview-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
}

.preview-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.preview-table th {
    text-align: left;
    color: #94a3b8;
    font-size: 11px;
    text-transform: uppercase;
    padding: 8px 14px;
}

.preview-table td {
    padding: 8px 14px;
    color: #e2e8f0;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.preview-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: var(--radius-pill);
    font-size: 11px;
    font-weight: 600;
}

.preview-badge-present {
    background: rgba(34, 197, 94, 0.18);
    color: #4ade80;
}

.preview-badge-absent {
    background: rgba(248, 113, 113, 0.18);
    color: #f87171;
}

/* ---- Right: sign-in panel ---- */

.login-right {
    flex: 1 1 54%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface);
    padding: 40px;
    box-sizing: border-box;
}

.login-right-inner {
    width: 100%;
    max-width: 380px;
}

/* Real SNAK Consultancy logo PNG (navy "S.N.A.K" + orange arc), small and inline with the
   product name at the top of the card - this panel's own background is white, so (unlike the
   left panel's .brand-pill-logo, recolored white via a CSS filter) the image shows its real
   navy/orange colors as-is here, no recoloring needed to stay legible. */
.login-brand-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 28px;
}

.login-brand-logo {
    display: block;
    height: 26px;
    width: auto;
}

.login-brand-name {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 20px;
    color: var(--text);
}

.login-welcome {
    font-family: var(--font-heading);
    font-size: 26px;
    margin: 0 0 8px 0;
}

.login-welcome-sub {
    color: var(--text-muted);
    font-size: 14px;
    margin: 0 0 24px 0;
}

.ms-signin-btn {
    display: block;
    background: var(--sidebar-bg);
    color: #ffffff;
    text-decoration: none;
    text-align: center;
    padding: 14px 16px;
    border-radius: var(--radius-btn);
    font-weight: 600;
    font-family: var(--font-heading);
}

.ms-signin-btn:hover {
    background: #14304f;
}

.login-footer {
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1.6;
    margin: 28px 0 4px 0;
}

.login-footer a {
    color: var(--accent);
}

.login-copyright {
    color: #94a3b8;
    font-size: 12px;
    margin: 0;
}

@media (max-width: 860px) {
    .login-split {
        flex-direction: column;
    }

    .login-left, .login-right {
        max-width: 100%;
        flex: none;
    }

    .login-left {
        padding: 40px 24px;
    }

    .preview-card {
        display: none;
    }

    .login-right {
        padding: 40px 24px;
    }
}

/* ---- App shell (fragments/appshell.html) - icon sidebar + topbar ----

   Restored to this after a brief detour into a "Top Nav + Tabs" shell (built literally to match
   the Design-canvas prototype linked from claude/attendance-history-ui-design.md). That version's
   own top nav/tab labels were mostly inert placeholders for pages that don't exist in this app
   yet, which left Mark Attendance, My Attendance, My Team and Settings - all real, working pages -
   unreachable from any nav at all. Reverted back to the icon-sidebar + topbar shape this app had
   before that, with all six real destinations as real links again (see fragments/appshell.html's
   own comment for the activeNav values and the Attendance History / Settings visibility gates).

   Styled after the sibling internal tool at D:\Java\jira-data-portal ("SNAK Pulse") own icon
   sidebar + topbar (its fragments/header.html + app.css) rather than approximated from memory,
   since that's the same reference this app's whole color system already follows - see the
   --sidebar-* and --topbar-bg tokens above. Two pieces: a fixed 84px icon rail on the left
   (.app-sidebar) and a topbar across the rest of the width (.app-topbar) with the brand + current
   page title on the left and the bell/user/sign-out on the right. */

.app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

.app-sidebar {
    flex: 0 0 84px;
    width: 84px;
    background: var(--sidebar-bg);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px 0;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    box-sizing: border-box;
}

/* ---- Sidebar brand mark - the real SNAK Consultancy logo image (navy "S.N.A.K" + orange arc),
   replacing the earlier CSS/SVG-built monogram (first "SP" for PunchPoint, then "OS" for
   OneSphere) now that the actual logo PNG is available - see fragments/appshell.html for the
   markup this styles. White badge background (not the sidebar's own navy) so the logo's own
   navy/orange colors read true against the dark sidebar instead of navy-on-navy disappearing. */
.app-sidebar-brand {
    width: 40px;
    height: 40px;
    border-radius: 11px;
    background: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 26px;
    flex: none;
    padding: 6px;
    box-sizing: border-box;
}

.app-sidebar-brand-logo {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.app-sidebar-nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.app-sidebar-link {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    width: 68px;
    padding: 10px 4px 9px;
    border-radius: 12px;
    color: var(--sidebar-text);
    text-decoration: none;
    text-align: center;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    line-height: 1.15;
    transition: background 0.18s ease, color 0.18s ease;
}

.app-sidebar-link:hover {
    background: var(--sidebar-hover);
    color: #fff;
}

.app-sidebar-link-active {
    background: var(--sidebar-active);
    color: #fff;
}

.app-sidebar-link-active::before {
    content: '';
    position: absolute;
    left: -9px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 20px;
    border-radius: 3px;
    background: var(--accent);
    box-shadow: 0 0 10px var(--accent);
}

.app-sidebar-icon {
    width: 20px;
    height: 20px;
    flex: none;
}

.app-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.app-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 24px;
    box-sizing: border-box;
    background: var(--topbar-bg);
    border-bottom: 1px solid rgba(0, 0, 0, 0.14);
    position: sticky;
    top: 0;
    z-index: 5;
    flex-wrap: wrap;
}

.app-topbar-left {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

.app-topbar-brand {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1rem;
    letter-spacing: 0.01em;
    color: #fff;
    white-space: nowrap;
    text-decoration: none;
}

.app-topbar-brand-accent {
    color: #38dfe0;
}

.app-topbar-divider {
    width: 1px;
    height: 18px;
    background: rgba(255, 255, 255, 0.28);
    flex: none;
}

.app-topbar-page {
    font-weight: 600;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-header-right {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: none;
}

/* ---- Topbar Punch In/Punch Out quick action (see TopbarAttendanceAdvice + fragments/appshell.html)
   ---- */

.app-topbar-punch-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 7px 14px;
    border-radius: var(--radius-pill);
    background: var(--accent);
    color: #ffffff;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 12.5px;
    text-decoration: none;
    white-space: nowrap;
    flex: none;
    transition: background 0.15s ease;
}

.app-topbar-punch-btn:hover {
    background: var(--accent-hover);
}

.app-topbar-punch-btn-out {
    background: var(--danger);
}

.app-topbar-punch-btn-out:hover {
    background: #b91c1c;
}

/* The "already punched in, not out yet" state - punch-in time + a Punch Out button together in
   one white pill, the same treatment .app-user already uses for the signed-in person's own
   name/role so the topbar's right side reads as one consistent family of pills rather than mixed
   styles. */
.app-topbar-punch {
    display: flex;
    align-items: center;
    gap: 8px;
    background: #ffffff;
    border-radius: var(--radius-pill);
    padding: 5px 5px 5px 14px;
    flex: none;
}

.app-topbar-punch-time {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
}

.app-bell-btn {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex: none;
    transition: background 0.15s ease;
}

.app-bell-btn:hover {
    background: rgba(255, 255, 255, 0.26);
}

/* ---- Topbar notification bell (punch-in/out -> manager + HR): see TopbarNotificationAdvice,
   NotificationController, fragments/appshell.html's ".notif-wrap", static/js/notifications.js.
   Dropdown styled after .filters-popover for visual consistency with the other topbar popover. */

.notif-wrap {
    position: relative;
}

.notif-badge {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--danger);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--topbar-bg);
    box-sizing: border-box;
}

.notif-dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    width: 340px;
    max-height: 420px;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);
    z-index: 30;
}

.notif-dropdown[hidden] {
    display: none;
}

.notif-dropdown-head {
    padding: 14px 16px;
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    background: var(--surface);
}

.notif-item {
    padding: 12px 16px;
    border-bottom: 1px solid var(--surface-2);
}

.notif-item:last-child {
    border-bottom: none;
}

.notif-item-unread {
    background: var(--accent-soft);
}

.notif-message {
    margin: 0 0 4px;
    font-size: 13px;
    color: var(--text);
    line-height: 1.4;
}

.notif-time {
    font-size: 11.5px;
    color: var(--text-muted);
}

.notif-empty {
    padding: 24px 16px;
    text-align: center;
    font-size: 13px;
    color: var(--text-muted);
    margin: 0;
}

.app-user {
    display: flex;
    align-items: center;
    gap: 10px;
    background: #ffffff;
    border-radius: var(--radius-pill);
    padding: 6px 14px 6px 6px;
    flex: none;
    min-width: 0;
}

.app-user-avatar-wrap {
    width: 30px;
    height: 30px;
    border-radius: 999px;
    flex: none;
    position: relative;
    overflow: hidden;
    background: var(--accent-soft);
}

.app-user-avatar-photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.app-user-avatar {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 700;
    font-family: var(--font-heading);
    font-size: 12.5px;
    align-items: center;
    justify-content: center;
}

.app-user-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    line-height: 1;
    min-width: 0;
}

.app-user-name {
    color: var(--text);
    font-weight: 600;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 160px;
}

.app-user-role {
    font-size: 10px;
    color: #94a3b8;
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
}

.app-signout-form {
    margin: 0;
    flex: none;
}

.app-signout-btn {
    background: rgba(255, 255, 255, 0.14);
    color: #ffffff;
    border: 1px solid rgba(255, 255, 255, 0.3);
    padding: 6px 14px;
    border-radius: 8px;
    font-weight: 600;
    font-size: 12.5px;
    cursor: pointer;
}

.app-signout-btn:hover {
    background: rgba(255, 255, 255, 0.26);
}

.app-content {
    flex: 1;
    padding: 24px 32px 32px;
    box-sizing: border-box;
    overflow-x: hidden;
}

@media (max-width: 720px) {
    .app-sidebar-link span {
        display: none;
    }

    .app-sidebar {
        flex-basis: 60px;
        width: 60px;
    }

    .app-user-text {
        display: none;
    }

    .app-topbar-page {
        display: none;
    }

    .app-content {
        padding: 20px 16px 32px;
    }

    .app-topbar {
        padding: 10px 16px;
    }
}

/* ---- Shared page-content wrapper (used inside each page's <section>, under the app shell) ---- */

.page-wrap {
    max-width: 480px;
    margin: 0 auto;
    padding-bottom: 40px;
}

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    margin: 0 16px;
    padding: 24px;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
}

.card h1 {
    font-family: var(--font-heading);
    font-size: 20px;
    margin-top: 0;
}

/* ---- Notices ---- */

.notice {
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 14px;
    margin: 12px 0;
}

.notice-error {
    background: var(--danger-soft);
    color: var(--danger-text);
}

.notice-success {
    background: var(--ok-soft);
    color: var(--ok-text);
}

.notice-info {
    background: var(--accent-soft);
    color: var(--accent-hover);
}

/* ---- Buttons / links ---- */

.primary-btn {
    display: inline-block;
    width: 100%;
    box-sizing: border-box;
    background: var(--accent);
    color: #ffffff;
    text-decoration: none;
    text-align: center;
    padding: 14px 16px;
    border: none;
    border-radius: var(--radius-btn);
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 15px;
    cursor: pointer;
    margin-top: 16px;
    transition: background 0.15s ease;
}

.primary-btn:hover {
    background: var(--accent-hover);
}

.primary-btn:disabled {
    background: #94a3b8;
    cursor: not-allowed;
}

.primary-link {
    margin-top: 20px;
}

/* Outlined accent button - Settings' "Run Sync Now"/"Send Test Message" and home.html's own
   secondary actions. (Attendance History's Download CSV uses the newer, neutral-outline
   .export-btn instead - see the Attendance History page section below - so this one stays scoped
   to Settings/Home rather than every outline button in the app.) */
.secondary-btn {
    background: var(--surface);
    color: var(--accent);
    border: 1px solid var(--accent);
    padding: 8px 14px;
    border-radius: 6px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
}

.secondary-btn:hover {
    background: var(--accent-soft);
}

/* ---- Mark Attendance ---- */

.mark-card video {
    width: 100%;
    border-radius: 8px;
    background: #000000;
    max-height: 360px;
    object-fit: cover;
}

.punch-summary {
    border-top: 1px solid var(--border);
    padding-top: 12px;
    margin-top: 12px;
}

.punch-summary h3 {
    margin: 0 0 8px 0;
    font-size: 14px;
    text-transform: uppercase;
    color: var(--text-muted);
}

.punch-thumb {
    width: 100%;
    max-width: 240px;
    border-radius: 8px;
    display: block;
    margin-bottom: 8px;
}

.address {
    color: var(--text-muted);
    font-size: 13px;
}

/* The day-by-day table's punch-in/punch-out address text (attendance/fragments/day-table.html)
   sits inside .data-table, which sets white-space: nowrap on every cell so sortable columns of
   plain values never wrap mid-value - but that same rule was also forcing this long, free-text
   reverse-geocoded address onto a single unbroken line, stretching the Login/Logout Time columns
   (and so the whole table) far wider than the page, which is what forced the table into permanent
   horizontal scroll and left a sliver of the Status column peeking in at the left edge whenever
   the table wasn't scrolled all the way back to 0. Overriding back to a wrapped, width-capped
   inline-block here keeps every other column's nowrap behavior untouched (this selector only
   matches .address) while letting the address itself wrap onto a couple of short lines instead -
   same information, without dragging the table wider than it needs to be. */
.data-table .address {
    display: inline-block;
    white-space: normal;
    max-width: 190px;
    line-height: 1.35;
    vertical-align: top;
}

/* ---- Attendance History / Settings: wide pages ---- */

/* History (roster/day-by-day tables) and Settings (now a wide tabbed screen - see
   fragments/settingstabs.html) both need far more room than the 480px mobile-first shell the
   punch/login/home pages use. 1600px rather than no cap at all - "cover the whole space from both
   sides" on a normal/large monitor, without a table stretching uncomfortably wide on an ultra-wide
   one; .card's own 16px side margin (unchanged) is what keeps a small gutter either side rather
   than content running edge-to-edge. */
.history-wrap, .settings-wrap {
    max-width: 1600px;
}

/* ---- Attendance History page - matches the Design-canvas prototype exactly (see the CSS comment
   above .app-header for the artifact link/path) rather than the earlier, looser restyle. Most
   colors below are literal, one-off values copied straight from that prototype's own inline
   styles rather than pushed through the shared --accent/--text-muted tokens, since the prototype
   itself is mostly literal hex too - see its project/Main.dc.html if this ever needs a re-sync. */

.ah-lead {
    margin: 0;
    font-size: 13px;
    color: #64748b;
    max-width: 980px;
    line-height: 1.5;
}

.ah-toolbar-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 16px;
}

.dept-filter-label, .time-range-label {
    font-size: 12px;
    color: #94a3b8;
    font-weight: 600;
}

.dept-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #eff6ff;
    color: #1d4ed8;
    font-size: 13px;
    font-weight: 600;
    padding: 4px 8px 4px 12px;
    border-radius: var(--radius-pill);
    text-decoration: none;
    margin-left: 8px;
}

.dept-chip svg {
    flex: none;
}

.dept-select {
    margin-left: 8px;
    padding: 5px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

.time-range {
    display: flex;
    align-items: center;
    gap: 2px;
    background: #f1f5f9;
    border-radius: 8px;
    padding: 3px;
}

.time-range-tab {
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 500;
    color: #64748b;
    text-decoration: none;
    display: inline-block;
}

.time-range-tab-active {
    font-weight: 700;
    color: #0f172a;
    background: #ffffff;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
}

.ah-divider {
    height: 1px;
    background: #eef1f5;
    margin-bottom: 16px;
}

.stat-chip-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 16px;
}

.stat-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border-radius: var(--radius-pill);
    padding: 6px 14px 6px 10px;
}

.stat-chip-dot {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    flex: none;
}

.stat-chip-count {
    font-size: 13.5px;
    font-weight: 700;
}

.stat-chip-label {
    font-size: 13px;
}

.stat-chip-neutral { background: #f1f5f9; }
.stat-chip-neutral .stat-chip-dot { background: #64748b; }
.stat-chip-neutral .stat-chip-count { color: #0f172a; }
.stat-chip-neutral .stat-chip-label { color: #475569; }

.stat-chip-accent { background: var(--accent-soft); }
.stat-chip-accent .stat-chip-dot { background: var(--accent); }
.stat-chip-accent .stat-chip-count { color: #0f172a; }
.stat-chip-accent .stat-chip-label { color: #475569; }

.stat-chip-present { background: #f0fdf4; }
.stat-chip-present .stat-chip-dot { background: #16a34a; }
.stat-chip-present .stat-chip-count, .stat-chip-present .stat-chip-label { color: #15803d; }

.stat-chip-absent { background: #fef2f2; }
.stat-chip-absent .stat-chip-dot { background: #dc2626; }
.stat-chip-absent .stat-chip-count, .stat-chip-absent .stat-chip-label { color: #b91c1c; }

.stat-chip-leave { background: #fffbeb; }
.stat-chip-leave .stat-chip-dot { background: #d97706; }
.stat-chip-leave .stat-chip-count, .stat-chip-leave .stat-chip-label { color: #b45309; }

.stat-chip-holiday { background: var(--accent-soft); }
.stat-chip-holiday .stat-chip-dot { background: var(--accent); }
.stat-chip-holiday .stat-chip-count, .stat-chip-holiday .stat-chip-label { color: var(--accent); }

/* ---- Search + Filters (collapsible popover) + Export toolbar ---- */

.list-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 12px;
}

.list-search-wrap {
    position: relative;
    flex-grow: 1;
    max-width: 340px;
}

.list-search-icon {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: #94a3b8;
    pointer-events: none;
    display: flex;
}

.list-search-input {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 12px 9px 32px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 13.5px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

.list-search-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.list-showing {
    font-size: 13px;
    color: #94a3b8;
}

.list-toolbar-spacer {
    flex-grow: 1;
}

.filters-popover-wrap {
    position: relative;
}

.filters-btn {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px;
    border: 1px solid #bfdbfe;
    border-radius: 8px;
    background: #eff6ff;
    color: #1d4ed8;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}

.filters-btn:hover {
    background: #dbeafe;
}

.filters-badge {
    background: var(--accent);
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    width: 17px;
    height: 17px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.filters-popover {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    width: 360px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14);
    padding: 18px;
    z-index: 20;
    box-sizing: border-box;
}

.filters-popover[hidden] {
    display: none;
}

.filters-popover-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}

.filters-popover-title {
    font-size: 14px;
    font-weight: 700;
    color: #0f172a;
}

.filters-popover-close {
    cursor: pointer;
    color: #94a3b8;
    background: none;
    border: none;
    padding: 0;
    display: flex;
}

.filters-popover-close:hover {
    color: #0f172a;
}

.filters-popover-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.filters-popover-pair {
    display: flex;
    gap: 10px;
}

.filters-popover-body label {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 12px;
    color: #64748b;
    font-weight: 500;
}

.filters-popover-body input[type="date"],
.filters-popover-body select {
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 13.5px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
}

.filters-popover-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 4px;
}

.filters-reset {
    font-size: 12.5px;
    color: #64748b;
    font-weight: 600;
    cursor: pointer;
    background: none;
    border: none;
    padding: 0;
    text-decoration: none;
    font-family: inherit;
}

.filters-reset:hover {
    text-decoration: underline;
}

.filters-apply-btn {
    padding: 9px 22px;
    border: none;
    border-radius: 8px;
    background: var(--accent);
    color: #ffffff;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    font-family: var(--font-heading);
}

.filters-apply-btn:hover {
    background: var(--accent-hover);
}

.export-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 16px;
    border: 1px solid #cbd5e1;
    border-radius: 8px;
    background: var(--surface);
    color: #334155;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    font-family: inherit;
}

.export-btn:hover {
    background: #f8fafc;
}

.summary-row {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 20px;
}

.summary-tile {
    flex: 1;
    min-width: 100px;
    background: var(--surface-2);
    border-radius: 8px;
    padding: 12px;
    text-align: center;
}

.summary-tile strong {
    display: block;
    font-family: var(--font-heading);
    font-size: 22px;
}

.summary-tile span {
    font-size: 12px;
    color: var(--text-muted);
}

.summary-tile.present strong {
    color: var(--ok-text);
}

.summary-tile.absent strong {
    color: var(--danger-text);
}

/* Wraps every table.data-table (roster + day-by-day) in the same bordered, rounded, shadowed
   card the reference app at D:\Java\jira-data-portal ("SNAK Pulse") uses for its own listing
   tables (see that app's app.css .table-wrap) - visually separates the table from the page's own
   outer .card instead of the two blending into one flat surface. overflow-x here (not on the
   table itself) is what lets the table scroll horizontally on a narrow screen without the rest of
   the page moving - see .data-table's own min-width comment just below for why. */
.table-wrap {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    overflow-x: auto;
    box-shadow: var(--shadow-card);
    margin-bottom: 12px;
}

/* min-width, not width: a flat "width: 100%" caps the table at exactly .table-wrap's width no
   matter how many columns it has, forcing every column to compress instead of letting the table
   grow past the wrapper - which is what .table-wrap's own overflow-x: auto is there to handle.
   min-width: 100% keeps the "fill the card when there's room" look on a narrow table while still
   letting a wide one (the roster's 7 columns) grow past 100% and scroll. Matches jira-data-portal's
   own table.data for the same reason - see that app's app.css. */
.data-table {
    min-width: 100%;
    border-collapse: collapse;
    font-size: 14px;
    white-space: nowrap;
}

.data-table th, .data-table td {
    text-align: left;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

/* Regular case (not uppercase) - matches the Design-canvas prototype's own table headers, a
   deliberate departure from this app's other tables (Settings' sync-status rows, etc.), which
   keep the small-caps treatment .data-table used to apply everywhere. Background + letter-spacing
   copied from jira-data-portal's own table.data thead th, so a listing table's header reads the
   same in both apps. */
.data-table th {
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 12.5px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

/* Row hover + a first-column accent bar that grows in on hover - both copied from
   jira-data-portal's own table.data tbody tr / tr td:first-child::before (see that app's app.css
   for the full rationale on why the bar lives on the <td>, not the <tr>, itself). The -14px/-10px
   offsets there matched that app's own 14px/10px cell padding; ours is 14px/10px too (see the
   th/td rule above) so the same offsets carry over unchanged. */
.data-table tbody tr {
    transition: background 0.15s ease;
}

.data-table tbody tr td:first-child {
    position: relative;
}

.data-table tbody tr td:first-child::before {
    content: '';
    position: absolute;
    left: -14px;
    top: -10px;
    bottom: -10px;
    width: 3px;
    background: var(--accent);
    transform: scaleY(0);
    transition: transform 0.18s ease;
}

.data-table tbody tr:hover {
    background: rgba(15, 35, 60, 0.035);
}

.data-table tbody tr:hover td:first-child::before {
    transform: scaleY(1);
}

/* A row whose whole selected range is absent (no Present days at all) gets a faint pink tint, so
   it reads at a glance without waiting to read the status pill in the last column - matches the
   prototype's own rowBg logic (project/Main.dc.html: `allAbsent ? '#fef7f7' : '#ffffff'`). */
.roster-row-absent {
    background: #fef7f7;
}

/* Per-row Entra ID photo avatar in the My Team / HR roster tables' Employee column (see
   EmployeePhotoController/EmployeePhotoService and attendance/history.html) - same shape/fallback
   pattern as the app shell header's own .app-user-avatar-wrap/-photo/-avatar, just sized down for
   a table row instead of the topbar. */
.roster-name-cell {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.roster-avatar-wrap {
    width: 26px;
    height: 26px;
    border-radius: 999px;
    flex: none;
    position: relative;
    overflow: hidden;
    background: var(--accent-soft);
}

.roster-avatar-photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.roster-avatar {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 700;
    font-family: var(--font-heading);
    font-size: 11px;
    align-items: center;
    justify-content: center;
}

/* Per-row "View" action in the roster table - used to be a bare underlined text link, easy to
   miss/mistake for body text (especially sitting inside a .roster-row-absent tinted row). Turned
   into a small pill button instead - its own class rather than reusing .secondary-btn/.export-btn
   (both sized for a single page-level action, not once per row) or .filters-apply-btn (solid
   accent, sized for a popover's Apply). Starts as a soft accent tint rather than solid accent so a
   whole column of these doesn't read as a wall of blue buttons down the table; goes solid on hover
   to confirm it's clickable, with the chevron nudging over to reinforce "go to this record". */
.roster-view-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 6px 14px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 12.5px;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}

.roster-view-btn svg {
    transition: transform 0.15s ease;
}

.roster-view-btn:hover {
    background: var(--accent);
    color: #ffffff;
}

.roster-view-btn:hover svg {
    transform: translateX(2px);
}

.roster-view-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ---- Attendance History "drilled into one employee" back link (DETAIL view only, see
   attendance/history.html) ---- */

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 16px;
    padding: 6px 12px 6px 10px;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text);
    font-family: var(--font-heading);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s ease, color 0.15s ease;
}

.back-link svg {
    flex: none;
    transition: transform 0.15s ease;
}

.back-link:hover {
    background: var(--accent);
    color: #ffffff;
}

.back-link:hover svg {
    transform: translateX(-2px);
}

.back-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ---- Sortable column headers (Attendance History day-by-day + roster tables) ---- */

.sortable-col {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.sortable-col::after {
    content: "\21C5"; /* up/down arrows - unsorted */
    display: inline-block;
    margin-left: 6px;
    font-size: 11px;
    font-weight: 400;
    color: #cbd5e1;
}

.sortable-col:hover::after {
    color: #475569;
}

.sortable-col[data-sort-dir="asc"]::after {
    content: "\2191"; /* up arrow */
    color: var(--accent);
}

.sortable-col[data-sort-dir="desc"]::after {
    content: "\2193"; /* down arrow */
    color: var(--accent);
}

.status-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    font-size: 12px;
    font-weight: 600;
}

.status-PRESENT {
    background: var(--ok-soft);
    color: var(--ok-text);
}

.status-ABSENT {
    background: var(--danger-soft);
    color: var(--danger-text);
}

.status-LEAVE {
    background: var(--warn-soft);
    color: var(--warn-text);
}

.status-HOLIDAY {
    background: var(--accent-soft);
    color: var(--accent);
}

/* Three-state "X/Y Present" pill for the roster's Status column (attendance/history.html's
   HR_ROSTER/TEAM_ROSTER views) - distinct from .status-badge/.status-PRESENT/.status-ABSENT above,
   which are the single-day-table's own two-state badge and Settings' sync-status rows; this one
   needs a third, amber "partial" state a plain present/absent badge doesn't have. */
.attendance-pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    font-size: 12px;
    font-weight: 600;
}

.attendance-pill-present {
    background: #f0fdf4;
    color: #15803d;
}

.attendance-pill-partial {
    background: #fffbeb;
    color: #b45309;
}

.attendance-pill-absent {
    background: #fef2f2;
    color: #b91c1c;
}

/* ---- List pagination (static/js/list-pagination.js) - any table.data-table gets this ---- */

.pagination-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    margin: 12px 0 4px 0;
}

.pagination-btn {
    padding: 7px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    font-size: 13px;
    font-weight: 500;
    font-family: inherit;
}

.pagination-btn:disabled {
    color: #cbd5e1;
    cursor: not-allowed;
}

/* Applied (via JS) to whichever of Prev/Next isn't disabled - a filled-looking accent outline
   rather than the plain bordered look .pagination-btn has by default, matching the prototype's
   own enabled-Next/disabled-Prev example state. */
.pagination-btn-active {
    border-color: #bfdbfe;
    background: #eff6ff;
    color: var(--accent);
    font-weight: 600;
    cursor: pointer;
}

.pagination-label {
    font-size: 13px;
    color: #94a3b8;
}

.pagination-page-badge {
    font-size: 13px;
    color: #334155;
    font-weight: 600;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 7px 14px;
}

.row-thumb {
    width: 40px;
    height: 40px;
    object-fit: cover;
    border-radius: 6px;
    vertical-align: middle;
    margin-right: 6px;
}

/* ---- Settings (§3.3 HRMS Integration) ---- */

/* .settings-wrap's max-width now lives in the ".history-wrap, .settings-wrap" rule above (1600px,
   "cover the whole space" per the SNAKPulse-parity request) - a second, narrower 640px rule used
   to live here and silently win the cascade by appearing later in the file, which is why widening
   the earlier rule alone didn't visibly widen the Settings screen. Left as a comment so a future
   "make settings narrow again" change has one obvious place to look, not two conflicting rules. */

/* Horizontal tab strip used by fragments/settingstabs.html across all four Settings pages
   (HRMS Integration / Company Configurations / Microsoft Teams Notifications / Email Settings) -
   same structure and color tokens as the reference app's own .settings-tabs/.settings-tab/
   .settings-tab.active (D:\Java\jira-data-portal's app.css): a row of plain links with a bottom
   border, the active one picked out with an accent-colored underline and text. */
.settings-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    margin: 4px 0 20px;
}

.settings-tab {
    display: inline-block;
    padding: 10px 16px;
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 500;
    color: var(--text-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.settings-tab:hover {
    color: var(--text);
}

.settings-tab-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

.settings-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.settings-list li {
    margin-bottom: 8px;
}

.settings-link {
    display: block;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    text-decoration: none;
    color: var(--text);
}

.settings-link:hover {
    background: var(--surface-2);
}

.settings-link strong {
    display: block;
    margin-bottom: 4px;
    color: var(--accent);
}

.settings-link span {
    font-size: 13px;
    color: var(--text-muted);
}

.helptext {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 4px;
    display: block;
}

.sync-status-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 12px 0;
    font-size: 13px;
}

.status-SUCCESS {
    background: var(--ok-soft);
    color: var(--ok-text);
}

.status-FAILED {
    background: var(--danger-soft);
    color: var(--danger-text);
}

.status-NEVER_RUN {
    background: var(--neutral-soft);
    color: var(--neutral-text);
}

.status-PARTIAL {
    background: var(--warn-soft);
    color: var(--warn-text);
}

.settings-form {
    margin-top: 24px;
    border-top: 1px solid var(--border);
    padding-top: 20px;
}

.form-section {
    margin-bottom: 24px;
}

.form-section h2 {
    font-family: var(--font-heading);
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    margin: 0 0 14px 0;
}

.settings-form label {
    display: block;
    margin-bottom: 14px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
}

/* Puts several short fields side by side in one row instead of each stacking full-width - matches
   the reference app's Settings screen (e.g. its Jira Site URL / Account Email / API Token row).
   Wrap 2-4 related labels in a <div class="form-row"> right where they'd otherwise sit stacked;
   auto-fit means a row with fewer labels than fit at the current width still lays out correctly
   (they just take equal shares of the row) and the whole thing collapses to one column per field
   on a narrow/mobile screen instead of squeezing. Only meant for ordinary text/number/password/
   email/time inputs - a textarea or a long free-text field (e.g. a webhook URL) reads better left
   full-width outside a form-row. */
.form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 4px 20px;
    margin-bottom: 14px;
}

.form-row label {
    margin-bottom: 0;
}

.settings-form label.checkbox-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
}

.settings-form label.checkbox-row input[type="checkbox"] {
    width: 16px;
    height: 16px;
}

.settings-form input[type="text"],
.settings-form input[type="number"],
.settings-form input[type="password"],
.settings-form input[type="email"],
.settings-form input[type="time"],
.settings-form textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    font-size: 14px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
    margin-top: 4px;
}

.settings-form input:focus,
.settings-form textarea:focus {
    outline: none;
    border-color: var(--accent);
}

.settings-form textarea {
    font-family: inherit;
    resize: vertical;
    min-height: 72px;
}

.settings-form input[disabled] {
    background: var(--bg);
    color: var(--text-muted);
}

.form-actions {
    display: flex;
    gap: 12px;
    margin-top: 20px;
}

.form-actions .primary-btn {
    width: auto;
    margin-top: 0;
    padding: 10px 24px;
}

/* Bordered row + animated pill toggle for a boolean setting, same component as the reference
   app's own .switch-row/.switch (D:\Java\jira-data-portal's settings.html/app.css). Originally
   reserved for just the one feature-level enable flag each Settings tab has (e.g. "Enable HRMS
   Integration", "Enable Email Notifications"), with same-page secondary options (e.g. "Include
   weekends", "Use TLS") left as a plain .checkbox-row - now also used for Settings > Company
   Configurations' "Ask employees to punch out"/"Include weekends" per an explicit ask for toggle
   buttons instead of checkboxes there. .checkbox-row (below) is still used elsewhere (e.g.
   Settings > Email Settings' "Use TLS") and isn't being removed. */
.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 16px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-btn);
    margin-bottom: 18px;
}

.switch-row-label {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}

.switch-row .helptext {
    margin-top: 2px;
}

.switch {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
    flex: none;
}

.switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.switch .track {
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background: var(--border);
    transition: background 0.25s ease;
    cursor: pointer;
}

.switch .track::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(15, 35, 60, 0.35);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.switch input:checked + .track {
    background: var(--accent);
    box-shadow: 0 0 12px rgba(37, 99, 235, 0.5);
}

.switch input:checked + .track::after {
    transform: translateX(18px);
}

.switch input:focus-visible + .track {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ---- Home dashboard ----

   The Home page's role-scoped dashboard (see HomeController#home/DashboardService) reuses
   .stat-chip-row/.time-range/.data-table/.attendance-pill/.roster-view-btn (Attendance History's
   own components - see above) wherever those already fit, so these are only the pieces genuinely
   new to this page: the panel card shell, the department-breakdown bars, the plain-CSS trend bars,
   and the two conic-gradient pie/donut charts (see DashboardService's own Javadoc for why those
   are hand-rolled CSS rather than a charting library - no new JS dependency for two small charts). */

.dash-self-today {
    margin: 4px 0 18px;
    padding: 10px 14px;
    background: var(--surface-2);
    border-radius: var(--radius-btn);
    font-size: 14px;
    color: var(--text);
}

.dash-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: 18px 20px;
    margin-top: 18px;
}

.dash-panel-title {
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
    margin-bottom: 14px;
}

.dash-panel-note {
    font-size: 12px;
    color: var(--text-muted);
    margin: -10px 0 14px;
}

.dash-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 18px;
    margin-top: 18px;
}

.dash-grid .dash-panel {
    margin-top: 0;
}

.dash-grid-wide {
    grid-column: 1 / -1;
}

/* Trend bars - a plain flex row of divs whose height (0-100%, set inline per bar via
   TrendPoint#ratePercent) stands in for a bar chart, inside a fixed-height track so 0% still
   renders as a visible baseline rather than collapsing to nothing. */
.dash-trend {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    height: 120px;
}

.dash-trend-bar-wrap {
    flex: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.dash-trend-bar {
    width: 100%;
    min-height: 3px;
    border-radius: 4px 4px 0 0;
    background: var(--accent);
    background: linear-gradient(180deg, var(--accent), var(--accent-hover));
}

.dash-trend-bar-label {
    font-size: 11px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Department breakdown - one labeled progress bar per department. */
.dash-bar-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 7px 0;
}

.dash-bar-row + .dash-bar-row {
    border-top: 1px solid var(--surface-2);
}

/* Now a small flex row itself (name text + employee count), same overall 140px column as before -
   see home.html's own comment on why the count was added next to the name rather than, say,
   appended into the percentage column, which is about the rate, not headcount. */
.dash-bar-name {
    flex: 0 0 140px;
    display: flex;
    align-items: baseline;
    gap: 4px;
    min-width: 0;
}

.dash-bar-name-text {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.dash-bar-count {
    flex: none;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
}

.dash-bar-track {
    flex: 1;
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.dash-bar-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--accent);
}

.dash-bar-pct {
    flex: 0 0 44px;
    text-align: right;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
}

/* The two "right now, today" charts - a CSS conic-gradient circle with a plain-white centre hole
   (a donut/pie both use the same markup; a pie just has no --dash-hole-size gap) plus a simple
   dot-legend beside it. Each chart's own conic-gradient stops are built server-side (see
   TodayStatusSnapshot's *End fields) and set inline via th:style - this file only styles the
   shape. */
.dash-chart-row {
    display: flex;
    align-items: center;
    gap: 22px;
    flex-wrap: wrap;
}

.dash-donut {
    position: relative;
    width: 130px;
    height: 130px;
    border-radius: 50%;
    flex-shrink: 0;
}

.dash-donut-hole {
    position: absolute;
    inset: 18px;
    border-radius: 50%;
    background: var(--surface);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1.2;
}

.dash-donut-hole strong {
    font-size: 20px;
    color: var(--text);
}

.dash-donut-hole span {
    font-size: 11px;
    color: var(--text-muted);
}

.dash-legend {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 13px;
    color: var(--text);
}

.dash-legend li {
    display: flex;
    align-items: center;
    gap: 8px;
}

.dash-legend strong {
    margin-left: auto;
}

.dash-legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    display: inline-block;
}

.dash-roster-foot {
    margin-top: 12px;
    display: flex;
    justify-content: flex-end;
}


/* ---------------------------------------------------------------------------------------------
   Payslips - My Payslips list, Payroll screen and the on-screen payslip (payslips/view.html).
   The payslip block mirrors the company's existing salary-slip layout (and PayslipPdfService's PDF).
   --------------------------------------------------------------------------------------------- */
.payroll-month {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 4px 0 16px;
    flex-wrap: wrap;
}

.payroll-month-label {
    font-family: var(--font-heading);
    font-size: 18px;
    min-width: 150px;
    text-align: center;
}

.payroll-disabled {
    opacity: 0.4;
    pointer-events: none;
}

.payroll-warn {
    color: #a1271b;
}

.data-table .num,
.slip .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.slip-actions {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.slip {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 32px 36px;
    max-width: 820px;
    margin: 0 auto;
    color: #1c1c1c;
    font-size: 14px;
}

.slip-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 20px;
}

.slip-logo {
    height: 56px;
    width: auto;
}

.slip-company {
    text-align: right;
    line-height: 1.5;
    font-size: 15px;
}

.slip-title {
    background: #b7dde8;
    border: 1px solid #000;
    text-align: center;
    font-size: 18px;
    padding: 8px;
    margin-bottom: 20px;
}

.slip-grid,
.slip-parts {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 18px;
}

.slip-grid th,
.slip-grid td,
.slip-parts th,
.slip-parts td {
    border: 1px solid #000;
    padding: 6px 8px;
    text-align: left;
}

.slip-grid th {
    width: 21%;
    font-weight: 700;
}

.slip-grid td {
    width: 29%;
    color: #444;
}

.slip-parts th {
    background: #b7dde8;
    text-align: center;
}

.slip-parts th:first-child {
    text-align: left;
}

.slip-parts .num {
    text-align: right;
}

.slip-total td {
    background: #b7dde8;
    font-weight: 700;
}

.slip-bar {
    display: grid;
    grid-template-columns: 46% 28% 26%;
    background: #b7dde8;
    padding: 6px 8px;
    font-weight: 700;
    margin-bottom: 14px;
}

.slip-bar .num {
    text-align: right;
}

.slip-note {
    text-align: center;
    color: #444;
    margin: 18px 0 0;
}

@media (max-width: 640px) {
    .slip {
        padding: 18px 14px;
        overflow-x: auto;
    }

    .slip-company {
        text-align: left;
    }
}

/* ---------------------------------------------------------------------------------------------
   Payslips - My Payslips / Payroll use the app's own listing look (page-wrap history-wrap > card >
   ah-lead + toolbar + table-wrap/data-table, status-badge, stat-chip, export-btn); only the few
   extras below are payslip-specific.
   --------------------------------------------------------------------------------------------- */
.pay-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 16px 0;
}

.pay-spacer {
    flex: 1 1 auto;
}

.pay-actions {
    display: inline-flex;
    gap: 8px;
}

.pay-dl {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.pay-dl:hover {
    background: var(--accent-hover);
}

.pay-sub-line {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 400;
}

.pay-row-pending td {
    color: var(--text-muted);
}

.pay-empty {
    text-align: center;
    color: var(--text-muted);
    padding: 28px 14px;
}

.pay-search {
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-family: inherit;
    color: var(--text);
    background: var(--surface);
    min-width: 240px;
}

.pay-sort {
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.pay-sort:hover {
    color: var(--accent);
}

.data-table tbody tr[hidden] {
    display: none;
}
