/* =============================================================================
   NoExcel — overrides on top of KeenThemes Craft (light theme only).

   Stock Keen Craft wearing the NoExcel blue, plus the looks the project owner kept:
   heading polish, tabs and pills, the sidebar, DataTables sort carets, cards, table
   headers and numerals, form labels and the keyboard focus ring. Build everything else
   with Bootstrap/Keen utility classes in the template. Before adding a rule here, try
   a utility — and if you still need CSS, write down why a utility could not do it.
   ============================================================================= */

/* The NoExcel blue. Keen hard-codes its own #00A3FF family into dozens of variables
   instead of reading --bs-primary, so every one that reaches the UI is set here. The
   marketing pages pin data-bs-theme="light" on a wrapper, where Keen re-declares the
   variables, hence the second selector.
   Not overridden: success / warning / danger / info / greys / secondary stay Keen's. */
:root,
[data-bs-theme="light"] {
    --brand-primary-rgb: 53, 104, 221;
    --bs-primary: #3568dd;
    --bs-primary-rgb: var(--brand-primary-rgb);
    --bs-primary-hover: #4b79e3;
    --bs-primary-active: #2d59bf;
    --bs-primary-light: #e1e9fb;
    /* Bootstrap's own tints/shade of the primary, worked out for the brand
       (80% / 60% white, 60% black). Read by .alert-primary and *-primary-subtle. */
    --bs-primary-bg-subtle: #d7e1f8;
    --bs-primary-border-subtle: #aec3f1;
    --bs-primary-text-emphasis: #152a58;
    --bs-text-primary: #3568dd;
    --bs-link-color: #3568dd;
    --bs-link-color-rgb: var(--brand-primary-rgb);
    --bs-link-hover-color: #2d59bf;
    --bs-link-hover-color-rgb: 45, 89, 191;
    --bs-focus-ring-color: rgba(var(--brand-primary-rgb), 0.25);
    --bs-component-active-bg: #3568dd;
    --bs-component-hover-color: #3568dd;
    --bs-menu-link-color-hover: #3568dd;
    --bs-menu-link-color-show: #3568dd;
    --bs-menu-link-color-here: #3568dd;
    --bs-menu-link-color-active: #2d59bf;
    --bs-scrolltop-bg-color-hover: #2d59bf;
    --bs-ribbon-label-bg: #3568dd;
    --bs-ribbon-label-border-color: #2d59bf;
}

/* Surfaces and motion for the sidebar, cards and tables below. Borders-first theme:
   a card lifts with a 1px ring and two whisper-quiet depths, not a drop shadow. */
:root {
    --nx-border-hairline: rgba(0, 0, 0, 0.06);
    --nx-shadow-card:
        0 0 0 1px var(--nx-border-hairline), 0 1px 2px -1px rgba(0, 0, 0, 0.06),
        0 2px 6px rgba(0, 0, 0, 0.03);
    --nx-shadow-card-hover:
        0 0 0 1px rgba(var(--brand-primary-rgb), 0.25),
        0 4px 10px -2px rgba(0, 0, 0, 0.08), 0 10px 24px rgba(0, 0, 0, 0.05);
    --nx-radius-lg: 0.9rem;
    --nx-ease: cubic-bezier(0.23, 1, 0.32, 1);
    --nx-duration-fast: 120ms;
}

/* The rest of Keen's blue, which no :root variable reaches: rules that write #00a3ff,
   rgba(0,163,255,.25) or rgb(51,181,255) as a literal, and variables Bootstrap declares on the
   component itself. */

/* Checked checkbox / radio / switch and an indeterminate box. The coloured variants
   (.form-check-success …) out-rank this and keep their own colour. */
.form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
}

.form-check.form-check-solid .form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--bs-primary);
}

/* Keyboard focus ring on tab / pill links. */
.nav-link:focus-visible {
    box-shadow: 0 0 0 0.25rem var(--bs-focus-ring-color);
}

/* Bootstrap declares these on the component itself, so :root cannot reach them: the active
   pill's fill, and the fill of a .progress-bar that carries no bg-* class. */
.nav-pills {
    --bs-nav-pills-link-active-bg: var(--bs-primary);
}

.progress,
.progress-stacked {
    --bs-progress-bar-bg: var(--bs-primary);
}

/* The chevron of an expanded accordion (a data-URI SVG, so only a full redeclaration works). */
.accordion {
    --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%233568DD'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

/* Bootstrap's hover tint for .link-primary (login page links). !important: Bootstrap's is. */
.link-primary:hover,
.link-primary:focus {
    color: var(--bs-primary-hover) !important;
}

/* -----------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */

body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Headings tighten as they grow — default tracking on a 28px heading reads like a document, not
   an interface — and wrap evenly instead of leaving a one-word last line. */
h1,
h2,
h3,
.h1,
.h2,
.h3 {
    letter-spacing: -0.02em;
    text-wrap: balance;
}

p,
.text-muted,
.form-text {
    text-wrap: pretty;
}

/* Nastaliq is a connected script — the negative tracking above would break the joins. */
html[dir="rtl"] :is(h1, h2, h3, .h1, .h2, .h3) {
    letter-spacing: normal;
}

/* Urdu (RTL). A font family and an @font-face cannot be a utility class; and
   Nastaliq's tall ascenders/descenders clip at Keen's default line-heights. */
@font-face {
    font-family: "Noto Nastaliq Urdu";
    src: url("/preCompiledAssets/fonts/Noto_Nastaliq_Urdu/static/NotoNastaliqUrdu-Regular.ttf")
        format("truetype");
    font-display: swap;
}

html[dir="rtl"] body,
html[dir="rtl"] input,
html[dir="rtl"] button,
html[dir="rtl"] textarea,
html[dir="rtl"] select {
    font-family: "Noto Nastaliq Urdu", "Inter", sans-serif;
}

html[dir="rtl"]
    :is(
        body,
        h1,
        h2,
        h3,
        .h1,
        .h2,
        .h3,
        .card-title,
        .form-control,
        .form-select,
        .btn,
        .menu-title,
        .badge
    ) {
    line-height: 1.8;
}

/* Directional glyphs must mirror in RTL. Neither Bootstrap Icons nor Font Awesome
   flip themselves, and a direction-conditional transform is not a utility class. */
html[dir="rtl"] .bi-chevron-right,
html[dir="rtl"] .bi-chevron-left,
html[dir="rtl"] .bi-arrow-right,
html[dir="rtl"] .bi-arrow-left,
html[dir="rtl"] .bi-box-arrow-up-right,
html[dir="rtl"] .fa-arrow-left,
html[dir="rtl"] .fa-arrow-right {
    display: inline-block;
    transform: scaleX(-1);
}

/* -----------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */

/* Hairline dividers: the aside's edge, under the logo, under the header. */
.aside {
    border-inline-end: 1px solid var(--nx-border-hairline);
}

.aside-logo,
.header {
    border-block-end: 1px solid var(--nx-border-hairline);
}

/* The menu is a flex column under the logo, so the scroll area is sized by flex rather than
   by the viewport sum in data-kt-scroll (it survives a wrapped logo or an impersonation bar).
   Primary nav stays at the top; the last section (Users / Settings / Support) is pinned to the
   bottom with a divider above it. Flex layout and a section divider are not utilities. */
.aside-menu {
    flex-shrink: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.aside-menu .menu {
    flex-grow: 1;
    min-height: 0;
    padding-block: 0.5rem 1rem;
}

.aside-menu .menu .hover-scroll-y {
    flex-grow: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.aside-menu .menu .hover-scroll-y > .menu-section:last-child {
    margin-block-start: auto;
    padding-block-start: 0.75rem;
    border-block-start: 1px solid var(--nx-border-hairline);
}

/* Scrollbar. Only Safari (and old Chromium) render these: current Chromium and Firefox follow
   Keen's scrollbar-width / scrollbar-color, which makes them ignore the pseudo-elements. */
.aside-menu .menu .hover-scroll-y::-webkit-scrollbar {
    width: 6px;
}

.aside-menu .menu .hover-scroll-y::-webkit-scrollbar-track {
    background: transparent;
}

.aside-menu .menu .hover-scroll-y::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.1);
    border-radius: 3px;
}

.aside-menu .menu .hover-scroll-y:hover::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.16);
}

.aside-menu .menu-link {
    transition:
        background-color var(--nx-duration-fast) var(--nx-ease),
        color var(--nx-duration-fast) var(--nx-ease);
}

/* The active item earns a leading marker as well as a tint — colour alone is a weak signal,
   and it is the one thing the eye scans for on every page load. A pseudo-element is not a
   utility. */
.aside-menu .menu-item .menu-link.active {
    position: relative;
    font-weight: 600;
}

.aside-menu .menu-item .menu-link.active::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 1.25rem;
    border-radius: 0 3px 3px 0;
    background-color: var(--bs-primary);
}

html[dir="rtl"] .aside-menu .menu-item .menu-link.active::before {
    border-radius: 3px 0 0 3px;
}

.aside-menu .menu-icon {
    flex-basis: 1.75rem;
}

/* -----------------------------------------------------------------------------
   Keyboard focus
   -------------------------------------------------------------------------- */

/* One brand-blue ring for whatever a keyboard can reach, drawn only for keyboard focus
   (:focus-visible), never after a mouse click. Text inputs and selects keep Keen's own focus
   style: `.form-control:focus { outline: 0 }` is more specific than this. */
:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

/* Buttons and menu links need !important: Keen sets `.menu-item .menu-link { outline: 0
   !important }` on sidebar and dropdown links, and Bootstrap `.btn:focus-visible { outline: 0 }`,
   so a plain rule leaves them with no focus indicator at all. */
.btn:focus-visible,
.menu-item .menu-link:focus-visible {
    outline: 2px solid var(--bs-primary) !important;
    outline-offset: 2px;
}

/* A destructive menu item (row_action `danger`) gets a pale red wash on hover and keyboard focus,
   its red text unchanged. !important: Keen's `menu-state-bg*` hover selectors are far more specific. */
.menu-link.text-danger:hover,
.menu-link.text-danger:focus-visible {
    background-color: rgba(var(--bs-danger-rgb), 0.08) !important;
}

/* -----------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.card {
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-card);
}

/* Concentric radius: a header flush against a rounded card needs the card's radius. */
.card > .card-header:first-child {
    border-start-start-radius: var(--nx-radius-lg);
    border-start-end-radius: var(--nx-radius-lg);
}

/* A card that is itself a link (the settings hub): lift and ring on hover/focus. */
a > .card,
.card.hover-scale {
    transition:
        box-shadow 180ms var(--nx-ease),
        transform 180ms var(--nx-ease);
}

a:hover > .card,
a:focus-visible > .card,
.card.hover-scale:hover {
    box-shadow: var(--nx-shadow-card-hover);
    transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
    a:hover > .card,
    a:focus-visible > .card,
    .card.hover-scale:hover {
        transform: none;
    }
}

/* -----------------------------------------------------------------------------
   Tables and numerals
   -------------------------------------------------------------------------- */

/* The header row demotes to a label so the data leads. Size, weight, colour and case come from
   utility classes on the <tr> (`text-gray-500 fw-bold fs-7 text-uppercase`); Craft's
   `.table:not(.table-bordered) th` forces those four to `inherit`, and the utilities win only
   because they are !important — so only tracking and wrapping live here. */
.table > thead > tr > th {
    letter-spacing: 0.04em;
    white-space: nowrap;
    vertical-align: middle;
}

/* Nastaliq is a connected script — letter-spacing breaks the joins. */
html[dir="rtl"] .table > thead > tr > th {
    letter-spacing: normal;
}

/* Row height is the biggest readability lever on a dense listing; table-sm alone packs rows too tight. */
.table > tbody > tr > td {
    padding-block: 0.7rem;
    vertical-align: middle;
}

.table-hover > tbody > tr {
    transition: background-color var(--nx-duration-fast) var(--nx-ease);
}

/* Row-action dropdowns. `.menu-sub-dropdown` has no width of its own and Keen defines no `w-180px`
   (or `w-160px`) utility, so KTMenu's fixed-position dropdown would span the whole viewport.
   !important: it also fixes the menus that carry a real utility such as `w-200px`. */
.table td > .menu.menu-sub.menu-sub-dropdown {
    width: 180px !important;
}

/* Fixed-width digits for every figure compared down a column, so decimals line up. */
.table td,
.table th,
.fs-2hx,
.fs-2x,
.fs-2,
.badge {
    font-variant-numeric: tabular-nums;
}

/* DataTables sort indicators. assets/nx-datatable.js injects `.nx-sort` (an up and a down caret,
   laid out and muted with utility classes) into every sortable header. Only what a utility cannot
   express lives here: switching off Keen's own pseudo-element arrows, and turning the caret that
   matches the <th>'s `sorting_asc` / `sorting_desc` state primary. */
table.dataTable > thead > tr > th.sorting::before,
table.dataTable > thead > tr > th.sorting::after,
table.dataTable > thead > tr > th.sorting_asc::before,
table.dataTable > thead > tr > th.sorting_asc::after,
table.dataTable > thead > tr > th.sorting_desc::before,
table.dataTable > thead > tr > th.sorting_desc::after {
    display: none !important;
}

table.dataTable > thead > tr > .sorting_asc .nx-sort > .bi-caret-up-fill,
table.dataTable > thead > tr > .sorting_desc .nx-sort > .bi-caret-down-fill {
    /* !important: the carets carry `text-gray-300`, itself !important, which this must outrank. */
    color: var(--bs-primary) !important;
}

/* form_errors() renders a field's errors as a bare <ul> with no class hook, so only a descendant
   selector can reach it; in a narrow line-grid cell its 2rem indent and bullets squeeze the
   message to a word per line. */
.table td .invalid-feedback > ul {
    padding: 0;
    margin: 0;
    list-style: none;
}

/* -----------------------------------------------------------------------------
   Tabs and pills
   -------------------------------------------------------------------------- */

/* Grey until hovered, brand-dark when active; the active pill is a bold tint rather than Keen's
   solid fill. Keen's own line-tab colours are more specific and stay for inactive line tabs. */
.nav .nav-link {
    color: var(--bs-gray-700);
}

.nav .nav-link:hover,
.nav .nav-link:focus {
    color: var(--bs-primary);
}

.nav .nav-link.active,
.nav .show > .nav-link,
.nav-line-tabs .nav-item .nav-link.active,
.nav-line-tabs .nav-item .nav-link.active i {
    color: var(--bs-primary-active);
}

.nav-pills .nav-link.active {
    font-weight: bold;
    background-color: var(--bs-primary-light);
}

.nav-tabs .nav-item.show .nav-link,
.nav-tabs .nav-link.active {
    color: var(--bs-primary-active);
    font-weight: bold;
}

/* -----------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

/* Keen rounds inputs at its small radius (.425rem); the rest of the UI uses the base one. */
.form-control,
.form-select {
    border-radius: var(--bs-border-radius);
}

/* A label reads as a label, not as body copy. */
.form-label {
    font-weight: 600;
    color: var(--bs-gray-700);
    margin-bottom: 0.4rem;
}

.form-check-label {
    color: var(--bs-gray-800);
}

/* Active/inactive switch (admin/components/active_switch.html.twig): both words are in the markup
   and the one for the checkbox's current state is shown. A sibling-of-:checked selector — no
   utility class can react to the input's state, and this needs no JS. */
.nx-state-switch .form-check-input:checked ~ .form-check-label .nx-state-off,
.nx-state-switch
    .form-check-input:not(:checked)
    ~ .form-check-label
    .nx-state-on {
    display: none;
}

/* Dashboard bar charts put the full (up to 255-char) name in the tooltip title; ApexCharts' title
   is nowrap and injected by the library, so it can only be reached from here. */
.apexcharts-tooltip-title {
    max-width: 22rem;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* -----------------------------------------------------------------------------
   Compact layout, the admin default. Keen hard-codes every one of these gaps in px on its own
   element, per breakpoint (.content 30/20, .container(-fluid) 30/20, .toolbar 30/20, .wrapper 40,
   .card-header and .card-body 29/26), so no utility class can reach them from the shared layout:
   one rule per Keen rule, nothing else. Each selector matches the specificity of the Keen rule it
   replaces and this file loads after the Keen bundle, so it wins on order; where Keen's rule is
   more specific (`.toolbar-enabled .content .toolbar`, `.aside-default-enabled.aside-fixed
   .wrapper`) the selector repeats Keen's. Only the admin shell (admin/base.html.twig) uses these
   layout classes; the POS and the public pages have their own markup and are untouched.
   -------------------------------------------------------------------------- */

/* Header -> page title, and the gap under the title row. */
.content {
    padding-block: 1rem;
}

.toolbar-enabled .content .toolbar {
    margin-bottom: 0;
    padding-bottom: 0.5rem;
}

/* Sidebar -> card gutter; the header bar, the title row and the cards share it so they stay aligned.
   `.container` is the centred wrapper the narrow form pages use inside `.content`. */
.header .container-fluid,
.content .container,
.content .container-fluid {
    padding-inline: 1.25rem;
}

/* Far edge of the page (Keen has no right margin below lg, so only wide screens). */
@media (min-width: 992px) {
    .wrapper {
        padding-inline-end: 1.25rem;
    }
}

/* Inside the cards. Keen's `.card-px-0`/`-p-0` variants are more specific and still win. */
.card .card-header {
    padding-inline: 1.25rem;
}

.card .card-body {
    padding: 1.25rem;
}

/* The listing filter bar's `pt-6` is a utility (!important), so only !important can tighten it. */
.card-header.pt-6 {
    padding-top: 0.75rem !important;
}

/* Compact shell: the sidebar's width and the header's height. Keen writes both as bare px in a
   dozen places (aside, aside menu, wrapper padding, header height, the minimised hover state), so
   they are set once as two variables here and every rule below reads them. Desktop only for the
   width: under 992px the aside is a drawer. Not synced: Keen's `data-kt-sticky-header` rules
   (fixed header at 65px, `left: 300px`, wrapper `padding-top: 90px`) - nothing in the app puts
   `data-kt-sticky` on the header, so that state never turns on. */
:root {
    --nx-header-h: 52px;
    --nx-aside-w: 240px;
}

.header {
    height: var(--nx-header-h);
}

@media (min-width: 992px) {
    :root {
        --nx-header-h: 64px;
    }

    /* The minimised rail (100px) and its wrapper offset are Keen's own and stay: their rules are
       more specific than these, so only the expanded width changes. */
    .aside.aside-default {
        width: var(--nx-aside-w);
    }

    .aside-default-enabled.aside-fixed .wrapper {
        padding-inline-start: var(--nx-aside-w);
    }

    /* The menu is clipped by the aside, so it must be as wide as the aside's expanded (and
       hover-expanded) width. */
    .aside.aside-default .aside-menu {
        width: var(--nx-aside-w);
    }

    [data-kt-aside-minimize="on"] .aside.aside-default.aside-hoverable:hover {
        width: var(--nx-aside-w);
    }

    /* The logo block ends where the header does, so their hairlines line up. The markup's `py-5`
       is a utility (!important), so dropping the padding needs !important too. */
    .aside-logo {
        height: var(--nx-header-h);
        padding-block: 0 !important;
    }

    .aside-logo img {
        height: 40px;
    }
}

/* Login/reset split shell: brand-blue gradient + dot pattern. A gradient with a layered pattern cannot be
   expressed with utilities; reads the brand tokens so it follows the primary colour. */
.nx-auth-aside {
    background:
        radial-gradient(rgba(255, 255, 255, 0.12) 1px, transparent 1px) 0 0 /
            22px 22px,
        linear-gradient(
            145deg,
            var(--bs-primary) 0%,
            var(--bs-primary-active) 100%
        );
}
