/* ===========================================================================
 * Design tokens — ported from the Node app's src/app/globals.css.
 *
 * Two layers: neutrals (shared, light-only) and brand (per-company, set via
 * App\Brand::style() as an inline `style` attribute on the app shell — see
 * partials/nav.php). Status semantics (success/warning/danger/info) are
 * brand-agnostic on purpose: "late" reads the same amber at AZ and at PDI,
 * regardless of company.
 *
 * Deliberately light-only, no prefers-color-scheme dark variant — that was a
 * product decision in the Node app, not an oversight, and carries over here.
 * `color-scheme: light` keeps native form controls/scrollbars from switching
 * to a dark rendering on a dark-mode OS.
 *
 * The --bg/--text/--line/--accent/--ok-.../--err-... names below are legacy
 * aliases kept for pages not yet restyled onto the token names directly;
 * every new component in this file uses the token names themselves.
 * ========================================================================= */

:root {
    color-scheme: light;

    --background: #fafaf8;
    --foreground: #1a1b1f;
    --surface: #fff;
    --surface-raised: #ffffff;
    --border: #e6e3dc;
    --muted: #6b6f78;

    /* Overridden per company via App\Brand::style(); AZ International is the fallback. */
    --brand-primary: #22304f;
    --brand-primary-tint: #33456e;
    --brand-accent: #a8c84b;
    --brand-on-accent: #1b2338;
    --brand-accent-2: #a8c84b;

    /* Status semantics — consistent meaning across both companies. */
    --status-success: #1fa971;
    --status-warning: #d89a2e;
    --status-danger: #d9564b;
    --status-info: #3d7fbf;

    --status-success-bg: color-mix(in srgb, var(--status-success) 12%, transparent);
    --status-success-border: color-mix(in srgb, var(--status-success) 35%, transparent);
    --status-warning-bg: color-mix(in srgb, var(--status-warning) 12%, transparent);
    --status-warning-border: color-mix(in srgb, var(--status-warning) 35%, transparent);
    --status-danger-bg: color-mix(in srgb, var(--status-danger) 12%, transparent);
    --status-danger-border: color-mix(in srgb, var(--status-danger) 35%, transparent);
    --status-info-bg: color-mix(in srgb, var(--status-info) 12%, transparent);
    --status-info-border: color-mix(in srgb, var(--status-info) 35%, transparent);

    /* Glass header — a translucent surface tint, not a fixed alpha hex, so it
       tracks --surface automatically. */
    --surface-glass: color-mix(in srgb, var(--surface) 82%, transparent);

    /* Legacy aliases — old component classes below (not yet ported to the
       token names) read these. */
    --bg: var(--background);
    --text: var(--foreground);
    --line: var(--border);
    --accent: var(--brand-primary);
    --ok-bg: var(--status-success-bg);
    --ok-text: var(--status-success);
    --err-bg: var(--status-danger-bg);
    --err-text: var(--status-danger);
}

* { box-sizing: border-box; }

/* The `hidden` attribute must always win — several element selectors below
   (label, fieldset, etc.) set their own `display`, which otherwise ties with
   the UA stylesheet's [hidden] rule on specificity and can lose the cascade
   to whichever was declared later. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--background);
    color: var(--foreground);
    font: 16px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* Latin digits in Arabic too — the product keeps numbers in English. */
:lang(ar) {
    font-variant-numeric: lining-nums;
    -moz-font-feature-settings: "lnum";
    font-feature-settings: "lnum";
}

/* ===========================================================================
 * Brand motifs — the graphic device lifted from each logo, echoed as quiet
 * background decoration wherever [data-motif] wraps content. Both AZ and
 * PDI currently use 'arc', a soft curved sweep; 'blocks' (a loose stack of
 * translucent squares) is unused for now but kept below for a future brand
 * whose logo suits it better. Both sit behind content, low-opacity, and
 * never affect layout.
 * ========================================================================= */

[data-motif] {
    position: relative;
    overflow: hidden;
}

[data-motif]::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

[data-motif="arc"]::before {
    background:
        radial-gradient(120% 140% at 85% -20%, color-mix(in srgb, var(--brand-accent) 16%, transparent), transparent 60%),
        radial-gradient(80% 100% at 100% 0%, color-mix(in srgb, var(--brand-primary) 10%, transparent), transparent 55%);
}

[data-motif="blocks"]::before {
    background-image:
        linear-gradient(color-mix(in srgb, var(--brand-accent) 12%, transparent), color-mix(in srgb, var(--brand-accent) 12%, transparent)),
        linear-gradient(color-mix(in srgb, var(--brand-accent-2) 12%, transparent), color-mix(in srgb, var(--brand-accent-2) 12%, transparent)),
        linear-gradient(color-mix(in srgb, var(--brand-accent) 9%, transparent), color-mix(in srgb, var(--brand-accent) 9%, transparent)),
        linear-gradient(color-mix(in srgb, var(--brand-accent-2) 9%, transparent), color-mix(in srgb, var(--brand-accent-2) 9%, transparent));
    background-repeat: no-repeat;
    background-size: 9% 22%, 6% 16%, 8% 20%, 5% 14%;
    background-position: 14% -4%, 34% 3%, 60% -6%, 82% 2%;
}

/* The logos are bitmaps with a white background, so they need a light plate
   to sit on rather than floating directly on a tinted or brand-colored
   surface. */
.logo-plate {
    background: #ffffff;
    border-radius: .5rem;
}

/* ===========================================================================
 * App header — logo/company name left, role/language/sign-out actions right.
 * Sticky, translucent, with a thin brand-accent gradient bar on top. Direct
 * port of the Node app's (app)/layout.tsx header markup.
 * ========================================================================= */

.app-header {
    position: sticky;
    top: 0;
    z-index: 10;
    border-bottom: 1px solid var(--border);
    background: var(--surface-glass);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 1px 2px rgb(0 0 0 / 0.04);
}

.app-header__accent-bar {
    height: 3px;
    width: 100%;
    background: linear-gradient(to right, var(--brand-accent), color-mix(in srgb, var(--brand-accent) 30%, transparent));
}

.app-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-top: .75rem;
    padding-bottom: .75rem;
    position: relative;
    z-index: 1;
}

.brand-mark {
    display: flex;
    align-items: center;
    gap: .75rem;
    text-decoration: none;
    color: inherit;
}

.brand-mark__logo-plate {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: .35rem;
}

.brand-mark__logo { display: block; height: 1.75rem; width: auto; }
.brand-mark__logo--wide { height: 1.75rem; width: auto; max-width: none; }

.brand-mark__name { font-size: .9rem; font-weight: 600; line-height: 1.2; }

.header-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

.header-link {
    border-radius: .5rem;
    padding: .35rem .75rem;
    font-size: .875rem;
    font-weight: 500;
    color: inherit;
    text-decoration: none;
    transition: background-color .15s ease;
}

.header-link:hover { background: rgb(0 0 0 / 0.05); }

.lang, .lang-form, .signout-form { margin: 0; }

.lang-btn, .signout-btn {
    border-radius: .375rem;
    border: 1px solid var(--border);
    padding: .35rem .75rem;
    font: inherit;
    font-size: .75rem;
    font-weight: 500;
    color: var(--muted);
    background: transparent;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.lang-btn:hover, .signout-btn:hover { color: var(--foreground); border-color: var(--brand-accent); }
.signout-btn:disabled { opacity: .6; cursor: default; }

/* ===========================================================================
 * Admin tab bar — port of the Node app's AdminNav.tsx. Shown only above
 * /admin/* pages, at the top of the main content column.
 * ========================================================================= */

.admin-nav {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: .75rem;
    margin-bottom: 1.5rem;
}

.admin-nav__tab {
    border-radius: .5rem;
    padding: .35rem .75rem;
    font-size: .875rem;
    font-weight: 500;
    color: var(--muted);
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}

.admin-nav__tab:hover { background: rgb(0 0 0 / 0.05); color: var(--foreground); }

.admin-nav__tab--active, .admin-nav__tab--active:hover {
    background: var(--brand-primary);
    color: #fff;
}

.footer {
    max-width: 60rem;
    margin: 0 auto;
    padding: 1rem 1.25rem 2rem;
    color: var(--muted);
    font-size: .8rem;
}

.container { max-width: 60rem; margin: 0 auto; padding: 1.5rem 1.25rem; }

.card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: .6rem;
    padding: 1.5rem;
}

.card--narrow { max-width: 30rem; margin: 0 auto; }
.card h1 { margin-top: 0; font-size: 1.4rem; }

/* A card's <h1>/<h2> plus a primary action, e.g. directory heading + "Create employee". */
.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.card-header h1, .card-header h2 { margin: 0; }

.muted { color: var(--muted); }
.hint { color: var(--muted); font-size: .85rem; margin: .35rem 0 0; }
.req { color: var(--err-text); }

/* Forms */
label { display: block; margin: 1rem 0 .3rem; font-weight: 500; font-size: .9rem; }

input[type="text"], input[type="email"], input[type="tel"],
input[type="password"], input[type="date"], input[type="time"], input[type="file"],
select, textarea {
    width: 100%;
    padding: .6rem .75rem;
    border: 1px solid var(--line);
    border-radius: .5rem;
    background: var(--bg);
    color: var(--text);
    font: inherit;
    transition: border-color .15s ease, box-shadow .15s ease;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-accent) 20%, transparent);
}

textarea { resize: vertical; }

/* Branded file inputs — port of the Node app's `file:` pseudo-element
   button (bg-brand pill) via the standards file-selector-button. */
input[type="file"] {
    border: 0;
    padding: 0;
    background: none;
}

input[type="file"]::file-selector-button {
    margin-inline-end: .75rem;
    padding: .4rem .9rem;
    border: 0;
    border-radius: .5rem;
    background: var(--brand-primary);
    color: #fff;
    font: inherit;
    font-size: .8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease;
}

input[type="file"]::file-selector-button:hover { background: var(--brand-primary-tint); }

fieldset {
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: 1rem 1.25rem 1.35rem;
    margin: 1.5rem 0 0;
}

legend {
    padding: 0 .4rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}

.fieldset--disabled { opacity: .65; }

.avatar {
    width: 4rem;
    height: 4rem;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--line);
}

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0 1rem;
}

/* Buttons */
.btn {
    display: inline-block;
    margin-top: 1.25rem;
    padding: .55rem 1.1rem;
    border: 1px solid var(--line);
    border-radius: .4rem;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.btn:hover { border-color: var(--accent); }
.btn--primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--danger { background: var(--err-bg); border-color: var(--status-danger-border); color: var(--err-text); }
.btn--danger:hover { background: var(--status-danger-border); }
.btn--link {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    text-decoration: underline;
}

/* Alerts */
.alert {
    padding: .7rem 1rem;
    border-radius: .4rem;
    margin-bottom: 1.25rem;
}

.alert--success { background: var(--ok-bg); color: var(--ok-text); }
.alert--error { background: var(--err-bg); color: var(--err-text); }

/* Definition lists */
.facts {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: .4rem 1.25rem;
    margin: 1.25rem 0 0;
}

.facts dt { color: var(--muted); }
.facts dd { margin: 0; }

/* Shift panel */
.shift__headline {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    margin-bottom: .5rem;
}

.badge {
    display: inline-block;
    padding: .2rem .6rem;
    border-radius: 999px;
    font-size: .85rem;
    font-weight: 600;
    background: var(--line);
    color: var(--text);
}

.badge--on_time, .badge--shift_complete { background: var(--ok-bg); color: var(--ok-text); }
.badge--late { background: var(--err-bg); color: var(--err-text); }

.elapsed { font-variant-numeric: tabular-nums; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.warn { color: var(--err-text); }

.actions { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }
.actions form { margin: 0; }

.card + .card { margin-top: 1.25rem; }
.card h2 { margin-top: 0; font-size: 1.1rem; }

/* Direction
   ----------
   There is no RTL stylesheet. The layout is flex/gap throughout, which mirrors
   itself when <html dir="rtl"> flips, so the only changes needed were the two
   physical properties above: margin-right -> margin-inline-end and
   text-align: left -> start. Keep it that way — reach for the logical property
   (inline-start/inline-end) rather than left/right in anything new. */

/* Tables */
.table-wrap { overflow-x: auto; margin-top: 1.25rem; }
.table { width: 100%; border-collapse: collapse; font-size: .95rem; }
.table th, .table td { padding: .6rem .75rem; text-align: start; border-bottom: 1px solid var(--line); vertical-align: top; }
.table th { color: var(--muted); font-weight: 600; font-size: .85rem; }
.table tbody tr:last-child td { border-bottom: 0; }
.table .reason { max-width: 22rem; }
.table form { margin: 0; }

/* Responsive tables (admin mobile access)
   ----------------------------------------
   Below the breakpoint, every .table row becomes its own card and each cell
   stacks its value under a label instead of a column. The label text comes
   from a data-label="<?= t(...) ?>" attribute on the <td> — same translation
   key already used in that column's <th> — rather than being duplicated here,
   so this stays correct in both languages with no CSS-side copy of its own.
   A <td> with no data-label (an actions-only column with an empty <th>, e.g.
   shift-overrides' delete button) just gets no label line — see :not() below.

   The label sits ABOVE the value as its own block, not beside it, which is
   what lets this handle a cell containing a whole form (approvals' inline
   decide form, with its textarea and buttons) or a lone button (shift-
   overrides' delete) the same way it handles plain text, with no per-table
   exception: the cell's real content just flows normally underneath its
   label, whatever that content is. */
@media (max-width: 700px) {
    .table-wrap { overflow-x: visible; }
    .table thead { display: none; }
    .table, .table tbody, .table tr, .table td { display: block; width: 100%; }

    .table tr {
        border: 1px solid var(--line);
        border-radius: .5rem;
        padding: .75rem;
        margin-bottom: .75rem;
    }
    .table tbody tr:last-child { margin-bottom: 0; }

    .table td {
        padding: .5rem 0;
        border-bottom: 1px solid var(--line);
    }
    .table td:last-child { border-bottom: 0; }
    /* Same selector as the desktop-only "last row has no bottom borders" rule
       above, so it wins on source order rather than losing on specificity —
       that rule meant something different when tr was a row; here it would
       otherwise strip every per-field divider out of the last card. */
    .table tbody tr:last-child td { border-bottom: 1px solid var(--line); }
    .table tbody tr:last-child td:last-child { border-bottom: 0; }

    .table td::before {
        content: attr(data-label);
        display: block;
        font-size: .8rem;
        font-weight: 600;
        color: var(--muted);
        margin-bottom: .2rem;
    }
    .table td:not([data-label])::before { content: none; }

    /* Definition lists (admin home, employee detail): stack dt above dd —
       they already alternate in that order in the markup, so no data
       attribute is needed here the way the table cells need one. */
    .facts { grid-template-columns: 1fr; gap: 0; }
    .facts dt { margin-top: .6rem; }
    .facts dt:first-child { margin-top: 0; }
}

.badge--ok { background: var(--ok-bg); color: var(--ok-text); }
.badge--err { background: var(--err-bg); color: var(--err-text); }
.badge--muted { background: var(--line); color: var(--muted); }
.badge--info { background: var(--status-info-bg); color: var(--status-info); }
.badge--active { background: var(--ok-bg); color: var(--ok-text); }
.badge--upcoming { background: var(--status-info-bg); color: var(--status-info); }
.badge--past { background: var(--line); color: var(--muted); }

/* Admin */
.filters {
    display: flex;
    gap: .75rem;
    align-items: flex-end;
    flex-wrap: wrap;
    margin: 1.25rem 0 0;
}

.filters label { margin: 0 0 .25rem; }
.filters select, .filters input { width: auto; min-width: 11rem; }
.filters .btn { margin-top: 0; }

.tallies { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 1.25rem; }

.tally {
    border: 1px solid var(--line);
    border-radius: .5rem;
    padding: .6rem 1rem;
    min-width: 7rem;
}

.tally__n { display: block; font-size: 1.5rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.tally__l { display: block; font-size: .8rem; color: var(--muted); }

.notes { font-size: .85rem; }
.notes span { display: block; }
.ok { color: var(--ok-text); }

.badge--clocked_in { background: var(--ok-bg); color: var(--ok-text); }
.badge--absent { background: var(--err-bg); color: var(--err-text); }
.badge--on_leave { background: var(--line); color: var(--muted); }
.badge--day_off { background: var(--status-info-bg); color: var(--status-info); }

.decide { display: flex; gap: .5rem; flex-wrap: wrap; }
.decide .btn { margin-top: 0; white-space: nowrap; }

.checkbox { display: flex; align-items: center; gap: .5rem; font-weight: 400; }
.checkbox input { width: auto; }

/* Visually-hidden label, still read by assistive tech. */
.sr-label {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.card h3 { margin: 1.5rem 0 0; font-size: 1rem; }

/* ===========================================================================
 * Desktop-only enforcement (Part B) — paired with the synchronous <script>
 * in header.php that sets [data-viewport-blocked] on <html> before <body> is
 * parsed. Whichever branch applies is already decided before first paint, so
 * neither state ever flashes. The phone-UA case (App\Device) never renders
 * #app-shell at all, so these rules only matter for the viewport case.
 * ========================================================================= */

[data-viewport-blocked] #app-shell { display: none; }

html:not([data-viewport-blocked]) #desktop-only-block { display: none; }

.desktop-only {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    padding: 1.5rem;
    text-align: center;
}

.lang--corner {
    position: absolute;
    inset-inline-end: 1rem;
    top: 1rem;
}

.desktop-only__icon {
    width: 3.5rem;
    height: 3.5rem;
    padding: .85rem;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--muted);
    box-sizing: border-box;
}

.desktop-only__text { max-width: 26rem; }
.desktop-only__text h1 { font-size: 1.15rem; margin: 0; }
.desktop-only__text p { margin: .5rem 0 0; }

/* ===========================================================================
 * Shared elevation + section-header utilities — used by the dashboard hero,
 * status cards, profile sections, and leave panels below. Same ambient,
 * brand-tinted shadow as the login card (see .auth-card).
 * ========================================================================= */

.shadow-brand {
    box-shadow: 0 16px 40px -24px color-mix(in srgb, var(--brand-accent) 45%, transparent),
                0 2px 8px -2px rgb(0 0 0 / 0.06);
}

.eyebrow {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}

/* ===========================================================================
 * Dashboard — direct port of the Node app's dashboard/page.tsx hero +
 * ShiftStatusBar.tsx + OvertimeStatusBar.tsx. Status classes reuse the same
 * keys as .badge--<status> (DashboardController::statusLabel()).
 * ========================================================================= */

.dash-hero {
    position: relative;
    overflow: hidden;
    border-radius: 1rem;
    padding: 1.5rem 1.5rem 1.65rem;
    background: var(--brand-primary);
    color: #fff;
}

.dash-hero__eyebrow { font-size: .6875rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: rgb(255 255 255 / .7); }
.dash-hero h1 { position: relative; z-index: 1; margin: .3rem 0 0; font-size: 1.5rem; font-weight: 800; letter-spacing: -.01em; }
.dash-hero p { position: relative; z-index: 1; margin: .35rem 0 0; font-size: .8rem; color: rgb(255 255 255 / .8); }

.status-card {
    border-radius: 1rem;
    border: 1px solid var(--line);
    background: var(--surface);
    padding: 1.25rem;
    transition: border-color .3s ease, box-shadow .3s ease;
}

.status-card--on_time, .status-card--shift_complete { border-color: color-mix(in srgb, var(--status-success) 45%, var(--line)); }
.status-card--late { border-color: color-mix(in srgb, var(--status-danger) 45%, var(--line)); }
.status-card--on_leave, .status-card--day_off { border-color: color-mix(in srgb, var(--status-info) 45%, var(--line)); }

.status-card__head { display: flex; align-items: center; gap: .4rem; }

.status-card__label {
    margin-top: .5rem;
    font-size: .9rem;
    font-weight: 600;
}

.status-card--on_time .status-card__label, .status-card--shift_complete .status-card__label { color: var(--status-success); }
.status-card--late .status-card__label { color: var(--status-danger); }
.status-card--on_leave .status-card__label, .status-card--day_off .status-card__label { color: var(--status-info); }

.status-card__clock {
    margin: .75rem 0 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-variant-numeric: tabular-nums;
    font-size: 2.75rem;
    font-weight: 700;
    letter-spacing: -.02em;
    direction: ltr;
    text-align: start;
}

.status-card__meta { display: flex; flex-wrap: wrap; gap: .25rem 1rem; margin: .4rem 0 0; font-size: .8rem; color: var(--muted); }

.status-card__hint {
    margin: .6rem 0 0;
    padding: .5rem .75rem;
    border-radius: .5rem;
    background: var(--status-info-bg);
    color: var(--status-info);
    font-size: .8rem;
}

.status-card__hint--warn { background: var(--err-bg); color: var(--err-text); }

.status-card--compact { padding: 1rem 1.25rem; }
.status-card--compact .status-card__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; }
.status-card--compact .status-card__clock { margin: 0; font-size: 1.15rem; font-weight: 600; }
.status-card--compact .status-card__meta { margin-top: .25rem; }

/* ===========================================================================
 * Pill toggle group — company selector on login, leave-type selector on the
 * leave request form. Same visual language, generic name for reuse.
 * ========================================================================= */

.pill-toggle, .company-toggle {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
    gap: .5rem;
}

.pill-toggle__btn, .company-toggle__btn {
    border: 1px solid var(--line);
    border-radius: .5rem;
    padding: .5rem .6rem;
    font: inherit;
    font-size: .75rem;
    font-weight: 500;
    color: var(--muted);
    background: var(--surface);
    cursor: pointer;
    transition: transform .15s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
}

.pill-toggle__btn:hover, .company-toggle__btn:hover { border-color: var(--brand-accent); transform: translateY(-1px); }

.pill-toggle__btn[aria-pressed="true"], .company-toggle__btn[aria-pressed="true"] {
    border-color: var(--brand-accent);
    background: var(--brand-primary);
    color: #fff;
}

/* ===========================================================================
 * Profile completion — sectioned layout, direct port of ProfileForm.tsx
 * (each fieldset already looks like a section thanks to the eyebrow legend
 * upgrade above; this just tightens the page-level rhythm).
 * ========================================================================= */

.profile-head { margin: 0 0 1.5rem; }
.profile-head h1 { margin: 0; font-size: 1.4rem; }
.profile-head p { margin: .3rem 0 0; }

.profile-section { margin-top: 1.5rem; }
.profile-section:first-of-type { margin-top: 0; }

/* ===========================================================================
 * Leave — request form + list. Direct port of LeaveRequestForm.tsx /
 * LeaveRequestsList.tsx, table-based list kept (matches the pattern already
 * used for overtime credit requests on the dashboard).
 * ========================================================================= */

.leave-balances { margin-bottom: 1.5rem; }

/* ===========================================================================
 * Login page — bare layout (partials/auth-header.php / auth-footer.php), no
 * app header/nav. Direct port of the Node app's login/page.tsx + LoginPanel
 * + LoginForm.
 * ========================================================================= */

.auth-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    position: relative;
}

.auth-card-wrap {
    position: relative;
    width: 100%;
    max-width: 24rem;
}

/* Ambient, brand-tinted glow behind the card — port of the radial-gradient
   the Node LoginPanel drew behind itself. */
.auth-card-glow {
    position: absolute;
    inset: -3.5rem;
    z-index: -1;
    border-radius: 3rem;
    background: radial-gradient(closest-side, var(--brand-accent) 0%, transparent 70%);
    opacity: .55;
    filter: blur(40px);
    pointer-events: none;
}

.auth-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 1rem;
    padding: 1.85rem;
    box-shadow: 0 16px 40px -24px color-mix(in srgb, var(--brand-accent) 45%, transparent),
                0 2px 8px -2px rgb(0 0 0 / 0.06);
}

/* [data-motif]'s ::before backdrop (see the block near the top of this file)
   paints at z-index 0 — same reasoning as .app-header__inner: real content
   needs its own stacking context above it. */
.auth-card__inner { position: relative; z-index: 1; }

.auth-card__head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .85rem;
    text-align: center;
    margin-bottom: 1.5rem;
}

.auth-card__logo { display: block; height: 3.5rem; width: auto; }

.auth-card__head h1 { margin: 0; font-size: 1.15rem; font-weight: 600; }
.auth-card__head p { margin: .3rem 0 0; font-size: .8rem; color: var(--muted); }

.auth-card fieldset.company-toggle-fieldset {
    border: 0;
    padding: 0;
    margin: 1rem 0 0;
}

.auth-card .company-toggle-fieldset legend {
    padding: 0;
    margin: 0 0 .5rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
}

.company-toggle {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .5rem;
}

.company-toggle__btn {
    border: 1px solid var(--line);
    border-radius: .5rem;
    padding: .5rem .6rem;
    font: inherit;
    font-size: .75rem;
    font-weight: 500;
    color: var(--muted);
    background: var(--surface);
    cursor: pointer;
    transition: transform .15s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
}

.company-toggle__btn:hover { border-color: var(--brand-accent); transform: translateY(-1px); }

.company-toggle__btn[aria-pressed="true"] {
    border-color: var(--brand-accent);
    background: var(--brand-primary);
    color: #fff;
}

.auth-card label {
    margin: 1rem 0 .35rem;
    font-size: .75rem;
    font-weight: 500;
    color: var(--muted);
}

.auth-card input[type="email"],
.auth-card input[type="password"] {
    border-radius: .5rem;
    padding: .65rem .85rem;
}

.auth-card input[type="email"]:focus,
.auth-card input[type="password"]:focus {
    outline: none;
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-accent) 20%, transparent);
}

/* Grid, not the label/input/button source order you'd expect from the visual
   layout: the toggle sits next to the label (row 1) but comes AFTER the
   input in the markup, so Tab goes email -> password -> toggle -> submit,
   not email -> toggle -> password. Visual position is independent of DOM/tab
   order in a grid, so this needs no tabindex trickery. */
.password-field {
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: .75rem;
    align-items: center;
    margin-top: 1rem;
}

.password-field label {
    grid-column: 1;
    grid-row: 1;
    margin: 0 0 .35rem;
}

.password-field input {
    grid-column: 1 / -1;
    grid-row: 2;
}

.password-toggle {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    border: 0;
    background: none;
    padding: 0;
    font: inherit;
    font-size: .7rem;
    font-weight: 500;
    color: var(--muted);
    cursor: pointer;
}

.password-toggle:hover { color: var(--foreground); }

.auth-card .btn--primary {
    display: block;
    width: 100%;
    margin-top: 1.5rem;
    padding: .65rem 1rem;
    border-radius: .5rem;
    text-align: center;
    font-weight: 600;
}

.auth-card .btn--primary:hover { background: var(--brand-primary-tint); border-color: var(--brand-primary-tint); }

.auth-card .alert { margin: 1rem 0 0; font-size: .8rem; }

.auth-card__footer {
    margin: 1.25rem 0 0;
    text-align: center;
    font-size: .7rem;
    color: var(--muted);
}

/* Admin: logs export toolbar — count on one side, the CSV export button
   (styled like Node LogsView.tsx's plain .btn-equivalent export links) on
   the other. */
.logs-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 1.25rem 0 0;
}

.logs-toolbar p { margin: 0; }

/* Working-times: the weekend-day pill row. A plain checkbox per weekday,
   :has() styles the label so this works with JS off like every other form
   in the app — checked = day off. */
.daypills { display: flex; gap: .4rem; flex-wrap: wrap; }

.daypill {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.75rem;
    padding: .35rem .5rem;
    border: 1px solid var(--line);
    border-radius: .5rem;
    background: var(--surface);
    color: var(--muted);
    font-size: .8rem;
    font-weight: 600;
    cursor: pointer;
    user-select: none;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.daypill input {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
}

.daypill:has(input:checked) { background: var(--accent); border-color: var(--accent); color: #fff; }
.daypill:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Holidays: the month-grid calendar widget. */
.calendar-nav { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: 1.25rem; }
.calendar-nav h2 { margin: 0; font-size: 1.1rem; }

.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: .35rem;
    margin-top: 1rem;
}

.calendar-grid__weekday {
    text-align: center;
    font-size: .75rem;
    font-weight: 600;
    color: var(--muted);
    padding-bottom: .25rem;
}

.calendar-day {
    min-height: 3.5rem;
    border: 1px solid var(--line);
    border-radius: .5rem;
    padding: .35rem .4rem;
    font-size: .8rem;
}

.calendar-day--empty { border-color: transparent; }
.calendar-day--weekend { background: var(--line); }
.calendar-day--holiday { background: var(--status-info-bg); border-color: var(--status-info-border); }

.calendar-day__n { font-weight: 600; font-variant-numeric: tabular-nums; }
.calendar-day__label {
    display: block;
    margin-top: .2rem;
    font-size: .68rem;
    line-height: 1.2;
    color: var(--status-info);
}

.holiday-list { margin-top: 1.25rem; }
.holiday-list__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .6rem 0;
    border-bottom: 1px solid var(--line);
}
.holiday-list__row:last-child { border-bottom: 0; }
.holiday-list__date { font-variant-numeric: tabular-nums; color: var(--muted); min-width: 6rem; }
.holiday-list__actions { display: flex; gap: .5rem; flex-shrink: 0; }
.logs-toolbar .btn { margin-top: 0; }
