/* ============================================================================
 * upk.css — THE ui_upmedik COMPONENT KIT (mygereja CMS). SINGLE SOURCE.
 *
 * Every button, badge / pill, filter chip, card, stat tile, alert, form
 * control (incl. the searchable-dropdown / date / time triggers, which carry
 * `upk-input`), table and tab in the CMS is styled HERE and nowhere else.
 *   - Contract + class list + migration table: _md/_docs/UI_KIT.md
 *   - Live reference (every class, click-to-copy): /ui_kit (superadmin)
 *   - To restyle a component sitewide: edit THIS file (usually a token in §1).
 *     Never hand-roll a button/badge/card/alert class string in a view or JS.
 *   - Component rules paint with the --upk-* tokens ONLY (never var(--primary)
 *     / var(--destructive) / a hex directly), so one token recolours every
 *     component that shows that colour.
 *
 * LAYER. Everything is inside `@layer components` (the layer style.css already
 * declares: properties < theme < base < components < utilities). So — like
 * Bootstrap — a Tailwind utility written on the element still wins
 * (`upk-btn upk-btn-primary w-full`, `upk-input text-right`), and `.hidden`
 * hides any component without a special rule. NO !important in this file: a
 * layered !important would beat every utility and every unlayered rule.
 * ONE exception to "utilities win": §14 `@layer upk-lock`, declared after
 * `utilities` (table cell padding, the <th> / .up-panel-head band, and two
 * searchable-dropdown internals).
 *
 * LOAD ORDER (main_master.php / auth_master.php $_css_files):
 *   style → radius → components → erp-compat → app-responsive → upk
 *   → app-utilities → app-compat
 * (upk after erp-compat/app-responsive, before app-utilities/app-compat.)
 *
 * Sections: 1 tokens · 2 colour bindings · 3 buttons · 4 badges/pills ·
 * 5 chips · 6 cards/sections/stat · 7 alerts · 8 forms · 9 tables · 10 tabs ·
 * 11 misc (empty state, timeline, fav, overlay, spinner) · 12 legacy aliases
 * + the back button · 13 shape modifier (.upk-pill, last so it wins) ·
 * 14 upk-lock layer (the only rules above utilities).
 * ==========================================================================*/
@layer components {

/* ─── 1. TOKENS ──────────────────────────────────────────────────────────────
   Change a token → every component that uses it changes. The semantic colours
   map onto the theme tokens of style.css where one exists (primary =
   --primary, danger = --destructive, light = --secondary), otherwise onto the
   house 600-level hues the app already uses (success #16a34a = the export
   green, warning #d97706, info #0d9488, secondary #64748b — the same values
   as the up-badge-* / up-btn-* hues).
   NOTE: style.css's own --success / --warning / --info (emerald / amber /
   teal, used by the text-success / bg-success / text-amber … UTILITIES) are
   lighter hues than these kit tokens. Status colour = a kit class, never
   those utilities (UI_KIT.md §1).
   Declared on `:root, .dark, .upk-scope` so a `.dark` SUBTREE (the /ui_kit
   dark preview) or a `.upk-scope` subtree that re-declares the theme tokens
   (the /ui_kit light preview on a dark site) re-derives every kit token from
   its own theme values. */
:root, .dark, .upk-scope {
    --upk-primary:   var(--primary);      --upk-primary-fg:   var(--primary-foreground);
    --upk-secondary: #64748b;             --upk-secondary-fg: #fff;
    --upk-success:   #16a34a;             --upk-success-fg:   #fff;
    --upk-danger:    var(--destructive);  --upk-danger-fg:    #fff;
    --upk-warning:   #d97706;             --upk-warning-fg:   #fff;
    --upk-info:      #0d9488;             --upk-info-fg:      #fff;
    --upk-light:     var(--secondary);    --upk-light-fg:     var(--secondary-foreground);
    --upk-dark:      #1e293b;             --upk-dark-fg:      #fff;
    /* legacy hues kept only for the up-badge-rose / up-*-violet aliases (§12) */
    --upk-rose:      #e11d48;             --upk-violet:       #7c3aed;

    /* -text: readable foreground ON the soft tint (soft badges, alerts, soft /
       outline buttons, chip hover, back button) */
    --upk-primary-text:   var(--upk-primary);
    --upk-secondary-text: #475569;
    --upk-success-text:   #15803d;
    --upk-danger-text:    var(--upk-danger);
    --upk-warning-text:   #b45309;
    --upk-info-text:      #0f766e;
    --upk-light-text:     var(--secondary-foreground);
    --upk-dark-text:      #1e293b;

    /* -soft: the tint (soft badge / alert / soft button / back button fill).
       10% = the `bg-primary/10` the hand-built soft pills already use. */
    --upk-soft-pct: 10%;
    --upk-primary-soft:   color-mix(in oklab, var(--upk-primary)   var(--upk-soft-pct), transparent);
    --upk-secondary-soft: color-mix(in oklab, var(--upk-secondary) var(--upk-soft-pct), transparent);
    --upk-success-soft:   color-mix(in oklab, var(--upk-success)   var(--upk-soft-pct), transparent);
    --upk-danger-soft:    color-mix(in oklab, var(--upk-danger)    var(--upk-soft-pct), transparent);
    --upk-warning-soft:   color-mix(in oklab, var(--upk-warning)   var(--upk-soft-pct), transparent);
    --upk-info-soft:      color-mix(in oklab, var(--upk-info)      var(--upk-soft-pct), transparent);
    --upk-light-soft:     var(--muted);
    --upk-dark-soft:      color-mix(in oklab, var(--upk-dark)      var(--upk-soft-pct), transparent);

    /* -border: alert / outline edges */
    --upk-primary-border:   color-mix(in oklab, var(--upk-primary)   40%, transparent);
    --upk-secondary-border: color-mix(in oklab, var(--upk-secondary) 40%, transparent);
    --upk-success-border:   color-mix(in oklab, var(--upk-success)   40%, transparent);
    --upk-danger-border:    color-mix(in oklab, var(--upk-danger)    40%, transparent);
    --upk-warning-border:   color-mix(in oklab, var(--upk-warning)   40%, transparent);
    --upk-info-border:      color-mix(in oklab, var(--upk-info)      40%, transparent);
    --upk-light-border:     var(--border);
    --upk-dark-border:      color-mix(in oklab, var(--upk-dark)      40%, transparent);

    /* geometry + derived primaries */
    --upk-radius:      var(--radius);                 /* .4rem (radius.css) — buttons, inputs, cards, chips, alerts */
    --upk-radius-pill: 9999px;                        /* .upk-pill */
    --upk-focus-ring:  color-mix(in oklab, var(--upk-primary) 60%, transparent);
    --upk-head-tint:   color-mix(in oklab, var(--upk-primary) 10%, var(--card));   /* section header + table <th> */
    --upk-band-tint:   color-mix(in oklch, var(--upk-primary) 20%, transparent);   /* any other <th> / .up-panel-head */

    /* button sizes (-FORMAT §B2: -sm is THE default; .upk-btn alone = -sm) */
    --upk-btn-h-xs: 1.375rem;  --upk-btn-px-xs: .375rem;  --upk-btn-fs-xs: 10.5px;
    --upk-btn-h-sm: 1.625rem;  --upk-btn-px-sm: .5rem;    --upk-btn-fs-sm: 11px;
    --upk-btn-h-md: 2rem;      --upk-btn-px-md: .75rem;   --upk-btn-fs-md: 12px;
    --upk-btn-h-lg: 2.25rem;   --upk-btn-px-lg: 1rem;     --upk-btn-fs-lg: 13px;
    --upk-btn-weight: 500;

    /* form control sizes (.upk-input alone = md, THE ONE FIELD) */
    --upk-input-h-sm: 1.625rem;  --upk-input-h-md: 2.25rem;  --upk-input-h-lg: 2.5rem;
    --upk-input-fs-sm: 11px;     --upk-input-fs-md: 12px;    --upk-input-fs-lg: 13px;
}
/* Dark mode (html.dark). The theme-mapped tokens (primary, danger, light) follow
   style.css by themselves; the literal hues and the -text values need their
   own dark answer. The near-black "dark" colour tints/edges with the
   foreground instead, or it would vanish on the dark page. */
.dark {
    --upk-dark:           oklch(9% .02 260);
    --upk-secondary-text: #cbd5e1;
    --upk-success-text:   #4ade80;
    --upk-warning-text:   #fbbf24;
    --upk-info-text:      #2dd4bf;
    --upk-light-text:     var(--foreground);
    --upk-dark-text:      #e2e8f0;
    --upk-dark-soft:      color-mix(in oklab, var(--foreground) var(--upk-soft-pct), transparent);
    --upk-dark-border:    var(--border);
}

/* ─── 2. COLOUR BINDINGS ─────────────────────────────────────────────────────
   Each colour class sets five private variables; the component rules below
   paint with them. --upk-c fill · --upk-cf text on fill · --upk-cs soft tint ·
   --upk-ct text on tint · --upk-cb edge. Adding a colour = one block here. */
.upk-badge, .upk-alert,
.upk-btn-primary, .upk-btn-outline-primary, .upk-btn-soft-primary, .upk-badge-primary, .upk-badge-soft-primary, .upk-alert-primary {
    --upk-c: var(--upk-primary); --upk-cf: var(--upk-primary-fg); --upk-cs: var(--upk-primary-soft); --upk-ct: var(--upk-primary-text); --upk-cb: var(--upk-primary-border);
}
.upk-btn-secondary, .upk-btn-outline-secondary, .upk-btn-soft-secondary, .upk-badge-secondary, .upk-badge-soft-secondary, .upk-alert-secondary {
    --upk-c: var(--upk-secondary); --upk-cf: var(--upk-secondary-fg); --upk-cs: var(--upk-secondary-soft); --upk-ct: var(--upk-secondary-text); --upk-cb: var(--upk-secondary-border);
}
.upk-btn-success, .upk-btn-outline-success, .upk-btn-soft-success, .upk-badge-success, .upk-badge-soft-success, .upk-alert-success {
    --upk-c: var(--upk-success); --upk-cf: var(--upk-success-fg); --upk-cs: var(--upk-success-soft); --upk-ct: var(--upk-success-text); --upk-cb: var(--upk-success-border);
}
.upk-btn-danger, .upk-btn-outline-danger, .upk-btn-soft-danger, .upk-badge-danger, .upk-badge-soft-danger, .upk-alert-danger {
    --upk-c: var(--upk-danger); --upk-cf: var(--upk-danger-fg); --upk-cs: var(--upk-danger-soft); --upk-ct: var(--upk-danger-text); --upk-cb: var(--upk-danger-border);
}
.upk-btn-warning, .upk-btn-outline-warning, .upk-btn-soft-warning, .upk-badge-warning, .upk-badge-soft-warning, .upk-alert-warning {
    --upk-c: var(--upk-warning); --upk-cf: var(--upk-warning-fg); --upk-cs: var(--upk-warning-soft); --upk-ct: var(--upk-warning-text); --upk-cb: var(--upk-warning-border);
}
.upk-btn-info, .upk-btn-outline-info, .upk-btn-soft-info, .upk-badge-info, .upk-badge-soft-info, .upk-alert-info {
    --upk-c: var(--upk-info); --upk-cf: var(--upk-info-fg); --upk-cs: var(--upk-info-soft); --upk-ct: var(--upk-info-text); --upk-cb: var(--upk-info-border);
}
.upk-btn-light, .upk-btn-outline-light, .upk-btn-soft-light, .upk-badge-light, .upk-badge-soft-light, .upk-alert-light {
    --upk-c: var(--upk-light); --upk-cf: var(--upk-light-fg); --upk-cs: var(--upk-light-soft); --upk-ct: var(--upk-light-text); --upk-cb: var(--upk-light-border);
}
.upk-btn-dark, .upk-btn-outline-dark, .upk-btn-soft-dark, .upk-badge-dark, .upk-badge-soft-dark, .upk-alert-dark {
    --upk-c: var(--upk-dark); --upk-cf: var(--upk-dark-fg); --upk-cs: var(--upk-dark-soft); --upk-ct: var(--upk-dark-text); --upk-cb: var(--upk-dark-border);
}

/* ─── 3. BUTTONS ─────────────────────────────────────────────────────────────
   class="upk-btn upk-btn-{colour} [upk-btn-{size}]"   (-FORMAT §B2–§B10)
   Roles: primary = AKSI (Tambah/Edit/Simpan/Detail) · success = CETAK
   (PDF/Excel/CSV) · danger = HAPUS · outline = neutral Batal/Tutup ·
   ghost = borderless inline · soft-* = the §B5 "light" whitelist only.
   The size lives in .upk-btn + a size class; the colour class only paints.
   -xs is NOT an action size (-FORMAT §B2): widget chrome only (UI_KIT §2.1). */
.upk-btn {
    --_h: var(--upk-btn-h-sm); --_px: var(--upk-btn-px-sm); --_fs: var(--upk-btn-fs-sm);
    display: inline-flex; align-items: center; justify-content: center; gap: .25rem;
    min-height: var(--_h); padding: 0 var(--_px);
    font-size: var(--_fs); font-weight: var(--upk-btn-weight); line-height: 1.25;
    white-space: nowrap; text-decoration: none; cursor: pointer;
    border: 1px solid transparent; border-radius: var(--upk-radius);
    transition: background-color .15s, color .15s, opacity .15s, border-color .15s;
}
.upk-btn-xs { --_h: var(--upk-btn-h-xs); --_px: var(--upk-btn-px-xs); --_fs: var(--upk-btn-fs-xs); }
.upk-btn-sm { --_h: var(--upk-btn-h-sm); --_px: var(--upk-btn-px-sm); --_fs: var(--upk-btn-fs-sm); }
.upk-btn-md { --_h: var(--upk-btn-h-md); --_px: var(--upk-btn-px-md); --_fs: var(--upk-btn-fs-md); }
.upk-btn-lg { --_h: var(--upk-btn-h-lg); --_px: var(--upk-btn-px-lg); --_fs: var(--upk-btn-fs-lg); }
.upk-btn-block { display: flex; width: 100%; }
/* icon-only layout chrome (-FORMAT §B9: sidebar toggle, modal ✕) — square */
.upk-btn-icon { width: var(--_h); min-width: var(--_h); padding: 0; flex-shrink: 0; }
.upk-btn-icon > svg { width: 1rem; height: 1rem; flex-shrink: 0; }

/* filled (the default look — §B3) */
.upk-btn-primary, .upk-btn-secondary, .upk-btn-success, .upk-btn-danger,
.upk-btn-warning, .upk-btn-info, .upk-btn-light, .upk-btn-dark {
    background-color: var(--upk-c); color: var(--upk-cf); border-color: transparent;
}
.upk-btn-primary:hover, .upk-btn-secondary:hover, .upk-btn-success:hover, .upk-btn-danger:hover,
.upk-btn-warning:hover, .upk-btn-info:hover, .upk-btn-light:hover, .upk-btn-dark:hover {
    opacity: .9; color: var(--upk-cf);
}
/* outline (coloured edge + text, fills on hover) */
.upk-btn-outline-primary, .upk-btn-outline-secondary, .upk-btn-outline-success, .upk-btn-outline-danger,
.upk-btn-outline-warning, .upk-btn-outline-info, .upk-btn-outline-light, .upk-btn-outline-dark {
    background-color: transparent; color: var(--upk-ct); border-color: var(--upk-c);
}
.upk-btn-outline-primary:hover, .upk-btn-outline-secondary:hover, .upk-btn-outline-success:hover, .upk-btn-outline-danger:hover,
.upk-btn-outline-warning:hover, .upk-btn-outline-info:hover, .upk-btn-outline-light:hover, .upk-btn-outline-dark:hover {
    background-color: var(--upk-c); color: var(--upk-cf); border-color: var(--upk-c);
}
/* soft = Bootstrap/Metronic "btn-light-{colour}" (§B5 whitelist) — solid on hover */
.upk-btn-soft-primary, .upk-btn-soft-secondary, .upk-btn-soft-success, .upk-btn-soft-danger,
.upk-btn-soft-warning, .upk-btn-soft-info, .upk-btn-soft-light, .upk-btn-soft-dark {
    background-color: var(--upk-cs); color: var(--upk-ct); border-color: transparent;
}
.upk-btn-soft-primary:hover, .upk-btn-soft-secondary:hover, .upk-btn-soft-success:hover, .upk-btn-soft-danger:hover,
.upk-btn-soft-warning:hover, .upk-btn-soft-info:hover, .upk-btn-soft-light:hover, .upk-btn-soft-dark:hover {
    background-color: var(--upk-c); color: var(--upk-cf);
}
/* edges that would vanish: the pale "light" edge on a white page, the
   near-black "dark" fill / edge / tint on the dark page */
.upk-btn-outline-light, .upk-btn-outline-light:hover { border-color: var(--border); }
.dark .upk-btn-dark, .dark .upk-btn-outline-dark, .dark .upk-btn-soft-dark { border-color: var(--border); }
.dark .upk-badge-dark, .dark .upk-badge-soft-dark { box-shadow: inset 0 0 0 1px var(--border); }
/* neutral outline (modal Batal / Tutup) and ghost (borderless inline action) */
.upk-btn-outline { background-color: var(--card); border-color: var(--border); color: var(--foreground); }
.upk-btn-ghost   { background-color: transparent; color: var(--foreground); }
.upk-btn-outline:hover,
.upk-btn-ghost:hover { background-color: var(--accent); color: var(--accent-foreground); }

/* states — ONE disabled opacity for every colour (.55) */
.upk-btn:focus-visible { outline: 2px solid var(--upk-focus-ring); outline-offset: 2px; }
.upk-btn:disabled, .upk-btn[disabled], .upk-btn.is-disabled, .upk-btn[aria-disabled="true"] {
    opacity: .55; cursor: not-allowed; pointer-events: none;
}
.upk-btn.is-busy, .upk-btn[aria-busy="true"] { opacity: .65; cursor: progress; pointer-events: none; }
.upk-btn.is-busy::before, .upk-btn[aria-busy="true"]::before {
    content: ""; width: .75em; height: .75em; flex-shrink: 0;
    border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
    animation: upk-spin .75s linear infinite;
}

/* ─── 4. BADGES / PILLS ──────────────────────────────────────────────────────
   class="upk-badge [upk-badge-{colour}|upk-badge-soft-{colour}] [upk-pill] [upk-badge-sm]"
   -FORMAT §B13: solid primary by default; empty / zero → secondary (grey).
   Not a control: no hover, no cursor. Baseline-aligned and free to wrap,
   exactly like the hand-built `inline-flex … rounded-full px-2 py-0.5 text-xs
   font-medium` pill it replaces (add `whitespace-nowrap` where needed). */
.upk-badge {
    display: inline-flex; align-items: center; gap: .25rem;
    padding: .125rem .5rem; font-size: .75rem; line-height: 1rem; font-weight: 500;
    border-radius: var(--upk-radius);
}
.upk-badge, .upk-badge-primary, .upk-badge-secondary, .upk-badge-success, .upk-badge-danger,
.upk-badge-warning, .upk-badge-info, .upk-badge-light, .upk-badge-dark {
    background-color: var(--upk-c); color: var(--upk-cf);
}
.upk-badge-soft-primary, .upk-badge-soft-secondary, .upk-badge-soft-success, .upk-badge-soft-danger,
.upk-badge-soft-warning, .upk-badge-soft-info, .upk-badge-soft-light, .upk-badge-soft-dark {
    background-color: var(--upk-cs); color: var(--upk-ct);
}
.upk-badge-sm { padding: 0 .375rem; font-size: 11px; line-height: 1rem; }
.upk-badge-md { padding: .125rem .5rem; font-size: .75rem; line-height: 1rem; }

/* ─── 5. FILTER CHIPS / SEGMENTED OPTIONS ("THE ONE PILL") ───────────────────
   -FORMAT §B11.6. One control, four drivers for "selected":
     .is-active / .active (JS class) · [aria-pressed="true"] · [data-active]
     (_filter_select / _pill_group) · input.upk-chip-input:checked + label.upk-chip
     (_form_choice radios).
   .upk-chip = 28px/12px (form choice) · .upk-chip-sm = 26px/11px (toolbar /
   filter row — lines up with .upk-btn). .up-select-pill is the -sm alias.
   House deviations from §B11.6 (UI_KIT.md §2.3): .4rem corners (add upk-pill
   for the rounded look) and <button> chips (keyboard-reachable). */
.upk-chip, .up-select-pill, .up-seg, .up-seg-on, .up-seg-done {
    display: inline-flex; align-items: center; justify-content: center; gap: .375rem;
    min-height: 1.75rem; padding: 0 .75rem;
    border: 1px solid var(--border); border-radius: var(--upk-radius);
    background-color: var(--card); color: var(--foreground);
    font-size: 12px; font-weight: 500; line-height: 1.25;
    white-space: nowrap; cursor: pointer; text-decoration: none; user-select: none;
    transition: background-color .15s, color .15s, border-color .15s;
}
.upk-chip-sm, .up-select-pill { min-height: 1.625rem; padding: 0 .5rem; font-size: 11px; gap: .25rem; }
.upk-chip-group { display: flex; flex-wrap: wrap; align-items: center; gap: .375rem; }
/* the radio/checkbox itself is hidden — the label IS the control */
.upk-chip-group .upk-chip-input, input.upk-chip-input { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; }
/* hover only on UNSELECTED — hovering the chosen chip must not look like a change */
.upk-chip:hover, .up-select-pill:hover, .up-seg:hover { border-color: var(--upk-primary); color: var(--upk-primary-text); }
/* SELECTED — one blue, whichever driver set it */
.upk-chip.is-active, .upk-chip.active, .upk-chip[data-active], .upk-chip[aria-pressed="true"],
.upk-chip-input:checked + .upk-chip,
.up-select-pill.is-active, .up-select-pill.active, .up-select-pill[data-active], .up-select-pill[aria-pressed="true"], .up-seg-on,
.upk-chip.is-active:hover, .upk-chip.active:hover, .upk-chip[data-active]:hover, .upk-chip[aria-pressed="true"]:hover,
.upk-chip-input:checked + .upk-chip:hover,
.up-select-pill.is-active:hover, .up-select-pill.active:hover, .up-select-pill[data-active]:hover, .up-select-pill[aria-pressed="true"]:hover {
    background-color: var(--upk-primary); border-color: var(--upk-primary); color: var(--upk-primary-fg);
}
/* the one green state a segmented row can carry (mom "selesai") */
.up-seg-done, .up-seg-done:hover { background-color: var(--upk-success); border-color: var(--upk-success); color: var(--upk-success-fg); }
.upk-chip:focus-visible, .up-select-pill:focus-visible,
.upk-chip-input:focus-visible + .upk-chip { outline: 2px solid var(--upk-primary); outline-offset: 2px; }

/* ─── 6. CARDS · SECTIONS · STAT TILES ───────────────────────────────────────
   .upk-card  = the form / detail / modal card (plain header, roomy 20px body).
   .upk-section = the list / table card of _shared/_uptable (tinted compact
   header, uppercase title, 12px body). Same edge, radius and fill. */
.upk-card { background-color: var(--card); border: 1px solid var(--border); border-radius: var(--upk-radius); }
.upk-card-head {
    display: flex; align-items: center; justify-content: space-between; gap: .75rem;
    padding: .75rem 1.25rem; border-bottom: 1px solid var(--border);
}
.upk-card-title { margin: 0; font-size: .875rem; line-height: 1.25rem; font-weight: 600; }
.upk-card-sub   { font-size: .75rem; line-height: 1rem; color: var(--muted-foreground); }
.upk-card-body  { padding: 1.25rem; }
.upk-card-foot {
    display: flex; align-items: center; justify-content: flex-end; gap: .5rem;
    padding: .75rem 1.25rem; border-top: 1px solid var(--border);
}

.upk-section {
    background-color: var(--card); border: 1px solid var(--border); border-radius: var(--upk-radius);
    margin-bottom: 1rem; box-shadow: none;
}
.upk-section-header {
    display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
    padding: .5rem .75rem; border-bottom: 1px solid var(--border);
    border-top-left-radius: inherit; border-top-right-radius: inherit;
    background: var(--upk-head-tint);
}
/* SECTION HEADING — also usable on its own above any block (one line; a long
   heading truncates with an ellipsis) */
.upk-section-title {
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.upk-section-body { padding: .75rem; }

.upk-stat { background-color: var(--card); border: 1px solid var(--border); border-radius: var(--upk-radius); padding: .625rem .75rem; }
.upk-stat-value { font-size: 1.25rem; line-height: 1; font-weight: 600; letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.upk-stat-label { margin-top: .375rem; display: flex; align-items: center; gap: .375rem; font-size: .75rem; line-height: 1rem; color: var(--muted-foreground); }

/* ─── 7. ALERTS (inline, never SweetAlert — -FORMAT §B12) ────────────────────
   class="upk-alert [upk-alert-{colour}] [upk-alert-dashed] [upk-alert-dismissible]"
   — soft fill + 40% edge + readable text; default flavour primary. A BLOCK,
   like Bootstrap's .alert (inline text / <strong> flow normally); add
   `flex items-start gap-3` for an icon row. Padding = the 16×20px of the
   app's hand-built notices. Close: <button class="upk-alert-close"
   data-upk-dismiss="alert" aria-label="Tutup">×</button> (erp_ui_rules.js
   removes the alert). */
.upk-alert {
    display: block; position: relative;
    padding: 1rem 1.25rem; font-size: .875rem; line-height: 1.25rem;
    background-color: var(--upk-cs); color: var(--upk-ct);
    border: 1px solid var(--upk-cb); border-radius: var(--upk-radius);
}
.upk-alert-dashed { border-style: dashed; }
.upk-alert-title  { margin: 0 0 .125rem; font-weight: 600; }
.upk-alert-dismissible { padding-right: 3rem; }
.upk-alert-close {
    position: absolute; top: .625rem; right: .625rem;
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.5rem; height: 1.5rem; padding: 0; border: 0; border-radius: var(--upk-radius);
    background: transparent; color: inherit; font-size: 1.125rem; line-height: 1;
    opacity: .6; cursor: pointer; transition: opacity .15s, background-color .15s;
}
.upk-alert-close:hover { opacity: 1; background-color: color-mix(in oklab, currentColor 12%, transparent); }
.upk-alert-close:focus-visible { outline: 2px solid var(--upk-focus-ring); outline-offset: 1px; opacity: 1; }

/* ─── 8. FORMS ("THE ONE FIELD") ─────────────────────────────────────────────
   .upk-input on <input>/<select>/<textarea> (or .upk-select / .upk-textarea).
   36px / 12px / 500, border --border, radius --upk-radius, card fill, NO
   shadow, NO ring — focus turns the border primary.
   The shared widgets wear it too: the searchable-dropdown trigger
   (searchable_select.js — select_searchable.js mirrors the <select>'s
   upk-input-sm/-lg / is-invalid / is-valid / border-destructive / aria-invalid
   onto it), the date / time triggers (datepicker.js, up_datepicker()), dt24
   (copies the input's classes) and the UpTable / UpTableDom search + length
   fields. .upk-filter = legacy alias of .upk-input-sm. */
.upk-input, .upk-select, .upk-textarea, .upk-filter {
    display: flex; width: 100%; height: var(--upk-input-h-md); padding: .25rem .75rem;
    border: 1px solid var(--border); border-radius: var(--upk-radius);
    background-color: var(--card); color: var(--foreground);
    font-size: var(--upk-input-fs-md); font-weight: 500; line-height: 1.25;
    box-shadow: none; outline: none;
    transition: border-color .15s, box-shadow .15s;
}
textarea.upk-input, .upk-textarea { height: auto; min-height: 4rem; padding: .5rem .75rem; }
.upk-input::placeholder, .upk-select::placeholder, .upk-textarea::placeholder, .upk-filter::placeholder { color: var(--muted-foreground); }
.upk-input:focus, .upk-select:focus, .upk-textarea:focus, .upk-filter:focus,
.upk-filter:focus-visible { border-color: var(--upk-primary); box-shadow: none; outline: none; }
.upk-input:disabled, .upk-select:disabled, .upk-textarea:disabled, .upk-filter:disabled { cursor: not-allowed; opacity: .5; }
.upk-input:disabled, .upk-input[readonly], .upk-select:disabled, .upk-textarea:disabled, .upk-textarea[readonly],
.upk-filter:disabled, .upk-filter[readonly] { background-color: var(--muted); color: var(--muted-foreground); }
/* sizes — -sm is the filter / toolbar control (lines up with .upk-btn) */
.upk-input-sm, .upk-filter { height: var(--upk-input-h-sm); min-height: var(--upk-input-h-sm); padding: 0 .4rem; font-size: var(--upk-input-fs-sm); }
select.upk-input-sm, select.upk-filter { padding-right: 1.25rem; }
.upk-input-lg { height: var(--upk-input-h-lg); padding: .375rem .875rem; font-size: var(--upk-input-fs-lg); }
/* validation (-FORMAT §B11.4) */
.upk-input.is-invalid, .upk-input[aria-invalid="true"], .upk-input.border-destructive,
.upk-select.is-invalid, .upk-textarea.is-invalid, .upk-filter.is-invalid, .upk-filter[aria-invalid="true"],
.upk-input.is-invalid:focus, .upk-input[aria-invalid="true"]:focus { border-color: var(--upk-danger); }
.upk-input.is-valid, .upk-select.is-valid, .upk-textarea.is-valid, .upk-filter.is-valid { border-color: var(--upk-success); }
.upk-label { display: block; margin-bottom: .25rem; font-size: 12px; font-weight: 600; color: var(--foreground); }
.upk-req   { color: var(--upk-danger-text); margin-left: .125rem; }
.upk-help  { display: block; margin-top: .25rem; font-size: 11px; line-height: 1rem; color: var(--muted-foreground); }
.upk-error { display: block; margin-top: .25rem; font-size: 11px; line-height: 1rem; color: var(--upk-danger-text); }
/* checkbox / radio / switch / range (-FORMAT §B11.1 / §B11.2) */
.upk-check { width: 1rem; height: 1rem; accent-color: var(--upk-primary); cursor: pointer; }
.upk-check-label { display: inline-flex; align-items: center; gap: .5rem; font-size: .875rem; line-height: 1.25rem; cursor: pointer; user-select: none; }
.upk-switch {
    -webkit-appearance: none; appearance: none; flex-shrink: 0; margin: 0; vertical-align: middle;
    width: 2.25rem; height: 1.25rem; cursor: pointer;
    border: 1px solid var(--border); border-radius: var(--upk-radius-pill);
    background-color: var(--muted);
    background-image: radial-gradient(circle closest-side, var(--muted-foreground) 72%, transparent 78%);
    background-size: 1.125rem 1.125rem; background-repeat: no-repeat; background-position: left center;
    transition: background-position .15s, background-color .15s, border-color .15s;
}
.upk-switch:checked {
    background-color: var(--upk-primary); border-color: var(--upk-primary); background-position: right center;
    background-image: radial-gradient(circle closest-side, var(--upk-primary-fg) 72%, transparent 78%);
}
.upk-switch:focus-visible { outline: 2px solid var(--upk-focus-ring); outline-offset: 2px; }
.upk-switch:disabled { opacity: .5; cursor: not-allowed; }
.upk-range { width: 100%; accent-color: var(--upk-primary); cursor: pointer; }
.upk-range:disabled { opacity: .5; cursor: not-allowed; }
/* input group (-FORMAT §B11.3): <div class="upk-input-group"><span class="upk-input-addon">Rp</span><input class="upk-input"></div> */
.upk-input-group { display: flex; align-items: stretch; width: 100%; }
.upk-input-group > .upk-input { flex: 1 1 auto; width: 1%; min-width: 0; }
.upk-input-group > .upk-input:focus { position: relative; z-index: 1; }
.upk-input-addon {
    display: flex; align-items: center; flex-shrink: 0; height: var(--upk-input-h-md); padding: 0 .75rem;
    border: 1px solid var(--border); border-radius: var(--upk-radius);
    background-color: var(--muted); color: var(--foreground);
    font-size: var(--upk-input-fs-md); font-weight: 500; line-height: 1.25; white-space: nowrap;
}
.upk-input-group > :not(:first-child) { margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.upk-input-group > :not(:last-child)  { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.upk-input-group-sm > .upk-input, .upk-input-group-sm > .upk-input-addon {
    height: var(--upk-input-h-sm); min-height: var(--upk-input-h-sm); padding: 0 .4rem; font-size: var(--upk-input-fs-sm);
}

/* ─── 9. TABLES ──────────────────────────────────────────────────────────────
   <table class="upk-table [upk-table-striped] [upk-table-compact] [upk-table-bordered] [upk-table-static]">
   Row hover is ON by default (upk-table-hover is a documented no-op;
   upk-table-static turns it off). Cell PADDING and the header BAND/TINT are in
   the upk-lock layer at the end of this file (one density for every table —
   per-cell px-/py- utilities are ignored there; use .upk-table-compact). */
.upk-table { width: 100%; border-collapse: collapse; caption-side: bottom; font-size: 13px; }
.upk-table thead th {
    height: 2.5rem; text-align: left; vertical-align: middle;
    font-weight: 500; color: var(--muted-foreground); white-space: nowrap;
    border-bottom: 1px solid var(--border);
}
.upk-table tbody td { vertical-align: middle; border-bottom: 1px solid var(--border); }
.upk-table tbody tr { transition: background-color .15s; }
.upk-table tbody tr:hover td { background: color-mix(in oklab, var(--muted) 50%, transparent); }
.upk-table tbody tr:last-child td { border-bottom: 0; }
.upk-table tfoot { border-top: 1px solid var(--border); background: color-mix(in oklab, var(--muted) 50%, transparent); font-weight: 500; }
/* repeater rows (_shared/repeater.js): pin every input to the top edge */
.upk-table tbody[data-repeater-list] > tr > td { vertical-align: top; }
.upk-table-striped tbody tr:nth-child(odd) td { background: color-mix(in oklab, var(--muted) 35%, transparent); }
.upk-table-compact thead th { height: 2rem; }
.upk-table-bordered th, .upk-table-bordered td { border: 1px solid var(--border); }
/* the generic last-row rule above is more specific; bordered tables keep their bottom edge */
.upk-table-bordered tbody tr:last-child td { border-bottom: 1px solid var(--border); }
.upk-table-static tbody tr:hover td { background: transparent; }

/* ─── 10. TABS (-TABS.md: hash persistence is the page JS's job) ─────────────
   <div class="upk-tabs" role="tablist"><button class="upk-tab is-active" role="tab" aria-selected="true">…</button>… */
.upk-tabs {
    display: flex; flex-wrap: wrap; gap: .25rem; overflow-x: auto;
    padding: .5rem .75rem 0; border-bottom: 1px solid var(--border);
}
.upk-tab {
    margin-bottom: -1px; padding: .5rem .75rem; white-space: nowrap;
    border: 0; border-bottom: 2px solid transparent; background: none;
    font-size: .875rem; line-height: 1.25rem; font-weight: 500; color: var(--muted-foreground);
    cursor: pointer; text-decoration: none;
}
.upk-tab:hover { color: var(--foreground); }
.upk-tab.is-active, .upk-tab[aria-selected="true"], .upk-tab.is-active:hover, .upk-tab[aria-selected="true"]:hover {
    border-bottom-color: var(--upk-primary); color: var(--upk-primary-text);
}
.upk-tab:focus-visible { outline: 2px solid var(--upk-focus-ring); outline-offset: -2px; }

/* ─── 11. MISC ───────────────────────────────────────────────────────────── */
/* empty state — "Tidak ada data." block */
.upk-empty { padding: 2.5rem 1rem; text-align: center; font-size: .875rem; line-height: 1.25rem; color: var(--muted-foreground); }
/* timeline (harvested from ci_erp) */
.upk-tl { position: relative; padding-left: 1.25rem; }
.upk-tl::before { content: ""; position: absolute; top: .25rem; bottom: .25rem; left: .375rem; width: 1px; background: var(--border); }
.upk-tl-item { position: relative; padding-bottom: 1rem; }
.upk-tl-dot {
    position: absolute; top: .3rem; left: -1.25rem; width: .5rem; height: .5rem; border-radius: 999px;
    background: var(--upk-primary); outline: 3px solid color-mix(in oklab, var(--upk-primary) 20%, transparent);
}
.upk-tl-photos { display: flex; flex-wrap: wrap; gap: .375rem; margin-top: .375rem; }
/* favourite toggle (harvested from ci_erp) — on a upk-btn upk-btn-ghost upk-btn-icon */
.upk-fav-btn.is-fav, .upk-fav-btn.is-fav:hover { color: var(--upk-warning); }
.upk-fav-btn.is-fav svg { fill: currentColor; }
/* full-screen busy overlay + spinner (-LOADING.md look; loading.js has its own) */
.upk-busy-overlay {
    position: fixed; inset: 0; z-index: 120; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: .75rem;
    background-color: oklch(0% 0 0 / .8); color: oklch(100% 0 0);
    font-size: 14px; font-weight: 600; text-align: center;
}
.upk-busy-overlay .upk-spinner {
    width: 2.5rem; height: 2.5rem; border-radius: 999px;
    border: 3px solid oklch(100% 0 0 / .25); border-top-color: oklch(100% 0 0);
    animation: .8s linear infinite upk-spin;
}
@keyframes upk-spin { to { transform: rotate(360deg); } }

/* ─── 12. LEGACY ALIASES + THE BACK BUTTON ───────────────────────────────────
   Colour-only classes: the caller supplies the geometry (upk-badge / upk-btn).
   Do not use in new code. */
/* up-badge-* — hand-built pills in ~50 views still carry these (UpTable.badge()
   now emits upk-badge-{success,warning,danger,info,secondary}). emerald =
   success · amber = warning · teal = info · muted = secondary · rose / violet
   = legacy hues (rose is NOT the danger red — a view that means "error" should
   move to upk-badge-danger). Written after §4, so on a `upk-badge` element the
   alias colour wins (`upk-badge upk-pill up-badge-violet`). */
.up-badge-emerald { background-color: var(--upk-success);   color: var(--upk-success-fg); }
.up-badge-amber   { background-color: var(--upk-warning);   color: var(--upk-warning-fg); }
.up-badge-teal    { background-color: var(--upk-info);      color: var(--upk-info-fg); }
.up-badge-muted   { background-color: var(--upk-secondary); color: var(--upk-secondary-fg); }
.up-badge-rose    { background-color: var(--upk-rose);      color: #fff; }
.up-badge-violet  { background-color: var(--upk-violet);    color: #fff; }
/* up-btn-* — pre-sweep row-button hues (0 uses in mygereja; ci_erp parity) */
.up-btn-teal   { background-color: var(--upk-info);    color: var(--upk-info-fg); }
.up-btn-amber  { background-color: var(--upk-warning); color: var(--upk-warning-fg); }
.up-btn-rose   { background-color: var(--upk-rose);    color: #fff; }
.up-btn-violet { background-color: var(--upk-violet);  color: #fff; }
.up-btn-teal:hover, .up-btn-amber:hover, .up-btn-rose:hover, .up-btn-violet:hover { opacity: .9; }
/* up-pill — ci_erp header action pill (0 uses in mygereja): the md button on
   the button tokens, fully rounded. */
.up-pill {
    display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
    min-height: var(--upk-btn-h-md); padding: 0 var(--upk-btn-px-md); border-radius: var(--upk-radius-pill); border: 1px solid transparent;
    font-size: var(--upk-btn-fs-md); font-weight: var(--upk-btn-weight); line-height: 1.25; white-space: nowrap;
    text-decoration: none; cursor: pointer;
    transition: background-color .15s, color .15s, border-color .15s, opacity .15s;
}
.up-pill svg { height: .9rem; width: .9rem; flex-shrink: 0; }
.up-pill--primary { background-color: var(--upk-primary); color: var(--upk-primary-fg); }
.up-pill--pdf     { background-color: var(--upk-success); color: var(--upk-success-fg); }
.up-pill--primary:hover, .up-pill--pdf:hover { opacity: .9; }
.up-pill--locked  { background-color: var(--upk-light); color: var(--muted-foreground); border-color: var(--border); cursor: not-allowed; opacity: .7; }
/* THE back button (_partials/back_button, ~60 pages):
   class="upk-btn upk-btn-md upk-pill up-back" — size, type and shape come from
   the button tokens; .up-back only paints (soft primary + a hairline edge,
   solid primary on hover) and pushes itself right (layout chrome, like §B9). */
.up-back {
    margin-left: auto;
    background-color: var(--upk-primary-soft); color: var(--upk-primary-text);
    border-color: color-mix(in oklab, var(--upk-primary) 22%, transparent);
}
.up-back:hover { background-color: var(--upk-primary); color: var(--upk-primary-fg); border-color: var(--upk-primary); }

/* ─── 13. SHAPE MODIFIER — last in the file so it beats every component radius ── */
.upk-pill { border-radius: var(--upk-radius-pill); }

} /* @layer components */

/* ─── 14. LOCK LAYER — the ONLY kit rules a plain utility cannot override ────
   `upk-lock` is declared here, after style.css's `utilities`, so it sits ABOVE
   utilities (a `!`-important utility still wins: `!p-0`). Kept deliberately
   small:
   - every table cell in the app has ONE density and every <th> (and the
     .up-panel-head fold header) the ONE header colour (-UPMEDIK_PREREQ §10),
     whatever px-/py-/bg- utility the cell markup carries (UpTable and ~35
     views write `px-3 py-2` on cells that have always rendered at .5rem).
     Change the density HERE, never per cell;
   - two internals of the shared searchable dropdown, whose markup string
     (searchable_select.js) toggles utilities the kit must outrank: its label
     keeps the field text colour, its "Cari…" box has no border. */
@layer upk-lock {
    th, .up-panel-head { background-color: var(--upk-band-tint); }
    .upk-table thead th { padding: 0 .5rem; background: var(--upk-head-tint); }
    .upk-table tbody td { padding: .5rem; }
    .upk-table tfoot td, .upk-table tfoot th { padding: .5rem; }
    .upk-table-compact thead th { padding: 0 .375rem; }
    .upk-table-compact tbody td { padding: .25rem .375rem; }
    .ss-trigger .ss-label { color: var(--foreground); }
    .ss-search, .ss-search:focus, .ss-search:focus-visible { border: 0; box-shadow: none; outline: none; }
}
