/* OkePOS V2 — Web Admin.
 *
 * V1 exact presentation baseline. Values are measured from the reachable V1 Cloud Admin
 * (`okepos-cloud/resources/views/layouts/admin.blade.php` + Valex computed styles) and
 * reimplemented as OkePOS-owned CSS. No Valex code, font or icon asset is shipped.
 *
 * Dark is the V1 default; the theme is a server-side session decision, never localStorage.
 */

:root {
    color-scheme: dark;

    --okx-font: "Roboto", "Segoe UI", system-ui, -apple-system, sans-serif;
    --okx-sidebar-width: 240px;
    /* V1's `.app-header` measures 64px on the live app in BOTH themes
       (dashboard and a report screen), and its dark background is #19202f, not the page
       canvas. The 54px / #0c1424 pair came from reading Blade markup, which is what the
       2026-10-30 live-parity pass exists to correct. */
    --okx-header-height: 64px;

    --okx-bg: #0c1424;
    --okx-surface: #111c31;
    --okx-surface-elevated: #16233c;
    --okx-surface-muted: #1d2d4a;
    --okx-border: rgba(125, 152, 194, 0.18);
    --okx-border-strong: rgba(125, 152, 194, 0.3);
    --okx-text: #f3f7ff;
    --okx-text-soft: #afbdd7;
    --okx-text-faint: #8090af;
    --okx-primary: #2f7dff;
    --okx-primary-strong: #2563eb;
    --okx-primary-soft: rgba(47, 125, 255, 0.18);
    --okx-success: #2bc84b;
    --okx-success-soft: rgba(43, 200, 75, 0.18);
    --okx-success-text: #2bc84b;
    --okx-danger: #ff5f7a;
    --okx-danger-soft: rgba(255, 95, 122, 0.16);
    --okx-danger-text: #ff5f7a;
    --okx-warning: #ffb648;
    --okx-warning-soft: rgba(255, 182, 72, 0.16);
    --okx-warning-text: #ffb648;
    /* V1's KDS capability badges are `badge bg-info`, which the theme resolves to
       `rgb(var(--info-rgb))` = 0,185,255 (public/valex/assets/css/styles.css:18775
       and :73). `[data-theme-mode=dark]` overrides --light-rgb and --dark-rgb but
       not --info-rgb, so the same colour carries across both themes. */
    --okx-info: #00b9ff;
    /* V1's `badge bg-secondary` fill is --secondary-rgb = 95,109,136
       (public/valex/assets/css/styles.css:71). Like --info-rgb it is NOT redefined
       under [data-theme-mode=dark] (:182-193), so one value carries both themes. */
    --okx-badge-secondary: #5f6d88;

    --okx-menu-bg: #19202f;
    --okx-menu-ink: rgba(255, 255, 255, 0.6);
    --okx-menu-category: rgba(168, 184, 211, 0.9);
    --okx-header-bg: #19202f;
    --okx-header-border: rgba(255, 255, 255, 0.1);
    --okx-header-ink: #f0f5f8;
    --okx-input-bg: #16233c;
    --okx-table-head-bg: #16233c;
    --okx-table-head-ink: #afbdd7;
    --okx-card-title: #ffffff;
    --okx-footer-bg: #111c31;
    --okx-shadow: 0 18px 40px rgba(3, 8, 18, 0.34);
    --okx-footer-shadow: 0 4px 16px rgba(255, 255, 255, 0.05);

    --okx-radius-card: 6px;
    --okx-radius-control: 3px;
    --okx-radius-pill: 20px;
}

html[data-theme-mode="light"] {
    color-scheme: light;

    --okx-bg: #ecf0fa;
    --okx-surface: #ffffff;
    --okx-surface-elevated: #f8fafd;
    --okx-surface-muted: #ecf0fa;
    --okx-border: #eae8f1;
    --okx-border-strong: #d0d7e8;
    --okx-text: #031b4e;
    --okx-text-soft: #5b6e88;
    --okx-text-faint: #7987a1;
    --okx-primary: #2f7dff;
    --okx-primary-strong: #2563eb;
    --okx-primary-soft: rgba(47, 125, 255, 0.12);
    --okx-success: #2bc84b;
    --okx-success-soft: rgba(43, 200, 75, 0.12);
    --okx-success-text: #1a7f37;
    --okx-danger: #ff5f7a;
    --okx-danger-soft: rgba(255, 95, 122, 0.12);
    --okx-danger-text: #b42318;
    --okx-warning: #ffb648;
    --okx-warning-soft: rgba(255, 182, 72, 0.16);
    --okx-warning-text: #8a5a00;
    --okx-info: #00b9ff;

    --okx-menu-bg: #ffffff;
    --okx-menu-ink: #5b6e88;
    --okx-menu-category: #2c364c;
    --okx-header-bg: #ffffff;
    --okx-header-border: #f3f3f3;
    --okx-header-ink: #031b4e;
    --okx-input-bg: #ffffff;
    --okx-table-head-bg: transparent;
    --okx-table-head-ink: #031b4e;
    --okx-card-title: #242f48;
    --okx-footer-bg: transparent;
    --okx-shadow: -8px 12px 18px #dadee8;
    --okx-footer-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
}

[hidden] {
    display: none !important;
}

body.admin-body {
    min-height: 100vh;
    background: var(--okx-bg);
    color: var(--okx-text);
    font: 400 14px/21px var(--okx-font);
}

a {
    color: var(--okx-primary);
}

.okx-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.okx-icon {
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.okx-icon-sm {
    width: 16px;
    height: 16px;
}

.okx-icon-xs {
    width: 12px;
    height: 12px;
}

.admin-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ---------------------------------------------------------------- shell --- */

.page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.app-sidebar {
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: 103;
    display: flex;
    flex-direction: column;
    width: var(--okx-sidebar-width);
    height: 100vh;
    background: var(--okx-menu-bg);
    color: var(--okx-menu-ink);
    border-inline-end: 1px solid var(--okx-border);
}

.main-sidebar-header {
    flex: 0 0 64px;
    height: 64px;
    padding: 15px 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--okx-menu-bg);
    border-bottom: 1px solid var(--okx-border);
}

.main-sidebar-header .header-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}

.main-sidebar-header img {
    display: block;
    height: 32px;
    width: auto;
}

.main-sidebar {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 8px 0 24px;
    scrollbar-width: thin;
}

.main-menu-container {
    width: 100%;
}

.main-menu,
.slide-menu {
    list-style: none;
    margin: 0;
    padding: 0;
}

.app-header {
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    inset-inline-end: 0;
    z-index: 102;
    height: var(--okx-header-height);
    /* V1's bar spans the full viewport and reserves the sidebar width with padding
       (measured `1710x64 @0,0` with `padding-left: 240px`), so the band reads as one
       continuous surface instead of starting after the sidebar. */
    padding-inline-start: var(--okx-sidebar-width);
    background: var(--okx-header-bg);
    border-bottom: 1px solid var(--okx-header-border);
}

.main-header-container {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 100%;
    padding: 0 12px;
}

.header-content-left {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.header-content-right {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-inline-start: auto;
}

.main-content {
    flex: 1 0 auto;
    margin-inline-start: var(--okx-sidebar-width);
    margin-block-start: var(--okx-header-height);
    padding: 0 8px;
}

.app-content-inner {
    padding: 0 12px 34px;
}

.footer {
    padding: 16px 0 16px var(--okx-sidebar-width);
    background: var(--okx-footer-bg);
    border-top: 1px solid var(--okx-border);
    box-shadow: var(--okx-footer-shadow);
    color: var(--okx-text-soft);
    font-size: 14px;
    text-align: center;
}

.admin-sidebar-overlay {
    position: fixed;
    inset: 0;
    z-index: 101;
    background: rgba(3, 8, 18, 0.5);
}

/* --------------------------------------------------------------- sidebar --- */

.side-menu__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 10px 20px 10px 22px;
    color: var(--okx-menu-ink);
    font-size: 13px;
    line-height: 19.5px;
    font-weight: 400;
    text-decoration: none;
}

.side-menu__item:hover,
.side-menu__item:focus-visible {
    color: var(--okx-primary);
    outline: none;
}

.side-menu__icon {
    width: 22px;
    height: 22px;
    color: inherit;
    border-radius: 4.8px;
}

.side-menu__label {
    flex: 1 1 auto;
    font-size: 13.6px;
    line-height: 16.32px;
}

.side-menu__angle {
    width: 14px;
    height: 14px;
    color: inherit;
    transition: transform 0.15s ease;
}

.slide.has-sub.open > .side-menu__item,
.slide.has-sub.open > .side-menu__item .side-menu__label,
.slide.has-sub.open > .side-menu__item .side-menu__icon,
.slide.active > .side-menu__item {
    color: var(--okx-primary);
}

.slide.has-sub.open > .side-menu__item .side-menu__angle {
    transform: rotate(90deg);
}

.slide.active > .side-menu__item::after {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 2px;
    width: 3px;
    height: 40px;
    background: var(--okx-primary);
}

.slide-menu .side-menu__item::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 50%;
    width: 5px;
    height: 5px;
    border-top: 1.4px solid currentColor;
    border-right: 1.4px solid currentColor;
    transform: translateY(-50%) rotate(45deg);
    opacity: 0.75;
}

.slide-menu .slide.active > .side-menu__item::after {
    display: none;
}

.slide-menu.child1 > .slide > .side-menu__item {
    min-height: 36px;
    padding: 8px 20px 8px 28px;
    font-size: 13px;
}

.slide-menu.child1 > .slide > .side-menu__item .side-menu__label {
    font-size: 13px;
    line-height: 19.5px;
}

.slide-menu.child2 > .slide > .side-menu__item {
    min-height: 32px;
    padding: 7px 20px 7px 19px;
    font-size: 12px;
}

.slide-menu.child2 > .slide > .side-menu__item .side-menu__label {
    font-size: 12px;
    line-height: 18px;
}

.slide-menu.child1 > .slide > .side-menu__item .side-menu__angle,
.slide-menu.child2 > .slide > .side-menu__item .side-menu__angle {
    width: 12px;
    height: 12px;
}

.slide__category {
    position: relative;
    height: 15px;
    margin: 25px 0 12px;
    padding: 0 20px 0 25px;
    color: var(--okx-menu-category);
    font-size: 11.2px;
    line-height: 16.8px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    white-space: nowrap;
}

.slide__category .category-name {
    display: flex;
    align-items: center;
    gap: 8px;
}

.slide__category--report .category-name::before,
.slide__category--report .category-name::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--okx-border);
}

/* ---------------------------------------------------------------- header --- */

.header-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 52px;
    padding: 12.8px 10.4px;
    border: 0;
    background: none;
    color: var(--okx-header-ink);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.header-link > .okx-icon {
    width: 20px;
    height: 20px;
    color: var(--okx-text-soft);
}

.header-link:hover > .okx-icon,
.header-link:focus-visible > .okx-icon {
    color: var(--okx-primary);
}

.header-link:focus-visible {
    outline: 2px solid var(--okx-primary);
    outline-offset: -4px;
}

.sidemenu-toggle {
    flex: 0 0 auto;
}

.main-header-center {
    position: relative;
    width: 350px;
    max-width: 32vw;
    margin-inline-start: 4px;
}

.main-header-center input {
    width: 100%;
    height: 40px;
    padding: 0 44px 0 18px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-pill);
    background: var(--okx-surface-elevated);
    color: var(--okx-text);
    font: 400 14px/21px var(--okx-font);
}

.main-header-center input::placeholder {
    color: var(--okx-text-faint);
}

.main-header-center input:focus {
    outline: none;
    border-color: var(--okx-primary);
    box-shadow: 0 0 0 0.2rem var(--okx-primary-soft);
}

.main-header-center-icon {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: 14px;
    transform: translateY(-50%);
    display: flex;
    color: var(--okx-text-soft);
    pointer-events: none;
}

.main-header-center-icon .okx-icon {
    width: 18px;
    height: 18px;
}

.admin-menu-results {
    position: absolute;
    inset-block-start: calc(100% + 6px);
    inset-inline: 0;
    z-index: 1100;
    max-height: 300px;
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--okx-border);
    border-radius: 8px;
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
}

.admin-menu-result {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    color: var(--okx-text);
    font-size: 13px;
    text-decoration: none;
}

.admin-menu-result:hover,
.admin-menu-result:focus-visible {
    background: var(--okx-surface-muted);
    color: var(--okx-primary);
    outline: none;
}

.admin-menu-result span {
    color: var(--okx-text-faint);
    font-size: 11.5px;
}

.admin-outlet-switcher,
.admin-profile {
    position: relative;
}

.admin-outlet-switcher > summary,
.admin-profile > summary {
    list-style: none;
    cursor: pointer;
}

.admin-outlet-switcher > summary::-webkit-details-marker,
.admin-profile > summary::-webkit-details-marker {
    display: none;
}

.admin-outlet-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border: 1px solid transparent;
    border-radius: var(--okx-radius-pill);
    background: rgba(255, 255, 255, 0.06);
    color: var(--okx-header-ink);
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
}

html[data-theme-mode="light"] .admin-outlet-pill {
    background: rgba(3, 27, 78, 0.04);
}

.admin-outlet-pill .okx-icon {
    color: var(--okx-primary);
}

.admin-outlet-pill .okx-icon-xs {
    color: var(--okx-text-soft);
    transform: rotate(90deg);
}

.admin-outlet-pill.is-static {
    cursor: default;
}

.admin-dropdown {
    position: absolute;
    inset-block-start: calc(100% + 6px);
    inset-inline-end: 0;
    z-index: 1200;
    min-width: 220px;
    padding: 6px;
    border: 1px solid var(--okx-border);
    border-radius: 12px;
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
}

.admin-outlet-dropdown {
    inset-inline-start: 0;
    inset-inline-end: auto;
}

.admin-dropdown form {
    margin: 0;
}

.admin-dropdown-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 10px 10px;
    border-bottom: 1px solid var(--okx-border);
}

.admin-dropdown-head strong {
    color: var(--okx-text);
    font-size: 13px;
}

.admin-dropdown-head span {
    color: var(--okx-text-faint);
    font-size: 11.5px;
}

.admin-dropdown-lang {
    display: flex;
    gap: 4px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--okx-border);
}

.admin-dropdown-lang a {
    padding: 3px 8px;
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--okx-text-soft);
    font-size: 11.5px;
    font-weight: 700;
    text-decoration: none;
}

.admin-dropdown-lang a[aria-current="true"] {
    border-color: var(--okx-primary);
    color: var(--okx-primary);
}

.admin-dropdown-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--okx-text);
    font: 400 13px/19.5px var(--okx-font);
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}

.admin-dropdown-item:hover,
.admin-dropdown-item:focus-visible {
    background: var(--okx-surface-muted);
    color: var(--okx-primary);
    outline: none;
}

.admin-dropdown-item.is-active {
    color: var(--okx-primary);
}

.admin-profile-summary {
    padding-inline: 8px;
}

.admin-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--okx-primary-soft);
    color: var(--okx-primary);
    font-size: 10.4px;
    line-height: 28px;
    font-weight: 500;
}

.admin-profile-name {
    max-width: 140px;
    overflow: hidden;
    color: var(--okx-header-ink);
    font-size: 12px;
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admin-profile-summary .okx-icon-xs {
    transform: rotate(90deg);
}

.admin-profile-dropdown {
    min-width: 240px;
}

/* ----------------------------------------------------------------- pages --- */

.admin-page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin: 24px 0;
}

.admin-page-head h1 {
    margin: 0;
    color: var(--okx-text);
    font-size: 20px;
    line-height: 24px;
    font-weight: 600;
    letter-spacing: 0;
}

.admin-page-head p {
    margin: 3px 0 0;
    color: var(--okx-text-soft);
    font-size: 12px;
    line-height: 18px;
}

/* V1 list pages have no visible page title; keep the heading for screen readers. */
body:not([data-route="admin.dashboard"]) .admin-page-head > div:first-child {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

body:not([data-route="admin.dashboard"]) .admin-page-head {
    justify-content: flex-end;
}

body[data-route="admin.dashboard"] .admin-page-head {
    margin-top: 24px;
}

.admin-card {
    margin-bottom: 16px;
    padding: 20px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
}

.admin-card h2 {
    margin: 0 0 12px;
    color: var(--okx-card-title);
    font-size: 14px;
    line-height: 21px;
    font-weight: 700;
}

.admin-card:has(> .admin-table-wrap) {
    padding: 0;
    overflow: hidden;
}

.admin-card:has(> .admin-table-wrap) > h2 {
    padding: 16px 20px 0;
}

.admin-card:has(> .admin-table-wrap) > .admin-actions {
    padding: 0 20px 20px;
}

.admin-grid-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

/* V1 categories: 4/12 form card + 8/12 table card. */
.admin-grid-catalog {
    display: grid;
    grid-template-columns: minmax(280px, 1fr) minmax(0, 2fr);
    gap: 16px;
    align-items: start;
}

.admin-card--table {
    padding: 0;
    overflow: hidden;
}

.admin-card--table > h2 {
    padding: 16px 20px 0;
}

.admin-card-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px 0;
}

.admin-card-header-row h2 {
    margin: 0;
    padding: 0;
}

.admin-card-header-row .admin-field select {
    min-width: 220px;
}

.admin-card-header-row .admin-field input {
    width: 220px;
}

.admin-inline-control {
    display: flex;
    align-items: center;
    gap: 8px;
}

.admin-inline-control .admin-segmented {
    flex: 0 0 auto;
}

.admin-inline-control > input {
    flex: 1 1 auto;
    min-width: 0;
}

/* V1's per-outlet accordion on Master Shift Kerja
   (resources/views/admin/master/shifts.blade.php:104-151) is Bootstrap's
   `.accordion-item / .accordion-button / .accordion-body`. Measured from the theme:
   button padding 0.75rem 1rem, font-size 0.85rem, weight 500; body padding
   0.75rem 1rem, font-size 0.8125rem, colour --text-muted; item background
   --custom-white with a 1px --default-border edge and a 0.35rem outer corner; the
   open header and the chevron disc take --default-background, which is #f8fafd in
   light and rgba(255,255,255,0.05) in dark — the value V2 already owns as
   --okx-surface-elevated (public/valex/assets/scss/bootstrap/_accordion.scss:3-60,
   public/valex/assets/css/styles.css:97-114 and :182-193). Reimplemented here with
   OkePOS tokens and the OkePOS chevron; no vendor rule or glyph is shipped. */
.admin-accordion {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-accordion-item {
    overflow: hidden;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    background: var(--okx-surface);
}

.admin-accordion-header {
    margin: 0;
}

/* V1's header content is `d-flex align-items-center gap-2 flex-wrap` around a
   `fw-semibold` outlet name and its badges (shifts.blade.php:112-124). */
.admin-accordion-labels {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.admin-accordion-title {
    font-weight: 600;
}

.admin-accordion-button {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 12px 16px;
    border: 0;
    background: var(--okx-surface);
    color: var(--okx-text);
    font: 500 13.6px/20.4px var(--okx-font);
    text-align: start;
    cursor: pointer;
}

.admin-accordion-button[aria-expanded="true"] {
    background: var(--okx-surface-elevated);
}

.admin-accordion-button:focus-visible {
    outline: 2px solid var(--okx-primary);
    outline-offset: -2px;
}

/* V1's chevron sits in its own tinted disc and points the other way when open. */
.admin-accordion-caret {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50px;
    background: var(--okx-surface-elevated);
    color: var(--okx-text);
    transform: rotate(90deg);
    transition: transform 0.2s ease;
}

.admin-accordion-button[aria-expanded="true"] .admin-accordion-caret {
    transform: rotate(-90deg);
}

.admin-accordion-body {
    padding: 12px 16px;
    border-block-start: 1px solid var(--okx-border);
    color: var(--okx-text-soft);
    font-size: 13px;
}

.admin-accordion-body .admin-card-header-row {
    padding: 0;
}

.admin-accordion-body .admin-table-wrap {
    margin-block: 8px;
}

/* V1 modal workflow (category edit and later catalog dialogs). */
.admin-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 16px;
}

.admin-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(3, 8, 18, 0.55);
}

.admin-modal-dialog {
    position: relative;
    z-index: 1;
    width: min(520px, 100%);
    max-height: calc(100vh - 80px);
    overflow: auto;
    background: var(--okx-surface);
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    box-shadow: var(--okx-shadow);
}

.admin-modal-dialog-lg {
    width: min(820px, 100%);
}

.admin-action-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 16px;
}

.admin-action-bar .admin-actions {
    margin-top: 0;
}

.admin-breadcrumb {
    color: var(--okx-text-soft);
    font-size: 13px;
}

.admin-segmented {
    display: inline-flex;
    overflow: hidden;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
}

.admin-segmented label {
    padding: 6px 11px;
    background: var(--okx-surface-elevated);
    color: var(--okx-text-soft);
    font-size: 13.6px;
    line-height: 20.4px;
    cursor: pointer;
}

.admin-segmented label.is-active {
    background: var(--okx-primary);
    color: #ffffff;
}

.admin-segmented input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.admin-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--okx-text);
    font-size: 14px;
    line-height: 21px;
    cursor: pointer;
}

.admin-switch input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.admin-switch-track {
    position: relative;
    display: inline-block;
    width: 36px;
    height: 20px;
    border: 1px solid var(--okx-border);
    border-radius: 999px;
    background: var(--okx-surface-muted);
}

.admin-switch-track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #ffffff;
    transition: transform 0.15s ease;
}

.admin-switch input:checked + .admin-switch-track {
    border-color: var(--okx-primary);
    background: var(--okx-primary);
}

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

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

.admin-product-preview {
    display: block;
    max-width: 180px;
    max-height: 140px;
    margin: 8px 0 12px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    object-fit: cover;
}

.admin-option-row {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) 140px 32px;
    gap: 8px;
    align-items: center;
    padding: 8px;
    margin-bottom: 8px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-input-bg);
}

.admin-option-row input {
    width: 100%;
    min-height: 35px;
    padding: 6px 12px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-input-bg);
    color: var(--okx-text);
    font: 400 14px/21px var(--okx-font);
}

.admin-drag-handle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 4px;
    border: 0;
    background: transparent;
    color: var(--okx-text-faint);
    cursor: grab;
}

.admin-check-list {
    display: grid;
    gap: 6px;
    max-height: 200px;
    overflow: auto;
    padding: 10px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
}

.admin-table .actions .admin-link.is-danger {
    background: var(--okx-danger-soft);
    color: var(--okx-danger-text);
}

.admin-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--okx-border);
}

.admin-modal-header h3 {
    margin: 0;
    color: var(--okx-card-title);
    font-size: 16px;
    font-weight: 700;
}

.admin-modal-close {
    padding: 0 4px;
    border: 0;
    background: transparent;
    color: var(--okx-text-soft);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
}

.admin-modal-body {
    padding: 20px;
}

.admin-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 14px 20px;
    border-top: 1px solid var(--okx-border);
}

.admin-stat-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
}

.admin-stat {
    padding: 20px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
}

.admin-stat .label {
    color: var(--okx-text-soft);
    font-size: 14px;
    line-height: 21px;
    font-weight: 400;
}

.admin-stat .value {
    margin-top: 2px;
    color: var(--okx-text);
    font-size: 20px;
    line-height: 24px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- tables --- */

.admin-table-wrap {
    overflow-x: auto;
    border-radius: 5px;
}

.admin-table {
    width: 100%;
    min-width: 760px;
    border-collapse: collapse;
    color: var(--okx-text);
    font-size: 14px;
    line-height: 20.5px;
}

.admin-table th:first-child,
.admin-table td:first-child {
    min-width: 180px;
}

.admin-table th {
    padding: 12px;
    border-bottom: 1px solid var(--okx-border);
    background: var(--okx-table-head-bg);
    color: var(--okx-table-head-ink);
    font-size: 12px;
    line-height: 17.5px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-align: start;
    text-transform: uppercase;
    white-space: nowrap;
}

.admin-table td {
    padding: 12px;
    border-bottom: 1px solid var(--okx-border);
    color: var(--okx-text);
    font-size: 14px;
    line-height: 20.5px;
    vertical-align: middle;
}

.admin-table tbody tr:last-child td {
    border-bottom: 0;
}

.admin-table tbody tr:hover td {
    background: var(--okx-surface-elevated);
}

.admin-table .num {
    text-align: end;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.admin-table .actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.admin-table .actions .admin-link,
.admin-table .actions .admin-btn {
    display: inline-flex;
    align-items: center;
    padding: 3px 8px;
    border: 1px solid transparent;
    border-radius: var(--okx-radius-control);
    background: var(--okx-primary-soft);
    color: var(--okx-primary);
    font-family: inherit;
    font-size: 12px;
    line-height: 18px;
    font-weight: 400;
    text-decoration: none;
    cursor: pointer;
}

.admin-table .actions .admin-btn {
    border-color: var(--okx-border);
    background: var(--okx-surface-elevated);
    color: var(--okx-text-soft);
}

.admin-table .actions .admin-link:hover {
    text-decoration: none;
    filter: brightness(1.08);
}

.admin-table input,
.admin-table select {
    width: 100%;
    min-height: 35px;
    padding: 6px 12px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-input-bg);
    color: var(--okx-text);
    font: 400 14px/21px var(--okx-font);
}

.admin-inline-form {
    display: inline;
    margin: 0;
}

/* ----------------------------------------------------------------- forms --- */

.admin-empty {
    margin: 0;
    padding: 16px;
    color: var(--okx-text-faint);
    font-size: 14px;
    line-height: 21px;
    text-align: center;
}

/* V1's report filter row is `form.row g-3 align-items-end`. Measured on two screens of the running
   app on 2026-10-30 (`laporan-penjualan-varian` and `laporan-penjualan-varian-per-shift`): the row
   is a 12-column grid whose 16px rhythm comes from the row gap. V1 nests that row inside a card, so
   the measured arithmetic is: card 1430 wide at x=260, row 1404 at x=273 (13px of card padding),
   columns carrying 8px of gutter, controls starting at x=281 and 16px narrower than their column.
   V2's element is the card and the row at once, so it takes the 13px inline padding and NO negative
   margin — putting Bootstrap's -8px on the merged element pulls the surface 8px past V1's card edge.

   A field only takes a proportion when the page states V1's column, because the middle spans really
   do differ per screen (4 + 3 + 3 + 2 on one, 4 + 2 + 2 + 1 + 1 + 2 on the other). Unmarked fields
   keep their previous sizing rather than inheriting a guessed one. */
.admin-filter {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 0;
    row-gap: 16px;
    margin-bottom: 16px;
    padding: 20px 13px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
}

.admin-filter .admin-field {
    flex: 0 1 auto;
    min-width: 160px;
    padding-inline: 8px;
    margin: 0;
}

/* V1's `col-xl-N`: the field owns N twelfths of the row. */
.admin-filter .admin-field.v1-span-1 { --v1-span: 1; }
.admin-filter .admin-field.v1-span-2 { --v1-span: 2; }
.admin-filter .admin-field.v1-span-3 { --v1-span: 3; }
.admin-filter .admin-field.v1-span-4 { --v1-span: 4; }
.admin-filter .admin-field.v1-span-5 { --v1-span: 5; }
.admin-filter .admin-field.v1-span-6 { --v1-span: 6; }
.admin-filter .admin-field.v1-span-8 { --v1-span: 8; }
.admin-filter .admin-field.v1-span-12 { --v1-span: 12; }

.admin-filter .admin-field[class*="v1-span-"] {
    flex: 0 0 auto;
    min-width: 0;
    width: calc(var(--v1-span) / 12 * 100%);
}

.admin-filter .admin-field.grow {
    flex: 1 1 240px;
}

/* V1 renders Terapkan as `col-xl-2 d-grid` around a `btn btn-success`: measured 218x34 at
   rgb(43,200,75) with rgb(247,255,251) text on BOTH screens, stretched to fill its two-column slot.
   V2 used the shell primary and shrink-to-fit text width, which made it blue and 80px wide. */
/*
 * V1 does NOT colour every filter submit the same way, and the previous version of this rule
 * asserted that it did. Measured on the running app: a report filter's `Terapkan` is
 * `col-xl-2 d-grid` around `btn btn-success` (218x34, rgb(43,200,75)), while the employee and
 * master-data filters are `btn btn-primary` (Data Karyawan 82x35, rgb(47,125,255)) and Jabatan
 * Karyawan is blue too, and Arus Kas does not even say `Terapkan` — its button is
 * `btn btn-primary` labelled `Filter` (cash-transactions/index.blade.php:260).
 *
 * So the wide green bar is now opt-in per screen through `.admin-filter.is-report`, which only the
 * report pages plus Riwayat Penjualan (green in V1) carry. Everything else gets V1's blue default
 * at its natural width instead of inheriting a report's shape.
 */
.admin-filter > .admin-btn[type="submit"] {
    flex: 0 0 auto;
    margin-inline: 8px;
    border-color: rgb(47, 125, 255);
    background: rgb(47, 125, 255);
    color: rgb(248, 251, 255);
}

.admin-filter > .admin-btn[type="submit"]:hover {
    border-color: rgb(37, 99, 213);
    background: rgb(37, 99, 213);
    color: #ffffff;
}

.admin-filter.is-report > .admin-btn[type="submit"] {
    flex: 0 0 calc(2 / 12 * 100% - 16px);
    border-color: #2bc84b;
    background: #2bc84b;
    color: rgb(247, 255, 251);
}

.admin-filter.is-report > .admin-btn[type="submit"]:hover {
    border-color: #25a93f;
    background: #25a93f;
    color: #ffffff;
}

/* A few V1 report screens put `Terapkan` in a full-width `col-xl-12 d-grid` cell instead of the
   `col-xl-2` the majority uses. Measured 2026-11-01 across the 40 V1 report screens that render a
   green apply button: 23 use `col-xl-2 col-lg-6`, 9 use `col-xl-1 col-lg-6`, 5 use `col-xl-12`, and
   3 differ only in their `col-lg`. The rule above therefore matches V1 exactly on the 2/12 group and
   not on the others; this modifier opts a screen back into V1's full-width bar.
   `category-by-shift.blade.php` is one of the five, so `CategoryByShiftReportPage` carries it.
   The three ALREADY-migrated screens in that group (`cashier-item-sales`,
   `category-sales-by-payment`, `category-sales-by-sale-type`) and the nine 1-column screens do not
   carry it yet: retargeting shipped layout without any browser available to measure it is a decision
   for the owner, recorded rather than assumed. */
.admin-filter.is-report.is-report-wide > .admin-btn[type="submit"] {
    flex: 0 0 calc(12 / 12 * 100% - 16px);
}

/* The other side of the same measurement: NINE V1 report screens put `Terapkan` in
   `col-xl-1 col-lg-6 d-grid`, which is narrower than the 2/12 the `.is-report` default encodes. A
   screen newly migrated from that group gets V1's own width instead of the majority's, because for a
   screen that has never shipped there is no "retarget shipped layout" risk to avoid — the only
   honest target is V1's blade. Two of the nine have been migrated since: `outlet-sales-by-shift
   (`:57`) and `category-all-items-sales` (`:51`), so `OutletSalesByShiftReportPage` and
   `CategoryAllItemsSalesReportPage` carry `is-report-tight`. The seven already-shipped screens in
   that group remain unchanged for the owner-decision reason recorded above. */
.admin-filter.is-report.is-report-tight > .admin-btn[type="submit"] {
    flex: 0 0 calc(1 / 12 * 100% - 16px);
}

.admin-field {
    display: block;
    margin-bottom: 16px;
}

/* V1 hides the auto-settlement field with Bootstrap's `d-none` on its wrapper and reveals it from
   the ojek switch (`sale-types/index.blade.php:176-182 syncOjek()`). The field stays IN the DOM and
   keeps its value; it is only visually removed. `display: none` reproduces that exactly, where
   removing the node would change what the form posts. */
.admin-field.is-hidden {
    display: none;
}

.admin-field > span {
    display: block;
    margin-bottom: 8px;
    color: var(--okx-text);
    font-size: 14px;
    line-height: 21px;
    font-weight: 400;
}

.admin-field input,
.admin-field select,
.admin-field textarea {
    width: 100%;
    min-height: 35px;
    padding: 6px 12px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-input-bg);
    color: var(--okx-text);
    font: 400 14px/21px var(--okx-font);
}

.admin-field input:focus,
.admin-field select:focus,
.admin-field textarea:focus,
.admin-table input:focus,
.admin-table select:focus {
    outline: none;
    border-color: var(--okx-primary);
    box-shadow: 0 0 0 0.2rem var(--okx-primary-soft);
}

.admin-field textarea {
    min-height: 84px;
    resize: vertical;
}

.admin-field .help,
.admin-help {
    display: block;
    margin-top: 4px;
    color: var(--okx-text-faint);
    font-size: 12px;
    line-height: 18px;
}

.admin-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--okx-text);
    font-size: 14px;
    line-height: 21px;
    font-weight: 400;
}

.admin-check input {
    width: 16px;
    height: 16px;
    accent-color: var(--okx-primary);
}

.admin-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 16px;
}

.admin-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.admin-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 10px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-surface-elevated);
    color: var(--okx-text);
    font-size: 13px;
}

.admin-chip input {
    accent-color: var(--okx-primary);
}

.admin-template {
    display: none;
}

/* --------------------------------------------------------------- controls --- */

.admin-btn,
.admin-primary,
.admin-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: var(--okx-radius-control);
    font: 400 13.6px/20.4px var(--okx-font);
    text-decoration: none;
    cursor: pointer;
}

.admin-btn {
    border: 1px solid var(--okx-border-strong);
    background: var(--okx-surface-elevated);
    color: var(--okx-text-soft);
}

.admin-btn:hover {
    background: var(--okx-surface-muted);
    color: var(--okx-text);
}

.admin-primary {
    border: 1px solid var(--okx-primary);
    background: var(--okx-primary);
    color: #f8fbff;
}

.admin-primary:hover {
    background: var(--okx-primary-strong);
    border-color: var(--okx-primary-strong);
    color: #ffffff;
}

/* V1 disables this screen's action buttons instead of hiding them when no outlet
   is selected (employee-assignments/index.blade.php:23-28). The disabled look V1
   actually renders is Bootstrap's `.btn:disabled` in the stylesheet its admin
   layout loads: `pointer-events: none` plus
   `--bs-btn-disabled-opacity: 0.65`
   (public/valex/assets/libs/bootstrap/css/bootstrap.min.css). */
.admin-btn:disabled,
.admin-primary:disabled,
.admin-danger:disabled {
    pointer-events: none;
    opacity: .65;
}

.admin-danger {
    border: 1px solid var(--okx-danger);
    background: var(--okx-danger);
    color: #ffffff;
}

.admin-danger:hover {
    filter: brightness(0.94);
}

.admin-link {
    color: var(--okx-primary);
    font-size: 13.6px;
    font-weight: 400;
    text-decoration: none;
}

.admin-link:hover {
    text-decoration: underline;
}

.admin-btn:focus-visible,
.admin-primary:focus-visible,
.admin-danger:focus-visible,
.admin-link:focus-visible,
.admin-field input:focus-visible,
.admin-field select:focus-visible,
.admin-field textarea:focus-visible,
.admin-chip input:focus-visible {
    outline: 2px solid var(--okx-primary);
    outline-offset: 2px;
}

.admin-badge {
    display: inline-block;
    padding: 4px 5px 3px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-surface-muted);
    color: var(--okx-text-soft);
    font-size: 10.5px;
    line-height: 1;
    font-weight: 500;
    white-space: nowrap;
}

.admin-badge.is-success {
    border-color: var(--okx-success);
    background: var(--okx-success);
    color: #f7fffb;
}

.admin-badge.is-danger {
    border-color: var(--okx-danger);
    background: var(--okx-danger);
    color: #ffffff;
}

.admin-badge.is-warning {
    border-color: var(--okx-warning);
    background: var(--okx-warning);
    color: #3a2a0a;
}

/* V1's `.badge` rule sets padding, size and radius but no colour
   (styles.css:2556-2562), so a `bg-info` badge keeps the table's own text colour
   instead of a fixed white. That is what V1 really renders on this screen, and it
   is reproduced here rather than "corrected": changing the ink of a V1 badge is a
   user-visible deviation and needs the owner's explicit call. */
.admin-badge.is-info {
    border-color: var(--okx-info);
    background: var(--okx-info);
    color: var(--okx-text);
}

/* Master Shift Kerja's filled badges. V1 marks 🔵 Metode Shift and 🏪 Khusus with
   `badge bg-primary` and the "N shift khusus / warisan global" counter with
   `badge bg-secondary` (master/shifts.blade.php:19-20, :117-120). The compiled
   theme gives `.badge` no colour of its own (styles.css:2556-2562 declares padding,
   font-size, weight and radius only), so its ink is the inherited
   --default-text-color, which V2 owns as --okx-text — the same treatment --okx-info
   already gets above. */
.admin-badge.is-primary {
    border-color: var(--okx-primary);
    background: var(--okx-primary);
    color: var(--okx-text);
}

.admin-badge.is-secondary {
    border-color: var(--okx-badge-secondary);
    background: var(--okx-badge-secondary);
    color: var(--okx-text);
}

/* V1's shift name cell stacks the midnight badge under the name with `mt-1`. */
.admin-badge-row {
    margin-block-start: 4px;
}

/* V1's form section headings — `h6.text-success.border-bottom.pb-1.fw-bold.mb-2`
   in resources/views/admin/employees/partials/form.blade.php:7, :58 and :80.
   Success-coloured bold text on a hairline rule, 4px under the text and 8px
   before the next field. */
.admin-form-section {
    margin: 12px 0 8px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--okx-border);
    color: var(--okx-success-text);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.4;
}

.admin-alert {
    margin-bottom: 16px;
    padding: 12px 16px;
    border: 1px solid transparent;
    border-radius: var(--okx-radius-card);
    font-size: 14px;
    line-height: 21px;
}

.admin-alert.is-success {
    border-color: var(--okx-success);
    background: var(--okx-success-soft);
    color: var(--okx-success-text);
}

.admin-alert.is-error {
    border-color: var(--okx-danger);
    background: var(--okx-danger-soft);
    color: var(--okx-danger-text);
}

.admin-alert ul {
    margin: 0;
    padding-inline-start: 18px;
}

.admin-readonly-banner {
    margin-bottom: 16px;
    padding: 12px 16px;
    border: 1px solid var(--okx-warning);
    border-radius: var(--okx-radius-card);
    background: var(--okx-warning-soft);
    color: var(--okx-warning-text);
    font-size: 14px;
    font-weight: 400;
    line-height: 21px;
}

/* ---------------------------------------------------------------- preview --- */

.admin-floor-wrap {
    overflow: auto;
    min-height: 360px;
    max-height: 70vh;
    padding: 10px;
    border: 1px solid var(--okx-border);
    border-radius: 14px;
    background: #0b1220;
}

.admin-floor {
    position: relative;
}

.admin-floor .sb-table {
    cursor: default;
}

.admin-floor-empty {
    padding: 60px 16px;
    color: #94a3b8;
    font-size: 13px;
    text-align: center;
}

/* ----------------------------------------------------------------- login --- */

body.admin-login-body {
    min-height: 100vh;
    background:
        radial-gradient(75rem 75rem at 10% 10%, #4f73ff55 0, transparent 60%),
        linear-gradient(140deg, #0f172a, #1f2a4d, #3d3cd6);
    /* V1's login body computes rgb(3, 27, 78); the ADMIN shell keeps #1f2937. */
    color: #031b4e;
    font: 400 14px/21px var(--okx-font);
}

.auth-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 22px;
}

.auth-shell {
    display: grid;
    grid-template-columns: 1.05fr 1fr;
    width: min(1120px, 100%);
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 22px;
    background: rgba(10, 20, 40, 0.26);
    box-shadow: 0 22px 60px rgba(4, 8, 25, 0.35);
    backdrop-filter: blur(12px);
}

/* V1 adds `.auth-brand-logo-only` on the login page: the brand panel keeps its centre and
   flattens the vertical padding to 0 (measured padding 0px 18px, logo box 494x148). */
.auth-brand-logo-only {
    padding: 0 18px;
}

.auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100%;
    padding: 18px;
}

.auth-logo {
    width: min(760px, 92%);
    max-height: 70vh;
    height: auto;
    object-fit: contain;
    filter: drop-shadow(0 12px 30px rgba(0, 0, 0, 0.28));
}

/* V1's login card. Every value below was read off the rendered page on 2026-10-30
   (pos.ookey.id/admin/login, demo account, read-only) and cross-checked against
   `okepos-cloud/resources/views/admin/auth/login.blade.php` 21-95. V2 may not vendor Valex's
   Bootstrap bundle (AGENTS §4.3), so the classes V1 uses are reproduced here with V1's MEASURED
   numbers: `row g-3` is 16px vertical rhythm with 8px column padding, the submit is 485x34 in
   #0162e8 at 13.6px/700, and the field labels take the body colour #031b4e rather than the
   heading's #1f2937. */

.auth-card {
    padding: 30px;
    background: #ffffff;
    color: #031b4e;
}

.auth-card h1 {
    margin: 0 0 8px;
    color: #1f2937;
    font-size: 1.7rem;
    line-height: 1.2;
    font-weight: 800;
}

.auth-card .subtitle {
    margin: 0 0 18px;
    color: #6b7280;
    font-size: 14px;
    line-height: 21px;
}

/* V1's `form.row g-3`. Bootstrap's row cancels its own column padding with a negative inline
   margin, so the ROW is 501px wide and starts 8px outside the card's content box, which is how the
   fields come back to exactly 485px at x=899 while the columns still carry 8px of padding and 16px
   of vertical rhythm. Without the negative margin every field lands 16px narrower than V1. */
.auth-card form.row {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    margin-inline: -8px;
    row-gap: 16px;
}

.auth-card .col-12 {
    grid-column: span 12;
    padding: 0 8px;
}

.auth-card .col-md-6 {
    grid-column: span 6;
    padding: 0 8px;
}

.auth-card .text-end {
    text-align: right;
}

.auth-card .d-grid {
    display: grid;
}

.auth-card .form-label {
    /* V1's `.form-label` is Bootstrap's inline-block, so its box is the text width (measured
       164x21) rather than a full-width block. Same left edge, same line; the box is what matches. */
    display: inline-block;
    margin: 0 0 8px;
    color: #031b4e;
    font-size: 14px;
    line-height: 21px;
    font-weight: 400;
}

.auth-card .form-control {
    width: 100%;
    min-height: 35px;
    padding: 6px 12px;
    border: 1px solid #dbe4f6;
    border-radius: 12px;
    background: #ffffff;
    color: #031b4e;
    font: 400 14px/21px var(--okx-font);
}

/* Measured on V1 while focused: border #6c5ffc with a 3.2px rgba(108, 95, 252, .18) ring.
   `0 0 0 .2rem` is exactly that. Reading this value needs the focus to settle — sampling
   computed style in the same tick as focus() reports the pre-transition value and looks like
   "no ring at all", which is not what V1 renders. */
.auth-card .form-control:focus {
    outline: none;
    border-color: #6c5ffc;
    box-shadow: 0 0 0 0.2rem rgba(108, 95, 252, 0.18);
}

.auth-card .form-control.is-invalid {
    border-color: #dc3545;
    box-shadow: none;
}

/* V1's password toggle is a real `.input-group`: the input loses width (446px against the
   card's 485px) and the 40x35 anchor carries the right-hand corners with a -1px overlap. */
.auth-card .input-group {
    display: flex;
    align-items: stretch;
}

.auth-card .input-group > .form-control {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.auth-card .input-group > .input-group-text {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    margin-left: -1px;
    padding: 6px 12px;
    border: 1px solid #dbe4f6;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-top-right-radius: 12px;
    border-bottom-right-radius: 12px;
    background: #f9fbff;
    color: #031b4e;
    text-decoration: none;
}

/* V1's remember switch: 28x14 track with the label after it. */
.auth-card .form-check {
    display: flex;
    align-items: center;
    min-height: 24px;
}

.auth-card .form-switch {
    padding-left: 36px;
}

.auth-card .form-check-input {
    float: left;
    width: 28px;
    height: 14px;
    margin-top: 0;
    margin-left: -36px;
    appearance: none;
    border: 1px solid #dbe4f6;
    border-radius: 999px;
    background: #eef2fb;
    cursor: pointer;
}

.auth-card .form-check-input:checked {
    border-color: #0162e8;
    background: #0162e8;
}

.auth-card .form-check-label {
    margin-left: 8px;
    color: #031b4e;
    font-size: 14px;
    line-height: 21px;
    cursor: pointer;
}

.auth-card .input-group-text svg,
.auth-card .input-group-text .okx-icon {
    width: 16px;
    height: 16px;
}

/* V1's submit: 485x34, #0162e8 fill and border, 12px radius, 13.6px/20.4px at weight 700.
   Note this is NOT the file value: `valex/okepos-auth.css` declares `--auth-primary: #6c5ffc`
   for `.btn-primary`, but the rendered login button computes rgb(1, 98, 232) because Valex's
   bundle wins the cascade for this page. The render is the contract, so the measured value is
   what V2 reproduces, and it differs from the admin shell's #2f7dff for the same reason. */
.auth-card .btn-primary {
    width: 100%;
    padding: 6px 12px;
    border: 1px solid #0162e8;
    border-radius: 12px;
    background: #0162e8;
    color: #ffffff;
    font: 700 13.6px/20.4px var(--okx-font);
    cursor: pointer;
}

.auth-card .btn-primary:focus-visible {
    outline: 2px solid #0162e8;
    outline-offset: 2px;
}

.auth-card .alert {
    margin: 0 0 16px;
    padding: 10px 13.6px;
    border: 1px solid transparent;
    border-radius: 4.8px;
    font-size: 14px;
    line-height: 21px;
}

.auth-card .alert-success {
    border-color: rgba(34, 192, 60, 0.1);
    background: rgba(34, 192, 60, 0.1);
    color: #22c03c;
}

.auth-card .alert-danger {
    border-color: rgba(238, 51, 94, 0.1);
    background: rgba(238, 51, 94, 0.1);
    color: #ee335e;
}

.auth-card a {
    color: #3b4863;
    font-size: 14px;
    line-height: 21px;
    text-decoration: none;
}

/* The UMKM registration block: `hr.my-4` then `.rounded.border.p-3.bg-light` (485x140). */
.auth-card hr {
    margin: 24px 0;
    border: 0;
    border-top: 1px solid #031b4e;
    opacity: 0.25;
}

.auth-card .rounded {
    border-radius: 4.8px;
}

.auth-card .border {
    border: 1px solid #eae2f1;
}

.auth-card .p-3 {
    padding: 16px;
}

.auth-card .bg-light {
    background: #f0f1f6;
}

.auth-card .fw-semibold {
    font-weight: 600;
}

.auth-card .mb-1 {
    margin-bottom: 4px;
}

.auth-card .mb-3 {
    margin-bottom: 16px;
}

.auth-card .text-muted {
    color: #7987a1;
}

.auth-card .small {
    font-size: 12.25px;
    line-height: 18.375px;
}

.auth-card .btn-outline-primary {
    display: inline-block;
    padding: 4px 8px;
    border: 1px solid #0162e8;
    border-radius: 4px;
    background: transparent;
    color: #0162e8;
    font: 400 12px/18px var(--okx-font);
    text-decoration: none;
}

.auth-card .visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 992px) {
    .auth-shell {
        grid-template-columns: 1fr;
    }

    .auth-brand {
        display: none;
    }
}

/* ------------------------------------------------------------- responsive --- */

@media (min-width: 992px) {
    body.admin-sidebar-collapsed .app-sidebar {
        transform: translateX(-100%);
    }

    body.admin-sidebar-collapsed .app-header {
        inset-inline-start: 0;
        padding-inline-start: 0;
    }

    body.admin-sidebar-collapsed .main-content {
        margin-inline-start: 0;
    }

    body.admin-sidebar-collapsed .footer {
        padding-inline-start: 0;
    }
}

@media (max-width: 991.98px) {
    .app-sidebar {
        transform: translateX(-100%);
        transition: transform 0.2s ease;
    }

    .app-sidebar.is-open {
        transform: translateX(0);
        box-shadow: var(--okx-shadow);
    }

    .app-header {
        inset-inline-start: 0;
        padding-inline-start: 0;
    }

    .main-content {
        margin-inline-start: 0;
        padding: 0;
    }

    .footer {
        padding-inline-start: 0;
    }

    .main-header-center {
        display: none;
    }
}

@media (max-width: 1199.98px) {
    .admin-stat-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 1100px) {
    .admin-grid-catalog {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 767.98px) {
    .admin-profile-name {
        display: none;
    }

    .admin-outlet-pill {
        max-width: 44vw;
        overflow: hidden;
    }

    .admin-outlet-pill > span {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .admin-grid-2 {
        grid-template-columns: 1fr;
    }

    .admin-page-head {
        align-items: flex-start;
    }
}

@media (max-width: 575.98px) {
    .admin-stat-grid {
        grid-template-columns: 1fr;
    }

    .admin-outlet-pill.is-static {
        display: none;
    }

    .app-content-inner {
        padding-inline: 10px;
    }

    .admin-card,
    .admin-filter,
    .admin-stat {
        padding: 16px;
    }

    .admin-table {
        min-width: 620px;
    }

    .header-link {
        padding-inline: 8px;
    }

    .auth-shell {
        grid-template-columns: 1fr;
    }

    .auth-brand {
        display: none;
    }

    .auth-card {
        padding: 22px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-sidebar,
    .side-menu__angle {
        transition: none;
    }
}

/*
 * WAVE B — V1's two "Hak Akses" screens.
 *
 * Breakpoints and spacing come from V1's own bootstrap utilities, measured from
 * `employee-permissions/index.blade.php:36-55` (`row g-3` + `col-12 col-xl-6`,
 * i.e. one column until 1200px, then two) and
 * `admin-outlet-accesses/index.blade.php:51-72` (`col-12 col-md-6 col-xl-4`:
 * one column below 768px, two until 1200px, three from 1200px). `g-3` is a 16px
 * gutter, `p-3` 16px of padding, `gap-2` 8px, `gap-3` 16px, `.small` 12px and
 * `.rounded` V1's 6px — which is the existing `--okx-radius-card` token.
 */
.admin-grid-xl-2 {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}

.admin-grid-outlets {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}

@media (min-width: 768px) {
    .admin-grid-outlets {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .admin-grid-xl-2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .admin-grid-outlets {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* V1's catalog panel: `border rounded p-3 h-100` with an `fw-bold mb-3` title. */
.admin-panel {
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    padding: 16px;
    background: var(--okx-surface);
    height: 100%;
}

.admin-panel > h2 {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 700;
    line-height: 21px;
    text-transform: none;
    letter-spacing: 0;
}

/* V1's rows: `d-flex flex-column gap-2`, each row a label with the raw key pushed right. */
.admin-check-column {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-check-column .admin-check {
    display: flex;
    width: 100%;
}

.admin-check-key {
    margin-inline-start: auto;
    color: var(--okx-text-faint);
    font-size: 12px;
    line-height: 18px;
}

/* V1's outlet card: `border rounded p-3 d-flex align-items-start gap-3 h-100`. */
.admin-outlet-card {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    padding: 16px;
    background: var(--okx-surface);
    height: 100%;
    font-weight: 400;
}

.admin-outlet-card input {
    margin-top: 4px;
    width: 16px;
    height: 16px;
    accent-color: var(--okx-primary);
}

.admin-outlet-card strong {
    display: block;
    font-weight: 600;
}

.admin-outlet-card small {
    display: block;
    color: var(--okx-text-faint);
    font-size: 12px;
    line-height: 18px;
}

.admin-outlet-card em {
    color: var(--okx-warning-text);
    font-style: normal;
}

/*
 * V1 "Laporan Penjualan" surfaces, ported from
 * `okepos-cloud/resources/views/admin/reports/sales-menu-compact.blade.php` and
 * `okepos-cloud/resources/views/admin/reports/general-sales.blade.php`
 * (V1_MODE = READ_ONLY, traced 2026-10-28).
 *
 * Geometry — grid columns, gaps, radii, paddings, min-heights, type sizes and the hover
 * lift — is V1's own inline block. Colour comes from the OkePOS tokens instead of V1's
 * literal hex values because V1's block hard-coded one theme only; the dark values it
 * resolves to are the measured V1 ones.
 */
.compact-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.compact-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--okx-text);
}

.compact-note {
    margin: 0;
    color: var(--okx-text-soft);
    font-size: 0.85rem;
}

.compact-section {
    border: 1px solid var(--okx-border-strong);
    border-radius: 12px;
    background: var(--okx-surface);
    margin-bottom: 1rem;
    overflow: hidden;
    box-shadow: var(--okx-shadow);
}

.compact-section-head {
    padding: 0.75rem 0.9rem;
    background: var(--okx-surface-elevated);
    border-bottom: 1px solid var(--okx-border-strong);
    color: var(--okx-card-title);
    font-size: 0.92rem;
    font-weight: 700;
}

.compact-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
    padding: 0.75rem;
}

.compact-card {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    border: 1px solid var(--okx-border-strong);
    border-radius: 10px;
    padding: 0.65rem 0.75rem;
    min-height: 58px;
    color: inherit;
    text-decoration: none;
    background: var(--okx-surface-muted);
    transition: 0.14s ease;
}

.compact-card:hover {
    border-color: var(--okx-primary);
    background: var(--okx-surface-elevated);
    box-shadow: 0 6px 16px rgba(12, 36, 79, 0.55);
    transform: translateY(-1px);
}

/* V1's card, shown without a destination because V2 has no working screen for that report yet. */
.compact-card.is-pending {
    opacity: 0.72;
}

.compact-card.is-pending:hover {
    transform: none;
    border-color: var(--okx-border-strong);
    box-shadow: none;
}

.compact-icon {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--okx-primary-soft);
    color: var(--okx-primary);
    flex-shrink: 0;
}

.compact-icon .okx-icon {
    width: 1rem;
    height: 1rem;
}

.compact-card-title {
    margin: 0;
    color: var(--okx-card-title);
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1.2;
}

.compact-card-desc {
    margin: 0.1rem 0 0;
    color: var(--okx-text-faint);
    font-size: 0.74rem;
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.compact-card-state {
    margin: 0.1rem 0 0;
    color: var(--okx-warning-text);
    font-size: 0.72rem;
    line-height: 1.25;
}

.report-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.report-page-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--okx-success-text);
}

.report-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem 0.9rem;
    border-bottom: 1px solid var(--okx-border);
    font-size: 0.85rem;
    color: var(--okx-text-soft);
}

.report-summary strong {
    color: var(--okx-text);
    font-weight: 700;
}

.report-summary strong.is-success {
    color: var(--okx-success-text);
}

.report-invoice {
    font-weight: 600;
}

/* V1 `category-all-items-sales.blade.php:85` marks ONLY the item cell `fw-semibold` (600) while its
   neighbours stay regular, so the page weights that one cell instead of wrapping it in <strong>,
   whose 700 is not V1's number. */
.report-item-cell {
    font-weight: 600;
}

.report-link-stack {
    display: grid;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.report-item-detail {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.8rem;
    font-style: italic;
    color: var(--okx-text-faint);
}

.report-empty {
    text-align: center;
    padding: 1.5rem 0;
    color: var(--okx-text-faint);
}

/* V1's report head puts its three export links in one `btn-group`: the buttons are
 * `btn-outline-success` / `btn-outline-primary` / `btn-outline-dark` at `btn-sm`, they keep only
 * the two outer corners rounded, and the shared border collapses to a single line because each
 * button after the first is pulled back by one pixel. Measured from V1's own admin screens; no
 * vendor rule is copied.
 */
.report-export-group {
    display: inline-flex;
    vertical-align: middle;
}

/* V1 renders this control from `btn btn-outline-* btn-sm` inside `.btn-group`:
   7.2px/12px padding, 12px/18px at weight 400, 34px tall, and only the OUTER corners are
   rounded — at 4px, not the shell's 3px control radius. */
.report-export-group .admin-btn {
    padding: 7.2px 12px;
    border-radius: 0;
    font: 400 12px/18px var(--okx-font);
}

.report-export-group .admin-btn + .admin-btn {
    margin-left: -1px;
}

.report-export-group .admin-btn:first-child {
    border-radius: 4px 0 0 4px;
}

.report-export-group .admin-btn:last-child {
    border-radius: 0 4px 4px 0;
}

/* V1's three arms, measured per theme on the running app. Dark: Excel #22c03c on a
   transparent field; PDF rgb(143,184,255) on rgba(59,130,246,.06) with a
   rgba(90,148,255,.45) border; Print rgb(240,245,248). Light: #22c03c, #0162e8, #3b4863,
   all transparent. One token cannot serve both, and the previous single purple-ish arm
   matched neither. */
.report-export-group .admin-btn.is-outline.is-success {
    border-color: #22c03c;
    background: transparent;
    color: #22c03c;
}

.report-export-group .admin-btn.is-outline {
    border-color: rgba(90, 148, 255, 0.45);
    background: rgba(59, 130, 246, 0.06);
    color: rgb(143, 184, 255);
}

.report-export-group .admin-btn.is-outline.is-dark {
    border-color: rgb(240, 245, 248);
    background: transparent;
    color: rgb(240, 245, 248);
}

html[data-theme-mode="light"] .report-export-group .admin-btn.is-outline {
    border-color: #0162e8;
    background: transparent;
    color: #0162e8;
}

html[data-theme-mode="light"] .report-export-group .admin-btn.is-outline.is-dark {
    border-color: #3b4863;
    background: transparent;
    color: #3b4863;
}

/* V1's `btn-outline-success` and `btn-outline-dark` arms of the same control. */
.admin-btn.is-outline.is-success {
    border-color: var(--okx-success);
    color: var(--okx-success-text);
}

.admin-btn.is-outline.is-success:hover {
    background: var(--okx-success-soft);
}

.admin-btn.is-outline.is-dark {
    border-color: var(--okx-text-soft);
    color: var(--okx-text);
}

.admin-btn.is-outline.is-dark:hover {
    background: var(--okx-surface-muted);
}

/*
 * V1's `btn-outline-secondary`, which the master-data toolbars use where the report screens use
 * `btn-outline-dark`. Measured on the running app (Data Rekening, dark theme, 2026-10-30):
 * color rgb(175,189,215), border rgba(125,152,194,.3), background rgb(22,35,60) at 94x34 and 54x34.
 * Valex's declaration (`--secondary-rgb: 95, 109, 136`) is NOT what paints, so the rendered values
 * are the ones that ship — the same declaration-versus-render lesson the login button taught.
 */
.admin-btn.is-outline.is-secondary {
    border-color: rgba(125, 152, 194, 0.3);
    color: rgb(175, 189, 215);
    background: rgb(22, 35, 60);
}

.admin-btn.is-outline.is-secondary:hover {
    background: rgb(28, 44, 74);
}

.report-center {
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* V1 centres those columns with `text-center` on the header cell too, and `.admin-table th`
   otherwise wins over the bare class — the same shape `.admin-table .num` already uses. */
.admin-table .report-center {
    text-align: center;
}

.report-table thead th {
    white-space: nowrap;
    vertical-align: middle;
}

.report-table td {
    vertical-align: top;
}

@media (max-width: 1200px) {
    .compact-grid {
        grid-template-columns: 1fr;
    }
}

/* V1 `cashier-sales.blade.php` prints a bold tfoot grand total with a heavier top rule. V2's
   table cells carry a bottom border, so the rule is written out in full here. */
.report-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
    vertical-align: middle;
}

.report-table tfoot .is-success {
    color: var(--okx-success-text);
}

/* V1 `sales-by-selling-price.blade.php` is the only report screen that stacks sub-sections inside one
   card: each band is `.card-body border-bottom` and each caption is `h6.fw-semibold.mb-2` —
   Bootstrap's 1rem heading at weight 600 with an 8px bottom margin — while both charts get a
   `min-height: 280px` host and the chart's own empty state is `.text-muted.small.py-3`, a different
   sentence from the three tables' empty rows. */
.report-section {
    padding: 1rem 0;
    border-bottom: 1px solid var(--okx-border);
}

.report-section-heading {
    margin: 0 0 8px;
    font-size: 1rem;
    font-weight: 600;
}

.report-chart {
    min-height: 280px;
}

.report-chart-empty {
    margin: 0;
    padding: 12px 0;
    font-size: 0.875rem;
    color: var(--okx-text-muted);
}

/* V1 `rounding-sales.blade.php` colours the rounding figures by their sign. */
.report-summary strong.is-danger {
    color: var(--okx-danger-text);
}

.report-table td.num.is-success {
    color: var(--okx-success-text);
}

.report-table td.num.is-danger {
    color: var(--okx-danger-text);
}

/*
 * Laporan Penjualan Best Seller Produk — V1 `reports/product-best-seller.blade.php`.
 *
 * V1 carries this screen's rules in a page-inline `<style>` (lines 21-62). The SPA is ONE document,
 * so those rules cannot be pasted as bare `.best-seller-table …` selectors: `best-seller-table` is
 * also the dashboard card's wrapper (`DashboardBestSellerCard.tsx:161`), and V1 never applied this
 * block there. `.report-best-seller` is therefore the page scope that reproduces "only while this
 * page is loaded".
 *
 * The measured cascade decides two visible things, and both are counter-intuitive from the markup:
 * V1 tags the quantity cells `text-success` and the `No` cell `text-muted`
 * (`:236`, `:239`), while the same block declares `.best-seller-table tbody td { color:#e6eefc
 * !important }`. Both utilities are `!important` too (bootstrap.min.css `.text-success`,
 * `styles.css:20750`), so specificity breaks the tie: `.best-seller-table tbody td` is (0,1,2) and
 * a single utility class is (0,1,0). The table rule WINS — the ranking's numbers and its `No`
 * column render near-white on V1, green only in the summary strip (`:219`), where no competing
 * selector exists. Ported as measured rather than as the class names suggest.
 */
/*
 * V1 Valex `text-success` is rgb(34,192,60), distinct from the V1
 * `btn-success` fill #2bc84b. Keep the override ONLY on this report:
 * global --okx-success-text serves other screens and is theme-dependent.
 * V1 source: product-best-seller.blade.php:219 (summary text-success).
 * Source-only alignment; browser parity remains NOT_VERIFIED until remote DEV is ready.
 */
.report-best-seller .report-summary strong.is-success {
    color: rgb(34, 192, 60);
}

.report-best-seller .best-seller-table {
    /* V1 gives this table no top margin; the dashboard block above owns `.best-seller-table
       { margin-top: 16px }`, so the report screen has to cancel it to keep V1's spacing. */
    margin-top: 0;
}

.report-best-seller .best-seller-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc !important;
}

.report-best-seller .best-seller-table tbody td,
.report-best-seller .best-seller-table tfoot td {
    color: #e6eefc !important;
    vertical-align: middle;
}

.report-best-seller .best-seller-table tfoot td {
    border-top-width: 2px;
    font-weight: 700;
}

/* V1 `:227` and `:229` pin two of the four columns by inline style. */
.report-best-seller .best-seller-col-no {
    width: 80px;
}

.report-best-seller .best-seller-col-quantity {
    width: 200px;
}

/* V1 `:238` `fw-semibold` = 600 and `:239` `fw-bold` = 700. */
.report-best-seller .best-seller-cell-product {
    font-weight: 600;
}

.report-best-seller .best-seller-cell-quantity {
    font-weight: 700;
}

/*
 * Highlight panel — V1 `:101-135`. `row g-3 mb-4` gives a 16px gutter (`--bs-gutter-x/y: 1rem`)
 * carried as 8px of padding per column against the row's own -8px overhang, so the outermost cards
 * stay flush with the container; `mb-4` is 24px. Every column is `width:20%; min-width:180px` in an
 * INLINE style (`:110`), which is why the `col-md-4 col-sm-6` classes beside it never take effect:
 * five cards per row at every width, and a wrap only below the 180px floor.
 */
.best-seller-highlight-grid {
    display: flex;
    flex-wrap: wrap;
    row-gap: 16px;
    margin: 0 -8px 24px;
}

.best-seller-highlight-heading {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 100%;
    margin: 0 0 8px;
    padding: 0 8px;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.5;
    color: rgb(34, 192, 60);
}

.best-seller-highlight-cell {
    flex: 0 0 20%;
    min-width: 180px;
    padding: 0 8px;
    box-sizing: border-box;
}

/* V1 `card best-seller-card h-100 bg-dark text-white` + the inline block at `:38-46`. */
.best-seller-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 6px;
    background-color: rgb(33, 37, 41);
    color: #ffffff;
    transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
}

.best-seller-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.25);
}

/* V1 `card-body p-3 d-flex flex-column justify-content-between`. */
.best-seller-card-body {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1 1 auto;
    padding: 16px;
}

.best-seller-card-rank-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 8px;
}

.best-seller-card-name {
    margin: 0 0 4px;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.5;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* V1 `text-muted small mb-2 text-truncate`; `--bs-secondary-color` is the theme token V2's
   `--okx-text-faint` already carries the same rendered value for. */
.best-seller-card-category {
    margin: 0 0 8px;
    font-size: .875em;
    color: var(--okx-text-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* V1 `mt-2 pt-2 border-top border-secondary` — 1px solid rgb(108,117,125). */
.best-seller-card-foot {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid rgb(108, 117, 125);
}

.best-seller-card-quantity {
    font-size: 1.25rem;
    font-weight: 700;
    color: rgb(34, 192, 60);
}

.best-seller-card-suffix {
    font-size: .875em;
    color: var(--okx-text-faint);
}

/* V1 `:48-62` — a 28px circle, gold/silver/bronze for the podium and slate beyond it. */
.best-seller-highlight-grid .badge-rank {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-weight: bold;
    font-size: .85rem;
}

.best-seller-highlight-grid .rank-1 {
    background-color: #ffd700;
    color: #1a1a1a;
}

.best-seller-highlight-grid .rank-2 {
    background-color: #c0c0c0;
    color: #1a1a1a;
}

.best-seller-highlight-grid .rank-3 {
    background-color: #cd7f32;
    color: #1a1a1a;
}

.best-seller-highlight-grid .rank-other {
    background-color: #495057;
    color: #ffffff;
}

/*
 * KDS Performance — V1 `admin/kitchen-display/performance.blade.php`, measured 2026-11-01.
 *
 * `h5.mb-2` (`:86`, `:118`, `:150`) is Bootstrap's heading (1.25rem/500/1.2) with an 8px bottom
 * margin, and `td.fw-semibold` (`:77`, `:108`, `:141`) is 600 — both only reachable as literals
 * here because V2 ships no vendor stylesheet.
 *
 * The status pair at `:170-172` is the part worth writing down, because the class names mislead in
 * both directions. `bg-light` and `text-dark` are Bootstrap classes, but Valex redefines BOTH
 * (`styles.min.css`: `.bg-light{background-color:rgb(var(--light-rgb))!important}`,
 * `.text-dark{color:rgb(var(--dark-rgb))!important}`), so the chip is V1's own pale slate
 * (240,241,246 / ink 59,72,99 in light; 33,41,59 / ink 240,245,248 in dark) and not BS's
 * `--bs-light-rgb`. `bg-success-subtle` and `border-success-subtle` are the opposite case: Valex
 * ships no rule for either name, so they stay Bootstrap 5.3's theme-split subtles
 * (`--bs-success-bg-subtle` #d1e7dd light / #051b11 dark, `--bs-success-border-subtle`
 * #a3cfbb / #0f5132). The ink `text-success` is Valex's `rgb(34,192,60)` — which is NOT the
 * `--okx-success` (#2bc84b = 43,200,75) this file uses for V1's `.btn-success` surfaces, so the
 * literal is written rather than the token, and the difference between V1's two greens is reported
 * as a tracked finding instead of being silently unified.
 */
.kds-performance-heading {
    margin: 0 0 8px;
    font-size: 1.25rem;
    font-weight: 500;
    line-height: 1.2;
}

.kds-cell-total {
    font-weight: 600;
}

/* V1's `bx bx-right-arrow-alt text-muted` between the two chips (`:171`). */
.kds-status-arrow {
    color: var(--okx-text-faint);
    vertical-align: middle;
}

.admin-badge.is-bg-light {
    background: rgb(33, 41, 59);
    color: rgb(240, 245, 248);
}

.admin-badge.is-success-subtle {
    border-color: #0f5132;
    background-color: #051b11;
    color: rgb(34, 192, 60);
}

/* V1's rank chip (`:136`): `bg-primary-subtle text-primary border-primary-subtle`, ink Valex's
   `--primary-color` = rgb(1,98,232), which is the same blue the login card renders. */
.admin-badge.is-primary-subtle {
    border-color: #084298;
    background-color: #031633;
    color: rgb(1, 98, 232);
}

html[data-theme-mode="light"] .admin-badge.is-bg-light {
    background: rgb(240, 241, 246);
    color: rgb(59, 72, 99);
}

html[data-theme-mode="light"] .admin-badge.is-success-subtle {
    border-color: #a3cfbb;
    background-color: #d1e7dd;
}

html[data-theme-mode="light"] .admin-badge.is-primary-subtle {
    border-color: #9ec5fe;
    background-color: #cfe2ff;
}

/*
 * V1 `daily-sales.blade.php` master/detail rows. Geometry (28px toggle, 12px radius,
 * 14px/16px padding, two-column item list with a 24px gap) is V1's inline block; colour comes
 * from the OkePOS tokens because V1's block hard-coded its light theme only.
 */
.daily-sales-row {
    cursor: pointer;
}

.daily-sales-row:hover {
    background: var(--okx-success-soft);
}

.daily-sales-toggle {
    width: 28px;
    text-align: center;
    color: var(--okx-success-text);
    font-weight: 700;
}

.daily-sales-detail-card {
    border: 1px solid var(--okx-border);
    border-radius: 12px;
    padding: 14px 16px;
    background: var(--okx-surface);
}

.daily-sales-detail-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.daily-sales-detail-head .admin-help {
    margin: 0;
}

.daily-sales-detail-list {
    columns: 2;
    column-gap: 24px;
    margin: 0;
    padding-left: 18px;
}

.daily-sales-detail-list li {
    break-inside: avoid;
    margin-bottom: 6px;
}

.daily-sales-detail-list .unit {
    color: var(--okx-text-faint);
}

@media (max-width: 767.98px) {
    .daily-sales-detail-list {
        columns: 1;
    }
}

/* V1 `variant-by-shift.blade.php` closes each day with a right-aligned bold subtotal row, and
   `payment-method-by-shift.blade.php` does the same inside a `table-secondary` row. Neither of those
   two screens forces an ink, so this class carries only the alignment and the weight — `fw-semibold
   text-end` in V1's words. */
.report-subtotal {
    text-align: end;
    font-weight: 600;
}

/* V1 `sales-recap-by-shift.blade.php` ships its OWN inline block instead of the shared report
   tokens. Its summary strip forces `#9fb3d1` ink with `#e6eefc` figures — the dark-theme tokens are
   `--okx-text-soft: #afbdd7` and `--okx-text: #f3f7ff`, so reusing them would shift every figure on
   this screen by a measurable amount. Its per-day subtotal row is painted `#1a2c4a` under
   `!important`, precisely because Bootstrap's striped table would otherwise win the cascade, and V1
   adds hairlines above and below it. V1's inline block is theme-blind: the same values print in the
   light theme too, so they are reproduced literally here rather than mapped to tokens (AGENTS.md
   §4.1, colour is V1 exact). The `.sales-recap-filter-row` label tightening is V1's own `.35rem`.
   `category-by-shift`, `variant-by-shift` and `extra-option-by-shift` ship that subtotal block
   BYTE-FOR-BYTE under their own class names, so one `.report-subtotal-shift` serves all four.
   `sale-type-by-shift` and `payment-method-by-shift` do NOT: their blades have no style block and
   give the row `table-secondary`, whose Valex override (`background-color:#fff` plus
   `--bs-table-bg: rgba(var(--secondary-rgb), 0.1)`) cannot be resolved without a rendered capture,
   so those two rows carry the weight and alignment only. */
.report-summary-forced {
    color: #9fb3d1;
}

.report-summary-forced strong {
    color: #e6eefc;
}

/* Every V1 day-subtotal row — `sales-recap-by-shift`, `category-by-shift`, `variant-by-shift`,
   `extra-option-by-shift`, `sale-type-by-shift`, `payment-method-by-shift` — marks each of its cells
   `fw-semibold`, which is Bootstrap's `font-weight: 600 !important`, so the row class carries the
   weight rather than the pages wrapping cells in <strong> (whose 700 is not V1's number). */
.report-subtotal-row td {
    font-weight: 600;
}

.report-subtotal-shift td {
    background: #1a2c4a !important;
    color: #e6eefc !important;
    border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
}

/* V1 `outlet-sales-by-shift.blade.php:7-17` ships its OWN subtotal block, and its values are NOT the
   ones above: `#1b2d50` under `#d9e6ff` with `#2a3f68` hairlines. Reusing `.report-subtotal-shift`
   here would shift the row's colour by a measurable amount (AGENTS §4.1, colour is V1 exact). Its
   second rule forces `#f0f6ff` on `td strong` and `td.fw-semibold`, and EVERY cell of that row
   carries `fw-semibold`, so the ink an operator actually sees on this screen is `#f0f6ff`, not the
   `#d9e6ff` the first rule declares — V1's own markup makes its first colour dead, and the rendered
   result is what is reproduced here (`.report-subtotal-row` is V2's carrier of that same
   `fw-semibold`, so the override keys off the pair rather than off V1's class name). */
.report-subtotal-outlet td {
    background: #1b2d50 !important;
    color: #d9e6ff !important;
    border-top: 1px solid #2a3f68 !important;
    border-bottom: 1px solid #2a3f68 !important;
}

.report-subtotal-row.report-subtotal-outlet td {
    color: #f0f6ff !important;
}

/* V1 `outlet-sales-by-day.blade.php:15-71` ships its OWN screen stylesheet and it is the only report in
   this wave that opens with FOUR summary CARDS and TWO chart panels. Every value below is V1's literal:
   labels `#a9bfdc` over figures `#e6eefc` inside `rgba(15,23,42,.32)` cards with `.75rem` radius, panels
   on `rgba(15,23,42,.28)` with `.85rem` radius, hairlines `rgba(148,163,184,.28)`, a `2fr 1fr` chart
   grid and a `min-height: 320px` canvas. `--okx-text` is `#f3f7ff`, so binding these to the theme tokens
   would move every figure on the page — the same finding recorded for the subtotal rows above — so the
   literals stay. V1's `Grand Total` card adds `text-success`, mapped to `--okx-success-text` exactly as
   `hourly-sales` maps it. The `border-bottom` between the three sections is V1's
   `card-body border-bottom`, carried by the token `.report-summary` already uses for that role. */
.outlet-daily-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(170px, 1fr));
    gap: .75rem;
}

.outlet-daily-summary-card {
    padding: .75rem .9rem;
    border: 1px solid rgba(148, 163, 184, .28);
    border-radius: .75rem;
    background: rgba(15, 23, 42, .32);
}

.outlet-daily-summary-label {
    font-size: .78rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #a9bfdc;
}

.outlet-daily-summary-value {
    margin-top: .25rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: #e6eefc;
}

.outlet-daily-summary-value.is-success {
    color: var(--okx-success-text);
}

.outlet-daily-chart-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: .75rem;
}

.outlet-daily-chart-panel {
    padding: .75rem;
    border: 1px solid rgba(148, 163, 184, .28);
    border-radius: .85rem;
    background: rgba(15, 23, 42, .28);
}

.outlet-daily-chart-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .5rem;
}

.outlet-daily-chart-title {
    margin: 0;
    font-weight: 700;
    color: var(--okx-text);
}

.outlet-daily-chart-note {
    font-size: .85rem;
    color: var(--okx-text-muted);
}

.outlet-daily-canvas {
    min-height: 320px;
}

.outlet-daily-section {
    padding-bottom: .75rem;
    margin-bottom: .75rem;
    border-bottom: 1px solid var(--okx-border);
}

@media (max-width: 992px) {
    .outlet-daily-summary-grid {
        grid-template-columns: 1fr;
    }
    .outlet-daily-chart-grid {
        grid-template-columns: 1fr;
    }
}

/* V1 `outlet-sales-by-day.blade.php:53-62` declares its per-day subtotal row with EXACTLY the four
   values A1-R42's screen declares (`#1b2d50` under `#d9e6ff`, `#2a3f68` hairlines, and `#f0f6ff` forced
   over `td strong`/`td.fw-semibold`, which every cell of that row carries), so this screen reuses
   `.report-subtotal-outlet` + `.report-subtotal-row` instead of re-declaring identical numbers under a
   second name. A third screen with the same block would be the moment to rename the pair. */

.report-filter-tight .admin-field > span {
    margin-bottom: .35rem;
}

/* V1 `sales-recap.blade.php` puts each table under a bold card header and shades its tfoot.
   Its own stylesheet paints that tfoot `#f8fafc`; that is V2's light `--okx-surface-elevated`
   (#f8fafd), so the token is used and the footer stays readable in the dark theme too. */
.report-card-header {
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--okx-border);
    color: var(--okx-card-title);
    font-weight: 700;
}

.recap-table tfoot td {
    background: var(--okx-surface-elevated);
}

/* V1 `hourly-sales.blade.php` opens its transaction list in a Bootstrap `modal-xl` (1140px),
   wider than the CRUD dialogs the other admin screens use. */
.admin-modal-dialog-xl {
    width: min(1140px, 100%);
}

.hourly-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(170px, 1fr));
    gap: 0.75rem;
    padding: 20px;
}

.hourly-summary-card {
    padding: 0.75rem 0.9rem;
    border: 1px solid rgba(148, 163, 184, 0.28);
    border-radius: 12px;
    background: rgba(15, 23, 42, 0.32);
}

.hourly-summary-label {
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--okx-text-muted);
}

.hourly-summary-value {
    margin-top: 0.25rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--okx-text);
}

.hourly-summary-value.is-success {
    color: var(--okx-success-text);
}

.hourly-chart-panel {
    padding: 0.75rem;
    margin: 0 20px 20px;
    border: 1px solid rgba(148, 163, 184, 0.28);
    border-radius: 14px;
    background: rgba(15, 23, 42, 0.28);
}

.hourly-chart-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.hourly-chart-title {
    font-weight: 700;
    color: var(--okx-text);
}

.hourly-chart-zone {
    color: var(--okx-text-muted);
    font-weight: 500;
    font-size: 0.85rem;
}

.hourly-chart-body {
    position: relative;
    min-height: 360px;
}

.hourly-chart-tooltip {
    position: absolute;
    top: 8px;
    min-width: 150px;
    padding: 8px 10px;
    border-radius: 8px;
    background: #10192e;
    border: 1px solid rgba(148, 163, 184, 0.35);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
    pointer-events: none;
}

.hourly-chart-tooltip-x {
    margin-bottom: 4px;
    color: var(--okx-text-muted);
    font-size: 0.8rem;
}

.hourly-chart-tooltip-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
    color: var(--okx-text);
}

.hourly-chart-tooltip-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.hourly-chart-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1rem;
    margin-top: 6px;
    font-size: 0.82rem;
    color: var(--okx-text);
}

.hourly-chart-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.hourly-chart-legend-marker {
    width: 10px;
    height: 10px;
    border-radius: 3px;
}

.hourly-tx-count {
    background: none;
    border: 0;
    padding: 0;
    color: #7ec8ff;
    font-weight: 600;
    cursor: pointer;
}

.hourly-tx-count:hover {
    color: #a5dcff;
    text-decoration: underline;
}

@media (max-width: 992px) {
    .hourly-summary-grid {
        grid-template-columns: 1fr;
    }

    .hourly-chart-body {
        min-height: 300px;
    }
}

/* V1's modal invoice link carries this screen's own `#9fd3ff` / 600 treatment, not the shared
   admin link colour. */
.hourly-invoice-link {
    color: #9fd3ff;
    font-weight: 600;
    text-decoration: none;
    transition: color 0.15s ease;
}

.hourly-invoice-link:hover {
    color: #c8e8ff;
    text-decoration: underline;
}

/* V1 `hourly-sales.blade.php` pins this screen's own ink with `!important`, in both themes:
   the summary cards, the chart panel and the table all stay on the dark palette even when the
   rest of the admin is light. The literals are V1's, not a V2 reinterpretation. */
.hourly-summary-label {
    color: #a9bfdc;
}

.hourly-summary-value {
    color: #e6eefc;
}

.hourly-summary-value.is-success {
    color: var(--okx-success-text);
}

.hourly-chart-zone,
.hourly-chart-title {
    color: #b8c9e6;
}

.hourly-chart-title {
    font-weight: 700;
    color: #e6eefc;
}

.hourly-table thead th,
.hourly-table tbody td,
.hourly-table tfoot td {
    color: #e6eefc;
}

.hourly-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

/* V1 `cashier-sales-detail.blade.php`: its own table metrics and the italic item-detail line
   that prints `Varian:` / `Extra:` under an item name. `#9ca3af` is V1's literal grey. */
.cashier-detail-table thead th {
    white-space: nowrap;
    vertical-align: middle;
}

.cashier-detail-table td {
    vertical-align: top;
}

.item-detail-line {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.8rem;
    font-style: italic;
    color: #9ca3af;
}

/* V1 `tax-sales.blade.php`: its outline `Laporan Bulanan` button next to the solid Terapkan,
   the same pinned ink it forces on the tax table, and the invoice link colour. */
.admin-btn-outline {
    border: 1px solid var(--okx-primary);
    background: transparent;
    color: var(--okx-primary);
}

.admin-btn-outline:hover {
    background: var(--okx-primary);
    color: #f8fbff;
}

.tax-sales-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc;
}

.tax-sales-table tbody td,
.tax-sales-table tfoot td {
    color: #e6eefc;
    vertical-align: top;
}

.tax-sales-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

.tax-sales-tax-name {
    min-width: 180px;
}

.tax-sales-invoice-link {
    color: #7cc4ff;
    text-decoration: none;
}

.tax-sales-invoice-link:hover {
    text-decoration: underline;
}

/* V1 `customer-average-spending.blade.php` forces the same pinned ink on its table as the tax
   screen does, with a heavier tfoot rule. */
.customer-average-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc;
}

.customer-average-table tbody td,
.customer-average-table tfoot td {
    color: #e6eefc;
    vertical-align: top;
}

.customer-average-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

/* V1 `payment-recap.blade.php` keeps the same pinned ink as the tax and average screens, but
   centres its cells vertically, and its footer percentage is a literal `100,00%`. */
.payment-recap-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc;
}

.payment-recap-table tbody td,
.payment-recap-table tfoot td {
    color: #e6eefc;
    vertical-align: middle;
}

.payment-recap-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

/* V1 `extra-option-sales.blade.php` reuses the same pinned, vertically centred table ink. */
.extra-option-sales-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc;
}

.extra-option-sales-table tbody td,
.extra-option-sales-table tfoot td {
    color: #e6eefc;
    vertical-align: middle;
}

.extra-option-sales-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

/* V1 `sales-by-type.blade.php` reuses the same pinned, vertically centred table ink. */
.sales-by-type-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc;
}

.sales-by-type-table tbody td,
.sales-by-type-table tfoot td {
    color: #e6eefc;
    vertical-align: middle;
}

.sales-by-type-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

/* V1 `sales-detail-by-type.blade.php`: nowrap centred headers, top-aligned cells. Unlike the
   Pilihan Ekstra screen this one does not pin its ink to #e6eefc, so it does not here either. */
.sales-detail-by-type-table thead th {
    white-space: nowrap;
    vertical-align: middle;
}

.sales-detail-by-type-table td {
    vertical-align: top;
}

/* V1 `hourly-item-sales.blade.php`: the same pinned, vertically centred table ink as the
   Pilihan Ekstra screen. Its `.hourly-item-summary-*` rules are byte-for-byte the ones already
   served by `.hourly-summary-*` above, so the shared classes are reused rather than duplicated. */
.hourly-item-table thead th {
    white-space: nowrap;
    vertical-align: middle;
    color: #e6eefc;
}

.hourly-item-table tbody td,
.hourly-item-table tfoot td {
    color: #e6eefc;
    vertical-align: middle;
}

.hourly-item-table tfoot td {
    border-top: 2px solid var(--okx-border-strong);
    font-weight: 700;
}

/* V1 pins only the three rowspan cells of this screen to the top with its `align-top` utility;
   every other cell stays vertically centred by the table rule above. */
.hourly-item-table .align-top {
    vertical-align: top;
}

/* =============================================================================
 * WAVE B — "Data Rekening" and the kas create form.
 *
 * V1 lays both forms out with Bootstrap's `row g-3` of `col-md-4` label / `col-md-8` control
 * columns (`okepos-cloud/resources/views/admin/payment-accounts/partials/form-fields.blade.php:11-20`
 * and `admin/cash-transactions/partials/form.blade.php:56-68`), measured as: a 16px gutter
 * (`g-3` = --bs-gutter-x/y: 1rem), a one-third / two-thirds split at the md breakpoint and above,
 * and the two columns stacking to full width below 768px. The label keeps V1's body ink
 * (`form-label`: 14px/21px, weight 400) and is top-aligned with the control it names.
 *
 * The controls themselves reuse the `.admin-field` metrics above, because V1 gives both forms the
 * same `.form-control` / `.form-select` it uses everywhere else; duplicating those numbers here
 * would be a second source of truth for one component.
 * ========================================================================== */
.admin-form-grid {
    display: grid;
    gap: 16px;
}

.admin-form-row {
    display: grid;
    gap: 16px;
    align-items: start;
}

.admin-form-label {
    color: var(--okx-text);
    font-size: 14px;
    line-height: 21px;
    font-weight: 400;
    padding-top: 6px;
}

.admin-form-control {
    display: grid;
    gap: 8px;
    min-width: 0;
}

.admin-form-control input,
.admin-form-control select,
.admin-form-control textarea {
    width: 100%;
    min-height: 35px;
    padding: 6px 12px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
    background: var(--okx-input-bg);
    color: var(--okx-text);
    font: 400 14px/21px var(--okx-font);
}

.admin-form-control input:focus,
.admin-form-control select:focus,
.admin-form-control textarea:focus {
    outline: none;
    border-color: var(--okx-primary);
    box-shadow: 0 0 0 0.2rem var(--okx-primary-soft);
}

.admin-form-control input[readonly] {
    background: var(--okx-surface);
    color: var(--okx-text-faint);
}

.admin-form-control textarea {
    min-height: 84px;
    resize: vertical;
}

/* V1's `d-flex flex-wrap gap-2` button group in the camera block. */
.admin-form-inline {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.admin-form-inline > input,
.admin-form-inline > select,
.admin-form-inline > textarea {
    flex: 1 1 220px;
}

.admin-check-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
}

/* V1's MDR `input-group` with the % suffix, capped at 220px (`style="max-width: 220px"`). */
.admin-rate-input {
    max-width: 160px;
}

.admin-rate-unit {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    border: 1px solid var(--okx-border);
    border-left: 0;
    border-radius: 0 var(--okx-radius-control) var(--okx-radius-control) 0;
    background: var(--okx-surface);
    color: var(--okx-text-faint);
    font: 400 14px/21px var(--okx-font);
}

/* V1's camera preview (`#camera-box` at full width, rounded) and its 220px-tall snapshot. */
.admin-camera-preview {
    width: 100%;
    border-radius: var(--okx-radius-control);
    border: 1px solid var(--okx-border);
}

.admin-camera-snapshot {
    max-height: 220px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-control);
}

/* V1's `btn-outline-primary`, used by the transfer action and the camera controls. */
.admin-btn.is-outline {
    border-color: var(--okx-primary);
    color: var(--okx-primary);
    background: transparent;
}

.admin-btn.is-outline:hover {
    background: var(--okx-primary-soft);
}

.admin-btn.is-outline.is-danger {
    border-color: var(--okx-danger);
    color: var(--okx-danger);
}

/*
 * V1's third export arm, `btn-outline-info`, on the Tipe Penjualan toolbar
 * (`sale-types/index.blade.php` 18-20). Valex paints it as rgb(0,185,255) through `--info-rgb`
 * (measured in `public/valex/assets/css/styles.min.css` on 2026-10-30), and `--okx-info` already
 * carries exactly that, so token and V1 agree here. `btn-outline-danger` in the same theme paints
 * rgb(238,51,94) while `--okx-danger` is #ff5f7a: that gap is app-wide, older than this screen, and
 * repainting the token would move every danger control in Admin — so the arm ships on the existing
 * token and the divergence is reported, not silently fixed here.
 */
.admin-btn.is-outline.is-info {
    border-color: var(--okx-info);
    color: var(--okx-info);
}

@media (min-width: 768px) {
    .admin-form-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    }

    .admin-form-row--full {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* =============================================================================
   DASHBOARD — V1 `resources/views/admin/dashboard.blade.php`, ported card by
   card. The trend rules below are V1's OWN inline styles (blade 8-33), copied as
   literals rather than re-pointed at tokens, because V1 hardcodes them and the
   owner contract is the rendered result, not the declaration.
   ============================================================================= */

/* blade 8-18: the KPI trend note. */
.trend-up {
    color: #17a00e !important;
}

.trend-down {
    color: #d93025 !important;
}

.trend-note {
    font-size: 12px !important;
    margin-top: 4px !important;
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: 4px;
}

.trend-note .okx-icon {
    width: 13px;
    height: 13px;
    flex: 0 0 auto;
}

/* blade 19-33: the whole KPI card is a link and lifts on hover. */
.admin-kpi-link {
    display: block;
    text-decoration: none;
    color: inherit;
}

.admin-kpi-card {
    margin-bottom: 0;
    padding: 16px;
    border: 1px solid transparent;
    border-radius: 10px;
    overflow: hidden;
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.admin-kpi-link:hover .admin-kpi-card,
.admin-kpi-link:focus-visible .admin-kpi-card {
    transform: translateY(-3px);
    box-shadow: 0 10px 20px rgba(15, 23, 42, 0.1);
    border-color: rgba(13, 110, 253, 0.2);
}

/* blade 560: `row row-cols-1 row-cols-md-2 row-cols-xl-4 g-3`. */
.admin-kpi-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    margin-bottom: 16px;
}

.admin-kpi-grid__body {
    display: flex;
    align-items: center;
    gap: 8px;
}

.admin-kpi-grid__label {
    margin: 0;
}

.admin-kpi-grid__value {
    margin: 0;
    font-size: 20px;
    line-height: 1.2;
    font-weight: 600;
}

.admin-kpi-grid__icon {
    margin-left: auto;
}

/* blade 578: `bx font-30`. */
.okx-icon-lg {
    width: 30px;
    height: 30px;
}

/* blade 581/605/629/653: `div#w-chart5..8`. ApexCharts sizes these itself at 65px, so the
   container must not add its own height or the card stops matching V1's measured 345x170. */
.admin-kpi-grid__chart {
    margin-top: 4px;
}

/* blade 733-741: the chart card's header is `card-header d-flex justify-content-between`. */
.admin-chart-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.admin-chart-card__head h2 {
    margin: 0;
}

.admin-chart-card__menu {
    color: var(--okx-text-faint);
    display: inline-flex;
}

@media (min-width: 768px) {
    .admin-kpi-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .admin-kpi-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- filter card, blade 109-158 (`card mb-3 date-filter-card`) --------------
   V1's row is `row g-2 align-items-end`: an 8px gutter, and `col-12 col-lg-N`
   spans that only engage at the lg breakpoint (992px), unlike the report
   filters, which are xl. Measured 1426x114 at 1710px viewport. */
.admin-date-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0;
    row-gap: 8px;
    margin-bottom: 16px;
    padding: 20px 13px;
    border: 1px solid var(--okx-border);
    border-radius: var(--okx-radius-card);
    background: var(--okx-surface);
    box-shadow: var(--okx-shadow);
}

.admin-date-filter > * {
    padding-inline: 4px;
    margin: 0;
}

.admin-date-filter .is-outlet,
.admin-date-filter .is-ranges {
    flex: 0 0 100%;
}

.admin-date-filter .is-date,
.admin-date-filter .is-apply {
    flex: 0 0 50%;
}

@media (min-width: 992px) {
    /* col-lg-3 / col-lg-2 / col-lg-2 / col-lg-2 / col-lg-3 */
    .admin-date-filter .is-outlet,
    .admin-date-filter .is-ranges {
        flex: 0 0 25%;
    }

    .admin-date-filter .is-date,
    .admin-date-filter .is-apply {
        flex: 0 0 16.6667%;
    }
}

/* blade 132-133: `col-12 col-lg-2 d-grid` with `btn btn-success btn-apply`.
   Same measured green as the report apply, because V1 uses the same class. */
.admin-date-filter .is-apply .admin-btn {
    width: 100%;
    border-color: #2bc84b;
    background: #2bc84b;
    color: rgb(247, 255, 251);
}

.admin-date-filter .is-apply .admin-btn:hover {
    border-color: #25a93f;
    background: #25a93f;
    color: #ffffff;
}

/* blade 136-148: two rows of quick-range buttons, right-aligned from lg up. */
.admin-date-filter .is-ranges {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-date-filter .quick-range-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

@media (min-width: 992px) {
    .admin-date-filter .is-ranges,
    .admin-date-filter .quick-range-row {
        align-items: flex-end;
        justify-content: flex-end;
    }
}

/* V1 `btn btn-sm quick-range-btn`: 28px tall, 4px radius, 14px/18px at 400.
   Inactive is `btn-outline-primary` and active is `btn-primary active`; the
   outline colour pair is the rendered value measured on the live app
   (docs/ui/evidence/admin-cloud/shell/2026-10-30-v1-live-button-and-dashboard-inventory.md §1),
   not Valex's declaration. */
.quick-range-btn {
    min-height: 28px;
    padding: 4px 8px;
    border-radius: 4px;
    font: 400 14px/18px var(--okx-font);
    border: 1px solid var(--okx-primary);
    background: rgba(59, 130, 246, 0.06);
    color: rgb(143, 184, 255);
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
}

.quick-range-btn:hover {
    background: var(--okx-primary-soft);
}

.quick-range-btn.is-active {
    border-color: var(--okx-primary);
    background: var(--okx-primary);
    color: rgb(248, 251, 255);
}

/* blade 151-154: the 180-day clamp notice, V1's `small.text-warning`. */
.admin-date-filter .range-adjusted {
    flex: 0 0 100%;
    color: var(--okx-warning-text);
    font-size: 12px;
}

/* --- dashboard cards 7-8: V1's half-width row, blade 743-782 -----------------
   `row g-3 mb-3` with two `col-12 col-lg-6`, each holding `card h-100 mb-0`.
   The two cards are 705px wide at the measured 1710px viewport, 498 and 677 tall. */
.admin-chart-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    margin-bottom: 16px;
}

@media (min-width: 992px) {
    .admin-chart-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.admin-chart-row > .admin-chart-card {
    margin-bottom: 0;
    display: flex;
    flex-direction: column;
}

.admin-chart-row > .admin-chart-card .admin-chart-card__body {
    flex: 1 1 auto;
}

/* blade 748/1001: the Download control is `text-success fw-semibold` with `bx-download me-1`.
   #22c03c is the rendered success text measured on the live app (Bantuan label, shell
   inventory 2026-10-30 §1), not a token guess. */
.admin-chart-card__action {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #22c03c;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

/* blade 759: `small text-muted` under the donut card title. */
.admin-chart-card__subtitle {
    color: var(--okx-text-faint);
    font-size: 12px;
}

/* blade 66-73: V1's empty widget is a 190px centred muted line. */
.admin-chart-card__empty {
    min-height: 190px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--okx-text-faint);
    font-size: 13px;
}

/* blade 764 `table-responsive mt-2` inside `dashboard-widget-list` (blade 58-65): tighter
   vertical padding and a softer row rule than the ledger tables. */
.admin-chart-card__table {
    margin-top: 8px;
}

/* --- dashboard card 9: Performa KDS Karyawan, blade 786-830 ---------------------
   A full-width card whose body is V1's `row g-3` with `col-12 col-xl-5` holding the 260px chart and
   `col-12 col-xl-7` the employee table: the split is 5/7 and only at Bootstrap's xl (1200px); below
   that the two stack at full width, which is what `col-12` means. `g-3` is a 1rem gutter. */
.admin-chart-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
}

@media (min-width: 1200px) {
    .admin-chart-split {
        grid-template-columns: 5fr 7fr;
    }
}

/* blade 817: the Total Aksi cell is `text-end fw-semibold`, the only column V1 bolds. */
.admin-chart-card__total {
    font-weight: 600;
}

.admin-table.is-compact > tbody > tr > td,
.admin-table.is-compact > thead > tr > th {
    padding-top: .45rem;
    padding-bottom: .45rem;
    border-color: rgba(148, 163, 184, 0.15);
}

/* --- dashboard card 10: Best Seller hide-lists, chart and table ----------------
   Ported from V1's own inline rules (`dashboard.blade.php` 34-57), keeping its numbers:
   a 10px rounded box on a 3% white wash, a 13px/600 summary, a checklist that stops at 170px
   and scrolls, and a 12px muted note. V1's `--default-border` / `--text-muted` become the
   OkePOS tokens that carry the same rendered values. */
.best-seller-filter-form {
    margin-bottom: 16px;
}

.best-seller-filter-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    row-gap: 8px;
}

@media (min-width: 768px) {
    /* V1 `row g-2` with two `col-12 col-md-6`: an 8px gutter from md up. */
    .best-seller-filter-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: 8px;
    }
}

.best-seller-filter-form details {
    border: 1px solid var(--okx-border);
    border-radius: 10px;
    padding: 8px 10px;
    background: rgba(255, 255, 255, 0.03);
}

.best-seller-filter-form summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 13px;
}

.best-seller-checklist {
    max-height: 170px;
    overflow: auto;
    margin-top: 8px;
    padding-right: 4px;
}

.best-seller-check {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 6px;
}

.best-seller-check__input {
    margin-top: 2px;
}

.best-seller-check__label {
    font-size: 13px;
}

.best-seller-mini-note {
    font-size: 12px;
    color: var(--okx-text-faint);
}

.admin-muted {
    color: var(--okx-text-faint);
    font-size: 12px;
}

/* V1 961-963: `col-12 d-flex gap-2` with two `btn-sm` controls. */
.best-seller-filter-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.admin-btn.is-sm {
    min-height: 28px;
    padding: 4px 8px;
    border-radius: 4px;
    font: 400 14px/18px var(--okx-font);
}

/* V1 `btn-sm btn-primary` measured rgb(47,125,255) / rgb(248,251,255). */
.admin-btn.is-sm.is-primary {
    border-color: var(--okx-primary);
    background: var(--okx-primary);
    color: rgb(248, 251, 255);
}

.admin-btn.is-sm.is-primary:hover {
    border-color: var(--okx-primary-strong);
    background: var(--okx-primary-strong);
    color: #ffffff;
}

/* V1 969-970: `table-responsive mt-3` over `table table-sm table-borderless align-middle`. */
.best-seller-table {
    margin-top: 16px;
}

.admin-table.is-borderless > thead > tr > th,
.admin-table.is-borderless > tbody > tr > td {
    border: 0;
}

/* V1 973 pins the Rank column at 54px. */
.admin-table .best-seller-rank {
    width: 54px;
}

/* --- dashboard card 12: Outlet Terlaris (enterprise-only in V1) ----------------
   V1 stacks it under the recap card as `card mt-3` (blade 1008) inside the same
   `col-lg-6`, and its list opens with a 46px rank cell (blade 1021). */
.admin-chart-column {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.admin-chart-column > .admin-chart-card {
    margin-bottom: 0;
}

.admin-table .top-outlet-rank {
    width: 46px;
}

.top-outlet-table {
    margin-top: 8px;
}

/*
 * V1's Master Meja list, two measured declarations (AGENTS §4.3 re-implements V1's presentation
 * faithfully instead of copying the vendor bundle). V1 tags the name cell `fw-bold fs-15`
 * (`outlet-tables/index.blade.php:208`) and the QR URL input `font-monospace fs-12` (`:211`).
 * Measured from what V1's admin layout actually loads (`layouts/admin.blade.php:133-134`):
 * bootstrap.min.css defines `.fw-bold{font-weight:700!important}` and
 * `.font-monospace{font-family:var(--bs-font-monospace)!important}` with
 * `--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace`;
 * styles.css:20598 and :20610 define `.fs-12{font-size:0.75rem}` and `.fs-15{font-size:0.9375rem}`.
 */
.meja-table .meja-cell-number {
    font-weight: 700;
    font-size: 0.9375rem;
}

.meja-table .meja-order-url {
    font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    font-size: 0.75rem;
}

/*
 * V1's Master Meja form pages (`outlet-tables/create.blade.php` and `edit.blade.php`, read
 * 2026-11-02 under V1_MODE = READ_ONLY). Both open with `<div class="mb-3"><a class="btn
 * btn-outline-secondary">&larr; Kembali</a></div>`, then one `card` whose `card-header` holds the
 * page title and whose `card-body` holds a single `form class="row g-3"` of `col-lg-6` / `col-lg-3`
 * fields ending in `col-12 d-flex justify-content-end` + `button class="btn btn-success px-5">Simpan`.
 * Every number here is measured from what V1's admin layout actually loads
 * (`layouts/admin.blade.php:133` bootstrap.min.css and `:134` styles.min.css), not copied from it:
 * `.g-3,.gx-3` / `.g-3,.gy-3` set both gutters to 1rem; `.col-lg-6` is 50% and `.col-lg-3` is 25%,
 * and they only apply from Bootstrap's lg breakpoint `@media (min-width:992px)` — below it every
 * column is full width, which is what the 12-track grid's default span reproduces; `.px-4` is
 * 1.5rem, `.px-5` is 3rem and `.mb-3` is 1rem.
 */
.meja-form-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 16px;
}

.meja-form-grid > * {
    grid-column: span 12;
}

@media (min-width: 992px) {
    .meja-form-grid .is-half {
        grid-column: span 6;
    }

    .meja-form-grid .is-third {
        grid-column: span 3;
    }
}

.meja-form-grid .meja-form-actions {
    display: flex;
    justify-content: flex-end;
}

.meja-back-row {
    margin-bottom: 16px;
}

.admin-btn.is-px-4,
.admin-primary.is-px-4 {
    padding-inline: 1.5rem;
}

.admin-btn.is-px-5,
.admin-primary.is-px-5 {
    padding-inline: 3rem;
}
