/* Petrol Pump System — shared styling. RTL/Urdu throughout, no external JS/icon library. */

* { box-sizing: border-box; }

:root {
    /* Pump/fuel-company brand colors — fallback only; real values are injected as
       inline :root vars by includes/header.php from config/app.php (BRAND_COLOR_1/2/3),
       which is the single place to change them. */
    --brand-1: #E31E24;
    --brand-2: #00338D;
    --brand-3: #F7941D;

    /*
     * Poore theme ke structural colors (topbar, sidebar, buttons, active states,
     * login screen) ab seedha brand colors se nikalte hain — is liye pump ki
     * company badalne par (config/app.php mein sirf 3 lines) poori site ka color
     * scheme khud-b-khud update ho jata hai, kisi aur jagah kuch badalne ki
     * zaroorat nahi. color-mix() se lighter/darker shades apne aap ban jate hain.
     */
    --navy: var(--brand-2);
    --navy-light: color-mix(in srgb, var(--brand-2) 78%, white 22%);
    --navy-dark: color-mix(in srgb, var(--brand-2) 72%, black 28%);
    /* Sep 2026 REVERT (owner: "side bar ka aur border ka color jo blue
       pehlay tha woh kar do") — a "premium look" pass earlier this month had
       moved the sidebar/topbar/handle from the original heavy dark navy
       gradient to a light, near-white surface (see this same comment's
       previous wording, kept in git history / earlier patch zips if it's
       ever needed again). The owner wants the original blue back, so
       --sidebar-from/--sidebar-to/--topbar-bg/--sidebar-text/
       --sidebar-text-hover/--sidebar-hover-bg below are restored to the
       same dark-navy-gradient values the pristine baseline (orig139) used —
       exact values confirmed against that baseline, not guessed. The .topbar
       rule and the two "active" rules (.sidebar a.active,
       .sidebar-group summary.active) further down needed matching direct
       reverts too (their light-mode versions don't just fall out of these
       vars) — see their own comments. --navy itself stays UNCHANGED either
       way — every other page's headings/buttons/active states never moved. */
    --sidebar-from: color-mix(in srgb, var(--brand-2) 55%, black 45%);
    --sidebar-to: color-mix(in srgb, var(--brand-2) 22%, black 78%);
    --topbar-bg: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);
    --sidebar-text: #a9b6c9;
    --sidebar-text-hover: #fff;
    --sidebar-hover-bg: rgba(255,255,255,0.06);
    --accent: var(--brand-3);        /* primary call-to-action / active-state color */
    --accent-dark: color-mix(in srgb, var(--brand-3) 78%, black 22%);
    --accent-soft: color-mix(in srgb, var(--brand-3) 16%, transparent);
    --brand-red: var(--brand-1);
    --blue: #2563eb;
    --purple: #7c3aed;
    --green: #16a34a;
    --bg: #f4f6fa;
    --border: #e5e7eb;
    --text: #1f2937;
    --muted: #6b7280;

    /* Modern layered shadow scale (Stripe/Linear-style soft elevation) — used
       across cards, inputs, buttons instead of one flat box-shadow value. */
    --shadow-xs: 0 1px 2px rgba(16,24,40,0.05);
    --shadow-sm: 0 1px 3px rgba(16,24,40,0.08), 0 1px 2px rgba(16,24,40,0.05);
    --shadow-md: 0 4px 10px rgba(16,24,40,0.07), 0 2px 4px rgba(16,24,40,0.05);
    --shadow-lg: 0 12px 28px rgba(16,24,40,0.12), 0 4px 10px rgba(16,24,40,0.06);
    --radius-sm: 10px;
    --radius-md: 14px;
    --radius-lg: 20px;
}

/*
 * Jameel Noori Nastaleeq — the standard Urdu font used across Pakistan (bundled with
 * InPage and most Urdu word processors, so it's already installed on most Windows PCs
 * used for this kind of work). If it's installed locally the browser uses it directly
 * via local(); if not, and a copy has been placed in assets/fonts/ (see the README
 * there), that file is used instead; if neither is available it falls back to
 * Noto Nastaliq Urdu (loaded from Google Fonts) so Urdu text always looks right.
 */
@font-face {
    font-family: 'Jameel Noori Nastaleeq';
    src: local('Jameel Noori Nastaleeq'),
         local('JameelNooriNastaleeq'),
         local('Jameel Noori Nastaleeq Regular'),
         url('fonts/JameelNooriNastaleeq.woff2') format('woff2'),
         url('fonts/JameelNooriNastaleeq.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

/*
 * Calibri — owner's request: "saari application main font calibri kar kay
 * daikho". Real Calibri is a Microsoft font (bundled with Windows/Office) —
 * not something that can legally be redistributed inside this project, so
 * it CANNOT simply be bundled the way Nastaleeq's file is (same reasoning
 * as the note in assets/fonts/README.txt). Instead these @font-face rules
 * register the name "Calibri" itself in two tiers, so every visitor sees
 * the exact same look regardless of what's installed on their device:
 *   1. local('Calibri') — a visitor on Windows/Office already has the real
 *      font installed, so the browser uses the genuine Calibri directly.
 *   2. Otherwise, falls back to the bundled Carlito files
 *      (assets/fonts/Carlito-*) — Carlito is Google/Red Hat's free,
 *      openly-licensed (SIL Open Font License) metric-compatible match for
 *      Calibri (it's literally what LibreOffice ships as its Calibri
 *      substitute), so spacing/line-breaks match Calibri almost exactly and
 *      it reads as the same typeface to the eye. This is what makes a phone,
 *      Mac or Linux visitor (none of which normally have real Calibri) also
 *      see a proper Calibri-style look instead of silently falling back to
 *      Segoe UI/Arial.
 * All existing "font-family: Calibri, 'Segoe UI', Arial, ..." rules below
 * (and elsewhere in this file) need no change — they already ask for
 * "Calibri" by name, so they pick this up automatically.
 */
@font-face {
    font-family: 'Calibri';
    src: local('Calibri'), local('Calibri Regular'),
         url('fonts/Carlito-Regular.woff') format('woff'),
         url('fonts/Carlito-Regular.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Calibri';
    src: local('Calibri Bold'), local('Calibri-Bold'),
         url('fonts/Carlito-Bold.woff') format('woff'),
         url('fonts/Carlito-Bold.ttf') format('truetype');
    font-weight: bold;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Calibri';
    src: local('Calibri Italic'), local('Calibri-Italic'),
         url('fonts/Carlito-Italic.woff') format('woff'),
         url('fonts/Carlito-Italic.ttf') format('truetype');
    font-weight: normal;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: 'Calibri';
    src: local('Calibri Bold Italic'), local('Calibri-BoldItalic'),
         url('fonts/Carlito-BoldItalic.woff') format('woff'),
         url('fonts/Carlito-BoldItalic.ttf') format('truetype');
    font-weight: bold;
    font-style: italic;
    font-display: swap;
}

body {
    margin: 0;
    font-family: Calibri, 'Segoe UI', Arial, -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.5;
}

h1, h2, h3, h4 { font-family: inherit; }

/* Urdu mode: Jameel Noori Nastaleeq (falls back to Noto Nastaliq Urdu, then Tahoma) */
html[lang="ur"] body {
    font-family: 'Jameel Noori Nastaleeq', 'Noto Nastaliq Urdu', Tahoma, sans-serif;
    font-size: 19px;
    line-height: 2.1; /* Nastaliq needs extra breathing room */
}

/* English mode: Calibri first (most PCs have it via MS Office), Segoe UI as a
   modern-Windows fallback, then Arial as the universal fallback. */
html[lang="en"] body {
    font-family: Calibri, 'Segoe UI', Arial, -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
    font-size: 15px;
    line-height: 1.5;
}

.icon { flex-shrink: 0; }

/* ---- top bar ----
   Sep 2026 REVERT (owner: "side bar ka aur border ka color jo blue pehlay
   tha woh kar do") — back to the original dark navy gradient (--topbar-bg
   now HOLDS that gradient — see the :root comment above) with a heavier
   drop-shadow instead of the light/white "premium" hairline-border version
   that briefly replaced it. The brand strip (::after, unchanged below)
   still reads as a nice colored accent line right under it, same as always. */
.topbar {
    /* Sticky positioning is kept (a header that stays put while you scroll
       is a plain usability win, unrelated to the color revert above). */
    background: var(--topbar-bg);
    color: #fff;
    padding: 12px 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 2px 10px rgba(0,0,0,0.15);
    position: sticky;
    top: 0;
    z-index: 5;
}

/* thin 3-color brand strip (config/app.php: BRAND_COLOR_1/2/3) echoing the
   fuel company's identity right under the top bar */
.topbar::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -3px;
    height: 3px;
    background: linear-gradient(90deg, var(--brand-1), var(--brand-2), var(--brand-3));
}

.topbar .brand {
    /* Sep 2026 REVERT — no explicit color: the topbar itself is dark navy
       again (see .topbar above), so this just inherits its white text,
       same as the original. (It briefly needed its own navy color here
       while the topbar was light/white — that's gone now.) */
    font-weight: 700;
    font-size: 20px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.brand-emoji {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%);
    font-size: 19px;
    box-shadow: 0 3px 8px rgba(0,0,0,0.25);
}
.login-box h1 .brand-emoji { width: 50px; height: 50px; font-size: 26px; }

/* used only if config/app.php's APP_LOGO is set to an image file */
.brand-logo { height: 34px; width: auto; vertical-align: middle; border-radius: 6px; }
.login-box h1 .brand-logo { height: 46px; }

.topbar .user-info {
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: 4px;
}

.user-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: rgba(255,255,255,0.10);
    padding: 6px 12px;
    border-radius: 999px;
}

.topbar a {
    color: #fff;
    text-decoration: none;
    margin-inline-start: 12px;
    opacity: 0.9;
}

.topbar a:hover { opacity: 1; }

/* Header "Hide/Show tabs" horizontal pull-tab (Oct 2026) — hangs from the bottom edge of the top
   bar, centred. Chevron points up while the tab strip is open (click = tuck it away) and flips to
   point down, with an orange accent, while it is hidden. */
.tabs-toggle {
    position: absolute;
    left: 50%; bottom: -19px;
    transform: translateX(-50%);
    z-index: 6;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px; height: 22px;
    padding: 0; margin: 0;
    color: rgba(255,255,255,0.92);
    background: linear-gradient(180deg, var(--navy-dark) 0%, color-mix(in srgb, var(--navy) 88%, white 12%) 100%);
    border: 1px solid rgba(255,255,255,0.22);
    border-top: none;
    border-bottom-left-radius: 12px;
    border-bottom-right-radius: 12px;
    box-shadow: 0 5px 14px rgba(15,23,42,0.28), inset 0 -1px 0 rgba(255,255,255,0.18);
    cursor: pointer;
    transition: width 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.tabs-toggle[hidden] { display: none; }
.tabs-toggle::before {
    content: '';
    position: absolute; left: 16px; right: 16px; bottom: 3px; height: 2px; border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--brand-3, #F7941D), transparent);
    opacity: 0.8;
}
.tabs-toggle svg { width: 15px; height: 15px; stroke-width: 2.4; margin-top: -3px; transition: transform 0.3s ease; }
.tabs-toggle:hover {
    width: 82px;
    background: linear-gradient(180deg, var(--navy-dark) 0%, color-mix(in srgb, var(--brand-3, #F7941D) 55%, var(--navy) 45%) 100%);
    box-shadow: 0 6px 18px rgba(247,148,29,0.38), inset 0 -1px 0 rgba(255,255,255,0.25);
}
.tabs-toggle.is-off svg { transform: rotate(180deg); }
.tabs-toggle.is-off::before { opacity: 1; height: 3px; }

/* Sep 2026 REVERT (owner: "...jo blue pehlay tha woh kar do") — back to the
   original translucent-white-on-dark treatment (a light frosted overlay
   that just gets a touch brighter on hover), matching the topbar's own
   dark-navy background again — the light-mode "soft color-tinted pill"
   version (pale red/blue backgrounds with colored text) briefly used here
   only made sense against a white topbar. */
.logout-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(255,255,255,0.10);
    padding: 6px 14px;
    border-radius: 999px;
    transition: background 0.15s ease;
}
.logout-link:hover { background: rgba(255,255,255,0.22); text-decoration: none !important; }

.lang-toggle {
    display: inline-flex;
    align-items: center;
    background: rgba(255,255,255,0.14);
    padding: 6px 14px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    transition: background 0.15s ease;
}
.lang-toggle:hover { background: rgba(255,255,255,0.26); text-decoration: none !important; }

.lang-toggle-standalone {
    position: fixed;
    top: 16px;
    inset-inline-end: 20px;
    background: linear-gradient(135deg, var(--navy) 0%, #24467a 100%);
    color: #fff;
    padding: 8px 18px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 3px 10px rgba(0,0,0,0.2);
}
.lang-toggle-standalone:hover { filter: brightness(1.1); }

/* ---- layout ---- */
.layout {
    display: flex;
    min-height: calc(100vh - 60px);
}

.sidebar {
    width: 240px;
    /* Sep 2026 REVERT (owner: "side bar ka aur border ka color jo blue
       pehlay tha woh kar do") — back to the original dark navy gradient
       (--sidebar-from/--sidebar-to restored to the pristine-baseline values
       in the :root comment above); the light/near-white "premium" version
       and its border-inline-end separator (needed there only because a
       white sidebar has no contrast against a white .content area) are
       gone — the dark background alone provides that separation again,
       same as the original never having that border either. */
    background: linear-gradient(180deg, var(--sidebar-from) 0%, var(--sidebar-to) 100%);
    color: var(--sidebar-text);
    padding: 18px 12px;
    flex-shrink: 0;
    overflow-x: hidden;
    white-space: nowrap;
    transition: width 0.35s ease, padding-inline 0.35s ease, opacity 0.25s ease;
    /* Sep 2026 owner request ("sidepan ke scrollbar alehda ho and body ke
       alehda body ke scroll bar pan par chal rhe") — .sidebar is a flex
       child of .layout with no height of its own, so it was stretching to
       match .content's height (flex's default align-items:stretch) on any
       page whose content ran long; on a tall Business Overview page this
       meant the sidebar's menu links scrolled away with the page along ONE
       shared scrollbar, leaving a blank stretch of its own background
       showing once you'd scrolled past them. Same fix already used for the
       narrow-screen drawer version of this same element just below (its own
       "position:fixed; top:60px; overflow-y:auto") — pin the sidebar under
       the sticky .topbar (60px, matching .layout's own calc(100vh - 60px))
       and let it scroll its OWN menu list independently, while .content
       keeps scrolling the page underneath it on the page's own scrollbar. */
    position: sticky;
    top: 60px;
    align-self: flex-start;
    height: calc(100vh - 60px);
    overflow-y: auto;
    scrollbar-width: thin;
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.22); border-radius: 4px; }
.sidebar::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.35); }

/* ---- auto-hide sidebar (Windows-taskbar style) ----
   20 second tak sidebar ke saath koi interaction na ho to wo khud collapse ho
   jata hai taake content ke liye zyada jagah mile; chhoti si "handle" tab
   humesha nazar aati hai jise hover/click/tap karne se sidebar wapas khul
   jata hai. Logic includes/footer.php mein hai (SIDEBAR_HIDE_DELAY_MS). */
body.sidebar-is-hidden .sidebar {
    width: 0;
    padding-inline: 0;
    opacity: 0;
    pointer-events: none;
}

.sidebar-handle {
    /* Oct 2026 premium vertical pull-tab (owner: "hide unhide ka icon ... vertical and horizental
       2no jagah lgao ... Premium look") — always visible on the sidebar's outer edge, slides to the
       screen edge while the menu is hidden, and its chevron flips to show which way it will go.
       It is a real <button>, so the site-wide `button { padding: 11px 24px }` needs the explicit
       padding:0 below or the box could never get narrower than that padding. */
    display: flex;
    position: fixed;
    top: 50%;
    inset-inline-start: 240px;
    transform: translateY(-50%);
    z-index: 20;
    width: 22px;
    height: 72px;
    padding: 0;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255,255,255,0.22);
    border-inline-start: none;
    border-start-end-radius: 12px;
    border-end-end-radius: 12px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--navy) 88%, white 12%) 0%, var(--navy-dark) 100%);
    color: rgba(255,255,255,0.92);
    cursor: pointer;
    box-shadow: 4px 0 16px rgba(15,23,42,0.28), inset 0 1px 0 rgba(255,255,255,0.18);
    transition: inset-inline-start 0.35s ease, background 0.2s ease, box-shadow 0.2s ease, width 0.2s ease;
}
.sidebar-handle svg { width: 15px; height: 15px; stroke-width: 2.4; transform: rotate(-90deg); transition: transform 0.35s ease; }
.sidebar-handle::before {
    /* thin brand-orange accent along the outer edge */
    content: '';
    position: absolute; top: 14px; bottom: 14px; inset-inline-end: 3px;
    width: 2px; border-radius: 2px;
    background: linear-gradient(180deg, transparent, var(--brand-3, #F7941D), transparent);
    opacity: 0.8;
}
.sidebar-handle:hover {
    width: 26px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--brand-3, #F7941D) 55%, var(--navy) 45%) 0%, var(--navy-dark) 100%);
    box-shadow: 5px 0 20px rgba(247,148,29,0.35), inset 0 1px 0 rgba(255,255,255,0.25);
}
body.sidebar-is-hidden .sidebar-handle { inset-inline-start: 0; }
body.sidebar-is-hidden .sidebar-handle svg { transform: rotate(90deg); }
[dir="rtl"] .sidebar-handle svg { transform: rotate(90deg); }
[dir="rtl"] body.sidebar-is-hidden .sidebar-handle svg { transform: rotate(-90deg); }
@media print { .sidebar-handle { display: none !important; } }

/* ---- narrow screens: sidebar becomes an off-canvas drawer ----
   Below this width the sidebar used to sit in the same flex row as .content
   (240px fixed + flex:1 content), which on a phone-width screen squeezed the
   entire page into a sliver a few tens of pixels wide. Taking it out of flow
   (position:fixed) and defaulting it to the existing sidebar-is-hidden state
   on load (see footer.php's script) means .content always gets the full
   width; the sidebar then opens ON TOP of the page as a drawer, closed again
   by the backdrop, a nav tap, or the handle tab — same open/close mechanics
   the desktop auto-hide sidebar already uses, just triggered differently. */
@media (max-width: 768px) {
    .sidebar {
        position: fixed;
        top: 60px;
        bottom: 0;
        z-index: 40;
        overflow-y: auto;
        box-shadow: 6px 0 24px rgba(15,23,42,0.14);
    }
    body.sidebar-is-hidden .sidebar { box-shadow: none; }
    .sidebar-backdrop {
        position: fixed;
        top: 60px; inset-inline-start: 0; inset-inline-end: 0; bottom: 0;
        background: rgba(15,23,42,0.45);
        z-index: 30;
    }
    .content { padding: 18px; }

    /* Topbar: the full pump name + user-name/role chip don't fit next to the
       language toggle and logout link on a phone screen — .user-info used to
       run off the right edge of the page (real overflow, found via an
       automated bounding-box sweep at 380px). Keep the logo mark and the
       essential controls (language switch, logout); drop the two labels
       that were causing the overflow. */
    .topbar { padding: 10px 12px; }
    .topbar .brand span { display: none; }
    .user-chip { display: none; }
    .topbar .user-info { gap: 6px; }
    .topbar a { margin-inline-start: 0; font-size: 13px; }
}

.sidebar a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 14px;
    margin-bottom: 3px;
    color: var(--sidebar-text);
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    border-radius: 8px;
    border-inline-start: 3px solid transparent;
    transition: background 0.15s ease, color 0.15s ease;
}

.sidebar a .icon { opacity: 0.75; transition: opacity 0.15s ease; }

.sidebar a:hover {
    background: var(--sidebar-hover-bg);
    color: var(--sidebar-text-hover);
}
.sidebar a:hover .icon { opacity: 1; }

/* Sep 2026 REVERT (owner: "...jo blue pehlay tha woh kar do") — back to the
   original "you are here" treatment: a solid accent-color gradient pill
   with white text and a glow shadow, which reads clearly against the dark
   navy sidebar again. The light "quiet tinted background" version (a pale
   accent tint + accent-colored text) briefly used here only worked against
   the near-white sidebar it was designed for. */
.sidebar a.active {
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%);
    color: #fff;
    border-inline-start-color: #fff;
    box-shadow: 0 3px 10px color-mix(in srgb, var(--accent) 35%, transparent);
}
.sidebar a.active .icon { opacity: 1; }

/* ---- sidebar submenu group (e.g. Fuel Price > Petrol/Diesel/High Octane) ---- */
.sidebar-group summary {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 14px;
    margin-bottom: 3px;
    color: var(--sidebar-text);
    font-size: 15px;
    font-weight: 500;
    border-radius: 8px;
    border-inline-start: 3px solid transparent;
    cursor: pointer;
    list-style: none;
    transition: background 0.15s ease, color 0.15s ease;
}
.sidebar-group summary::-webkit-details-marker { display: none; }
.sidebar-group summary:hover { background: var(--sidebar-hover-bg); color: var(--sidebar-text-hover); }
.sidebar-group summary::after {
    content: '▾';
    inset-inline-end: 14px;
    margin-inline-start: auto;
    font-size: 11px;
    opacity: 0.6;
    transition: transform 0.15s ease;
}
.sidebar-group[open] summary::after { transform: rotate(180deg); }
/* Sep 2026 REVERT (owner: "...jo blue pehlay tha woh kar do") — same
   solid-gradient/white-text "active" treatment as .sidebar a.active above,
   for consistency between a plain nav link and a submenu group header. */
.sidebar-group summary.active {
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%);
    color: #fff;
    font-weight: 700;
    border-inline-start-color: #fff;
}
.sidebar-submenu {
    padding-inline-start: 20px;
    display: flex;
    flex-direction: column;
}
.sidebar-submenu a {
    font-size: 14px;
    padding-top: 9px;
    padding-bottom: 9px;
    /* Sep 2026 REVERT — a translucent white line (visible against the dark
       navy sidebar again), not the gray --border used while it was white. */
    border-inline-start: 2px solid rgba(255,255,255,0.08);
    border-radius: 0;
}

.content {
    flex: 1;
    padding: 26px;
    min-width: 0; /* let wide tables scroll inside .content instead of blowing out layout */
}

.content h2 {
    color: var(--navy);
    margin-top: 4px;
}

/* ---- cards ---- */
.card {
    position: relative;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 24px;
    margin-bottom: 22px;
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.card:hover { box-shadow: var(--shadow-md); }

/* thin 3-color brand strip on every card, tying the whole UI to the pump's
   own brand colors (config/app.php: BRAND_COLOR_1/2/3) */
.card::before {
    content: '';
    position: absolute;
    top: 0; inset-inline-start: 0; inset-inline-end: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--brand-1), var(--brand-2), var(--brand-3));
}

.card h3 {
    margin-top: 0;
    color: var(--navy);
    font-size: 18px;
    border-bottom: 1px solid var(--border);
    padding-bottom: 12px;
    margin-bottom: 18px;
}

/* ---- login / forgot / reset pages ---- */
.login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at 20% 20%, var(--navy-light) 0%, var(--navy-dark) 55%, color-mix(in srgb, var(--navy-dark) 70%, black 30%) 100%);
}

.login-box {
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 20px 50px rgba(0,0,0,0.35);
    padding: 42px 40px;
    width: 380px;
}

.login-box h1 {
    font-size: 22px;
    text-align: center;
    color: var(--navy);
    margin-bottom: 28px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 6px;
    color: #374151;
}

input[type=text], input[type=password], input[type=number], input[type=date], input[type=datetime-local], select, textarea {
    width: 100%;
    padding: 11px 14px;
    border: 1.5px solid #d8dce3;
    border-radius: var(--radius-sm);
    font-size: 15px;
    margin-bottom: 16px;
    font-family: inherit;
    background: #fff;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
}

/* Buttons carry their own "button { display: inline-block }" rule below,
   same specificity as the browser's default "[hidden] { display: none }" —
   without this, a plain hidden="" button/element loses that tie by source
   order and stays visible (see the Net Profit modal fix note further down
   this file). One blanket override here beats every element rule in this
   sheet, so any future el.hidden = true just works. */
[hidden] { display: none !important; }

button, .btn {
    background: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);
    color: #fff;
    border: none;
    padding: 11px 24px;
    border-radius: var(--radius-sm);
    font-size: 15px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    box-shadow: var(--shadow-sm), 0 3px 8px color-mix(in srgb, var(--navy) 25%, transparent);
    transition: transform 0.12s ease, box-shadow 0.12s ease, filter 0.12s ease;
}

button:hover, .btn:hover { filter: brightness(1.08); transform: translateY(-1px); box-shadow: 0 5px 14px color-mix(in srgb, var(--navy) 30%, transparent); }
button:active, .btn:active { transform: translateY(0); }

.alert-error {
    background: #fdecea;
    color: #b91c1c;
    border: 1px solid #f5c2c0;
    padding: 12px 16px;
    border-radius: 8px;
    font-size: 14px;
    margin-bottom: 16px;
}

.alert-success {
    background: #eafaf0;
    color: #166534;
    border: 1px solid #bbf0cf;
    padding: 12px 16px;
    border-radius: 8px;
    font-size: 14px;
    margin-bottom: 16px;
}

.badge {
    display: inline-block;
    padding: 3px 12px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
}
.badge-active { background: #eafaf0; color: #166534; }
.badge-disabled { background: #fdecea; color: #b91c1c; }
/* Invoice Bill Type badge (Sep 2026) — Credit vs Cash on the saved-invoices list/print. */
.badge-credit { background: #fff4e5; color: #b45309; }

.table-scroll { overflow-x: auto; }

/* Generic "type to filter" search box above a table (Bank statement, Credit
   Customer list, Qarz-e-Hasna list) — see nsFilterTable() in footer.php. */
/* Oct 2026 (owner: "Search bar lga dy, koe premium level") — one look for every list search box:
   rounded pill, magnifier icon, soft shadow and an accent focus ring. */
.table-search {
    max-width: 380px; width: 100%; margin-bottom: 12px; box-sizing: border-box;
    padding: 11px 16px 11px 42px; font-size: 14px;
    border: 1.5px solid var(--border); border-radius: 999px; background-color: #fff;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: 15px center;
    box-shadow: 0 1px 2px rgba(15,23,42,.06); transition: border-color .15s, box-shadow .15s;
}
.table-search:focus { outline: none; border-color: var(--navy, #1e3a5f); box-shadow: 0 0 0 4px rgba(30,58,95,.12); }
[dir="rtl"] .table-search { padding: 11px 42px 11px 16px; background-position: calc(100% - 15px) center; }

/* Period selector (Daily/Monthly/Yearly/All) above a printable statement. */
.period-nav { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; align-items: center; }
.period-nav .btn-sm.active { background: var(--navy); color: #fff; }
/* Opening-balance checkbox (Bank Statement / Credit Customer Ledger /
   Qarz-e-Hasana Ledger) — owner's request: off by default, ticking it shows
   the balance carried over from before the selected period. */
.opening-balance-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    font-size: 13px;
    margin-left: 10px;
    cursor: pointer;
    color: var(--navy);
}
.opening-balance-toggle input { width: auto; margin: 0; }
.opening-balance-line { margin: 6px 0 14px; font-size: 14px; }
/* Current Fuel Stock (Reports > Fuel Reports) per-tank breakdown checkbox —
   owner's request: a fuel type with more than one tank (e.g. Diesel = Tank
   1 + Tank 5 + Tank 6) collapses to one combined row by default now;
   ticking this shows each tank's own row underneath it again. Same
   inline-checkbox look as .opening-balance-toggle above, kept as its own
   class since it isn't about an opening balance. */
.rp-fs-tank-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    color: var(--navy);
    margin-bottom: 8px;
}
.rp-fs-tank-toggle input { width: auto; margin: 0; }

table.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 15px;
}
table.data-table th, table.data-table td {
    text-align: start;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
table.data-table th {
    background: #f9fafb;
    font-size: 13px;
    color: var(--muted);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
table.data-table tbody tr:hover { background: #fef8f3; }
table.data-table tfoot td {
    font-weight: 700;
    background: #f9fafb;
    border-top: 2px solid var(--accent);
}

/* Owner's request: "Ledger main Horizontal scroll bar na ho ... Text bayshak
   thora squiz kar lo" — the Customer/Loan/Employee Detail dialog's ledger
   table (Date/Type/Description/Debit/Credit/Balance, 6 columns) was wide
   enough that .table-scroll's horizontal scrollbar kicked in inside the
   modal, which the owner found disruptive on a phone/small screen. Fixed
   widths (table-layout: fixed) + wrapping text instead of the base
   .data-table's white-space: nowrap means every column always fits the
   modal's own width — long Description text wraps onto a 2nd line instead
   of pushing the table wider, so there's simply nothing left to scroll.
   IMPORTANT: this block must stay AFTER the table.data-table rules above —
   both selectors are equal specificity, so with equal specificity the LATER
   rule in the file wins; this block was originally placed BEFORE the base
   .data-table rules by mistake, which silently let the base white-space:
   nowrap/padding win right back and defeated this override entirely (found
   via a real overlapping-text screenshot at a narrow/phone width). */
.ledger-table-wrap { overflow-x: hidden; }
table.ledger-table { table-layout: fixed; font-size: 12.5px; }
table.ledger-table th, table.ledger-table td {
    padding: 8px 6px;
    white-space: normal;
    word-break: break-word;
}
/* table-layout: fixed with no explicit widths already splits every column
   equally, which alone is enough to stop any column count from overflowing
   (used as-is by the Loan ledger's standalone tab, which has an extra
   no-print "By" column — 7 total). The 6-column ledgers (Customer's dialog
   + standalone tab, Loan's dialog, Employee's dialog: Date/Type/
   Description/Debit/Credit/Balance) additionally use this modifier to bias
   Description — the field most likely to hold long text — wider than an
   even split would give it. */
table.ledger-table-6col th:nth-child(1), table.ledger-table-6col td:nth-child(1) { width: 13%; }
table.ledger-table-6col th:nth-child(2), table.ledger-table-6col td:nth-child(2) { width: 15%; }
table.ledger-table-6col th:nth-child(3), table.ledger-table-6col td:nth-child(3) { width: 30%; }
table.ledger-table-6col th:nth-child(4), table.ledger-table-6col td:nth-child(4) { width: 14%; }
table.ledger-table-6col th:nth-child(5), table.ledger-table-6col td:nth-child(5) { width: 14%; }
table.ledger-table-6col th:nth-child(6), table.ledger-table-6col td:nth-child(6) { width: 14%; }

.btn-sm {
    padding: 7px 14px;
    font-size: 13px;
    border-radius: 7px;
}
.btn-danger { background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%); }

/* ---- dashboard stat cards ----
   Fixed-width cards (owner's request: "jab side bar hide ho tou card ka size
   change na ho ... neechay say card aa jain") — minmax's max is capped at
   260px instead of 1fr, so opening extra room (e.g. collapsing the sidebar)
   fits MORE cards per row at the same size instead of stretching each card
   wider; anything that doesn't fit wraps to the next row, same as before. */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 232px));
    gap: 14px;
    margin-bottom: 24px;
}

.stat-card {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 15px 16px;
    box-shadow: var(--shadow-sm);
    display: flex;
    align-items: center;
    gap: 12px;
    border-inline-start: 4px solid var(--navy);
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }

.stat-icon {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}
.stat-icon .icon { width: 18px; height: 18px; }

.stat-blue   { border-inline-start-color: var(--blue); }
.stat-blue   .stat-icon { background: linear-gradient(135deg, var(--blue) 0%, #1d4ed8 100%); }
.stat-orange { border-inline-start-color: var(--accent); }
.stat-orange .stat-icon { background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%); }
.stat-green  { border-inline-start-color: var(--green); }
.stat-green  .stat-icon { background: linear-gradient(135deg, var(--green) 0%, #15803d 100%); }
.stat-purple { border-inline-start-color: var(--purple); }
.stat-purple .stat-icon { background: linear-gradient(135deg, var(--purple) 0%, #6d28d9 100%); }
.stat-red    { border-inline-start-color: #b91c1c; }
.stat-red    .stat-icon { background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%); }

.stat-card .label { font-size: 10.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.stat-card .value { font-size: 21px; font-weight: 800; color: var(--navy); margin-top: 4px; letter-spacing: -0.01em; }

/* Sep 2026 "professional premium" pass (owner: "Premium Software wali look
   nae ae... designing Professional Premium do") — the frosted-glass cards,
   per-color permanent glow, rainbow top strip and bouncy icon-rotate from
   the previous "catchy" pass are gone. Scoped to `.stat-grid.dash-glass
   .stat-card` (the class is added only on the two stat-grid wrappers in
   index.php) so the 17+ other module pages that also use `.stat-card`
   (Reports, Bank, Loans, Customers, etc.) are unaffected — a slightly
   crisper, more deliberate hover is the only thing the Dashboard gets on
   top of the shared card style every page already uses. */
.stat-grid.dash-glass .stat-card { transition: transform 0.15s ease, box-shadow 0.15s ease; }
.stat-grid.dash-glass .stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.stat-grid.dash-glass .stat-icon { transition: transform 0.15s ease; }
.stat-grid.dash-glass .stat-card:hover .stat-icon { transform: scale(1.06); }

/* ---- Sep 2026 owner request: professional Credit Customers list + a
   click-to-open Customer Detail dialog instead of per-row action buttons
   ("Company active view ledger and block kay button na hon ... jab kisi bhe
   customer par click karain tou us ke Detail dialog main open ho"). Reused
   for any future "click a row, see a detail dialog" list in the app. ---- */
.cust-list-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
.cust-list-toolbar h3 { border: none; padding: 0; margin: 0; }
.cust-list-toolbar .table-search { margin: 0; flex: 1; min-width: 220px; max-width: 360px; }

.cust-row-clickable { cursor: pointer; }
.cust-row-clickable:hover { background: var(--accent-soft, #fff7ed); }

.cust-name-cell { display: flex; align-items: center; gap: 11px; }
.cust-avatar {
    flex-shrink: 0; width: 36px; height: 36px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--navy) 0%, var(--blue) 100%);
    color: #fff; font-weight: 700; font-size: 13px; letter-spacing: 0.02em;
    box-shadow: var(--shadow-xs);
}
.cust-name-text { display: flex; flex-direction: column; line-height: 1.4; }
.cust-name-text > span:first-child { font-weight: 600; color: var(--navy); }
.cust-name-text .cust-company-sub { font-size: 12px; color: var(--muted); font-weight: 500; }

/* Sep 2026 follow-up: "pic upload ka option bhe rakho ... choti se name kay
   sath us ke photograph bhe add ho" — an uploaded photo renders in the same
   36px circle the initials avatar used, object-fit:cover so any aspect
   ratio crops cleanly instead of stretching. */
.cust-avatar-photo { object-fit: cover; }

/* Sep 2026 follow-up: "list ko thora aur modern international standard par
   karo" — rounded card-contained table, right-aligned money column, subtle
   zebra striping (44+ rows reads easier at a glance), a touch more row
   breathing room. */
.cust-table-container { border-radius: 10px; border: 1px solid var(--border); overflow: hidden; }
.cust-table-container .data-table { border: none; }
.cust-table th, .cust-table td { padding: 13px 14px; }
.cust-table tbody tr:nth-child(even) { background: #fbfbfd; }
.cust-table tbody tr.cust-row-clickable:hover { background: var(--accent-soft, #fff7ed); }
.text-end { text-align: end; }

.cust-status-cell { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Sep 2026 follow-up: "yeh button status Active kay agay ayen main sheet
   main" — the Block/Unblock quick action sits right beside the badge in the
   list itself now (moved out of the Detail dialog, which is view/print/
   ledger only). event.stopPropagation() on the wrapping <form> (see the PHP
   markup) keeps this click from also opening the row's detail dialog. */
.cust-status-toggle-btn { padding: 4px 10px; font-size: 11.5px; }

/* ---- generic modal overlay/box (Add Customer + Customer Detail dialogs) ---- */
.ns-modal-overlay {
    display: none; position: fixed; inset: 0; z-index: 2000;
    background: rgba(15, 23, 42, 0.55);
    align-items: flex-start; justify-content: center;
    padding: 5vh 16px; overflow-y: auto;
}
.ns-modal-overlay.open { display: flex; }
.ns-modal-box {
    background: #fff; border-radius: var(--radius-md, 12px);
    box-shadow: var(--shadow-lg); width: 100%; max-width: 560px;
    max-height: 90vh; overflow-y: auto; animation: nsModalIn .16s ease;
}
/* Customer Detail dialog: wider — it now also holds the customer's complete
   ledger table (Sep 2026 owner request), which needs real room. */
.ns-modal-box-wide { max-width: 820px; }
@keyframes nsModalIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
.ns-modal-header {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--border);
}
.ns-modal-header h3 { margin: 0; border: none; padding: 0; font-size: 17px; }
.ns-modal-header .cust-modal-company { font-size: 12.5px; color: var(--muted); font-weight: 500; margin-top: 2px; }
.ns-modal-close {
    flex-shrink: 0; width: 30px; height: 30px; border-radius: 8px; border: none;
    background: #f1f5f9; color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer;
}
.ns-modal-close:hover { background: #e2e8f0; color: var(--navy); }

/* Sep 2026 owner request: "agay 3 button hon — print ka chotta sa icon,
   view ledger ka icon chotta sa, aur koi zaroori button" — a small row of
   icon-only actions next to the dialog title, before the close button. */
.ns-modal-header-actions { flex-shrink: 0; display: flex; align-items: center; gap: 6px; }
.ns-icon-btn {
    flex-shrink: 0; width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--border);
    background: #fff; color: var(--navy); display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.ns-icon-btn .icon { width: 17px; height: 17px; }
.ns-icon-btn:hover { background: var(--accent-soft, #fff7ed); border-color: var(--accent); }
.ns-icon-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Sep 2026 follow-up: same small icon buttons, sized down for use inline in
   a table row (Print / View Ledger, next to the Active/Block controls). */
.ns-icon-btn-sm { width: 28px; height: 28px; }
.ns-icon-btn-sm .icon { width: 14px; height: 14px; }

/* Sep 2026 — Super Admin "Bank Entries" tab's inline row-edit: icon-only
   Edit/Update/Delete buttons per row (owner: "yeh saray button icon walay
   hon"). Danger (Delete)/success (Update-Save) color variants of the same
   .ns-icon-btn-sm shape, matching .btn-danger/.btn-success's own colors. */
.ns-icon-btn-danger  { background: #dc2626; border-color: #dc2626; color: #fff; }
.ns-icon-btn-danger:hover  { background: #b91c1c; border-color: #b91c1c; }
.ns-icon-btn-success { background: #16a34a; border-color: #16a34a; color: #fff; }
.ns-icon-btn-success:hover { background: #15803d; border-color: #15803d; }

/* Sep 2026 (owner: "Printer and whatsapp and View and edit kay color hon
   state of art... jesay edit ka red, whatsapp ka green") — 4 distinct
   tinted colors for the Credit Customer/Qarz-e-Hasana/Employee list's
   per-row action icons (modules/reports/index.php). A soft tint (light
   background + colored border/icon), not the solid-fill .ns-icon-btn-danger
   /-success above — 4 solid-filled buttons side by side in one row reads
   as too heavy/alarm-like; a light tint stays calm while still color-coded
   at a glance. */
.ns-icon-btn-print    { background: #eff6ff; border-color: #bfdbfe; color: #2563eb; }
.ns-icon-btn-print:hover    { background: #dbeafe; border-color: #93c5fd; }
.ns-icon-btn-whatsapp { background: #f0fdf4; border-color: #bbf7d0; color: #16a34a; }
.ns-icon-btn-whatsapp:hover { background: #dcfce7; border-color: #86efac; }
.ns-icon-btn-ledger   { background: #f5f3ff; border-color: #ddd6fe; color: #7c3aed; }
.ns-icon-btn-ledger:hover   { background: #ede9fe; border-color: #c4b5fd; }
.ns-icon-btn-edit     { background: #fef2f2; border-color: #fecaca; color: #dc2626; }
.ns-icon-btn-edit:hover     { background: #fee2e2; border-color: #fca5a5; }
/* Sep 2026 (owner: "lubricant kay agay 3 small button lgao") — amber tint
   for the Lubricant item row's 3rd small history button (internal stock
   Transfer/movement history), same soft-tint family as the 4 above. */
.ns-icon-btn-transfer  { background: #fffbeb; border-color: #fde68a; color: #b45309; }
.ns-icon-btn-transfer:hover  { background: #fef3c7; border-color: #fcd34d; }
/* Sep 2026 (owner: "en sary icon ka color 1 na ho different karo" — Bank
   Ledger's row actions were still the plain uncoloured .ns-icon-btn, unlike
   Customer/Loan/Employee's own 4-tint row above) — teal tint for the
   date-range/calendar icon (Bank Ledger's 4th button, Reports' own
   "?type=...&entity_id=...#ledger" link), same soft-tint family, picked to
   stay visually distinct from all 5 tints above. */
.ns-icon-btn-calendar { background: #f0fdfa; border-color: #99f6e4; color: #0d9488; }
.ns-icon-btn-calendar:hover { background: #ccfbf1; border-color: #5eead4; }
/* Sep 2026 follow-up ("customer ledger main aap pdf ka icon button bhe lga
   do") — rust/orange tint for the new "Download PDF" icon button, same
   soft-tint family, picked to stay visually distinct from all 6 tints
   above (edit's red is the closest neighbour, deliberately kept apart). */
.ns-icon-btn-pdf { background: #fff7ed; border-color: #fed7aa; color: #c2410c; }
.ns-icon-btn-pdf:hover { background: #ffedd5; border-color: #fdba74; }

.cust-ledger-section-head { display: flex; align-items: center; justify-content: space-between; margin-top: 22px; }
.cust-ledger-section-title { margin: 0; border: none; padding: 0; font-size: 15px; }
.ns-modal-body { padding: 18px 20px; }
.ns-modal-footer {
    display: flex; align-items: center; justify-content: flex-end; gap: 8px;
    padding: 14px 20px; border-top: 1px solid var(--border); flex-wrap: wrap;
}
.ns-modal-footer .ns-modal-footer-left { margin-inline-end: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.cust-detail-balance-row {
    display: flex; align-items: center; justify-content: space-between;
    background: #f8fafc; border: 1px solid var(--border); border-radius: 10px;
    padding: 12px 16px; margin-bottom: 14px;
}
.cust-detail-balance-row .label { font-size: 11.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.cust-detail-balance-row .value { font-size: 22px; font-weight: 800; margin-top: 2px; }

/* Sep 2026 follow-up: photo (or initials fallback) next to the balance in
   the Detail dialog — same photo the list avatar shows, just bigger. */
.cust-detail-photo-name { display: flex; align-items: center; gap: 12px; }
.cust-detail-photo-wrap { flex-shrink: 0; }
.cust-detail-photo, .cust-detail-photo-fallback { width: 46px; height: 46px; border-radius: 50%; }
.cust-detail-photo { object-fit: cover; box-shadow: var(--shadow-xs); }
.cust-detail-photo-fallback { width: 46px; height: 46px; font-size: 15px; }

/* Sep 2026 follow-up: compact bold identity line (#ID / Name / Phone) that
   replaced the old boxed detail grid — this is what actually prints, since
   the dialog's on-screen <h3> title is .no-print. */
.cust-ident-line { margin: 0 0 4px; font-size: 15px; display: flex; flex-wrap: wrap; gap: 4px 14px; }
.cust-ident-line strong { color: var(--navy); }
.cust-ident-address { margin: 0 0 4px; font-size: 13.5px; color: var(--navy); }
.cust-ident-secondary { margin: 0; font-size: 12.5px; color: var(--muted); }

@media print {
    /* Only the open Customer Detail dialog's printable content should
       appear on paper — everything else on the page (stat cards, tab-nav,
       toolbar, list, Add Customer modal, and the detail dialog's own
       chrome/buttons) is either already .no-print or explicitly hidden
       here while printing is in progress (body.ns-printing-modal, toggled
       right before/after window.print() — see modules/customers/index.php). */
    /* Sep 2026 fix history (kept for context — the rule below replaced all
       of this): this used to be a fixed whitelist of every Detail dialog's
       own #id, repeated twice (once for the "don't hide the open dialog"
       rule, once per dialog for its own [hidden]-ledger-section override).
       That worked fine as long as a page only ever had ONE such dialog in
       its DOM (Customers/Loans/Payroll/Bank each do) — but owner report
       "abhe bhe theak nae ho rha ... kaheen par second page par aa rha
       Kaheen par 2 page blank aa rhay" (still broken — sometimes spills to
       a 2nd page, sometimes 2 blank pages, varies by which report tab) was
       traced to Reports: that ONE page holds ALL of its Detail dialogs
       (Customer/Borrower/Bank/Other Income/Other Expense/Employee/Expense —
       7 of them) in the DOM at once, and the ID-whitelist rule excluded
       every one of them from being hidden regardless of which single dialog
       the owner actually had open — so printing from any one of them
       printed ITS content plus 6 other (mostly empty, but never actually
       hidden) letterhead/footer blocks stacked after it, and the [hidden]-
       override rule forced EVERY dialog's ledger section open too, even
       ones that were never populated. Root cause: matching by a fixed list
       of #ids can never tell "the dialog that's actually open" apart from
       "every dialog that ever reuses this toggle, anywhere in the app".
       Fixed properly below by matching on the .open class instead — the
       browser already tracks exactly one dialog as open at a time, so this
       needs no id list, no per-dialog upkeep, and is automatically correct
       for every current AND future ns-printing-modal dialog everywhere in
       the app, no matter how many share one page's DOM. */
    body.ns-printing-modal > .layout > .content > *:not(.ns-modal-overlay.open) { display: none !important; }
    body.ns-printing-modal .ns-modal-overlay.open { position: static !important; background: none !important; padding: 0 !important; display: block !important; }
    body.ns-printing-modal .ns-modal-overlay.open .ns-modal-box { max-width: 100% !important; max-height: none !important; box-shadow: none !important; overflow: visible !important; }
    /* The ledger section inside a Detail dialog is collapsed by default on
       screen (owner's "view ledger" icon toggles it) but must ALWAYS print
       in full regardless of that toggle state (owner: "print karnay say
       complete ledger print ho jaye") — forces it open on paper, but ONLY
       inside the dialog that's actually open (see the note above — every
       Detail dialog's own ledger section uses this same [hidden] attribute,
       nothing else inside these dialogs does, so this one generic rule
       covers all of them, present and future, with no id list to maintain). */
    body.ns-printing-modal .ns-modal-overlay.open [hidden] { display: block !important; }

    /* Sep 2026 owner request: modernized Expenses / Other Income history
       lists each got a small per-row Print icon (no dialog — these pages
       have no persistent "party" the way Customers/Loans/Employees do) that
       prints a small one-row slip instead of the whole filtered statement.
       Same hide-everything-except-the-target-element pattern as the
       Customer Detail dialog above, toggled via body.ns-printing-row.
       Sep 2026 follow-up (owner: "Har purchase ki ek printable 'slip'
       (receipt) chahiye") — Fuel Purchase Report's Diesel/Petrol/High
       Octane/Lubricants tabs each got the exact same per-row slip. */
    body.ns-printing-row > .layout > .content > *:not(#expRowPrintCard):not(#oiRowPrintCard):not(#pfrRowPrintCard) { display: none !important; }
    body.ns-printing-row #expRowPrintCard, body.ns-printing-row #oiRowPrintCard, body.ns-printing-row #pfrRowPrintCard { display: block !important; }

    /* Sep 2026 owner request: "1 print total Cummulative saray list ka bhe
       print nekal sakay" — a Print List button on Customers/Loans/Employees
       prints the WHOLE (filtered) list as a statement with a grand-total
       row. Same hide-everything-else pattern, toggled via body.ns-printing-list.
       Sep 2026 follow-up (owner: "oper 1 print ka button bhe lga do jo saari
       list ko print karay") — same Print List button added to all 7 Reports
       ledger tabs; their print-card IDs (rp*ListPrintCard) MUST be listed
       here too or this reuses the exact "blank print" bug this file already
       warns about — see the missed-ID note above. */
    body.ns-printing-list > .layout > .content > *:not(#custListPrintCard):not(#borrowerListPrintCard):not(#employeeListPrintCard):not(#rpCustListPrintCard):not(#rpLoanListPrintCard):not(#rpEmployeeListPrintCard):not(#rpExpenseListPrintCard):not(#rpBankListPrintCard):not(#rpOtherIncomeListPrintCard):not(#rpOtherExpenseListPrintCard) { display: none !important; }
    body.ns-printing-list #custListPrintCard,
    body.ns-printing-list #borrowerListPrintCard,
    body.ns-printing-list #employeeListPrintCard,
    body.ns-printing-list #rpCustListPrintCard,
    body.ns-printing-list #rpLoanListPrintCard,
    body.ns-printing-list #rpEmployeeListPrintCard,
    body.ns-printing-list #rpExpenseListPrintCard,
    body.ns-printing-list #rpBankListPrintCard,
    body.ns-printing-list #rpOtherIncomeListPrintCard,
    body.ns-printing-list #rpOtherExpenseListPrintCard { display: block !important; }

    /* Invoice / Billing (Sep 2026) — its own View/Print dialog, kept on its
       own toggle class (ns-printing-invoice) rather than reusing
       ns-printing-modal, specifically so a missed dialog ID here can never
       repeat the blank-print bug the 3 rules above just got fixed for. */
    body.ns-printing-invoice > .layout > .content > *:not(#invoiceViewModalOverlay) { display: none !important; }
    body.ns-printing-invoice .ns-modal-overlay { position: static !important; background: none !important; padding: 0 !important; display: block !important; }
    body.ns-printing-invoice .ns-modal-box { max-width: 100% !important; max-height: none !important; box-shadow: none !important; overflow: visible !important; }

    /* Sep 2026 (owner: "yeh saaray card print ho sakain") — the Dashboard's
       Cash Movement Summary click-a-card dialog (index.php, #dashDetailOverlay)
       and Net Profit's identical dialog (modules/net_profit/index.php,
       #npDetailOverlay) get their own Print button too, each on its own
       toggle class — same reasoning as ns-printing-invoice above: each of
       these dialogs is the only one of its kind in its page's DOM, so a
       plain #id selector is safe (no "which dialog is open" ambiguity like
       Reports' 7 shared dialogs above), and a dedicated class per dialog
       type means a future page adding its own can never silently break
       this one by reusing ns-printing-modal without also being a
       .ns-modal-overlay. */
    body.ns-printing-dash-detail > .layout > .content > *:not(#dashDetailOverlay) { display: none !important; }
    body.ns-printing-dash-detail #dashDetailOverlay { position: static !important; background: none !important; padding: 0 !important; display: block !important; }
    body.ns-printing-dash-detail #dashDetailOverlay .dash-detail-modal { max-width: 100% !important; max-height: none !important; box-shadow: none !important; overflow: visible !important; }
    body.ns-printing-np-detail > .layout > .content > *:not(#npDetailOverlay) { display: none !important; }
    body.ns-printing-np-detail #npDetailOverlay { position: static !important; background: none !important; padding: 0 !important; display: block !important; }
    body.ns-printing-np-detail #npDetailOverlay .np-detail-modal { max-width: 100% !important; max-height: none !important; box-shadow: none !important; overflow: visible !important; }

    /* Sep 2026 (owner: "jab purchase and sale walay icon par click karain
       tou report wahan say bhe print ho") — Lubricants' Items & Stock >
       Purchase/Sale/Transfer history dialog gets its own Print button, same
       dedicated-toggle-class pattern as ns-printing-dash-detail/np-detail
       right above (only dialog of its kind on this page, so a plain #id
       selector is safe). */
    body.ns-printing-lub-history > .layout > .content > *:not(#lubHistoryModalOverlay) { display: none !important; }
    body.ns-printing-lub-history #lubHistoryModalOverlay { position: static !important; background: none !important; padding: 0 !important; display: block !important; }
    body.ns-printing-lub-history #lubHistoryModalOverlay .lub-history-modal-box { max-width: 100% !important; max-height: none !important; box-shadow: none !important; overflow: visible !important; }
}

/* ---- Quick Payments: Payment-In / Charge-Out direction toggle ---- */
.pay-direction-options { display: flex; gap: 18px; margin-top: 6px; flex-wrap: wrap; }
.pay-direction-option { display: flex; align-items: center; gap: 6px; font-weight: 500; cursor: pointer; }
.pay-direction-option input[type="radio"] { margin: 0; }

/* ---- form layout helper ---- */
.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 24px;
}
.form-grid-3col { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 640px) {
    .form-grid { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
    .form-grid-3col { grid-template-columns: 1fr; }
}

.hint {
    font-size: 12px;
    color: var(--muted);
    margin-top: -12px;
    margin-bottom: 14px;
}

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

.report-summary-row td { font-size: 18px; color: var(--navy); }

/* Quick Meter Entry — row already has today's reading (subtle tint so the
   attendant can see at a glance which nozzles are still pending), and the
   live "Litres Sold" preview cell (red once a typo would push it negative). */
.qm-row-done { background: #f4fbf6; }
.qm-diff-cell { font-weight: 700; color: var(--navy); }
.qm-diff-cell.qm-diff-negative { color: #b91c1c; }
/* Owner's request (Dip tab's "Change Litre Previous" column): "Ager purchase
   nae dalee tou yeh value jo negative hay yeh blink bhe karay" — a tank
   whose level rose since its last dip and has NO matching Fuel Purchase on
   record for that exact window is a genuine unexplained anomaly (missed
   delivery entry, or a bad dip reading) — this blinks so it can't be missed
   at a glance the way a plain colored number could be. Kept subtle (a slow
   opacity pulse, not a jarring flash) so it reads as "needs attention"
   rather than as a broken page. */
.qd-change-prev-blink {
    color: #b91c1c;
    font-weight: 800;
    animation: qd-blink 1.1s ease-in-out infinite;
}
@keyframes qd-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}
/* Owner's request: "Last Reading ... Size thora bra kar do" — this number is
   what the cashier reads digit-by-digit to key in the next reading, so it's
   bigger/bolder than plain table text, and tabular-nums keeps every digit
   the same width (easier to visually line up against the New Reading box
   next to it, which gets the same treatment below). */
.nr-last-reading-value { font-size: 16px; font-weight: 700; color: var(--navy); font-variant-numeric: tabular-nums; }
.qm-reading-input { font-size: 16px; font-variant-numeric: tabular-nums; }

/* Month-wise Rate History (Quick Fuel Price Entry) — a section-header row
   between each month's group of rate-change rows. */
.month-divider-row td {
    background: #f8fafc;
    color: var(--navy);
    font-weight: 700;
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding-top: 10px;
    padding-bottom: 10px;
    border-top: 1.5px solid var(--border);
}

/* Reports → Lubricants Purchase History inline item-detail expand
   (modules/reports/index.php) — on-screen only look for the expanded row;
   the print-only visibility override lives in the @media print block above. */
.rp-lp-invoice-row.rp-lp-open { background: #f8fafc; }
.rp-lp-detail-wrap { padding: 8px 8px 8px 30px; background: #f8fafc; }
.rp-lp-item-table { margin: 0; }
.rp-lp-item-table th, .rp-lp-item-table td { font-size: 13px; }

/* ---- tab navigation (Credit Customers / Lubricants / Fuel Purchases modules) ---- */
.tab-nav {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 20px;
    border-bottom: 2px solid var(--border);
    padding-bottom: 0;
}
.tab-link {
    display: inline-block;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    border-radius: 8px 8px 0 0;
    margin-bottom: -2px;
    border-bottom: 2px solid transparent;
    transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.tab-link:hover { color: var(--navy); background: #f9fafb; }
.tab-link.active { color: var(--accent-dark); border-bottom-color: var(--accent); background: var(--accent-soft); }
.tab-link .icon { width: 15px; height: 15px; vertical-align: -3px; margin-inline-end: 2px; }
/* A tab temporarily taken off the menu (LUB_SALE_TAB_DISABLED in
   config/app.php) — rendered as a plain <span>, not a link, so it can't be
   clicked at all; greyed + "not-allowed" cursor makes that obvious at a
   glance, and its title="" tooltip explains why. */
.tab-link-disabled {
    color: #b7bcc6;
    cursor: not-allowed;
    opacity: 0.7;
}
.tab-link-disabled:hover { color: #b7bcc6; background: none; }

.low-stock { color: #b91c1c; font-weight: 700; }
/* Sep 2026 — moved here from modules/lubricants/index.php's own <style>
   block (items tab only) so Reports > "Lubricant Stock" (same table, see
   nsLubricantStockValueSnapshot()) renders it correctly too. */
.lub-stock-subtext { font-size: 11px; color: var(--muted, #888); margin-top: 2px; }
.text-danger { color: #b91c1c; }
.text-success { color: #166534; }
.text-muted { color: var(--muted); }

/* ---- click-to-expand equipment gauges (Tank Readings / Petrol / Diesel / High Octane pages) ---- */
.dispenser-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 18px;
}
.tank-gauge-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 18px;
}

.tank-gauge-card, .dispenser-card {
    position: relative;
    background: #fbfcfe;
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 18px 14px 14px;
    overflow: hidden;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.tank-gauge-card:hover, .dispenser-card:hover { box-shadow: 0 8px 22px rgba(16,30,54,0.1); transform: translateY(-2px); }
.tank-gauge-card[open] { box-shadow: 0 8px 22px rgba(16,30,54,0.12); grid-column: 1 / -1; }
/* When a nozzle inside a dispenser card opens sideways, the card itself needs
   the room — widen it to the full grid row (same pattern as .tank-gauge-card[open]
   above) so the reading form has space to sit beside the nozzle chip instead of
   wrapping underneath it. */
.dispenser-card:has(.disp-nozzle[open]) { grid-column: 1 / -1; box-shadow: 0 8px 22px rgba(16,30,54,0.12); }

/* Pump/company brand-color stripe (config/app.php: BRAND_COLOR_1/2/3) — a small
   visual echo of the fuel company's own colors on every equipment card. */
.tank-gauge-card::before, .dispenser-card::before {
    content: '';
    position: absolute;
    top: 0; inset-inline-start: 0; inset-inline-end: 0;
    height: 5px;
    background: linear-gradient(90deg, var(--brand-1), var(--brand-2), var(--brand-3));
}

/* Dispenser cards get a richer, showroom-style treatment: a soft two-tone
   backdrop, a bigger radius, and a deeper resting shadow so the illustration
   reads as the hero of the card rather than sitting on flat white. */
.dispenser-card {
    background: linear-gradient(165deg, #ffffff 0%, #f7f9fc 60%, #eef2f8 100%);
    border-color: #e2e7f0;
    border-radius: var(--radius-lg);
    padding: 20px 16px 16px;
    box-shadow: var(--shadow-sm);
}
.dispenser-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-3px); }

.tank-gauge-card summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    position: relative;
    padding-bottom: 6px;
}
.tank-gauge-card summary::-webkit-details-marker { display: none; }

.tank-gauge-card summary::after {
    content: '▾';
    position: absolute;
    top: 0;
    inset-inline-end: 0;
    color: var(--muted);
    transition: transform 0.15s ease;
}
.tank-gauge-card[open] summary::after { transform: rotate(180deg); }

.tank-gauge-meta strong { display: block; font-size: 15px; color: var(--navy); margin-top: 6px; }
.tank-gauge-meta span { display: block; font-size: 12.5px; color: var(--muted); }
.tank-gauge-pct { font-weight: 700 !important; color: var(--text) !important; font-size: 14px !important; }

.tank-gauge-chart-tag {
    display: inline-flex !important;
    align-items: center;
    gap: 4px;
    background: var(--accent-soft);
    color: var(--accent-dark) !important;
    font-size: 11px !important;
    font-weight: 600;
    padding: 2px 9px;
    border-radius: 999px;
    margin: 2px 0 !important;
}
.tank-gauge-chart-tag .icon { width: 11px; height: 11px; }

.tank-dip-form, .dispenser-nozzle-form {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px dashed var(--border);
}
.tank-dip-form .form-grid, .dispenser-nozzle-form .form-grid { grid-template-columns: 1fr 1fr; }

/* ---- illustrated dispenser card (Petrol/Diesel/High Octane pages) ---- */
.dispenser-card-header {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    text-align: center;
    margin-bottom: 2px;
}
.dispenser-card-header strong {
    font-size: 18px;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--navy);
}
.dispenser-nozzle-count {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--accent-dark);
    background: var(--accent-soft);
    padding: 3px 10px;
    border-radius: 999px;
    white-space: nowrap;
}

/* "Showroom" spotlight behind the illustration: a soft radial glow plus a
   subtle floor line, so the dispenser reads as a lit display piece rather
   than clip-art floating on the card. */
.dispenser-illustration-wrap {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    margin: 2px 0 12px;
    padding-top: 6px;
}
.dispenser-illustration-wrap::before {
    content: '';
    position: absolute;
    top: -6px;
    inset-inline-start: 50%;
    transform: translateX(-50%);
    width: 84%;
    max-width: 220px;
    aspect-ratio: 1.4 / 1;
    background: radial-gradient(ellipse at 50% 38%, var(--accent-soft) 0%, rgba(255,255,255,0) 68%);
    opacity: 0.9;
    pointer-events: none;
    z-index: 0;
}
.dispenser-illustration-wrap .dispenser-illustration-svg {
    position: relative;
    z-index: 1;
    filter: drop-shadow(0 6px 10px rgba(16, 24, 40, 0.10));
}

/* animated fuel flow inside the tank->dispenser pipe */
.fuel-flow-line { animation: fuelFlow 0.8s linear infinite; }
@keyframes fuelFlow { to { stroke-dashoffset: -18; } }
@media (prefers-reduced-motion: reduce) { .fuel-flow-line { animation: none; } }

/* ---- Petrol/Diesel/High Octane page header (title + current-rate chip) ---- */
.dr-page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
}
.dr-page-head h2 { margin: 0; }
.dr-rate-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--accent-soft);
    color: var(--accent-dark);
    font-size: 13px;
    font-weight: 600;
    padding: 7px 14px;
    border-radius: 999px;
    text-decoration: none;
    box-shadow: var(--shadow-xs);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.dr-rate-chip:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.dr-rate-chip .icon { width: 14px; height: 14px; }
.dr-rate-chip strong { color: var(--navy); }

/* ---- compact nozzle chips, arranged in a row, that open HORIZONTALLY
   (sideways, next to the chip) to reveal the reading-entry fields — not a
   panel dropping down below. Tank fill % and each nozzle's current reading
   are drawn directly onto the dispenser illustration itself (gauges.php:
   dispenserIllustrationSvg()), not in a separate card. ---- */
.disp-nozzle-list {
    /* Left/Right here describe the physical hose position on the illustration
       above (a fixed picture, not text) - so keep this list's order fixed
       left-to-right even in Urdu/RTL, matching the picture, instead of flipping. */
    direction: ltr;
    display: grid;
    /* auto-fit + minmax: 2 nozzles sit in two parallel (side-by-side) columns;
       a single nozzle stretches to fill the row on its own. Columns stay
       side-by-side even while one nozzle is open - only that nozzle's own
       cell grows taller, its neighbor never gets pushed onto a new line. */
    grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
    align-items: start;
    gap: 8px;
}
.disp-nozzle {
    border: 1.5px solid var(--border);
    border-radius: 999px;
    background: #fff;
    box-shadow: var(--shadow-xs);
    overflow: hidden;
    transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease, border-radius 0.15s ease;
}
.disp-nozzle:hover { border-color: var(--brand-1); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.disp-nozzle[open] {
    border-radius: 16px;
    border-color: var(--brand-1);
    background: #fff8f5;
    box-shadow: var(--shadow-sm);
    transform: none;
}
.disp-nozzle-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 12px 7px 7px;
}
.disp-nozzle-summary::-webkit-details-marker { display: none; }

/* Icon badge: a small colored "medallion" behind the hose icon instead of a
   bare glyph, echoing the illuminated topper on the illustration above. */
.disp-nozzle-icon-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: linear-gradient(150deg, var(--accent-soft) 0%, #ffffff 100%);
    border: 1px solid var(--accent-soft);
}
.disp-nozzle-summary .nozzle-hose-icon { flex: 0 0 auto; }
.disp-nozzle-right .nozzle-hose-icon { transform: scaleX(-1); }
.disp-nozzle-id { display: flex; flex-direction: column; line-height: 1.25; text-align: start; min-width: 0; }
.disp-nozzle-side { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.disp-nozzle-code { font-size: 13px; font-weight: 700; color: var(--navy); }
.disp-nozzle-chevron { color: var(--muted); flex: 0 0 auto; margin-inline-start: auto; transition: transform 0.15s ease; }
.disp-nozzle[open] .disp-nozzle-chevron { transform: rotate(90deg); }

/* The reading form sits below the summary, inside the SAME nozzle pill -
   its own column never grows to swallow the sibling nozzle's column (see
   .disp-nozzle-list above). date + value fields still lay out side-by-side
   (horizontally) whenever the column is wide enough, and wrap onto their
   own line only when the pill is too narrow to fit both. */
.dr-meter-form-wrap {
    padding: 8px 12px 10px;
    border-top: 1px dashed var(--border);
}
.dr-meter-form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 10px;
    align-items: flex-end;
}
.dr-meter-form label { font-size: 11px; margin-bottom: 2px; }
.dr-meter-form input { margin-bottom: 0; }
.dr-meter-form input[type="datetime-local"] { flex: 1 1 150px; min-width: 140px; }
.dr-meter-form input[type="number"] { flex: 1 1 100px; min-width: 90px; }
.dr-meter-form button { flex: 0 0 auto; white-space: nowrap; }

.dr-shift-sale-toggle {
    flex-basis: 100%;
    margin-top: 8px;
    padding: 8px 10px 0;
    border-top: 1px dashed var(--border);
}
.dr-shift-sale-toggle summary {
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    list-style: none;
}
.dr-shift-sale-toggle summary::-webkit-details-marker { display: none; }
.dr-shift-sale-toggle summary::before { content: '+ '; }
.dr-shift-sale-toggle[open] summary::before { content: '− '; }
.dr-shift-sale-toggle .dispenser-nozzle-form { margin-top: 10px; padding-top: 10px; }

.dr-shift-sale-toggle {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
}
.dr-shift-sale-toggle summary {
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    list-style: none;
}
.dr-shift-sale-toggle summary::-webkit-details-marker { display: none; }
.dr-shift-sale-toggle summary::before { content: '+ '; }
.dr-shift-sale-toggle[open] summary::before { content: '− '; }
.dr-shift-sale-toggle .dispenser-nozzle-form { margin-top: 10px; padding-top: 10px; }

@media (max-width: 520px) {
    .tank-dip-form .form-grid, .dispenser-nozzle-form .form-grid { grid-template-columns: 1fr; }
}

.dispenser-icon-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    border-radius: 14px;
    color: #fff;
    margin: 0 auto 6px;
}
.dispenser-icon-wrap .icon { width: 30px; height: 30px; }

/* ---- printable report ---- */
.print-header { display: none; }
.print-footer { display: none; }

@media print {
    .topbar, .sidebar, .no-print, .lang-toggle-standalone { display: none !important; }
    /* Sep 2026 fix: "har dafa print main 2 page extra fetch kar rha hay"
       (every print job comes out with 2 extra pages) — .layout's own base
       rule (top of this file) sets min-height: calc(100vh - 60px) purely so
       the sidebar's gradient background fills the screen on-screen; that
       rule was never reset for print. A forced ~full-viewport-tall box is
       harmless on screen (no scrollbar-visible difference) but under print
       it forces that much BLANK trailing space onto the page after the
       actual (usually much shorter) printed content — a single Detail
       dialog or a short report can easily be a few hundred px tall, so the
       leftover forced blank height reliably spilled onto one or two extra,
       completely blank, printed pages every single time. min-height: 0
       here lets .layout size itself to its actual (visible) content only. */
    .layout { display: block; min-height: 0 !important; }
    .content { padding: 0; }
    body { background: #fff; }
    .card { box-shadow: none; border: none; padding: 0; }
    .print-header {
        display: block;
        text-align: center;
        margin-bottom: 20px;
        border-bottom: 2px solid #000;
        padding-bottom: 12px;
    }
    .print-header h2 { margin: 0; }

    /* ---- professional letterhead (includes/print_layout.php::printLetterheadHtml) ---- */
    /* Portrait per owner's explicit request. (Was landscape for a while —
       some reports' breakdown tables run 6-10 columns wide, e.g. Rate
       Difference/Net Profit — but table-layout stays auto with wrapping
       allowed below, so a wide table's columns shrink/wrap to fit a portrait
       page instead of being cut off; they'll just read tighter on paper than
       they did in landscape for those specific reports.) */
    @page { size: A4 portrait; margin: 14mm 12mm 18mm 12mm; }
    /* Oct 2026 (owner: "Es par Page number 1 of 3, 2 of 3, 3 of 3 par bhe lgao") — page numbers on EVERY printed
       report, bottom-right of each sheet ("Page 1 of 3"). Uses the @page margin box, which the Chrome/Edge print
       engine supports; the per-report @page rules that only set size/margin do not override this. */
    @page { @bottom-right { content: "Page " counter(page) " of " counter(pages); font-size: 10px; color: #333; font-weight: 700; font-family: Arial, Helvetica, sans-serif; vertical-align: middle; padding-right: 4mm; } }
    /* table-layout:fixed forces the browser to divide the page's actual
       available width evenly across however many columns a report has,
       instead of sizing each column to fit its content on one line — the
       breakdown tables here run 6-10 columns with long headers ("Credit
       Received (Customers)", etc.) and on-screen `white-space: nowrap`
       made several of those columns wide enough that, at real A4 width,
       the last 1-2 columns were silently pushed off the printable page
       and lost (confirmed by measuring the table's natural width against
       the printable content box). Allowing header/cell text to wrap
       (white-space: normal) is what makes fixed equal-width columns still
       readable instead of crushing long labels into nothing. */
    /* table-layout stays auto (not fixed): with white-space allowed to wrap,
       the browser sizes each column to its own content instead of splitting
       the page width evenly — so "Litres" stays narrow while "Sale Amount"
       (figures up to Rs. 2,678,717,516.64 for this business) gets the room
       it needs, and long headers like "Credit Received (Customers)" wrap
       at the space between words. A fixed equal-width split was tried first
       and rejected: it either fractured big rupee figures mid-digit-group
       (word-break: break-word) or let them overflow through neighbouring
       cells (overflow-wrap: normal) once a column was narrower than one
       unbreakable number. Auto layout with wrapping avoids both. */
    /* Text size bumped up and weighted a bit bolder (owner's request) —
       easier to read on a printed page than the original compact/light
       sizing, at the cost of slightly more pages for a very long report. */
    table.data-table { font-size: 10.5px; width: 100%; max-width: 100%; }
    table.data-table th, table.data-table td {
        padding: 3px 4px;
        white-space: normal;
        font-weight: 600;
    }
    table.data-table th { font-weight: 800; }
    /* Short cells (dates, rates, amounts — marked by the script in includes/footer.php) never
       break mid-value; long text cells (descriptions, cost breakdowns) still wrap. */
    table.data-table td.ns-nw, table.data-table th.ns-nw { white-space: nowrap; }
    table.data-table.ns-wide { font-size: 9.5px; }
    table.data-table.ns-wide th, table.data-table.ns-wide td { padding: 3px 3px; }
    /* Report tiles (Litres Sold / Sale Rate / Profit ... boxes) never go on paper — only the
       letterhead and the data table do (owner, Oct 2026). Left alone while a Detail dialog /
       list / slip is being printed (body.ns-printing-*), whose own layout may use them. */
    body:not([class*="ns-printing"]) .stat-grid,
    body:not([class*="ns-printing"]) .stat-box,
    body:not([class*="ns-printing"]) .stat-card,
    body:not([class*="ns-printing"]) div:has(> .stat-box) { display: none !important; }
    /* Grand-total rows use the normal table size on paper (the on-screen 18px made the last
       column overflow the page edge). */
    .report-summary-row td { font-size: 11px !important; }
    /* Inline-sized pieces inside cells (e.g. the 13px FIFO cost-breakdown text) follow the table. */
    table.data-table td[style*="font-size"], table.data-table td [style*="font-size"] { font-size: inherit !important; }
    .table-scroll { overflow: visible; }
    /* Column headers (thead) SHOULD repeat on every printed page of a long
       table — that's standard and helps readability. But a browser repeats
       <tfoot> the same way by default, which makes a "Grand Total" row
       appear after the very first partial page too (misleadingly, as if
       that page's few rows were the whole total). Forcing tfoot to render
       as a normal row group makes it flow to its natural position instead
       of being pinned to the bottom of every page, so it prints exactly
       once, after the last data row. */
    table.data-table tfoot { display: table-row-group; }
    /* Point 7 of the report-template feedback: a full grid, not just row
       separators — every cell gets all 4 borders on paper (screen tables
       keep the lighter row-only look; this only applies under print). */
    table.data-table, table.data-table th, table.data-table td {
        border: 1px solid #94a3b8;
    }
    table.data-table tfoot td { border-top: 2px solid var(--accent); }
    /* Calibri end-to-end on paper, matching the on-screen body font
       (assets/style.css :root font-family) — explicit here too so print
       never falls back to something else regardless of what a given
       element inherits. */
    body, table.data-table, .print-letterhead, .print-footer {
        font-family: Calibri, 'Segoe UI', Arial, -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
    }
    /* General print text a bit larger/bolder too (owner's request) — covers
       report body copy outside the data table itself (stat boxes, hints,
       headings) that isn't covered by the table.data-table rule above. */
    body { font-size: 12px; font-weight: 500; }
    h2, h3 { font-weight: 800; }

    /* ---- letterhead (includes/print_layout.php::printLetterheadHtml) ----
       Compact by design: a report is mostly its data table, so the header
       above it should read fast and get out of the way — smaller logo,
       tighter line spacing, less vertical padding than the first version. */
    .print-letterhead { text-align: left; }
    .print-letterhead-row {
        display: flex; align-items: center; justify-content: space-between;
        gap: 14px;
    }
    .print-letterhead-brand { display: flex; align-items: center; gap: 10px; }
    /* Both logos share the exact same bounding box (42x42) so they read as
       equal size on the page, regardless of each source image's own aspect
       ratio (ULFAT's mark is square; TOTAL's is a taller portrait crop) —
       object-fit:contain scales each one to fit that box without distorting
       or cropping it. */
    .print-letterhead-brand .brand-logo,
    .print-letterhead-brand .brand-emoji { width: 42px; height: 42px; font-size: 30px; line-height: 42px; }
    .print-letterhead-identity h2 { margin: 0 0 2px; font-size: 16px; }
    .print-letterhead-line { margin: 0; font-size: 10.5px; color: #444; line-height: 1.35; font-weight: 600; }
    .print-letterhead-supplier { text-align: right; flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; }
    .print-supplier-logo { width: 42px; height: 42px; object-fit: contain; }
    .print-supplier-text { font-weight: 800; font-size: 13px; color: #00338D; }
    .print-supplier-caption { margin: 1px 0 0; font-size: 7.5px; color: #666; text-transform: uppercase; letter-spacing: .5px; }
    /* "Catchy" report title (point 6): a solid brand-navy band with the
       report name in large white letter-spaced caps, instead of a plain
       black rule + text — reads like a real letterhead banner, and is what
       makes the report's own name (point 2 — the full name, e.g. "High
       Octane Sale Difference", not just a generic module label) the most
       visually prominent line on the page. */
    .print-letterhead-title {
        margin-top: 10px;
        padding: 8px 14px;
        background: #fff;
        border: 1.5px solid var(--navy, #00338D);
        border-left: 5px solid var(--brand-3, #F7941D);
        border-radius: 6px;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    .print-letterhead-title h3 {
        margin: 0; font-size: 17px; font-weight: 800; color: var(--navy, #00338D);
        letter-spacing: .2px;
    }
    .print-letterhead-title p { margin: 2px 0 0; font-size: 10.5px; font-weight: 800; color: var(--brand-3, #F7941D); text-transform: uppercase; letter-spacing: .6px; }

    /* ---- footer (includes/print_layout.php::printFooterHtml) ----
       Point 1: no more standalone disclaimer line about the address — kept
       to who/when it was generated plus a short report "path" (which
       report, which section) instead. */
    .print-footer {
        display: block; margin-top: 16px; padding-top: 6px;
        border-top: 1px solid #ccc; text-align: center;
    }
    .print-footer p { margin: 2px 0; font-size: 10px; color: #666; font-weight: 600; }
    .print-footer-path { font-weight: 600; color: #444 !important; }

    /* Reports → Lubricants Purchase History inline item-detail expand
       (modules/reports/index.php) — owner: "Pooria invoice detail open ho
       click homay par" plus "saari reports international standard kay
       mutaabiq hon" (consistent print format): whatever was expanded/
       collapsed on screen, a PRINTED copy always shows every invoice's full
       itemized breakdown, so [hidden] is overridden back to visible here. */
    .rp-lp-detail-row[hidden] { display: table-row !important; }
    .rp-lp-item-table { margin: 4px 0; width: 100%; max-width: 100%; table-layout: auto; }
    .rp-lp-detail-row > td { padding-left: 4px !important; padding-right: 4px !important; }
}

/* ---- lubricant stock-transfer slip (voucher-style, prints as a single small card) ---- */
.slip-card { max-width: 480px; margin: 0 auto; }
.slip-body { margin-top: 8px; }
.slip-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px dashed var(--border);
    font-size: 14.5px;
}
.slip-row span:first-child { color: var(--muted); }
.slip-row strong { color: var(--text); text-align: end; }
.slip-route {
    justify-content: center;
    gap: 14px;
    background: var(--accent-soft);
    border-radius: var(--radius-sm);
    border-bottom: none;
    padding: 14px 12px;
    margin: 8px 0;
    font-weight: 700;
    font-size: 15.5px;
    color: var(--accent-dark);
}
.slip-arrow { display: inline-flex; color: var(--accent-dark); }
.slip-arrow .icon { width: 20px; height: 20px; }
[dir="rtl"] .slip-arrow { transform: scaleX(-1); }
.slip-signatures {
    display: flex;
    gap: 32px;
    margin-top: 44px;
}
.slip-sign { flex: 1; text-align: center; font-size: 13px; color: var(--muted); }
.slip-sign span { display: block; border-top: 1px solid #9aa3b2; margin-bottom: 8px; height: 40px; }

/* =====================================================================
   Dashboard "Fuel Network" — Tank -> Dispenser -> Nozzle, drawn as a
   responsive card grid (every card wraps its own content, so nothing is
   ever clipped off-screen the way a wide horizontally-scrolling tree could
   hide equipment). Each tank card gets its own accent color (--net-line /
   --net-glow, set inline per fuel) so it reads as "this fuel's equipment"
   at a glance.
   ===================================================================== */
.fuel-network-card { overflow: visible; }

.equip-grid {
    display: grid;
    /* 4 tanks in a single row on a normal desktop width (owner's request —
       the dashboard only ever shows up to 4 tanks in the primary grid, extra
       tanks collapse behind "show more"), stepping down to 2 then 1 column
       as the viewport narrows instead of an odd 3+1 wrap. */
    grid-template-columns: repeat(4, 1fr);
    gap: 18px;
    margin-top: 4px;
}
@media (max-width: 1100px) {
    .equip-grid { grid-template-columns: repeat(2, 1fr); }
}

.equip-card {
    position: relative;
    background: linear-gradient(180deg, #ffffff 0%, color-mix(in srgb, var(--net-glow, var(--accent)) 5%, white) 100%);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-md);
    padding: 20px 20px 18px;
    overflow: hidden;
    box-shadow: var(--shadow-xs);
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
    animation: equipCardIn 0.4s ease backwards;
}
.equip-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: var(--net-line, var(--border));
}
@keyframes equipCardIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .equip-card { animation: none; } }

/* Pump/company brand-color stripe along the top — same touch used on the
   Tank Dip Reading page's own tank-gauge-card, so the dashboard's tanks
   read as the same family of "equipment card" rather than a plainer,
   one-off design. */
.equip-card::before {
    content: '';
    position: absolute;
    top: 0; inset-inline-start: 0; inset-inline-end: 0;
    height: 5px;
    background: linear-gradient(90deg, var(--brand-1), var(--brand-2), var(--brand-3));
}

/* ---- Redesigned instrument-panel layout (owner's request: "koe aur
   professional internationally standard design bnao" — a status-chip
   dashboard style like the reference design he shared). Header identity row
   first, then the gauge, then a bold percent+volume readout row, then each
   dispenser as its own bordered sub-panel instead of a flat list row. ---- */

.equip-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.equip-tank-title { flex: 1; min-width: 0; }
.equip-tank-code { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 15px; color: var(--navy); }

/* Small fuel-name pill under the tank code (replaces the old plain subtitle
   text) — tinted with the fuel's own gauge color so it reads as "this
   fuel's tank" at a glance, same spirit as the gauge liquid color. */
.fuel-badge {
    display: inline-block;
    margin-top: 5px;
    padding: 2px 9px;
    border-radius: 5px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
    /* Reuses --net-line/--net-glow already set on the parent .equip-card
       (same fuel colors the gauge itself uses) — the DARK tone as text so
       it stays readable, the LIGHT tone tinting the background. */
    color: var(--net-line, var(--navy));
    background: color-mix(in srgb, var(--net-glow, var(--accent)) 35%, white);
    border: 1px solid color-mix(in srgb, var(--net-line, var(--accent)) 25%, white);
}

/* Fill-level status chip (Optimal / Low / Critical) — data-driven by
   dashFillStatus() in index.php (the tank's own reorder level when set). */
.fill-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    padding: 4px 11px 4px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
}
.fill-chip-icon { flex-shrink: 0; color: currentColor; }
/* Vivid international-standard semantic colors (emerald/amber/red-600 —
   the same family Stripe/Linear/fleet-tracking SaaS use) — owner's request
   for a "catchy international standard" color treatment, Sep 2026. */
.fill-chip-optimal  { background: #dcfce7; color: #16a34a; }
.fill-chip-low      { background: #fef3c7; color: #d97706; }
.fill-chip-critical { background: #fee2e2; color: #dc2626; }

/* Card-level severity treatment — a colored inset left bar (+ background
   wash for Low/Critical, replacing the plain fuel tint so severity is what
   catches the eye across a busy grid, not just the small corner chip). A
   Critical tank gets a slow attention-pulse on that bar; Low stays static
   so only genuine urgency animates. */
.equip-card-low, .equip-card-critical {
    border-color: color-mix(in srgb, var(--status-color) 40%, var(--border));
    box-shadow: inset 3px 0 0 var(--status-color), var(--shadow-xs);
}
.equip-card-low {
    background: linear-gradient(180deg, #ffffff 0%, color-mix(in srgb, var(--status-color) 6%, white) 100%);
}
.equip-card-critical {
    background: linear-gradient(180deg, #ffffff 0%, color-mix(in srgb, var(--status-color) 8%, white) 100%);
    animation: equipCardIn 0.4s ease backwards, criticalPulse 2.6s ease-in-out infinite;
}
@keyframes criticalPulse {
    0%, 100% { box-shadow: inset 3px 0 0 var(--status-color), var(--shadow-xs); }
    50%      { box-shadow: inset 3px 0 0 var(--status-color), 0 0 0 3px color-mix(in srgb, var(--status-color) 16%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .equip-card-critical { animation: equipCardIn 0.4s ease backwards; } }

/* Percent ring — a second, severity-colored fill readout (percentRingSvg())
   sitting beside the litres text in the metrics row; the number is an
   absolutely-centered HTML label over the SVG rather than SVG <text> so its
   font matches the rest of the UI exactly. */
.percent-ring-wrap { position: relative; width: 60px; height: 60px; flex-shrink: 0; }
.percent-ring-wrap .percent-ring { display: block; }
.percent-ring-label {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 800; letter-spacing: -0.01em;
    color: var(--status-color);
}

/* Real glass-tank gauge illustration (same tankGaugeSvg() as Tank Dip
   Reading — a horizontal cylinder, the shape a real underground tank
   actually is) as the card's hero visual, centered below the header row. */
.equip-card-gauge { display: flex; justify-content: center; margin: 14px 0 4px; }
.equip-card-gauge .tank-gauge { width: 100%; max-width: 190px; height: auto; }

/* Tank starts empty and rises to its real level on page load (owner's
   request, Sep 2026) — transform-box:fill-box anchors the scale to the
   liquid shape's OWN bounding box (already only spans its fill height), so
   this works correctly at any percent with no per-tank CSS needed. A tiny
   per-card stagger (nth-child on the grid) keeps a row of tanks from
   snapping up in perfect lockstep. */
.gauge-liquid-fill {
    transform-box: fill-box;
    transform-origin: bottom;
    animation: gaugeFillIn 2.4s cubic-bezier(0.22, 0.9, 0.32, 1) both;
}
.equip-grid .equip-card:nth-child(1) .gauge-liquid-fill,
.equip-grid .equip-card:nth-child(5) .gauge-liquid-fill { animation-delay: 0s; }
.equip-grid .equip-card:nth-child(2) .gauge-liquid-fill,
.equip-grid .equip-card:nth-child(6) .gauge-liquid-fill { animation-delay: 0.12s; }
.equip-grid .equip-card:nth-child(3) .gauge-liquid-fill,
.equip-grid .equip-card:nth-child(7) .gauge-liquid-fill { animation-delay: 0.24s; }
.equip-grid .equip-card:nth-child(4) .gauge-liquid-fill,
.equip-grid .equip-card:nth-child(8) .gauge-liquid-fill { animation-delay: 0.36s; }
@keyframes gaugeFillIn {
    from { transform: scaleY(0); }
    to   { transform: scaleY(1); }
}
@media (prefers-reduced-motion: reduce) { .gauge-liquid-fill { animation: none; } }

/* Percent + exact volume readout, right under the gauge — a dashed rule
   above sets it apart as the card's primary instrument reading. */
.equip-tank-metrics {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 2px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
}
.equip-tank-meta { font-size: 12.5px; color: var(--muted); font-weight: 600; text-align: end; }
.equip-tank-meta strong { display: block; font-size: 15px; color: var(--text); font-weight: 800; }

/* Owner's request: dashboard tank cards ab dip reading se data lete hain —
   jab tak AAJ ka dip na ho, purana reading hi dikhta hai lekin is chhoti si
   amber note ke sath, taake number ko "aaj ka" na samjha jaye. */
.equip-tank-stale-note {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding: 6px 10px;
    background: #fffbeb;
    border: 1px solid #fde68a;
    border-radius: var(--radius-sm);
    font-size: 11.5px;
    font-weight: 600;
    color: #92400e;
}
.equip-tank-stale-note svg { width: 13px; height: 13px; flex-shrink: 0; }

.equip-divider { height: 1px; background: var(--border); margin: 14px 0 12px; }
.equip-body { display: flex; flex-direction: column; gap: 10px; }

/* Each dispenser as its own bordered sub-panel (was a flat unbounded row) —
   reads as a distinct instrument grouping and scales cleanly once a tank
   has several dispensers, the same "panel within a panel" convention a
   SCADA forecourt-controller screen uses. */
.disp-panel {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: #f8fafc;
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 12px;
}
.equip-disp-label {
    display: flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 700; color: var(--navy);
    text-transform: uppercase; letter-spacing: 0.03em;
}
.equip-disp-label .icon { width: 14px; height: 14px; color: var(--muted); }
.equip-unassigned-label { color: var(--muted); }
.equip-unassigned-label .icon { opacity: 0.6; }

.nozzle-chip-wrap { display: flex; flex-wrap: wrap; gap: 6px; }
.nozzle-chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 5px 11px 5px 9px;
    border-radius: 99px;
    background: #ffffff;
    border: 1px solid color-mix(in srgb, var(--net-line, var(--accent)) 22%, white);
    font-size: 12px; font-weight: 600; color: var(--text);
    white-space: nowrap;
}
/* Small equipment-status dot on each nozzle chip (active/maintenance/
   inactive — real equipment status, not a simulated "currently dispensing"
   state this app has no data for) — same 3-color convention as the tank/
   dispenser pulse dots, just static (no pulse animation) at this size. */
.nozzle-chip-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: #b0b7c3; }
.nozzle-chip-dot-active { background: var(--green); }
.nozzle-chip-dot-maintenance { background: var(--accent); }
.nozzle-chip-dot-inactive { background: #b0b7c3; }
.nozzle-chip .nozzle-hose-icon { width: 14px; height: 14px; flex-shrink: 0; }
.nozzle-chip-unassigned {
    background: #f4f5f7;
    border-style: dashed;
    border-color: var(--border);
    color: var(--muted);
}
.equip-dim { opacity: 0.5; }
.equip-tank-count { margin-top: 12px; font-size: 11px; color: var(--muted); text-align: end; }

/* "Show N more tanks" disclosure — 5th tank onward starts collapsed behind
   this, click to reveal. Native <details>/<summary> (no custom JS, no
   [hidden]-attribute CSS to fight with — see the Net Profit modal fix for
   why that pattern needs care). */
.equip-more { margin-top: 16px; }
.equip-more-summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--brand-2, var(--blue)) 8%, white);
    border: 1px solid color-mix(in srgb, var(--brand-2, var(--blue)) 22%, white);
    color: var(--navy);
    font-size: 13px;
    font-weight: 700;
}
.equip-more-summary::-webkit-details-marker { display: none; }
.equip-more-summary .icon { width: 16px; height: 16px; color: var(--brand-2, var(--blue)); }
.equip-more-summary::after {
    content: '▾';
    margin-inline-start: 2px;
    color: var(--muted);
    transition: transform 0.15s ease;
}
.equip-more[open] .equip-more-summary::after { transform: rotate(180deg); }
.equip-more-summary:hover { border-color: var(--brand-2, var(--blue)); }
.equip-grid-more { margin-top: 16px; }

/* ---- inline status dot (replaces the old absolutely-positioned corner pulse) ---- */
.net-pulse-inline {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #9ca3af;
    flex-shrink: 0;
}
.net-pulse-inline.net-pulse-sm { width: 6px; height: 6px; }
.net-pulse-inline.net-pulse-active {
    background: var(--green);
    box-shadow: 0 0 0 rgba(22,163,74,0.5);
    animation: netPulse 1.8s ease-out infinite;
}
.net-pulse-inline.net-pulse-maintenance { background: var(--accent); }
.net-pulse-inline.net-pulse-inactive { background: #b0b7c3; }
@keyframes netPulse {
    0%   { box-shadow: 0 0 0 0 rgba(22,163,74,0.55); }
    70%  { box-shadow: 0 0 0 6px rgba(22,163,74,0); }
    100% { box-shadow: 0 0 0 0 rgba(22,163,74,0); }
}
@media (prefers-reduced-motion: reduce) { .net-pulse-inline.net-pulse-active { animation: none; } }

/* ---- sidebar "Entry" pending-reading dot — blinks red until today's nozzle/dip
   readings are all in (includes/entry_status.php: nsHasPendingEntries()) ---- */
.pending-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #ef4444;
    margin-inline-start: 2px;
    align-self: flex-start;
    animation: pendingDotBlink 1.1s ease-in-out infinite;
}
@keyframes pendingDotBlink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.15; }
}
@media (prefers-reduced-motion: reduce) { .pending-dot { animation: none; } }

/* Same dot, used inline next to a nozzle/tank's code on the Entry page
   itself while that specific row's business-day reading is still missing
   (modules/entry/nozzle_tab.php, dip_tab.php). */
.pending-dot-row {
    margin-inline-start: 6px;
    vertical-align: super;
}

/* Sep 2026 owner request ("andes ko blink na karo" — on the Dip tab's new
   "Diesel Tanks (No Dip Chart)" block, Tank 5/6's own row dot) — same red
   dot, just without the blink; scoped to this one block only, the sidebar
   nav dot and the main dip table's row dots are unchanged and keep
   blinking exactly as before. */
.pending-dot-static {
    animation: none;
}

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

/* ==========================================================================
   Dashboard hero — refined greeting header (spacing/typography hierarchy to
   match the modernized stat-cards / Fuel Network card below it).
   ========================================================================== */
.dash-hero {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 26px;
}
.dash-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--accent-dark);
    background: var(--accent-soft);
    padding: 4px 12px;
    border-radius: 999px;
    margin-bottom: 10px;
}
.dash-hero-eyebrow .icon { width: 13px; height: 13px; }
/* Sep 2026 "professional premium" pass (owner: "Premium Software wali look
   nae ae... designing Professional Premium do") — the gradient-clip
   greeting text and its decorative blob from the previous "catchy" pass
   are gone; a solid navy heading reads as considered, confident software
   copy instead of a marketing-page flourish. */
.dash-hero h2 {
    margin: 0;
    font-size: 25px;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--navy);
}
.dash-hero p {
    margin: 6px 0 0;
    color: var(--muted);
    font-size: 14.5px;
}
.dash-hero-date {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 600;
    color: var(--navy);
    background: #fff;
    border: 1.5px solid var(--border);
    padding: 8px 16px;
    border-radius: 999px;
    box-shadow: var(--shadow-xs);
}
.dash-hero-date .icon { width: 15px; height: 15px; color: var(--muted); }
.dash-hero-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex-shrink: 0; }
/* Month picker (owner's request: "uper month bhe select ho jes month ka
   chahyain data daikh lain") — plain GET form, auto-submits on change, styled
   as a pill to match .dash-hero-date sitting right above it. */
.dash-month-form { display: inline-flex; align-items: center; gap: 8px; }
.dash-month-form label { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.dash-month-select {
    font-size: 13px;
    font-weight: 600;
    color: var(--navy);
    background: #fff;
    border: 1.5px solid var(--border);
    padding: 7px 14px;
    border-radius: 999px;
    box-shadow: var(--shadow-xs);
    cursor: pointer;
}
.dash-month-select:hover { border-color: var(--accent); }
@media (max-width: 640px) { .dash-hero { flex-wrap: wrap; } .dash-hero-right { order: -1; align-items: flex-start; width: 100%; } }

/* ==========================================================================
   Login page — modern split-screen layout (brand panel + form panel).
   Scoped entirely to login.php's own classes; forgot/reset password pages
   keep using the older shared .login-wrap/.login-box centered-card pattern
   (they still benefit from the global shadow/radius token refinements above).
   ========================================================================== */
.login-page-body {
    margin: 0;
    background: var(--bg);
    min-height: 100vh;
}

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

/* ---- brand panel (start side; hidden on narrow screens) ---- */
.login-brand-panel {
    flex: 0 0 44%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 60px 48px;
    overflow: hidden;
    background: radial-gradient(circle at 15% 15%, var(--navy-light) 0%, var(--navy) 45%, var(--navy-dark) 100%);
    color: #fff;
}

.login-brand-decor { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.login-brand-decor::before,
.login-brand-decor::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    background: radial-gradient(circle, color-mix(in srgb, var(--accent) 55%, transparent) 0%, transparent 70%);
    filter: blur(2px);
    animation: loginBlobFloat 12s ease-in-out infinite;
}
.login-brand-decor::before { width: 340px; height: 340px; top: -90px; inset-inline-end: -110px; animation-delay: 0s; }
.login-brand-decor::after {
    width: 260px; height: 260px; bottom: -80px; inset-inline-start: -70px;
    background: radial-gradient(circle, color-mix(in srgb, var(--brand-1) 45%, transparent) 0%, transparent 70%);
    animation-delay: -6s;
}
@keyframes loginBlobFloat {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50% { transform: translate(-14px, 16px) scale(1.06); }
}
@media (prefers-reduced-motion: reduce) { .login-brand-decor::before, .login-brand-decor::after { animation: none; } }

.login-brand-content { position: relative; z-index: 1; max-width: 380px; }
.login-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    border-radius: var(--radius-md);
    background: rgba(255,255,255,0.14);
    box-shadow: var(--shadow-lg);
    font-size: 28px;
    margin-bottom: 22px;
    backdrop-filter: blur(4px);
}
.login-brand-mark .brand-emoji { width: 100%; height: 100%; background: none; box-shadow: none; font-size: 28px; }
.login-brand-mark .brand-logo { height: 40px; }

.login-brand-content h1 {
    margin: 0 0 12px;
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -0.01em;
}
.login-brand-tagline {
    margin: 0 0 34px;
    font-size: 15.5px;
    line-height: 1.6;
    opacity: 0.86;
}

.login-brand-features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.login-brand-features li {
    display: flex;
    align-items: center;
    gap: 13px;
    font-size: 14.5px;
    font-weight: 600;
    opacity: 0.95;
}
.login-feature-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: rgba(255,255,255,0.14);
}

/* ---- form panel ----
   Sep 2026 "professional premium" pass (owner: "Premium Software wali look
   nae ae... designing Professional Premium do") — the animated color blobs
   and the frosted-glass floating card from the previous "catchy" pass are
   gone; back to one flat, quiet surface. This form side already did its job
   well before that pass (clean split-screen layout, the brand panel on the
   left carries all the color) — a plain background here is what keeps that
   side reading as calm, serious "sign in to your business software"
   rather than a marketing landing page. */
.login-form-panel {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 24px;
    background: var(--bg);
}

.login-form-wrap {
    width: 100%;
    max-width: 400px;
    animation: loginFormIn 0.5s ease both;
}
@keyframes loginFormIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .login-form-wrap { animation: none; } }

.login-mobile-brand {
    display: none;
    align-items: center;
    gap: 12px;
    margin-bottom: 28px;
}
.login-mobile-brand .brand-emoji { width: 44px; height: 44px; font-size: 22px; }
.login-mobile-brand strong { font-size: 17px; color: var(--navy); }

.login-form-header { margin-bottom: 26px; }
.login-form-header h2 {
    margin: 0 0 6px;
    font-size: 23px;
    font-weight: 800;
    color: var(--navy);
    letter-spacing: -0.01em;
}
.login-form-header p { margin: 0; color: var(--muted); font-size: 14.5px; }

.input-group { margin-bottom: 18px; }
.input-group label { margin-bottom: 7px; }

.input-with-icon { position: relative; display: flex; align-items: center; }
.input-with-icon input { margin-bottom: 0 !important; }
.input-with-icon input[type=text],
.input-with-icon input[type=password] {
    padding-inline-start: 44px;
}
.input-with-icon input#password { padding-inline-end: 44px; }

.input-icon {
    position: absolute;
    inset-inline-start: 14px;
    display: inline-flex;
    color: var(--muted);
    pointer-events: none;
}
.input-icon .icon { width: 18px; height: 18px; }

.pw-toggle {
    position: absolute;
    inset-inline-end: 8px;
    background: transparent;
    color: var(--muted);
    border: none;
    padding: 7px;
    border-radius: 8px;
    box-shadow: none;
    display: inline-flex;
    cursor: pointer;
}
.pw-toggle:hover { background: rgba(0,0,0,0.05); color: var(--navy); filter: none; transform: none; box-shadow: none; }
.pw-toggle:active { transform: none; }
.pw-toggle .icon { width: 18px; height: 18px; }
.pw-toggle-active { color: var(--accent-dark); }

.login-submit {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 13px 20px;
    font-size: 15.5px;
    margin-top: 6px;
}
/* A slightly deeper navy shadow on top of the global button hover-lift
   (from `button, .btn`) — restrained emphasis on the primary CTA, scoped to
   this login-only class. */
.login-submit:hover {
    box-shadow: 0 8px 22px color-mix(in srgb, var(--navy) 40%, transparent);
}
.login-submit-arrow { display: inline-flex; transition: transform 0.15s ease; }
.login-submit-arrow .icon { width: 18px; height: 18px; }
.login-submit:hover .login-submit-arrow { transform: translateX(3px); }
[dir="rtl"] .login-submit-arrow { transform: scaleX(-1); }
[dir="rtl"] .login-submit:hover .login-submit-arrow { transform: scaleX(-1) translateX(3px); }

.login-form-links { text-align: center; margin: 20px 0 0; font-size: 14px; }
.login-form-links a { color: var(--navy); font-weight: 600; text-decoration: none; }
.login-form-links a:hover { text-decoration: underline; }

.login-form-footnote { text-align: center; margin: 10px 0 0; font-size: 13px; color: var(--muted); }

@media (max-width: 900px) {
    .login-brand-panel { display: none; }
    .login-mobile-brand { display: flex; }
    .login-form-panel { padding: 32px 20px; min-height: 100vh; }
}

/* ---- Lubricant Sale — multi-row batch form (Lubricants Sale tab + Entry
   page's Lubricant Sale tab, includes/lubricant_sale_form.php) ----
   Lubricant Sale form redesign (owner's request: "es page ko update karna
   hay... jesay lubricants purchase ko kya hay" + "es ko poray page par aap
   woh bhe kar do width wise karo") — ONE live entry row ending in an "Add
   Item" button, exactly the same pattern (and the same "row width wise full
   page cover karay" full-width flex-grow treatment) as Quick Fuel
   Purchase's Lubricants tab .qfp-lub-entry below; the filled-in cart table
   below it reuses the app's standard .data-table/.table-scroll styling. */
/* .card normally clips (overflow:hidden) so its own ::before accent strip
   (further below) never pokes square corners past the card's rounded
   ones — but that same clipping was cutting off the item picker's search
   results dropdown here, since this card's shorter content (no Payment
   Mode/Discount fields any more) leaves little room below the entry row
   before hitting the card's own bottom edge. Scoped to just this card:
   let it overflow normally, and give its accent strip its own matching
   corner radius instead so it still doesn't need the clip. */
.card--lub-sale { overflow: visible; }
.card--lub-sale::before { border-radius: var(--radius-md) var(--radius-md) 0 0; }
/* Owner's request: on a narrow screen the LAST couple of fields (Total, Add
   Item) used to drop onto their own line while the rest of the row stayed
   put — confusing, since Add Item then reads like a separate control
   instead of the end of the same row. A CSS Grid (instead of the old flex
   row) with an EXPLICIT column per field lays the whole row out in one
   predictable pass at normal widths; a single breakpoint switches the
   whole row to a clean 2-per-line stack together, so Add Item never ends
   up alone on a trailing line while its neighbours stayed on the one
   above it. */
.lub-cart-entry {
    display: grid;
    /* 8 explicit tracks — one per field INCLUDING Actions (Add Item), which
       is what was missing before: with only 7 tracks defined for an 8-cell
       row (Short Code, Item, Quantity, Cost Ref, Remaining Stock, Sale
       Price, Total, Actions — when this install has Short Codes), the grid
       had nowhere left to put the 8th cell but an implicit new row, which is
       exactly why "Add Item" kept dropping onto its own line. Item's own
       track is also trimmed down a notch here (owner's request: "item ka
       size reduce kar lo") now that its label text — not this field's
       width — is what actually needs the room. */
    grid-template-columns: minmax(80px, 0.9fr) minmax(140px, 1.5fr) minmax(75px, 0.8fr) minmax(90px, 0.9fr) minmax(90px, 0.9fr) minmax(80px, 0.8fr) minmax(80px, 0.8fr) auto;
    align-items: end;
    gap: 10px;
    padding: 10px 0;
    width: 100%;
}
.lub-cart-entry #lubEntryCostRef { background: var(--bg-soft, #f3f4f6); color: var(--text-muted, #666); }
/* Owner's request: "Total price and remaining stock cost price ke tarahn
   grey and color zra light ho" — Remaining Stock and the Total box are both
   read-only, computed-for-reference fields exactly like Cost Price (nothing
   here is ever typed in directly), so they now share its same grey/muted
   look instead of Total's old white-background/bold-navy treatment — a
   visual cue that these 3 boxes are "for reading", not "for typing". */
.lub-cart-entry #lubEntryRemainingStock,
.lub-cart-entry .lub-line-total-box { background: var(--bg-soft, #f3f4f6); color: var(--text-muted, #666); }
/* Owner's request: "text size bhe reduce kar lo" — this row is a fast,
   repeated quick-entry control, not a normal form, so it can run noticeably
   smaller than the site's default label/input sizing (14px/15px) without
   losing readability. */
.lub-cart-entry label { font-size: 12px; margin-bottom: 4px; }
.lub-cart-entry input[type=text],
.lub-cart-entry input[type=number] { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.lub-cart-entry .lub-line-total-box { font-size: 13px; padding: 8px 10px; }
.lub-cart-entry .search-picker-item { font-size: 13px; padding: 8px 10px; }
/* Owner noticed (screenshot): the last 2 boxes — Total and Add Item — sat
   visibly lower than the rest of the row. Cause: every OTHER cell here is a
   <label> + real <input> (which gets a 16px margin-bottom from the site's
   global input rule, and align-items:end bottom-aligns cells by that full
   box). The Total cell's <output> isn't an <input> so it never got that
   margin, and the Add Item cell has no <label> above its (smaller, .btn-sm)
   button at all — both cells were shorter, so bottom-aligning them left
   visible empty space above, i.e. lower-looking content. Fix each on its
   own terms: give the Total box the same margin the real inputs get, and
   let the actions cell stretch to the row's full height and center its
   (still small) buttons within it, instead of bottom-hugging them.
   (That margin was later shrunk from 16px to 8px, alongside this whole
   row's other compacting/text-size tweaks above — kept matching the real
   inputs' own margin-bottom so this alignment fix still holds.) */
.lub-cart-entry .lub-line-total-box { margin-bottom: 8px; }
.lub-cart-entry .lub-cart-entry-actions { align-self: stretch; align-items: center; }
/* Owner's report: "Add item ka button use line main nae aa sakta" — the row's
   8 explicit tracks only need ~795px of content width to render without
   overflow (their minmax() minimums + gaps, worked out above), but this
   breakpoint was stacking to 2 columns at anything under 1120px — which is
   most normal desktop card widths — so Add Item kept getting pushed onto
   its own line well before it actually needed to. Lowered to 900px, just
   above the row's real minimum, so it only stacks when the row genuinely
   can't fit on one line. */
@media (max-width: 900px) {
    .lub-cart-entry { grid-template-columns: repeat(2, 1fr); }
    .lub-cart-entry .lub-entry-item-picker,
    .lub-cart-entry-actions { grid-column: 1 / -1; }
    .lub-cart-entry-actions { justify-content: flex-end; }
}

/* ---- Invoice / Billing (modules/invoices/index.php) item-add cart entry
   row — same "Add Item" cart pattern as .lub-cart-entry above (Item Name,
   Quantity, Rate, live Total, Add Item), just a simpler 5-track grid since
   there's no item picker/stock/cost-reference fields here (any freely-typed
   item name, not tied to a catalogue). */
.inv-cart-entry {
    display: grid;
    grid-template-columns: minmax(160px, 2fr) minmax(90px, 0.8fr) minmax(90px, 0.8fr) minmax(90px, 0.8fr) auto;
    align-items: end;
    gap: 10px;
    padding: 10px 0;
    width: 100%;
}
.inv-cart-entry label { font-size: 12px; margin-bottom: 4px; }
.inv-cart-entry input[type=text],
.inv-cart-entry input[type=number] { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.inv-cart-entry .lub-line-total-box { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.inv-cart-entry-actions { align-self: stretch; align-items: center; display: flex; gap: 6px; }
@media (max-width: 720px) {
    .inv-cart-entry { grid-template-columns: repeat(2, 1fr); }
    .inv-cart-entry-actions { grid-column: 1 / -1; justify-content: flex-end; }
}

.inv-credit-checkbox-label { display: flex; align-items: center; gap: 6px; font-weight: 500; margin-bottom: 4px; cursor: pointer; }
.inv-credit-checkbox-label input[type=checkbox] { margin: 0; }
.inv-credit-checkbox-label:has(input:disabled) { color: var(--text-muted, #888); cursor: not-allowed; }

.inv-search-form { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.inv-search-form label { display: block; font-size: 12px; margin-bottom: 4px; }
.inv-search-actions { display: flex; gap: 8px; }
.inv-print-meta { font-size: 13px; color: var(--muted); margin: 0 0 10px; }

/* ---- Quick Payments (modules/payments/index.php) entry row — owner's
   request: "jesay Lubricant sale hay 1 he line mian category, Amount
   payment mode and Description ho agay use line main add Item ka chotta sa
   button... es tarhan bank main bhe, customer waly tab main bhe" — same
   one-line cart-entry treatment as .lub-cart-entry above, applied to all 3
   top-level screens (Expense/Bank/Credit-Qarz-Employee).
   FIRST attempt here used `repeat(auto-fit, minmax(150px, 1fr))` reasoning
   the browser would just fit however many fields a screen shows — but
   auto-fit picks its column COUNT from the container's width alone, not
   from how many fields actually need to fit, so on a narrower card Bank/
   Person's larger field count (up to ~7-8, more than Expense) still wrapped
   to a 2nd line — exactly the "Add Item button not on this line" complaint
   again. Switched to the same fixed-explicit-track approach .lub-cart-entry
   itself uses: a set number of narrow tracks wide enough for the busiest
   screen (Bank), sized small enough (100px) that all 3 screens' fields fit
   on one row at a normal card width; a screen with fewer fields (Expense)
   just leaves its unused trailing tracks empty rather than stretching —
   trading the "stretch to fill" look for actually staying on one line,
   which is what was asked for. The trailing "auto" track (after the 7
   repeating ones) is what keeps Add Item itself small ("chotta sa button")
   instead of stretching wide like the field columns next to it. */
.pay-cart-entry {
    display: grid;
    grid-template-columns: repeat(7, minmax(100px, 1fr)) auto;
    align-items: end;
    gap: 10px;
    padding: 10px 0;
    width: 100%;
}
.pay-cart-entry label { font-size: 12px; margin-bottom: 4px; }
.pay-cart-entry input[type=text],
.pay-cart-entry input[type=number],
.pay-cart-entry input[type=date],
.pay-cart-entry select { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.pay-cart-entry .lub-cart-entry-actions { align-self: stretch; align-items: center; }
/* Owner's request (Sep 2026): "quick payments kay 3no tabs main date uper lay
   kar jane hay" — Date sits on its own full-width line at the TOP of the
   entry row on all 3 tabs (Expense/Bank/Person), not just Expense as before.
   It's already first in DOM order (index.php), so this only needs to span
   the full grid width; the input itself is capped so it doesn't stretch
   edge-to-edge like a field column would. */
.pay-date-row { grid-column: 1 / -1; }
.pay-date-row input[type=date] { max-width: 220px; }
@media (max-width: 900px) {
    .pay-cart-entry { grid-template-columns: repeat(2, 1fr); }
    .pay-cart-entry .lub-cart-entry-actions { grid-column: 1 / -1; justify-content: flex-end; }
    .pay-date-row input[type=date] { max-width: none; }
}
/* Owner's request: "Total ... pechay waly box ke tarhan ho" — a computed
   <output> (Row Total, Cost Rate preview, ...) that should still LOOK like
   the input box right before it, not plain text. Reused across every
   cart-style quick-entry form (Lubricant Sale, Quick Fuel Purchase), not
   just .lub-cart-entry, so it's a standalone class rather than scoped to it. */
.lub-line-total-box {
    display: block;
    width: 100%;
    padding: 11px 14px;
    border: 1.5px solid #d8dce3;
    border-radius: var(--radius-sm);
    font-size: 15px;
    font-weight: 700;
    color: var(--navy);
    background: #fff;
    box-sizing: border-box;
}
.lub-cart-entry-actions { flex: 0 0 auto; display: flex; gap: 8px; }
/* Owner's request: "agay chotta sa Add ka Green color ka button ho" — small
   green Add Item button, same size/shape as every other .btn-sm, just its
   own color (mirrors .btn-danger's pattern below). */
.btn-success { background: linear-gradient(135deg, #16a34a 0%, #15803d 100%); }
/* Sep 2026 owner request: "Latest Entry ka Edit button red ho, jab edit
   karay tou Update ka Dark Green button aye" — a darker shade than
   .btn-success's own green (used elsewhere for Add Item) so the two read as
   deliberately distinct actions. */
.btn-dark-green { background: linear-gradient(135deg, #15803d 0%, #14532d 100%); }

/* Sep 2026 owner request: "Neechay Latest Entry main es ko uper jese field
   main he lekho ... zra polish he hay" — Lubricant Sale's per-row inline
   edit form (modules/entry/lubricant_tab.php), styled as the same compact
   grid/spacing family as .lub-cart-entry's own Add Item row above it (same
   label/input sizing, same bottom-aligned grid, same colored-action-button
   idea) — its own class rather than reusing .lub-cart-entry directly since
   this form's field set is different (it also edits Date + Payment Mode/
   Bank Account, which the simplified Add Item row deliberately doesn't
   have — see lubricant_sale_form.php's own doc comment). Date sits on its
   own line above this grid (same convention the Add Item row itself uses),
   Payment Mode/Bank Account sit on their own compact line below it
   (.lub-edit-entry-secondary) since they're correction-only fields, not
   part of the main item/qty/price line. */
.lub-edit-entry {
    display: grid;
    /* Sep 2026: 7 tracks now (was 6) — Item, Quantity, Cost Price
       (reference — new, matches the Add Item row above it), Remaining
       Stock, Sale Price, Total, Actions. See this file's own doc comment
       above (owner: "en sub ko jesay enter wali row hain esi row main show
       karwao" — show these edit rows in the same field layout as the Add
       Item entry row itself). */
    grid-template-columns: minmax(140px, 1.6fr) minmax(75px, 0.8fr) minmax(90px, 0.9fr) minmax(90px, 0.9fr) minmax(90px, 0.9fr) minmax(90px, 0.9fr) auto;
    align-items: end;
    gap: 10px;
    padding: 10px 0;
    width: 100%;
}
.lub-edit-entry label { font-size: 12px; margin-bottom: 4px; }
.lub-edit-entry select,
.lub-edit-entry input[type=text],
.lub-edit-entry input[type=number],
.lub-edit-entry input[type=datetime-local] { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.lub-edit-entry .lub-line-total-box { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
/* Same "read-only reference box" grey treatment as .lub-cart-entry's own
   Cost Price/Remaining Stock/Total above — see that rule's doc comment. */
.lub-edit-entry input[readonly],
.lub-edit-entry .lub-line-total-box { background: var(--bg-soft, #f3f4f6); color: var(--text-muted, #666); }
.lub-edit-entry-actions { align-self: stretch; align-items: center; display: flex; gap: 8px; }
.lub-edit-entry-secondary { display: flex; gap: 12px; flex-wrap: wrap; margin: 0 0 12px; }
.lub-edit-entry-secondary > div { min-width: 170px; }
.lub-edit-entry-secondary label { font-size: 12px; margin-bottom: 4px; display: block; }
@media (max-width: 900px) {
    .lub-edit-entry { grid-template-columns: repeat(2, 1fr); }
    .lub-edit-entry-actions { grid-column: 1 / -1; justify-content: flex-end; }
}
/* Latest Entry list — each recorded line as its own row (owner's request:
   "multiple row hon tou woh bhe rows main es tarhan listed hote jayen") —
   plain flex rows, view line on the left, its own Edit button on the right. */
.lub-latest-entry-row {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 8px 0; border-bottom: 1px solid var(--border);
}
.lub-latest-entry-row:last-of-type { border-bottom: none; }

/* ---- Quick Fuel Purchase — batch product rows (Fuel + Lubricants tabs),
   same "always one line, horizontally scrollable" treatment as Lubricant
   Sale's rows above. ---- */
#qfpFuelRows, #qfpLubRows {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
/* Owner's request: "row width wise full page cover karay" — columns now
   GROW (flex: 1 1 <floor>) to fill the card's full width on wide screens
   instead of sitting fixed-width with empty space to the right; the floor
   (the flex-basis part) still protects each field on narrow screens, where
   the parent's overflow-x:auto above takes over instead of squeezing
   columns unreadably thin. */
.qfp-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-end;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px dashed var(--border);
    width: 100%;
    min-width: 100%;
}
.qfp-row:first-child { padding-top: 0; }
.qfp-row > div { flex: 1 1 0; min-width: 0; }
.qfp-row .qfp-row-item-picker { flex: 2 1 220px; }
.qfp-row .qfp-row-tank { flex: 1.6 1 170px; }
.qfp-row .qfp-row-qty,
.qfp-row .qfp-row-amount,
.qfp-row .qfp-row-fed,
.qfp-row .qfp-row-preview { flex: 1 1 110px; }
.qfp-row .qfp-row-preview output { display: block; padding: 8px 0; font-weight: 700; color: var(--navy); }
.qfp-row .qfp-row-remove {
    flex: 0 0 auto;
    margin-bottom: 1px;
    padding: 8px 12px;
    line-height: 1;
    font-size: 16px;
}
#qfpFuelTotal, #qfpLubTotal {
    display: block;
    padding: 8px 0;
    font-weight: 800;
    font-size: 18px;
    color: var(--navy);
}
/* Quick Fuel Purchase → Lubricants tab redesign: one single entry row (no
   more "Add Product" rows) ending in an "Add Item" button on the far right;
   items picked this way land in a table below instead.
   Owner's request (Sep 2026): "Entry Fuel Values, Quick payments, Quick
   Fuel Purchase en 3non ko bilkul same symmetry main kar do" — this row
   was still the OLD flex layout with its own bigger/looser sizing, visibly
   different from Lubricant Sale's row (.lub-cart-entry) and Quick Payments'
   row (.pay-cart-entry). Switched to the SAME CSS Grid approach, 8 explicit
   tracks (Short Code, Item, Cost Rate ref, Quantity, Rate, FED, Total,
   Actions — same field COUNT as .lub-cart-entry, just this form's own field
   set/order) and the SAME compact label/input sizing those two already use,
   so all 3 forms' entry rows now genuinely look like one shared design
   instead of 3 similar-but-not-quite ones.
   Sep 2026 update — owner's request to bring Boxes back: "Quantity" split
   into a typed "Boxes" field plus a readonly "Qty" field showing Boxes ×
   this item's own catalog Pieces/Box (a separate typed Pieces/Box field
   briefly existed here too, then was removed again per the owner's
   follow-up: "Pieces/box remove kar do"), so this row now has 9 tracks
   instead of 8 (Short Code, Item, Cost Rate ref, Boxes, Qty (readonly),
   Rate/Box, FED, Total, Actions). */
.qfp-lub-entry {
    display: grid;
    /* 10 tracks since Oct 2026: a Loose (pcs) field was added right after Boxes. */
    grid-template-columns: minmax(80px, 0.9fr) minmax(140px, 1.5fr) minmax(90px, 0.9fr) minmax(70px, 0.7fr) minmax(70px, 0.7fr) minmax(70px, 0.7fr) minmax(80px, 0.8fr) minmax(80px, 0.8fr) minmax(80px, 0.8fr) auto;
    align-items: end;
    gap: 10px;
    padding: 10px 0;
    width: 100%;
}
.qfp-lub-entry label { font-size: 12px; margin-bottom: 4px; }
.qfp-lub-entry input[type=text],
.qfp-lub-entry input[type=number] { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.qfp-lub-entry #qfpLubCostRateRef,
.qfp-lub-entry #qfpLubPiecesTotal { background: var(--bg-soft, #f3f4f6); color: var(--text-muted, #666); }
.qfp-lub-entry .lub-line-total-box { margin-bottom: 8px; }
.qfp-lub-entry .lub-cart-entry-actions { align-self: stretch; align-items: center; }
@media (max-width: 900px) {
    .qfp-lub-entry { grid-template-columns: repeat(2, 1fr); }
    .qfp-lub-entry .lub-cart-entry-actions { grid-column: 1 / -1; justify-content: flex-end; }
}

/* Quick Fuel Purchase → Fuel tab redesign (owner's request: "Fuel Purchase
   ko bhe aesay he kar do" — same cart pattern as the Lubricants tab above
   and the Lubricant Sale form). .lub-cart-entry-actions and .lub-line-total-box
   (includes/lubricant_sale_form.php's own CSS, further above) are reused
   here as-is.
   Owner's follow-up report: "Cost rate and add item ka button line main hay
   neechay hain zra and yeh row pori width par spread ane hay" — same root
   cause as .lub-cart-entry's own fix above (the Cost Rate <output> has no
   margin-bottom the way a real <input> gets, and the actions cell was
   bottom-hugging its buttons instead of centering in the row), plus this
   row was still the OLD flex layout instead of the grid treatment that
   fixed it there — switched to the same explicit-column CSS Grid so it
   reliably fills the card's full width and every cell lines up.
   Owner's later request (Sep 2026): match .lub-cart-entry/.pay-cart-entry's
   compact label/input sizing too (this row was still using the site's
   bigger default font/padding) and their 10px gap/padding, for full
   symmetry across all 3 quick-entry forms. */
.qfp-fuel-entry {
    display: grid;
    grid-template-columns: minmax(130px, 1.3fr) minmax(110px, 1fr) minmax(120px, 1fr) minmax(90px, 1fr) minmax(110px, 1fr) auto;
    align-items: end;
    gap: 10px;
    padding: 10px 0;
    width: 100%;
}
.qfp-fuel-entry label { font-size: 12px; margin-bottom: 4px; }
.qfp-fuel-entry input[type=text],
.qfp-fuel-entry input[type=number],
.qfp-fuel-entry select { font-size: 13px; padding: 8px 10px; margin-bottom: 8px; }
.qfp-fuel-entry .lub-line-total-box { margin-bottom: 8px; }
.qfp-fuel-entry .lub-cart-entry-actions { align-self: stretch; align-items: center; }
@media (max-width: 900px) {
    .qfp-fuel-entry { grid-template-columns: repeat(2, 1fr); }
    .qfp-fuel-entry .lub-cart-entry-actions { grid-column: 1 / -1; justify-content: flex-end; }
}

/* ---- Search Picker — searchable "type to find" dropdown, used wherever a
   customer/borrower needs to be picked from a potentially long list (Quick
   Payments: Credit Customer Payment / Qarz-e-Hasana Repayment tabs). Plain
   vanilla JS, initSearchPicker() in includes/footer.php.

   Sep 2026 "premium design" pass (owner: "es ka koe premium design bhe
   implement karo") — a small magnifying-glass icon inside the input, a
   softer/deeper dropdown shadow, a subtle open animation, and rounded
   hover rows instead of the old flat divider-line list. Purely visual —
   initSearchPicker()'s own DOM structure/classes are untouched, so this
   applies everywhere a .search-picker already exists (Quick Payments,
   Boost Payment, Invoices, Lubricant/Fuel Sale, Super Admin, ...) with no
   markup changes needed. ---- */
.search-picker { position: relative; }
.search-picker-input {
    padding-left: 38px !important;
    background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E") no-repeat 12px center;
    background-size: 15px 15px;
}
.search-picker-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 30;
    margin-top: -12px;
    max-height: 280px;
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: 0 14px 32px rgba(16,24,40,0.14), 0 4px 10px rgba(16,24,40,0.06);
    padding: 6px;
    animation: searchPickerOpen 0.12s ease;
}
@keyframes searchPickerOpen {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.search-picker-item {
    padding: 10px 12px;
    font-size: 14.5px;
    cursor: pointer;
    border-radius: 8px;
    transition: background-color 0.12s ease;
}
.search-picker-item + .search-picker-item { margin-top: 2px; }
.search-picker-item:hover, .search-picker-item.active { background: var(--accent-soft); color: var(--navy); }
.search-picker-error { color: #b91c1c; margin-top: -12px; }

/* ---- Super Admin picker tabs (modules/superadmin/) — Sep 2026 owner
   request: "search bar main data sahee tarhan show nae hota list katt rhe
   hay" (the results dropdown was getting clipped). Root cause: .card's own
   overflow:hidden (kept only so its ::before accent strip's square corners
   never poke past the card's rounded ones — see .card--lub-sale's own note
   above for the exact same fix, applied here the same way) was clipping the
   absolutely-positioned .search-picker-results the instant a tab's card had
   nothing below the search box yet (nothing picked). Scoped fix: let this
   card overflow normally and give its accent strip a matching top-only
   radius instead.

   Also owner: "upder heading description ... khatam karo ... 3rd heading ko
   search bar wali line main lay ao" — every Super Admin picker tab's own h3
   title + hint paragraph were removed (the tab strip above the card already
   names the active tab), and the field's label now sits INLINE with the
   search box (.sa-picker-bar) instead of stacked above it on its own line —
   applied identically on every tab that has one (Customer Credit/
   Qarz-e-Hasana/Employee/Bank/Assets/Other Income/Other Party). ---- */
.card--sa-picker { overflow: visible; }
.card--sa-picker::before { border-radius: var(--radius-md) var(--radius-md) 0 0; }
.sa-picker-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
}
.sa-picker-bar .sa-picker-label {
    margin: 0;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--navy);
    white-space: nowrap;
}
.sa-picker-bar .search-picker {
    flex: 1 1 300px;
    max-width: 420px;
}
.sa-picker-bar .search-picker-input { margin-bottom: 0; }
.sa-picker-bar .search-picker-results { top: calc(100% + 8px); margin-top: 0; }

/* ---- Date Range Picker — single-calendar From/To range selector, used on
   the two report pages that still had a plain pair of date inputs (Expenses'
   History tab, Fuel Purchase Report) and now every Daily/Monthly/Yearly
   report page's "Range" tab. Plain vanilla JS, initDateRangePicker() in
   includes/header.php.

   Two owner-reported bugs fixed here:
     - "kabhi neechay say cut jata hay" — the dropdown used to be
       position:absolute inside .card, which clips its own content
       (overflow:hidden, so its rounded corners stay clean under the
       brand-color strip — see .card::before). Any dropdown that would
       render past the bottom of a short card got sliced off. Fixed on the
       JS side: the panel is now positioned with position:fixed, placed
       against the input's live on-screen position (and flips to open
       ABOVE the input automatically when there isn't room below) — fixed
       positioning is only clipped by the browser viewport, not by an
       ancestor's overflow:hidden, so it can never be cut off by the card
       again.
     - "2no dates sari show nae hoteen" — the input was a fixed 220px
       showing the full "YYYY-MM-DD — YYYY-MM-DD" text, which is wider
       than that box at this site's normal font size, so the 2nd date ran
       past the edge and got clipped. Fixed by both widening the box and
       switching to a shorter "01 Sep – 15 Sep 2026" / "01 Sep 2025 – 15
       Jan 2026" display format (year written once when both dates fall
       in the same year) — see fmtShort()/updateInputText() in
       includes/header.php. */
.date-range-picker { position: relative; display: inline-block; }
.date-range-picker-input {
    cursor: pointer;
    background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16' rx='3'/%3E%3Cline x1='3' y1='9.5' x2='21' y2='9.5'/%3E%3Cline x1='8' y1='2.5' x2='8' y2='6.5'/%3E%3Cline x1='16' y1='2.5' x2='16' y2='6.5'/%3E%3C/svg%3E") no-repeat right 12px center / 17px 17px;
    width: 250px;
    max-width: 100%;
    padding-inline-end: 38px;
    font-size: 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 0;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
html[dir="rtl"] .date-range-picker-input,
[dir="rtl"] .date-range-picker-input { background-position: left 12px center; }
.date-range-picker-input:hover { border-color: var(--accent); }
.date-range-picker-panel {
    position: fixed;   /* positioned live by JS (positionPanel()) — escapes
                           any ancestor's overflow:hidden, see note above */
    z-index: 999;
    /* Wide enough for two independently-navigable calendars side by side
       (see initDateRangePicker()'s From/To redesign) — .drp-calendars below
       stacks them vertically instead once the viewport can't fit both. */
    width: 568px;
    max-width: calc(100vw - 16px);
    padding: 14px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    transform: translateY(-6px) scale(0.98);
    transform-origin: top left;
    transition: opacity 0.14s ease, transform 0.14s ease;
    pointer-events: none;
}
.date-range-picker-panel.drp-flip-up { transform-origin: bottom left; }
.date-range-picker-panel.drp-open {
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}
.drp-calendars { display: flex; gap: 18px; align-items: flex-start; }
.drp-calendar { flex: 1 1 0; min-width: 0; }
.drp-calendars .drp-calendar:first-child {
    border-inline-end: 1px solid var(--border);
    padding-inline-end: 18px;
}
html[dir="rtl"] .drp-calendars .drp-calendar:first-child,
[dir="rtl"] .drp-calendars .drp-calendar:first-child { padding-inline-end: 0; padding-inline-start: 18px; }
.drp-cal-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted, #888);
    margin-bottom: 6px;
}
/* Narrow viewports (also the RTL sidebar eating extra width) — stack the
   two calendars instead of squeezing both into one row. Owner's original
   complaint was specifically about mobile entry being fiddly, so this has
   to keep working comfortably on a phone screen too. */
@media (max-width: 640px) {
    .date-range-picker-panel { width: 300px; }
    .drp-calendars { flex-direction: column; gap: 14px; }
    .drp-calendars .drp-calendar:first-child {
        border-inline-end: none;
        padding-inline-end: 0;
        border-bottom: 1px solid var(--border);
        padding-bottom: 14px;
    }
    html[dir="rtl"] .drp-calendars .drp-calendar:first-child,
    [dir="rtl"] .drp-calendars .drp-calendar:first-child { padding-inline-start: 0; }
}
.drp-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    font-weight: 700;
    font-size: 15px;
    color: var(--navy);
}
.drp-nav-btn {
    border: none;
    background: transparent;
    color: var(--navy);
    box-shadow: none;
    border-radius: 999px;
    width: 30px;
    height: 30px;
    padding: 0;
    line-height: 1;
    cursor: pointer;
    font-size: 16px;
    font-weight: 700;
    transition: background 0.12s ease, transform 0.12s ease;
}
.drp-nav-btn:hover { background: var(--accent-soft); transform: scale(1.08); }
.drp-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3px 0;
}
.drp-dow {
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--muted, #888);
    padding: 4px 0 8px;
}
.drp-day {
    position: relative;
    border: none;
    background: transparent;
    color: var(--text, #333);
    box-shadow: none;
    border-radius: 50%;
    aspect-ratio: 1 / 1;
    width: 100%;
    font-size: 13px;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    padding: 0;
    z-index: 1;
    transition: background 0.12s ease, color 0.12s ease, transform 0.1s ease;
}
.drp-day:hover:not(.drp-range-start):not(.drp-range-end) { background: var(--accent-soft); }
.drp-day.drp-muted { color: var(--text-muted, #ccc); }
/* "today" gets a small dot underneath its number, same idea as most
   modern calendar UIs, so the current date is always easy to spot. */
.drp-day.drp-today::after {
    content: '';
    position: absolute;
    bottom: 3px;
    left: 50%;
    transform: translateX(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--accent);
}
.drp-day.drp-range-start.drp-today::after,
.drp-day.drp-range-end.drp-today::after { background: #fff; }
.drp-day.drp-in-range { background: var(--accent-soft); border-radius: 0; }
/* Start/end day: a solid navy circle sitting on top of a flat rectangular
   "track" (::before, z-index:-1) that reaches from the circle's own
   mid-point out to the next/previous day — since the circle only paints a
   round area (border-radius:50%), the track shows through the square
   cell's leftover corners, which is what makes the pill visually FUSE
   into the flat .drp-in-range background of the neighbouring days instead
   of looking like a disconnected dot. Scoped to .drp-has-range (a class
   render() only adds once both ends of an actual multi-day range are
   picked) so a single selected day (no range yet) shows a plain circle
   with no stray half-track poking out either side. */
.drp-grid.drp-has-range .drp-day.drp-range-start::before,
.drp-grid.drp-has-range .drp-day.drp-range-end::before {
    content: '';
    position: absolute;
    top: 3px;
    bottom: 3px;
    background: var(--accent-soft);
    z-index: -1;
}
.drp-grid.drp-has-range .drp-day.drp-range-start::before { left: 50%; right: 0; }
.drp-grid.drp-has-range .drp-day.drp-range-end::before { left: 0; right: 50%; }
.drp-day.drp-range-start, .drp-day.drp-range-end {
    background: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);
    color: #fff;
    font-weight: 700;
    transform: scale(1.04);
}

/* ---- Reports ledger dialog: Statement period panel (Opening date / Closing date), Sep 2026 ---- */
.rp-period-panel {
    margin: 0 0 16px; padding: 16px 18px 14px; border-radius: 14px;
    background: linear-gradient(135deg, #f8fafc 0%, #eef2ff 100%);
    border: 1px solid #dbe3f5; box-shadow: 0 6px 18px rgba(0, 51, 141, .08);
    position: relative; overflow: hidden;
}
.rp-period-panel[hidden] { display: none; }
.rp-period-panel::before { content: ''; position: absolute; left: 0; top: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--brand-1), var(--brand-2) 55%, var(--brand-3)); }
.rp-period-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.rp-period-title { font-size: 12px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--brand-2); }
.rp-period-x { background: transparent; border: 0; box-shadow: none; color: #64748b; font-size: 20px; line-height: 1; padding: 0 4px; cursor: pointer; }
.rp-period-hint { margin: 0 0 12px; font-size: 12px; color: #64748b; line-height: 1.5; }
.rp-period-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.rp-period-grid label span { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: #475569; margin-bottom: 4px; }
.rp-period-grid input[type=date] { width: 100%; margin: 0; background: #fff; border: 1px solid #cbd5e1; border-radius: 9px; padding: 9px 10px; font-size: 14px; font-weight: 600; }
.rp-period-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0 4px; }
.rp-period-chips button { background: #fff; color: var(--brand-2); border: 1px solid #c7d2fe; border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 700; box-shadow: none; cursor: pointer; }
.rp-period-chips button:hover { background: var(--brand-2); color: #fff; }
.rp-period-zero { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0 0; font-size: 13px; font-weight: 700; color: #1e293b; cursor: pointer; }
.rp-period-zero input { width: 18px; height: 18px; margin: 0; }
.rp-period-zero small { font-weight: 500; color: #64748b; font-size: 11.5px; }
.rp-period-actions { display: flex; gap: 8px; margin-top: 12px; }
.rp-period-actions .rp-p-apply { flex: 1; border-radius: 10px; padding: 10px 14px; font-weight: 800; }
.rp-period-actions .rp-p-reset { background: #fff; color: #475569; border: 1px solid #cbd5e1; border-radius: 10px; padding: 10px 14px; box-shadow: none; }
.rp-period-status { margin-top: 10px; font-size: 12px; font-weight: 700; color: #b45309; min-height: 1em; }

/* Oct 2026 — amount-in-words line under Voucher Entry amount boxes (see nsAmountWords() in includes/footer.php).
   Absolutely positioned inside the field's wrapper, in the gap the input's own bottom margin leaves, so it never
   changes row heights/alignment (the Debit row is a single scrolling line). */
.ns-amount-words {
    position: absolute; left: 0; margin: 0; padding: 0;
    font-size: 11px; line-height: 14px; font-weight: 700; color: #b45309; white-space: nowrap; pointer-events: none;
}
.ns-amount-words[hidden] { display: none; }
@media print { .ns-amount-words { display: none !important; } }

/* Oct 2026 (owner: "start main space empty kyon?") — the search boxes reserved 38px on the left for a magnifier
   icon, but the generic input[type=text] rule (higher specificity) wiped the icon's background, leaving an empty gap
   at the start of every picker (Name / Short Code / Item). Re-assert the icon with a stronger selector and keep the
   gap small so narrow boxes (Short Code) still show their text. */
.search-picker .search-picker-input {
    padding-left: 30px !important;
    background-color: #fff;
    background-position: 10px center;
    background-repeat: no-repeat;
    background-size: 14px 14px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
}
[dir="rtl"] .search-picker .search-picker-input { padding-left: 14px !important; padding-right: 30px !important; background-position: right 10px center; }

/* Oct 2026 — Items & Stock action cell: Edit + Activate/Discontinue + the 3 history icons laid out as two tidy
   rows instead of one narrow column; the status button matches Edit's size. */
.lub-actions-td { min-width: 200px; }
/* long item names wrap instead of stretching the table past the screen (which pushed the buttons out of view) */
.lub-item-name-td { max-width: 300px; min-width: 200px; white-space: normal !important; overflow-wrap: anywhere; }
.lub-actions-td .lub-status-btn, .lub-actions-td .lub-edit-toggle { white-space: nowrap; }
.lub-actions-td .cust-status-cell { gap: 6px; flex-direction: column; align-items: flex-start; }
.lub-actions-td .lub-act-row { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; }
.lub-actions-td .btn-sm, .lub-actions-td .lub-status-btn { padding: 6px 12px; font-size: 12.5px; line-height: 1.2; }

/* Oct 2026: ledger balances now carry a Dr/Cr suffix ("291,434.00 Dr") — keep amount + suffix on ONE line when printed. */
@media print {
    .data-table td strong { white-space: nowrap; }
}

/* Oct 2026 — phone view for the long list tables (Customers, Qarz-e-Hasana, every Ledger Reports list): below 640px each
   row becomes a small card (name on top, "label: value" lines under it) instead of a table that scrolls sideways. The
   labels come from the table's own header cells (see footer.php, data-label). Screen only — printing is untouched. */
@media screen and (max-width: 640px) {
    table.cust-table thead { display: none; }
    table.cust-table, table.cust-table tbody { display: block; width: 100%; }
    table.cust-table tbody tr { display: block; margin: 0 0 10px; padding: 8px 12px; border: 1px solid var(--border, #e5e7eb); border-radius: 10px; background: #fff; }
    table.cust-table tbody tr:nth-child(even) { background: #fff; }
    table.cust-table td { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 6px 0 !important; border: 0; text-align: end; }
    table.cust-table td[data-label]::before { content: attr(data-label); font-size: 12px; font-weight: 600; color: var(--muted, #6b7280); text-align: start; flex: 0 0 auto; }
    table.cust-table td:empty { display: none; }
    table.cust-table td .cust-name-cell { text-align: start; }
}
