/* ==========================================================================
   Design System - Premium Enterprise ERP
   Every class name below is preserved from the original stylesheet so no
   view/template needs to change. Only the visual language is upgraded:
   colors, spacing, shadows, radii, typography, motion, and dark mode.
   ========================================================================== */

:root {
    /* Brand - black + blue + white: buttons and links use blue as the one
       accent color; the sidebar and general chrome stay black/white.
       Colour is otherwise reserved for the semantic/status system below
       (success/warning/danger/info), which is what needs to stand out and
       be scannable at a glance. */
    --primary: #2563EB;
    --primary-dark: #1D4ED8;
    --primary-light: #EFF6FF;
    --secondary: #0EA5E9;

    /* Semantic - untouched: these ARE the indicators, kept distinct and
       colorful on purpose so status is still scannable at a glance. */
    --success: #16A34A;
    --success-bg: #DCFCE7;
    --warning: #F59E0B;
    --warning-bg: #FEF3C7;
    --danger: #DC2626;
    --danger-bg: #FEE2E2;
    --info: #475569;
    --info-bg: #F1F5F9;

    /* Surfaces */
    --bg: #F8FAFC;
    --surface: #ffffff;
    --surface-alt: #F1F5F9;
    --border: #E2E8F0;
    --border-strong: #CBD5E1;

    /* Text */
    --text: #0F172A;
    --text-muted: #475569;
    --text-faint: #94A3B8;

    /* Interaction */
    --hover: #F1F5F9;
    --active-bg: #EFF6FF;
    --disabled: #CBD5E1;

    /* Sidebar */
    --sidebar-bg: #0F172A;
    --sidebar-bg-alt: #1E293B;
    --sidebar-text: #94A3B8;
    --sidebar-text-active: #ffffff;
    --sidebar-border: rgba(255,255,255,0.08);
    --sidebar-accent: #111827;

    --radius: 6px;
    --radius-sm: 4px;
    --radius-lg: 6px;
    --shadow-sm: 0 1px 2px rgba(15,23,42,0.04);
    --shadow-md: 0 1px 3px rgba(15,23,42,0.06);
    --shadow-lg: 0 2px 6px rgba(15,23,42,0.08);

    /* Overrides Tailwind's own generated tokens of the same name
       (tailwind-built.css, @layer theme) - unlayered declarations always
       win over @layer ones regardless of file load order, so this is a
       reliable way to correct values that came from the compiled file
       without editing it directly. Radius and shadow both corrected here:
       0.75rem card corners and a soft drop shadow read as "modern SaaS
       startup," not "enterprise business software" - SAP/Oracle/Workday-
       class products use a much tighter radius (2-6px) and stay flat,
       bordered, with little to no elevation shadow. */
    --radius-xl: 6px;
    --radius-2xl: 8px;
    --shadow-card: 0 1px 2px rgba(15,23,42,0.05);
    --shadow-card-hover: 0 1px 3px rgba(15,23,42,0.08);

    /* Card/table section header - was a saturated mint-green color-block
       fill on every single card, ~150+ times across the app. Real
       enterprise software (SAP Fiori, Salesforce Lightning, Oracle,
       Workday) essentially never fills a section header with solid brand
       color - color there is reserved for status meaning. A header
       filled edge-to-edge with color on every card reads as a template
       or slide deck, not business software. Corrected to the pattern
       those systems actually use: white background, bold text, a thin
       bottom border, and a slim colored accent strip on the left edge
       for brand presence without color-blocking the whole band. One
       change here updates every card header in the app at once. */
    --header-accent-bg: #D7F5E3;
    --header-accent-border: var(--color-navy-900, #0F172A);
    --header-accent-strip: #0E8A6D;
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-mono: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", "Menlo", monospace;
    --transition: 160ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* ==========================================================================
   Card/table section headers - ONE real component instead of the two
   inline-style patterns that had been hand-typed across the app (a
   "bleed" version for cards with their own p-5/p-6 padding, and a "flat"
   version for cards built overflow-hidden with no padding wrapper). Both
   read from --header-accent-bg above, so the color and the two layout
   variants are each defined exactly once.
   ========================================================================== */
.card-header-accent {
    background-color: var(--header-accent-bg);
    border-bottom: 1px solid var(--header-accent-border);
    border-left: 3px solid var(--header-accent-strip, var(--primary));
}
/* Flat variant: card is built overflow-hidden with no padding wrapper, so
   the header can sit flush against the card edges with no extra work. */
.card-header-accent-flat {
    padding: 1rem 1.25rem;
}
/* Bleed variants: card uses a p-5 or p-6 wrapper for its body content, so
   the header needs to cancel that padding via negative margin to reach
   the card's own edges, then re-apply its own padding inside. */
.card-header-accent-bleed-5 {
    margin: -1.25rem -1.25rem 0;
    padding: 1.25rem 1.25rem 1rem;
    border-top-left-radius: var(--radius-xl, 0.75rem);
    border-top-right-radius: var(--radius-xl, 0.75rem);
}
.card-header-accent-bleed-6 {
    margin: -1.5rem -1.5rem 0;
    padding: 1.5rem 1.5rem 1rem;
    border-top-left-radius: var(--radius-xl, 0.75rem);
    border-top-right-radius: var(--radius-xl, 0.75rem);
}
/* Matching footer band for the few cards whose bottom edge also carries
   the accent color (mirrors -bleed-6, closing the rounded corners instead
   of opening them). */
.card-footer-accent-bleed-6 {
    background-color: var(--header-accent-bg);
    margin: 0 -1.5rem -1.5rem;
    padding: 0 1.5rem 1.5rem;
    border-bottom-left-radius: var(--radius-xl, 0.75rem);
    border-bottom-right-radius: var(--radius-xl, 0.75rem);
}
/* Purely additive - append to whatever class list a header/footer band
   already has, no need to touch its other layout classes. This is what
   every pre-existing inline style="background-color: #D6F6D6" was
   mechanically replaced with across the app, so the color now has
   exactly one source of truth (--header-accent-bg above) instead of
   living as a literal hex value copy-pasted in ~150 places. Now also
   carries the left accent strip - the enterprise-pattern replacement for
   the old full color-block fill (see --header-accent-bg comment above). */
.card-header-accent-bg {
    background-color: var(--header-accent-bg) !important;
    border-left: 3px solid var(--header-accent-strip, var(--primary)) !important;
}

/* Table header rows, app-wide - kept neutral (matches --color-surface-alt).
   The mint-green treatment lives on the card title bars instead (see
   --header-accent-bg below), not the data-table column labels. */
.thead-mint {
    background-color: #F1F5F9 !important;
}

/* A handful of Tailwind utilities used across the app (hover: color/border
   variants, transition-colors) that never made it into the static compiled
   tailwind-built.css bundle, because that file only contains classes that
   were already present in the source at its last build - any class used
   afterward silently does nothing rather than erroring, which is how this
   went unnoticed on several already-shipped pages (admin/dashboard,
   customers/show.php pipeline blocks, the sidebar/header hover states in
   both layouts, etc.). Defined here instead of waiting for a rebuild. */
.hover\:bg-surface:hover { background-color: var(--surface); }
.hover\:border-brandgreen-300:hover { border-color: #6FCBAB; }
.transition-colors {
    transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-duration: 150ms;
}
/* Same gap as above: sm:grid-cols-4 was never in the compiled bundle
   (sm:grid-cols-2/3 were, from earlier pages, but nothing had used
   4 columns at the sm breakpoint yet) - first hit was the Legal
   Documents edit forms and its KPI card row, silently collapsing to a
   single stacked column instead of 4 across. */
@media (min-width: 640px) {
    .sm\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

[data-theme="dark"] {
    /* Same three-surface-level dark system as the admin app - see the
       matching block in tailwind.src.css for the full rationale. */
    --bg: #020617;
    --surface: #0F172A;
    --surface-alt: #172033;
    --border: #334155;
    --border-strong: #475569;
    --text: #E2E8F0;
    --text-muted: #94A3B8;
    --text-faint: #64748B;
    --hover: #172033;
    --active-bg: #1E293B;
    --primary-light: #1E293B;
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
    --shadow-md: 0 4px 14px rgba(0,0,0,0.35);
    --shadow-lg: 0 12px 32px rgba(0,0,0,0.45);
}

* { box-sizing: border-box; }
html {
    -webkit-text-size-adjust: 100%;
    /* Deliberate density correction: with no override here, every rem-based
       value in the app (text sizes AND the spacing scale, since --spacing
       is itself in rem) was scaling off the browser's default 16px root.
       That's comfortable for a marketing site, but looser than real
       enterprise software runs - SAP/Oracle/Workday-class products sit
       noticeably tighter. This single line pulls text size and whitespace
       down together, proportionally, in the same ratio - not just
       shrinking padding independently of text, which would look cramped
       rather than dense. */
    font-size: 93.75%;
}

body {
    margin: 0;
    font-family: var(--font);
    color: var(--text);
    background: var(--bg);
    font-size: 14.5px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    transition: background var(--transition), color var(--transition);
}

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

/* Skip-to-content link - the standard pattern for a keyboard user to
   bypass the sidebar entirely instead of Tabbing through every nav item
   (this sidebar has several submenus, dozens of links total) on every
   single page load before reaching actual page content. Off-screen by
   default, moves into view the moment it receives keyboard focus - a
   mouse/touch user never sees it, since they never Tab to it. */
.skip-link {
    position: absolute;
    top: -100%;
    left: 0;
    z-index: 100;
    padding: 0.75rem 1.25rem;
    background: var(--primary, #2563eb);
    color: #fff;
    font-weight: 600;
    font-size: 0.875rem;
    border-radius: 0 0 var(--radius-sm, 4px) 0;
    text-decoration: none;
}
.skip-link:focus {
    top: 0;
}

/* Tom Select (searchable dropdown) - match the app's plain input style
   exactly. Tom Select hides the real <select> and renders its own
   .ts-wrapper/.ts-control/.ts-dropdown elements instead, so the classes
   already on the <select> (border, radius, padding) become invisible -
   they're sitting on a hidden element. Without this, every searchable
   dropdown in the app renders with Tom Select's own default vendor look
   (light gray border, 3px radius, different padding) right next to
   plain inputs styled completely differently, reading as "a mismatched
   box nested inside the input" rather than one consistent field. */
/* Tom Select copies the original <select> element's own class attribute
   onto the generated .ts-wrapper div (see tom-select.min.js: d = this.input.
   getAttribute("class"), then applied to the wrapper). Since every select
   in this app carries the plain-input classes (border, rounded-lg, px-3,
   py-2.5, w-full, ...) for the case JS never initializes, that means the
   wrapper ends up with its own full box - border, padding, radius -
   wrapped around .ts-control, which already has its own identical box
   below. Without this, every Tom Select field renders as two nested
   boxes (a bigger outer one from the copied classes, a smaller inner one
   from .ts-control). Strip all box styling from the wrapper unconditionally
   so only .ts-control's box is ever visible. */
.ts-wrapper {
    border: none !important;
    padding: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    width: 100% !important;
}

.ts-wrapper.single .ts-control,
.ts-control {
    border: 1px solid var(--color-navy-900, #0F172A) !important;
    border-radius: var(--radius-sm, 4px) !important;
    padding: 0.45rem 0.65rem !important;
    font-size: 0.875rem;
    background: #fff;
    box-shadow: none !important;
}
.ts-wrapper.single.input-active .ts-control,
.ts-wrapper:focus-within .ts-control {
    border-color: var(--color-brandgreen-500, #22C55E) !important;
    box-shadow: 0 0 0 1px var(--color-brandgreen-500, #22C55E) !important;
}
.ts-dropdown {
    border: 1px solid var(--color-navy-900, #0F172A);
    border-radius: var(--radius-sm, 4px);
    font-family: inherit;
    font-size: 0.875rem;
    box-shadow: var(--shadow-md);
}
.ts-dropdown .option.active,
.ts-dropdown .active {
    background-color: var(--color-brandgreen-50, #F0FDF4) !important;
    color: var(--color-navy-900, #0F172A) !important;
}
/* The actual typing/search box Tom Select puts inside .ts-control is a
   real <input> element - the app's own global input styling (border,
   padding, radius) reaches it same as any other input on the page,
   rendering a second visible bordered box nested inside the .ts-control
   box already styled above. Strip its own border/background/padding so
   only the single outer box is visible, the way one input field should
   look. */
.ts-control input,
.ts-control .ts-input,
.ts-control input.ts-input,
.ts-control.ts-control.ts-control.ts-control.ts-control input {
    border: none !important;
    background: transparent !important;
    padding: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    font-size: 0.875rem;
}

h1, h2, h3, h4 { font-weight: 700; letter-spacing: -0.015em; }
table.data-table td, .stat-card .value, .value { font-variant-numeric: tabular-nums; }

/* ---- Auth pages: split screen on desktop - a rich brand/marketing panel
   on one side, the actual sign-in form on the other. Sized to fit a single
   screen with no scrolling (a login page that scrolls looks broken), so
   the brand panel content is deliberately compact - a short heading, three
   one-line features, nothing more. Below the lg breakpoint the brand panel
   is dropped entirely and the form panel takes the full screen, since
   there's no room to do the split justice on a phone. ---- */
.auth-body {
    height: 100vh;
    overflow: hidden;
    background: var(--surface);
}
.auth-split {
    height: 100vh;
    display: grid;
    grid-template-columns: 1fr;
}

.auth-brand-panel {
    display: none;
    position: relative;
    flex-direction: column;
    justify-content: center;
    padding: 48px 56px;
    color: #fff;
    background: #0E8A6D;
    overflow: hidden;
}
.auth-brand-watermark {
    position: absolute;
    right: -60px;
    bottom: -60px;
    font-size: 22rem;
    color: rgba(255,255,255,.06);
    pointer-events: none;
    line-height: 1;
}

.auth-brand-content { position: relative; max-width: 440px; }
.auth-brand-badge {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 6px 14px; border-radius: 999px;
    background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.28);
    font-size: 0.75rem; font-weight: 600; letter-spacing: .02em;
    color: #fff; margin-bottom: 20px;
}
.auth-brand-heading {
    font-size: 1.9rem; line-height: 1.18; font-weight: 800;
    letter-spacing: -0.02em; margin: 0 0 14px; color: #fff;
}
.auth-brand-tagline {
    font-size: 0.92rem; line-height: 1.55; color: #E8FBF2; margin: 0 0 26px;
}
.auth-brand-features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.auth-brand-features li { display: flex; align-items: center; gap: 12px; font-size: 0.86rem; color: #fff; }
.auth-brand-feature-icon {
    width: 32px; height: 32px; flex-shrink: 0; border-radius: 9px;
    display: flex; align-items: center; justify-content: center; font-size: .95rem;
}
.auth-brand-feature-icon.is-blue  { background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.3); color: #fff; }
.auth-brand-feature-icon.is-green { background: rgba(255,193,94,.18); border: 1px solid rgba(255,193,94,.35); color: #FFC15E; }
.auth-brand-features strong { display: block; color: #fff; font-weight: 600; }

.auth-form-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow-y: auto;
    padding: 24px;
    background: #F4FBF7;
}

.auth-wrapper { width: 100%; max-width: 400px; }

.card, .auth-wrapper .card {
    background: #fff;
    border-radius: 18px;
    padding: 36px 32px;
    box-shadow: 0 24px 48px -16px rgba(11,77,54,.18);
    border: 1px solid rgba(11,77,54,.1);
    border-top: 4px solid #0E8A6D;
}

.auth-icon-badge {
    width: 52px; height: 52px; border-radius: 14px;
    background: #E8FBF2; color: #0E8A6D;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.35rem; margin-bottom: 18px;
}

.auth-title { margin: 0 0 4px; font-size: 1.7rem; font-weight: 800; color: #051F15; }
.auth-subtitle { margin: 0 0 26px; color: #4B5563; font-size: 0.92rem; }
.auth-footer { margin-top: 20px; text-align: center; font-size: 0.9rem; color: #4B5563; }
.auth-footer a { color: #0E8A6D; text-decoration: none; font-weight: 600; }
.auth-footer a:hover { text-decoration: underline; color: #0B4D36; }

/* Icon-prefixed inputs - redesigned as a combined chip + field group
   rather than an icon floated on top of the input's own padding, so
   there is no way for icon and typed text to visually collide
   regardless of browser/autofill quirks. */
.form-icon-group {
    display: flex;
    align-items: stretch;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface);
    transition: border-color var(--transition), box-shadow var(--transition);
}
.form-icon-group:focus-within { border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-light); }
.form-icon-chip {
    display: flex; align-items: center; justify-content: center;
    width: 44px; flex-shrink: 0;
    background: var(--surface-alt);
    border-right: 1px solid var(--border);
    color: var(--text-faint);
    font-size: 0.95rem;
}
.form-icon-group .form-control {
    border: none;
    border-radius: 0;
    flex: 1;
    min-width: 0;
}
.form-icon-group .form-control:focus { box-shadow: none; }

/* Auth-card-scoped mint styling - .form-control's own default colors
   (border/focus use var(--primary), blue) are shared with the customer
   portal and the install wizard, so overridden here rather than changed
   globally. */
.auth-card .form-icon-group { border-color: rgba(11,77,54,.18); }
.auth-card .form-icon-chip { background: #E8FBF2; color: #0E8A6D; border-right-color: rgba(11,77,54,.18); }
.auth-card .form-control { background: #F4FBF7; }
.auth-card .form-icon-group:focus-within {
    border-color: #0E8A6D;
    box-shadow: 0 0 0 4px rgba(14,138,109,.14);
}
.auth-card .form-icon-group:hover:not(:focus-within) { border-color: #6FCBAB; }
/* Browser autofill (saved email/password) paints its own yellow/blue
   background that ignores normal CSS - this is the one reliable
   override, using a long transition delay to fake a background color
   since autofill blocks background-color directly in most browsers. */
.auth-card .form-control:-webkit-autofill,
.auth-card .form-control:-webkit-autofill:hover,
.auth-card .form-control:-webkit-autofill:focus {
    -webkit-text-fill-color: #051F15;
    -webkit-box-shadow: 0 0 0px 1000px #F4FBF7 inset;
    transition: background-color 9999s ease-in-out 0s;
}

@media (min-width: 1024px) {
    .auth-split { grid-template-columns: 1.05fr 1fr; }
    .auth-brand-panel { display: flex; }
}

/* ---- Forms ---- */
.form-group { margin-bottom: 18px; }
.form-group label { display: block; margin-bottom: 6px; font-weight: 600; font-size: 0.86rem; color: var(--text); }

.form-control {
    width: 100%;
    padding: 10px 14px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 0.95rem;
    font-family: var(--font);
    background: var(--surface);
    color: var(--text);
    transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
}
.form-control::placeholder { color: var(--text-faint); }
.form-control:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-light); }
.form-control:hover:not(:focus) { border-color: var(--border-strong); }
.form-control[readonly] { background: var(--surface-alt); color: var(--text-muted); cursor: not-allowed; }
textarea.form-control { resize: vertical; min-height: 80px; }
select.form-control { cursor: pointer; }

/* ---- Buttons ---- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 20px;
    border-radius: var(--radius-sm);
    border: none;
    font-weight: 600;
    font-size: 0.9rem;
    font-family: var(--font);
    cursor: pointer;
    text-decoration: none;
    text-align: center;
    transition: background var(--transition), box-shadow var(--transition), transform var(--transition), color var(--transition);
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--primary); color: #fff; box-shadow: none; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-block { width: 100%; }

/* A little extra visual weight on the sign-in button specifically -
   scoped to .auth-card so it doesn't change buttons elsewhere in the
   customer portal that reuse the same .btn-primary class. Mint green
   here rather than the shared --primary (blue), which stays untouched
   for the customer portal / install wizard that also use .btn-primary. */
.auth-card .btn-primary {
    background: #0E8A6D;
    padding: 13px 20px;
    font-size: 0.98rem;
    font-weight: 700;
    border-radius: 10px;
    box-shadow: 0 8px 20px -6px rgba(14,138,109,.5);
}
.auth-card .btn-primary:hover { background: #0B4D36; box-shadow: 0 10px 24px -6px rgba(11,77,54,.55); }

.btn-sm { padding: 6px 14px; font-size: 0.82rem; border-radius: 7px; }
.btn-secondary { background: var(--surface-alt); color: var(--text); border: 1px solid var(--border); }
.btn-secondary:hover { background: var(--hover); border-color: var(--border-strong); }
.btn-danger { background: var(--danger-bg); color: var(--danger); }
.btn-danger:hover { filter: brightness(0.96); }

/* ---- Alerts ---- */
.alert { padding: 12px 16px; border-radius: var(--radius-sm); margin-bottom: 18px; font-size: 0.9rem; display: flex; align-items: center; gap: 8px; border: 1px solid transparent; }
.alert-danger { background: var(--danger-bg); color: var(--danger); border-color: rgba(220,38,38,0.25); }
.alert-success { background: var(--success-bg); color: var(--success); border-color: rgba(22,163,74,0.25); }

.error-code { font-size: 3.4rem; margin: 0; font-weight: 800; background: linear-gradient(135deg, var(--primary), var(--secondary)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.error-message { color: var(--text-muted); margin: 8px 0 24px; }
.text-center { text-align: center; }

/* ---- Admin shell ---- */
.admin-shell { display: flex; min-height: 100vh; background: var(--bg); }

.sidebar {
    width: 264px; background: var(--sidebar-bg); color: var(--sidebar-text); flex-shrink: 0;
    display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; overflow-y: auto;
    transition: width var(--transition), transform var(--transition);
    z-index: 40;
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 6px; }

.sidebar-nav { list-style: none; margin: 0; padding: 12px 12px 24px; flex: 1; }
.sidebar-nav a {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 12px; margin-bottom: 2px; color: var(--sidebar-text); text-decoration: none;
    font-size: 0.84rem; font-weight: 500; border-radius: 7px; position: relative;
    transition: background var(--transition), color var(--transition);
    white-space: nowrap; overflow: hidden;
}
.sidebar-nav a i { width: 16px; text-align: center; font-size: 0.92rem; flex-shrink: 0; opacity: 0.9; }
.sidebar-nav a:hover { background: var(--sidebar-bg-alt); color: #fff; }
.sidebar-nav a.active { background: rgba(255,255,255,0.08); color: #fff; font-weight: 600; box-shadow: inset 3px 0 0 var(--sidebar-accent); }
.sidebar-nav a.active i { opacity: 1; }

/* Collapsible module/category groups - only the relevant one needs to be
   open at a time, which keeps the sidebar from sprawling as more modules
   get added, and reads as organized "module wise" navigation. */
.sidebar-group { margin-top: 4px; }
.sidebar-section-toggle {
    width: 100%; display: flex; align-items: center; justify-content: space-between;
    background: none; border: none; cursor: pointer; font-family: var(--font);
    padding: 10px 12px 6px; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em;
    color: #64748B; font-weight: 700;
}
.sidebar-section-toggle:hover { color: var(--sidebar-text); }
.sidebar-section-toggle i { font-size: 0.75rem; transition: transform var(--transition); flex-shrink: 0; }
.sidebar-group.is-collapsed .sidebar-section-toggle i { transform: rotate(-90deg); }
.sidebar-group-links { list-style: none; margin: 0; padding: 0; overflow: hidden; max-height: 400px; transition: max-height 220ms ease; }
.sidebar-group.is-collapsed .sidebar-group-links { max-height: 0; }
.admin-shell.is-collapsed .sidebar-section-toggle span, .admin-shell.is-collapsed .sidebar-section-toggle i { display: none; }

/* Collapsed (icon-only) sidebar state, toggled via JS adding .is-collapsed on .admin-shell */
.admin-shell.is-collapsed .sidebar { width: 76px; }
.admin-shell.is-collapsed .sidebar-brand span.brand-text,
.admin-shell.is-collapsed .sidebar-nav a span.link-text,
.admin-shell.is-collapsed .sidebar-collapse-btn span.link-text,
.admin-shell.is-collapsed .sidebar-section { display: none; }
.admin-shell.is-collapsed .sidebar-nav a { justify-content: center; }

.sidebar-collapse-btn-wrap { padding: 12px; border-top: 1px solid var(--sidebar-border); }
.sidebar-collapse-btn {
    width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 9px; border-radius: 7px; border: 1px solid rgba(255,255,255,0.14); background: none;
    color: var(--sidebar-text); cursor: pointer; font-size: 0.8rem; font-family: var(--font);
    transition: background var(--transition), color var(--transition);
}
.sidebar-collapse-btn:hover { background: var(--sidebar-bg-alt); color: #fff; }
.admin-shell.is-collapsed .sidebar-collapse-btn i { transform: rotate(180deg); }

.main-area { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.topbar {
    height: 64px; background: var(--surface); border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between; padding: 0 24px;
    position: sticky; top: 0; z-index: 30; gap: 16px;
    box-shadow: none;
}
.topbar form { margin: 0; }
.topbar-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.topbar-right { display: flex; align-items: center; gap: 10px; }

.sidebar-toggle-btn, .icon-btn {
    width: 38px; height: 38px; border-radius: var(--radius-sm); border: 1px solid var(--border);
    background: var(--surface); color: var(--text-muted); display: flex; align-items: center; justify-content: center;
    cursor: pointer; font-size: 1rem; transition: background var(--transition), color var(--transition), border-color var(--transition);
    text-decoration: none; position: relative;
}
.sidebar-toggle-btn:hover, .icon-btn:hover { background: var(--hover); color: var(--text); border-color: var(--border-strong); }
.icon-btn .badge-dot { position: absolute; top: 5px; right: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); border: 2px solid var(--surface); }

.topbar-title { font-weight: 700; font-size: 1.02rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.breadcrumb { font-size: 0.76rem; color: var(--text-faint); margin-top: 1px; }
.breadcrumb a { color: var(--text-faint); text-decoration: none; }
.breadcrumb a:hover { color: var(--primary); }

.topbar-search { position: relative; display: none; }
.topbar-search input {
    width: 260px; padding: 8px 14px 8px 36px; border-radius: var(--radius-sm); border: 1px solid var(--border);
    background: var(--surface-alt); font-size: 0.85rem; color: var(--text); font-family: var(--font);
    transition: all var(--transition);
}
.topbar-search input:focus { outline: none; width: 320px; border-color: var(--primary); background: var(--surface); box-shadow: 0 0 0 4px var(--primary-light); }
.topbar-search i { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--text-faint); font-size: 0.85rem; }
.topbar-search-results {
    position: absolute; top: calc(100% + 8px); left: 0; width: 320px; background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg); overflow: hidden;
    display: none; z-index: 50;
}
.topbar-search-results a { display: flex; align-items: center; gap: 10px; padding: 10px 14px; color: var(--text); text-decoration: none; font-size: 0.86rem; }
.topbar-search-results a:hover { background: var(--hover); }
.topbar-search-results a i { color: var(--text-faint); width: 16px; }
.topbar-search-results .no-results { padding: 14px; color: var(--text-faint); font-size: 0.85rem; }
@media (min-width: 860px) { .topbar-search { display: block; } }

/* ---- Command Palette trigger + overlay (Ctrl+K) ---- */
.topbar-cmdk-btn {
    display: none; align-items: center; gap: 9px; padding: 8px 12px; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: var(--surface-alt); color: var(--text-muted);
    font-family: var(--font); font-size: 0.83rem; cursor: pointer; flex: 1 1 auto; min-width: 160px; max-width: 300px; text-align: left;
    transition: border-color var(--transition);
}
.topbar-cmdk-btn:hover { border-color: var(--border-strong); }
.topbar-cmdk-btn i { color: var(--text-faint); }
.topbar-cmdk-btn span:nth-child(2) { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmdk-kbd { font-size: 0.68rem; font-weight: 700; padding: 2px 6px; border-radius: 5px; background: var(--surface); border: 1px solid var(--border); color: var(--text-faint); }
@media (min-width: 860px) { .topbar-cmdk-btn { display: flex; } }

.cmdk-overlay {
    display: none; position: fixed; inset: 0; background: rgba(7,26,43,0.5); z-index: 200;
    align-items: flex-start; justify-content: center; padding-top: 12vh;
}
.cmdk-overlay.open { display: flex; }
.cmdk-box { width: 92%; max-width: 560px; background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden; border: 1px solid var(--border); }
.cmdk-input-row { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border); }
.cmdk-input-row i { color: var(--text-faint); font-size: 1rem; }
.cmdk-input-row input { flex: 1; border: none; outline: none; background: none; font-size: 0.95rem; color: var(--text); font-family: var(--font); }
.cmdk-results { max-height: 60vh; overflow-y: auto; padding: 8px; }
.cmdk-group-label { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; color: var(--text-faint); padding: 8px 10px 4px; }
.cmdk-results a { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: var(--radius-sm); color: var(--text); text-decoration: none; font-size: 0.87rem; }
.cmdk-results a:hover { background: var(--hover); }
.cmdk-results a i { color: var(--text-faint); width: 16px; }
.cmdk-results .no-results { padding: 16px; color: var(--text-faint); font-size: 0.85rem; text-align: center; }

/* ---- Skeleton loaders: for any async-loaded content (command palette
   while searching, future AJAX panels). Most of this app renders
   server-side so content is already present on page load, but any
   JS-driven section can drop these classes in while it waits. ---- */
@keyframes skeleton-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
.skeleton { background: var(--surface-alt); border-radius: var(--radius-sm); animation: skeleton-pulse 1.4s ease-in-out infinite; }
.skeleton-text { height: 12px; margin-bottom: 8px; width: 100%; }
.skeleton-text.short { width: 40%; }
.skeleton-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.skeleton-row .skeleton-avatar { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; }
.skeleton-row .skeleton-lines { flex: 1; }
.skeleton-card { padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); }
.skeleton-chart { height: 180px; width: 100%; }

.user-menu { position: relative; }
.user-menu-trigger {
    display: flex; align-items: center; gap: 9px; padding: 4px; border-radius: var(--radius-sm);
    border: none; background: none; cursor: pointer; transition: background var(--transition);
}
.user-menu-trigger:hover { background: var(--hover); }
.user-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--primary-light); color: var(--primary); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.8rem; flex-shrink: 0; }
.user-menu-trigger .user-name { font-size: 0.83rem; font-weight: 600; }
.user-menu-trigger i.chev { font-size: 0.7rem; color: var(--text-faint); }
@media (max-width: 480px) {
    .user-menu-trigger .user-name, .user-menu-trigger i.chev { display: none; }
    .user-menu-trigger { padding: 5px; }
    .topbar { padding: 0 12px; gap: 8px; }
    .topbar-right { gap: 6px; }
    .topbar-title { font-size: 0.92rem; }
}
.user-menu-dropdown {
    position: absolute; right: 0; top: calc(100% + 10px); width: 220px; background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg);
    padding: 8px; display: none; z-index: 50;
}
.user-menu-dropdown.open { display: block; animation: dropdownIn 140ms ease; }
.user-menu-dropdown a, .user-menu-dropdown button {
    display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px; border-radius: 7px;
    color: var(--text); text-decoration: none; font-size: 0.86rem; background: none; border: none; cursor: pointer;
    text-align: left; font-family: var(--font);
}
.user-menu-dropdown a:hover, .user-menu-dropdown button:hover { background: var(--hover); }
.user-menu-dropdown hr { border: none; border-top: 1px solid var(--border); margin: 6px 0; }

@keyframes dropdownIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }

.content { padding: 26px; flex: 1; max-width: 1600px; width: 100%; margin: 0 auto; }

/* ---- KPI / stat cards ---- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; margin-bottom: 22px; }
.stat-card {
    background: var(--surface); border-radius: var(--radius); padding: 12px 14px; box-shadow: none;
    border: 1px solid var(--border); position: relative; overflow: hidden; transition: border-color var(--transition);
    display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.stat-card:hover { border-color: var(--border-strong); }
.stat-card .kpi-icon {
    width: 26px; height: 26px; border-radius: 7px; display: flex; align-items: center; justify-content: center;
    background: var(--primary-light); color: var(--primary); font-size: 0.78rem; margin-bottom: 4px;
}
.stat-card .value { font-size: 1.15rem; font-weight: 800; letter-spacing: -0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stat-card .label { font-size: 0.72rem; color: var(--text-muted); font-weight: 500; }
@media (max-width: 900px) {
    .stat-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
}
@media (max-width: 600px) {
    .stat-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
    .stat-card { padding: 10px 12px; }
    .stat-card .value { font-size: 1.05rem; }
}

/* ---- Panels / cards ---- */
.panel { background: var(--surface); border-radius: var(--radius); padding: 26px 28px; box-shadow: none; border: 1px solid var(--border); margin-bottom: 20px; overflow-x: auto; }
.panel-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; padding-bottom: 14px; gap: 12px; flex-wrap: wrap; border-bottom: 1px solid var(--border); }
.panel-header h2 { margin: 0; font-size: 1.1rem; font-weight: 700; letter-spacing: -0.01em; }
.panel > h2:first-child { margin-bottom: 20px; padding-bottom: 14px; border-bottom: 1px solid var(--border); font-size: 1.1rem; }

/* ---- Tables ---- */
table.data-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
table.data-table th {
    text-align: left !important; padding: 11px 14px; border: 1px solid var(--border); color: var(--text-muted);
    font-weight: 700; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; background: var(--surface-alt);
    position: sticky; top: 0;
}
table.data-table th:first-child { border-top-left-radius: 8px; }
table.data-table th:last-child { border-top-right-radius: 8px; }
table.data-table th:last-child, table.data-table td:last-child { text-align: right !important; }
table.data-table td { padding: 12px 14px; border: 1px solid var(--border); color: var(--text); text-align: left !important; }
table.data-table tbody tr { transition: background var(--transition); }
table.data-table tbody tr:hover td { background: var(--hover); }
table.data-table tbody tr:last-child td { border-bottom: 1px solid var(--border); }

/* ---- Badges ---- */
.badge { display: inline-flex; align-items: center; gap: 4px; padding: 3px 11px; border-radius: 999px; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.01em; }
.badge-blue { background: var(--info-bg); color: var(--info); }
.badge-green { background: var(--success-bg); color: var(--success); }
.badge-yellow { background: var(--warning-bg); color: #92400E; }
.badge-red { background: var(--danger-bg); color: var(--danger); }
.badge-gray { background: var(--surface-alt); color: var(--text-muted); border: 1px solid var(--border); }

/* ---- Timeline ---- */
.timeline { list-style: none; margin: 0; padding: 0; border-left: 2px solid var(--border); margin-left: 8px; }
.timeline li { position: relative; padding: 0 0 20px 22px; }
.timeline li::before { content: ''; position: absolute; left: -7px; top: 3px; width: 12px; height: 12px; border-radius: 50%; background: var(--primary); box-shadow: 0 0 0 3px var(--primary-light); }
.timeline .t-date { font-size: 0.78rem; color: var(--text-muted); }
.timeline .t-title { font-weight: 600; }

.action-required { background: var(--warning-bg); border: 1px solid rgba(217,119,6,0.25); border-radius: var(--radius); padding: 16px; margin-bottom: 12px; }

/* ---- Tabs (for 360-style detail pages: Customer, Company, Application) ----
   Redesigned from an underline-tab style to a filled segmented control: the
   view wraps .tabs-bar in a white rounded pill container (shadow, padding),
   so the active indicator needs to be a filled pill to match, not a
   border-bottom line left over from an older flat tab-bar design. */
.tabs-bar { display: flex; gap: 2px; flex-wrap: wrap; }
.tab-btn {
    display: inline-flex; align-items: center; gap: 6px;
    background: none; border: none; border-radius: 8px;
    padding: 9px 16px; font-size: 0.86rem; font-weight: 600; color: var(--text-muted);
    cursor: pointer; white-space: nowrap;
    font-family: var(--font); transition: color .16s ease, background .16s ease;
}
.tab-btn:hover { color: var(--text); background: var(--surface-alt); }
.tab-btn.active { color: #fff; background: var(--primary); }
.tab-btn.active:hover { background: var(--primary); }
.tab-btn .tab-count { display: inline-block; padding: 1px 7px; border-radius: 999px; background: var(--surface-alt); color: var(--text-muted); font-size: 0.72rem; font-weight: 700; }
.tab-btn.active .tab-count { background: rgba(255,255,255,0.22); color: #fff; }
.tab-panel { display: none; }
.tab-panel.active { display: block; animation: fadeIn 180ms ease; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ---- Filter pills (Application Command Center, Task Work Queue, etc.) ---- */
.filter-bar { display: flex; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; }
.filter-pill {
    padding: 7px 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface);
    color: var(--text-muted); font-size: 0.82rem; font-weight: 600; text-decoration: none; white-space: nowrap;
    transition: all var(--transition);
}
.filter-pill:hover { border-color: var(--border-strong); color: var(--text); }
.filter-pill.active { background: var(--primary); border-color: var(--primary); color: #fff; }

.progress-bar-outer { background: var(--surface-alt); border-radius: 999px; height: 8px; overflow: hidden; }
.progress-bar-inner { background: linear-gradient(90deg, var(--primary), var(--secondary)); height: 100%; border-radius: 999px; transition: width 300ms ease; }

/* Row-based layout: every page is a single stacked column of full-width
   blocks rather than side-by-side panels. This is deliberate, not just a
   mobile fallback - it's what makes every panel below (tables, forms,
   pipelines) able to breathe and use its full width, and it means there is
   nothing further to do for responsiveness on any screen size. */
.two-col { display: block; }
.two-col > div { width: 100%; }
.two-col > div + div { margin-top: 0; }

/* Dashboard-only exception: the reference design's "at a glance" widgets
   sit side by side (a wider recent-activity table next to narrower summary
   cards) rather than stacking - this is a deliberate dashboard pattern, not
   a reversal of the row-based layout used everywhere else in the app. */
.dash-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 16px; }
@media (max-width: 1100px) {
    .dash-grid { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
    .sidebar { position: fixed; left: 0; transform: translateX(-100%); box-shadow: var(--shadow-lg); }
    .admin-shell.is-mobile-open .sidebar { transform: translateX(0); }
    .content { padding: 16px; }
}

/* ---- Customer portal shell (mobile-first) ---- */
.portal-body { background: var(--bg); }
.portal-topbar {
    background: var(--sidebar-bg); color: #fff; padding: 14px 16px;
    display: flex; align-items: center; justify-content: space-between; position: sticky; top: 0; z-index: 10;
    box-shadow: var(--shadow-md);
}
.portal-topbar .brand { font-weight: 700; font-size: 1rem; }
.portal-topbar form { margin: 0; }
.portal-content { padding: 16px; max-width: 720px; margin: 0 auto; padding-bottom: 90px; }

.portal-nav {
    position: fixed; bottom: 0; left: 0; right: 0; background: var(--surface); border-top: 1px solid var(--border);
    display: flex; justify-content: space-around; padding: 8px 0; z-index: 10; box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
}
.portal-nav a { flex: 1; text-align: center; text-decoration: none; color: var(--text-muted); font-size: 0.72rem; padding: 4px 0; transition: color var(--transition); }
.portal-nav a.active { color: var(--primary); font-weight: 700; }
.portal-nav .nav-icon { font-size: 1.2rem; display: block; }

@media (min-width: 720px) {
    .portal-content { padding: 24px; }
    .portal-nav { position: static; border-top: none; justify-content: flex-start; gap: 20px; background: transparent; padding: 0 24px 16px; box-shadow: none; }
    .portal-nav a { flex: none; }
}

.welcome-banner { margin-bottom: 16px; }
.welcome-banner h1 { font-size: 1.35rem; margin: 0 0 4px; }
.welcome-banner p { color: var(--text-muted); margin: 0; font-size: 0.9rem; }

.service-card { display: block; text-decoration: none; color: inherit; transition: box-shadow var(--transition), transform var(--transition); }
.service-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.service-card .service-name { font-weight: 600; margin-bottom: 4px; }
.service-card .service-meta { font-size: 0.82rem; color: var(--text-muted); }

/* ---- Scrollbar polish (desktop) ---- */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }

/* ==========================================================================
   Print stylesheet - used for "Print" on quotations/invoices (and anything
   else that opts in with .print-only content). Overriding the CSS variables
   here means every component (panels, tables, badges, buttons) automatically
   prints in clean black-on-white regardless of whether dark mode was on.
   ========================================================================== */
.print-only { display: none; }
.print-letterhead { display: none; }

/* Invoice/quotation footer content (bank details, terms, signature line) is
   admin-editable under Settings -> Invoice & Quotation Branding, and is
   shown both on screen and when printed - not print-only - so staff and
   customers see exactly what a printed/PDF copy will say. */
.print-footer-content {
    margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--border, #e2e8f0);
    font-size: 0.8rem; color: var(--text-muted, #475569); line-height: 1.55; white-space: pre-line;
}

@media print {
    :root, [data-theme="dark"] {
        --bg: #ffffff;
        --surface: #ffffff;
        --surface-alt: #ffffff;
        --border: #cbcbcb;
        --border-strong: #999999;
        --text: #000000;
        --text-muted: #333333;
        --text-faint: #666666;
        --shadow-sm: none;
        --shadow-md: none;
        --shadow-lg: none;
        --primary: #000000;
        --success: #1a7a35;
        --danger: #b91c1c;
    }

    body { background: #fff; font-size: 12px; }

    /* Chrome that only makes sense on screen */
    .sidebar, .topbar, .no-print, .portal-nav, .portal-topbar { display: none !important; }

    .admin-shell, .main-area { display: block; height: auto; }
    .content { padding: 0; max-width: 100%; margin: 0; }
    .portal-content { padding: 0; max-width: 100%; }

    .panel { box-shadow: none; border: 1px solid var(--border); break-inside: avoid; }
    .two-col { display: block; }
    .two-col > div { width: 100%; }

    table.data-table th { background: #F1F5F9; position: static; }
    table.data-table tbody tr:hover td { background: transparent; }

    .badge { border: 1px solid var(--border-strong); background: #fff !important; color: #000 !important; }

    a { color: #000; text-decoration: none; }

    .print-only { display: block; }
    .print-letterhead {
        display: flex; justify-content: space-between; align-items: flex-start;
        border-bottom: 2px solid #000; padding-bottom: 14px; margin-bottom: 20px;
    }
    .print-letterhead .brand-mark {
        width: 40px; height: 40px; border-radius: 8px; background: #000 !important;
        color: #fff !important; display: flex; align-items: center; justify-content: center;
        font-weight: 800; font-size: 0.95rem;
    }
    .print-letterhead .brand-name { font-weight: 800; font-size: 1rem; }
    .print-letterhead .print-meta { text-align: right; font-size: 0.78rem; color: #333; }
    .print-letterhead .brand-logo { max-height: 46px; max-width: 180px; object-fit: contain; }
    .print-letterhead .brand-header-content { margin-top: 3px; font-size: 0.72rem; color: #444; line-height: 1.4; white-space: pre-line; }
    .print-footer-content {
        display: block; margin-top: 22px; padding-top: 10px; border-top: 1px solid var(--border);
        font-size: 0.72rem; color: #444; line-height: 1.5; white-space: pre-line;
    }

    @page { margin: 1.6cm; }
}

/* ==========================================================================
   ADMIN SIDEBAR v2 — rebuilt from scratch (views/partials/admin-sidebar.php)
   --------------------------------------------------------------------------
   Self-contained. Labels are plain, high-contrast, and ALWAYS rendered — no
   opacity animation, no Alpine-driven per-element visibility. Alpine only
   toggles `.is-rail` on the <aside>; everything else is CSS below.

   If JavaScript never loads, the full labelled sidebar still shows, because
   the expanded state is the default and `.is-rail` is simply never added.
   ========================================================================== */

.app-sidebar {
    --rail: 72px;
    --open: 264px;
    width: var(--open);
    flex-shrink: 0;
    position: sticky;
    top: 0;
    height: 100vh;
    z-index: 50;
    display: flex;
    flex-direction: column;
    color: #0B4D36;                 /* dark green: readable on the light mint sidebar */
    background: #D7F5E3;
    border-right: none;
    box-shadow: none;
    transition: width .28s cubic-bezier(.16,1,.3,1), transform .28s cubic-bezier(.16,1,.3,1);
    overflow: hidden;
}

/* ---- Brand ---- */
.sidebar-brand {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 12px;
    height: 4rem;                   /* matches the main header's h-16 (4rem) exactly - a literal
                                        64px here would NOT match, since html{font-size:93.75%}
                                        makes 1rem = 15px on this page, so h-16 actually renders
                                        at 60px, not 64px. Must stay in rem to track that scaling. */
    padding: 0 18px;
    border-bottom: 1px solid rgba(11,77,54,.4);
    flex-shrink: 0;
    white-space: nowrap;
}
.sidebar-brand-mark {
    width: 36px; height: 36px; flex-shrink: 0;
    border-radius: 9px;
    background: #FFFFFF;
    border: 1px solid rgba(11,77,54,.1);
    color: #0E8A6D; font-weight: 800; font-size: 0.85rem;
    display: flex; align-items: center; justify-content: center;
}
.sidebar-brand-text { display: flex; flex-direction: column; line-height: 1.2; overflow: hidden; }
.sidebar-brand-title { font-size: 0.85rem; font-weight: 600; color: #0B4D36; letter-spacing: -0.01em; }
.sidebar-brand-sub   { font-size: 0.68rem; color: #3F8767; }
.sidebar-close {
    margin-left: auto; width: 32px; height: 32px; border: none; background: none;
    color: #3F8767; cursor: pointer; border-radius: 8px; display: none;
    align-items: center; justify-content: center;
}
.sidebar-close:hover { color: #0B4D36; background: rgba(11,77,54,.08); }

/* ---- Nav list ---- */
.sidebar-nav-list { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 12px 10px; }
.sidebar-nav-list::-webkit-scrollbar { width: 6px; }
.sidebar-nav-list::-webkit-scrollbar-thumb { background: rgba(11,77,54,.18); border-radius: 6px; }

.nav-group { margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(11,77,54,.16); }
.nav-group:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.nav-group-label,
.nav-group-toggle {
    padding: 0 10px 6px;
    font-size: 13px;
    font-weight: 700;
    color: #051F15;
    white-space: nowrap;
}
/* The header is now a real <button>: reset browser button chrome, add the
   chevron and hover/active affordance. FAIL-VISIBLE: nothing here hides the
   items below it - .nav-group-items is only ever hidden by Alpine's own
   x-show once Alpine has actually booted (see the partial's PHP comment). */
.nav-group-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    padding-top: 4px;
    padding-bottom: 8px;
    transition: color .16s ease, background .16s ease;
    border-radius: 6px;
}
.nav-group-label-inner { display: flex; align-items: center; gap: 9px; min-width: 0; }
.nav-group-icon-chip {
    width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0;
    background: rgba(11,77,54,.1);
    display: flex; align-items: center; justify-content: center;
}
.nav-group-icon-chip i { font-size: 12px; color: #B45309; }
.nav-group-toggle:hover { background: rgba(11,77,54,.08); color: #0B4D36; }
.nav-group-chevron {
    font-size: 14px;
    font-weight: 700;
    color: #3F8767;
    transition: transform .18s ease, color .16s ease;
    flex-shrink: 0;
}
.nav-group-toggle:hover .nav-group-chevron { color: #0B4D36; }
.nav-group-toggle.is-open .nav-group-chevron { transform: rotate(180deg); color: #0B4D36; }

/* Collapsed accordion panel. Vanilla JS (ui-kit.js) toggles this class -
   nothing here until the script runs, which is exactly the point: every
   panel is visible by default in the raw HTML and only .is-closed hides it,
   so a JS failure means "always expanded", never "stuck collapsed". */
.nav-group-items.is-closed { display: none; }

/* ---- Nav item: the link. HIGH CONTRAST, always readable. ---- */
.nav-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    margin-bottom: 2px;
    border-radius: 9px;
    font-size: 0.875rem;
    font-weight: 500;
    color: #17563D;                 /* dark mint-green, clearly visible on the light mint sidebar */
    text-decoration: none;
    white-space: nowrap;
    transition: background .16s ease, color .16s ease;
}
.nav-item:hover { background: rgba(11,77,54,.08); color: #0B4D36; }
.nav-item-icon { width: 18px; text-align: center; font-size: 15px; flex-shrink: 0; }
.nav-item-text { flex: 1; overflow: hidden; }

/* Tally's signature: the active/selected item gets a solid, warm
   accent block rather than just a subtle highlight. */
.nav-item-active {
    background: #FFA940;
    color: #1A1200;
    font-weight: 600;
    box-shadow: none;
}
.nav-item-active .nav-item-icon { color: #1A1200; }

/* Rail-only hover tooltip. Hidden entirely unless the sidebar is collapsed.
   Kept as a dark mint chip regardless of the (now light) sidebar background -
   it floats over the page content, not the sidebar itself, so it follows
   the app's normal dark-tooltip convention rather than the sidebar's colors. */
.nav-item-tip {
    display: none;
    position: absolute;
    left: 100%;
    margin-left: 12px;
    padding: 5px 10px;
    border-radius: 7px;
    background: #0E8A6D;
    color: #fff;
    font-size: 0.75rem;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s ease;
    box-shadow: 0 8px 20px rgba(14,138,109,0.35);
    z-index: 60;
}

/* ---- Collapse button ---- */
.sidebar-collapse-btn {
    display: none;                  /* shown on desktop via .lg:flex below */
    align-items: center;
    gap: 10px;
    height: 48px;
    padding: 0 20px;
    border: none;
    border-radius: 0;
    border-top: 1px solid rgba(11,77,54,.14);
    background: #0B0B0B;
    color: #FFFFFF;
    font-size: 0.875rem;
    font-family: inherit;
    cursor: pointer;
    flex-shrink: 0;
    transition: background .16s ease, color .16s ease;
}
.sidebar-collapse-btn i { color: #FFFFFF; }
.sidebar-collapse-btn:hover { background: #1F1F1F; color: #FFFFFF; }

/* ==========================================================================
   COLLAPSED RAIL — the only thing Alpine toggles is `.is-rail`.
   ========================================================================== */
.app-sidebar.is-rail { width: var(--rail); }
.app-sidebar.is-rail .sidebar-brand-text,
.app-sidebar.is-rail .nav-group-label,
.app-sidebar.is-rail .nav-group-toggle,
.app-sidebar.is-rail .nav-item-text { display: none; }
.app-sidebar.is-rail .nav-item { justify-content: center; }
.app-sidebar.is-rail .nav-group { margin-top: 8px; }
.app-sidebar.is-rail .nav-group::before {
    content: ''; display: block; width: 24px; height: 1px;
    background: rgba(11,77,54,.16); margin: 0 auto 8px;
}
.app-sidebar.is-rail .nav-item:hover .nav-item-tip { display: block; opacity: 1; }
.app-sidebar.is-rail .sidebar-collapse-btn { justify-content: center; }
/* The accordion only makes sense when there's a label to click. In rail
   (icons-only) mode every group's icons stay visible regardless of which
   group was open before collapsing - otherwise most of the app would become
   unreachable from the rail. Overrides Alpine's inline x-show style.
   Desktop-only (see mobile override below): on mobile the rail preference is
   ignored entirely and the drawer always shows full labels + the accordion. */
@media (min-width: 1024px) {
    .app-sidebar.is-rail .nav-group-items { display: block !important; }
}

/* ==========================================================================
   MOBILE — the sidebar becomes an off-canvas drawer, never a rail.
   ========================================================================== */
@media (min-width: 1024px) {
    .sidebar-collapse-btn { display: flex; }
}
@media (max-width: 1023px) {
    .app-sidebar {
        position: fixed;
        left: 0;
        transform: translateX(-100%);
        width: var(--open);
    }
    /* On mobile the drawer is always full-width and fully labelled, even if a
       collapsed preference was saved on desktop. */
    .app-sidebar.is-rail { width: var(--open); }
    .app-sidebar.is-rail .sidebar-brand-text,
    .app-sidebar.is-rail .nav-group-label,
    .app-sidebar.is-rail .nav-group-toggle,
    .app-sidebar.is-rail .nav-item-text { display: revert; }
    .app-sidebar.is-rail .nav-item { justify-content: flex-start; }
    .app-sidebar.is-rail .nav-group::before { display: none; }
    .app-sidebar.is-open-mobile { transform: translateX(0); }
    .sidebar-close { display: flex; }
}

/* File preview overlay (View button on a document) - a real on-page modal
   instead of navigating to a new tab. Plain CSS, no framework dependency -
   the JS that builds this markup (ui-kit.js) is vanilla too, per this
   project's standing rule against Alpine for anything that must reliably
   work on click. */
.file-preview-overlay {
    position: fixed; inset: 0; z-index: 200;
    background: rgba(15, 23, 42, 0.72);
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    animation: fadeIn 150ms ease;
}
.file-preview-panel {
    background: #fff; border-radius: 12px; overflow: hidden;
    width: 100%; max-width: 900px; max-height: 90vh;
    display: flex; flex-direction: column;
    box-shadow: 0 24px 60px -12px rgba(0, 0, 0, 0.45);
}
.file-preview-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 18px; border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}
.file-preview-title { font-weight: 700; font-size: 0.92rem; color: var(--text); }
.file-preview-close {
    background: none; border: none; cursor: pointer;
    width: 32px; height: 32px; border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    color: var(--text-muted); transition: background .15s ease;
}
.file-preview-close:hover { background: var(--surface-alt); }
.file-preview-body {
    flex: 1; min-height: 0; overflow: auto;
    display: flex; align-items: center; justify-content: center;
    background: #0f172a08; padding: 12px;
}
.file-preview-body img { max-width: 100%; max-height: 78vh; object-fit: contain; border-radius: 4px; }
.file-preview-body iframe { width: 100%; height: 78vh; border: none; background: #fff; }

/* No spin-button arrows on number inputs - typed directly, not nudged. */
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* Every form field - rectangular corners (not the old full pill), and
   tighter padding than before on every dimension, not just left/right.
   Scoped to exclude checkbox/radio/file/range/color, which are native
   small controls that padding/radius would distort rather than improve.
   This one rule is now the single source of truth for field shape across
   the whole app - the line-item table below no longer needs its own
   override, since this already matches what it was asking for. */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]),
select,
textarea {
    border-radius: var(--radius-sm, 8px) !important;
    padding: 0.45rem 0.65rem !important;
}
/* Line-item table fields (Qty/Price/Discount, and the Service/Description
   cells beside them) still get a shorter fixed height than the rule
   above alone would give them - narrow spreadsheet-style cells read
   better a little more compact than a standard-width field. */
.line-item .service-select,
.line-item .qty-input,
.line-item .price-input,
.line-item .discount-input {
    height: 32px;
    box-sizing: border-box;
}
.line-item .description-input {
    box-sizing: border-box;
}
/* ==========================================================================
   Complete spacing utility scale (0-12, standard Tailwind steps) - this
   compiled stylesheet only ever included whichever specific classes the
   original markup happened to use, not the full scale a real Tailwind build
   would generate. That gap caused several silent bugs this project hit
   directly (pl-10, pl-11, -mx-5, -mt-5 all resolved to nothing because they
   were simply never defined, not because anything was overriding them).
   This fills in every value on the standard scale for padding, margin, and
   gap, so referencing any of them from here on just works.
   ========================================================================== */
.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*0.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-3\.5{padding:calc(var(--spacing)*3.5)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-7{padding:calc(var(--spacing)*7)}.p-8{padding:calc(var(--spacing)*8)}.p-9{padding:calc(var(--spacing)*9)}.p-10{padding:calc(var(--spacing)*10)}.p-11{padding:calc(var(--spacing)*11)}.p-12{padding:calc(var(--spacing)*12)}
.px-0{padding-inline:calc(var(--spacing)*0)}.px-0\.5{padding-inline:calc(var(--spacing)*0.5)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-3\.5{padding-inline:calc(var(--spacing)*3.5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.px-7{padding-inline:calc(var(--spacing)*7)}.px-8{padding-inline:calc(var(--spacing)*8)}.px-9{padding-inline:calc(var(--spacing)*9)}.px-10{padding-inline:calc(var(--spacing)*10)}.px-11{padding-inline:calc(var(--spacing)*11)}.px-12{padding-inline:calc(var(--spacing)*12)}
.py-0{padding-block:calc(var(--spacing)*0)}.py-0\.5{padding-block:calc(var(--spacing)*0.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\.5{padding-block:calc(var(--spacing)*3.5)}.py-4{padding-block:calc(var(--spacing)*4)}.py-5{padding-block:calc(var(--spacing)*5)}.py-6{padding-block:calc(var(--spacing)*6)}.py-7{padding-block:calc(var(--spacing)*7)}.py-8{padding-block:calc(var(--spacing)*8)}.py-9{padding-block:calc(var(--spacing)*9)}.py-10{padding-block:calc(var(--spacing)*10)}.py-11{padding-block:calc(var(--spacing)*11)}.py-12{padding-block:calc(var(--spacing)*12)}
.pt-0{padding-top:calc(var(--spacing)*0)}.pt-0\.5{padding-top:calc(var(--spacing)*0.5)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-1\.5{padding-top:calc(var(--spacing)*1.5)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-2\.5{padding-top:calc(var(--spacing)*2.5)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-3\.5{padding-top:calc(var(--spacing)*3.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-5{padding-top:calc(var(--spacing)*5)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-7{padding-top:calc(var(--spacing)*7)}.pt-8{padding-top:calc(var(--spacing)*8)}.pt-9{padding-top:calc(var(--spacing)*9)}.pt-10{padding-top:calc(var(--spacing)*10)}.pt-11{padding-top:calc(var(--spacing)*11)}.pt-12{padding-top:calc(var(--spacing)*12)}
.pr-0{padding-right:calc(var(--spacing)*0)}.pr-0\.5{padding-right:calc(var(--spacing)*0.5)}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-2\.5{padding-right:calc(var(--spacing)*2.5)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-3\.5{padding-right:calc(var(--spacing)*3.5)}.pr-4{padding-right:calc(var(--spacing)*4)}.pr-5{padding-right:calc(var(--spacing)*5)}.pr-6{padding-right:calc(var(--spacing)*6)}.pr-7{padding-right:calc(var(--spacing)*7)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-9{padding-right:calc(var(--spacing)*9)}.pr-10{padding-right:calc(var(--spacing)*10)}.pr-11{padding-right:calc(var(--spacing)*11)}.pr-12{padding-right:calc(var(--spacing)*12)}
.pb-0{padding-bottom:calc(var(--spacing)*0)}.pb-0\.5{padding-bottom:calc(var(--spacing)*0.5)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-2\.5{padding-bottom:calc(var(--spacing)*2.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-3\.5{padding-bottom:calc(var(--spacing)*3.5)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-5{padding-bottom:calc(var(--spacing)*5)}.pb-6{padding-bottom:calc(var(--spacing)*6)}.pb-7{padding-bottom:calc(var(--spacing)*7)}.pb-8{padding-bottom:calc(var(--spacing)*8)}.pb-9{padding-bottom:calc(var(--spacing)*9)}.pb-10{padding-bottom:calc(var(--spacing)*10)}.pb-11{padding-bottom:calc(var(--spacing)*11)}.pb-12{padding-bottom:calc(var(--spacing)*12)}
.pl-0{padding-left:calc(var(--spacing)*0)}.pl-0\.5{padding-left:calc(var(--spacing)*0.5)}.pl-1{padding-left:calc(var(--spacing)*1)}.pl-1\.5{padding-left:calc(var(--spacing)*1.5)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-2\.5{padding-left:calc(var(--spacing)*2.5)}.pl-3{padding-left:calc(var(--spacing)*3)}.pl-3\.5{padding-left:calc(var(--spacing)*3.5)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-5{padding-left:calc(var(--spacing)*5)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.pl-8{padding-left:calc(var(--spacing)*8)}.pl-9{padding-left:calc(var(--spacing)*9)}.pl-10{padding-left:calc(var(--spacing)*10)}.pl-11{padding-left:calc(var(--spacing)*11)}.pl-12{padding-left:calc(var(--spacing)*12)}
.m-0{margin:calc(var(--spacing)*0)}.m-0\.5{margin:calc(var(--spacing)*0.5)}.m-1{margin:calc(var(--spacing)*1)}.m-1\.5{margin:calc(var(--spacing)*1.5)}.m-2{margin:calc(var(--spacing)*2)}.m-2\.5{margin:calc(var(--spacing)*2.5)}.m-3{margin:calc(var(--spacing)*3)}.m-3\.5{margin:calc(var(--spacing)*3.5)}.m-4{margin:calc(var(--spacing)*4)}.m-5{margin:calc(var(--spacing)*5)}.m-6{margin:calc(var(--spacing)*6)}.m-7{margin:calc(var(--spacing)*7)}.m-8{margin:calc(var(--spacing)*8)}.m-9{margin:calc(var(--spacing)*9)}.m-10{margin:calc(var(--spacing)*10)}.m-11{margin:calc(var(--spacing)*11)}.m-12{margin:calc(var(--spacing)*12)}
.mx-0{margin-inline:calc(var(--spacing)*0)}.mx-0\.5{margin-inline:calc(var(--spacing)*0.5)}.mx-1{margin-inline:calc(var(--spacing)*1)}.mx-1\.5{margin-inline:calc(var(--spacing)*1.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-2\.5{margin-inline:calc(var(--spacing)*2.5)}.mx-3{margin-inline:calc(var(--spacing)*3)}.mx-3\.5{margin-inline:calc(var(--spacing)*3.5)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-5{margin-inline:calc(var(--spacing)*5)}.mx-6{margin-inline:calc(var(--spacing)*6)}.mx-7{margin-inline:calc(var(--spacing)*7)}.mx-8{margin-inline:calc(var(--spacing)*8)}.mx-9{margin-inline:calc(var(--spacing)*9)}.mx-10{margin-inline:calc(var(--spacing)*10)}.mx-11{margin-inline:calc(var(--spacing)*11)}.mx-12{margin-inline:calc(var(--spacing)*12)}
.my-0{margin-block:calc(var(--spacing)*0)}.my-0\.5{margin-block:calc(var(--spacing)*0.5)}.my-1{margin-block:calc(var(--spacing)*1)}.my-1\.5{margin-block:calc(var(--spacing)*1.5)}.my-2{margin-block:calc(var(--spacing)*2)}.my-2\.5{margin-block:calc(var(--spacing)*2.5)}.my-3{margin-block:calc(var(--spacing)*3)}.my-3\.5{margin-block:calc(var(--spacing)*3.5)}.my-4{margin-block:calc(var(--spacing)*4)}.my-5{margin-block:calc(var(--spacing)*5)}.my-6{margin-block:calc(var(--spacing)*6)}.my-7{margin-block:calc(var(--spacing)*7)}.my-8{margin-block:calc(var(--spacing)*8)}.my-9{margin-block:calc(var(--spacing)*9)}.my-10{margin-block:calc(var(--spacing)*10)}.my-11{margin-block:calc(var(--spacing)*11)}.my-12{margin-block:calc(var(--spacing)*12)}
.mt-0{margin-top:calc(var(--spacing)*0)}.mt-0\.5{margin-top:calc(var(--spacing)*0.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-2\.5{margin-top:calc(var(--spacing)*2.5)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-3\.5{margin-top:calc(var(--spacing)*3.5)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-5{margin-top:calc(var(--spacing)*5)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-7{margin-top:calc(var(--spacing)*7)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-9{margin-top:calc(var(--spacing)*9)}.mt-10{margin-top:calc(var(--spacing)*10)}.mt-11{margin-top:calc(var(--spacing)*11)}.mt-12{margin-top:calc(var(--spacing)*12)}
.mr-0{margin-right:calc(var(--spacing)*0)}.mr-0\.5{margin-right:calc(var(--spacing)*0.5)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-1\.5{margin-right:calc(var(--spacing)*1.5)}.mr-2{margin-right:calc(var(--spacing)*2)}.mr-2\.5{margin-right:calc(var(--spacing)*2.5)}.mr-3{margin-right:calc(var(--spacing)*3)}.mr-3\.5{margin-right:calc(var(--spacing)*3.5)}.mr-4{margin-right:calc(var(--spacing)*4)}.mr-5{margin-right:calc(var(--spacing)*5)}.mr-6{margin-right:calc(var(--spacing)*6)}.mr-7{margin-right:calc(var(--spacing)*7)}.mr-8{margin-right:calc(var(--spacing)*8)}.mr-9{margin-right:calc(var(--spacing)*9)}.mr-10{margin-right:calc(var(--spacing)*10)}.mr-11{margin-right:calc(var(--spacing)*11)}.mr-12{margin-right:calc(var(--spacing)*12)}
.mb-0{margin-bottom:calc(var(--spacing)*0)}.mb-0\.5{margin-bottom:calc(var(--spacing)*0.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-2\.5{margin-bottom:calc(var(--spacing)*2.5)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-3\.5{margin-bottom:calc(var(--spacing)*3.5)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-7{margin-bottom:calc(var(--spacing)*7)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.mb-9{margin-bottom:calc(var(--spacing)*9)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.mb-11{margin-bottom:calc(var(--spacing)*11)}.mb-12{margin-bottom:calc(var(--spacing)*12)}
.ml-0{margin-left:calc(var(--spacing)*0)}.ml-0\.5{margin-left:calc(var(--spacing)*0.5)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-2\.5{margin-left:calc(var(--spacing)*2.5)}.ml-3{margin-left:calc(var(--spacing)*3)}.ml-3\.5{margin-left:calc(var(--spacing)*3.5)}.ml-4{margin-left:calc(var(--spacing)*4)}.ml-5{margin-left:calc(var(--spacing)*5)}.ml-6{margin-left:calc(var(--spacing)*6)}.ml-7{margin-left:calc(var(--spacing)*7)}.ml-8{margin-left:calc(var(--spacing)*8)}.ml-9{margin-left:calc(var(--spacing)*9)}.ml-10{margin-left:calc(var(--spacing)*10)}.ml-11{margin-left:calc(var(--spacing)*11)}.ml-12{margin-left:calc(var(--spacing)*12)}
.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*0.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-3\.5{gap:calc(var(--spacing)*3.5)}.gap-4{gap:calc(var(--spacing)*4)}.gap-5{gap:calc(var(--spacing)*5)}.gap-6{gap:calc(var(--spacing)*6)}.gap-7{gap:calc(var(--spacing)*7)}.gap-8{gap:calc(var(--spacing)*8)}.gap-9{gap:calc(var(--spacing)*9)}.gap-10{gap:calc(var(--spacing)*10)}.gap-11{gap:calc(var(--spacing)*11)}.gap-12{gap:calc(var(--spacing)*12)}
.gap-x-0{column-gap:calc(var(--spacing)*0)}.gap-x-0\.5{column-gap:calc(var(--spacing)*0.5)}.gap-x-1{column-gap:calc(var(--spacing)*1)}.gap-x-1\.5{column-gap:calc(var(--spacing)*1.5)}.gap-x-2{column-gap:calc(var(--spacing)*2)}.gap-x-2\.5{column-gap:calc(var(--spacing)*2.5)}.gap-x-3{column-gap:calc(var(--spacing)*3)}.gap-x-3\.5{column-gap:calc(var(--spacing)*3.5)}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-x-5{column-gap:calc(var(--spacing)*5)}.gap-x-6{column-gap:calc(var(--spacing)*6)}.gap-x-7{column-gap:calc(var(--spacing)*7)}.gap-x-8{column-gap:calc(var(--spacing)*8)}.gap-x-9{column-gap:calc(var(--spacing)*9)}.gap-x-10{column-gap:calc(var(--spacing)*10)}.gap-x-11{column-gap:calc(var(--spacing)*11)}.gap-x-12{column-gap:calc(var(--spacing)*12)}
.gap-y-0{row-gap:calc(var(--spacing)*0)}.gap-y-0\.5{row-gap:calc(var(--spacing)*0.5)}.gap-y-1{row-gap:calc(var(--spacing)*1)}.gap-y-1\.5{row-gap:calc(var(--spacing)*1.5)}.gap-y-2{row-gap:calc(var(--spacing)*2)}.gap-y-2\.5{row-gap:calc(var(--spacing)*2.5)}.gap-y-3{row-gap:calc(var(--spacing)*3)}.gap-y-3\.5{row-gap:calc(var(--spacing)*3.5)}.gap-y-4{row-gap:calc(var(--spacing)*4)}.gap-y-5{row-gap:calc(var(--spacing)*5)}.gap-y-6{row-gap:calc(var(--spacing)*6)}.gap-y-7{row-gap:calc(var(--spacing)*7)}.gap-y-8{row-gap:calc(var(--spacing)*8)}.gap-y-9{row-gap:calc(var(--spacing)*9)}.gap-y-10{row-gap:calc(var(--spacing)*10)}.gap-y-11{row-gap:calc(var(--spacing)*11)}.gap-y-12{row-gap:calc(var(--spacing)*12)}
.-m-0\.5{margin:calc(var(--spacing)*-0.5)}.-m-1{margin:calc(var(--spacing)*-1)}.-m-1\.5{margin:calc(var(--spacing)*-1.5)}.-m-2{margin:calc(var(--spacing)*-2)}.-m-2\.5{margin:calc(var(--spacing)*-2.5)}.-m-3{margin:calc(var(--spacing)*-3)}.-m-3\.5{margin:calc(var(--spacing)*-3.5)}.-m-4{margin:calc(var(--spacing)*-4)}.-m-5{margin:calc(var(--spacing)*-5)}.-m-6{margin:calc(var(--spacing)*-6)}.-m-7{margin:calc(var(--spacing)*-7)}.-m-8{margin:calc(var(--spacing)*-8)}.-m-9{margin:calc(var(--spacing)*-9)}.-m-10{margin:calc(var(--spacing)*-10)}.-m-11{margin:calc(var(--spacing)*-11)}.-m-12{margin:calc(var(--spacing)*-12)}
.-mx-0\.5{margin-inline:calc(var(--spacing)*-0.5)}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.-mx-1\.5{margin-inline:calc(var(--spacing)*-1.5)}.-mx-2{margin-inline:calc(var(--spacing)*-2)}.-mx-2\.5{margin-inline:calc(var(--spacing)*-2.5)}.-mx-3{margin-inline:calc(var(--spacing)*-3)}.-mx-3\.5{margin-inline:calc(var(--spacing)*-3.5)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.-mx-5{margin-inline:calc(var(--spacing)*-5)}.-mx-6{margin-inline:calc(var(--spacing)*-6)}.-mx-7{margin-inline:calc(var(--spacing)*-7)}.-mx-8{margin-inline:calc(var(--spacing)*-8)}.-mx-9{margin-inline:calc(var(--spacing)*-9)}.-mx-10{margin-inline:calc(var(--spacing)*-10)}.-mx-11{margin-inline:calc(var(--spacing)*-11)}.-mx-12{margin-inline:calc(var(--spacing)*-12)}
.-my-0\.5{margin-block:calc(var(--spacing)*-0.5)}.-my-1{margin-block:calc(var(--spacing)*-1)}.-my-1\.5{margin-block:calc(var(--spacing)*-1.5)}.-my-2{margin-block:calc(var(--spacing)*-2)}.-my-2\.5{margin-block:calc(var(--spacing)*-2.5)}.-my-3{margin-block:calc(var(--spacing)*-3)}.-my-3\.5{margin-block:calc(var(--spacing)*-3.5)}.-my-4{margin-block:calc(var(--spacing)*-4)}.-my-5{margin-block:calc(var(--spacing)*-5)}.-my-6{margin-block:calc(var(--spacing)*-6)}.-my-7{margin-block:calc(var(--spacing)*-7)}.-my-8{margin-block:calc(var(--spacing)*-8)}.-my-9{margin-block:calc(var(--spacing)*-9)}.-my-10{margin-block:calc(var(--spacing)*-10)}.-my-11{margin-block:calc(var(--spacing)*-11)}.-my-12{margin-block:calc(var(--spacing)*-12)}
.-mt-0\.5{margin-top:calc(var(--spacing)*-0.5)}.-mt-1{margin-top:calc(var(--spacing)*-1)}.-mt-1\.5{margin-top:calc(var(--spacing)*-1.5)}.-mt-2{margin-top:calc(var(--spacing)*-2)}.-mt-2\.5{margin-top:calc(var(--spacing)*-2.5)}.-mt-3{margin-top:calc(var(--spacing)*-3)}.-mt-3\.5{margin-top:calc(var(--spacing)*-3.5)}.-mt-4{margin-top:calc(var(--spacing)*-4)}.-mt-5{margin-top:calc(var(--spacing)*-5)}.-mt-6{margin-top:calc(var(--spacing)*-6)}.-mt-7{margin-top:calc(var(--spacing)*-7)}.-mt-8{margin-top:calc(var(--spacing)*-8)}.-mt-9{margin-top:calc(var(--spacing)*-9)}.-mt-10{margin-top:calc(var(--spacing)*-10)}.-mt-11{margin-top:calc(var(--spacing)*-11)}.-mt-12{margin-top:calc(var(--spacing)*-12)}
.-mr-0\.5{margin-right:calc(var(--spacing)*-0.5)}.-mr-1{margin-right:calc(var(--spacing)*-1)}.-mr-1\.5{margin-right:calc(var(--spacing)*-1.5)}.-mr-2{margin-right:calc(var(--spacing)*-2)}.-mr-2\.5{margin-right:calc(var(--spacing)*-2.5)}.-mr-3{margin-right:calc(var(--spacing)*-3)}.-mr-3\.5{margin-right:calc(var(--spacing)*-3.5)}.-mr-4{margin-right:calc(var(--spacing)*-4)}.-mr-5{margin-right:calc(var(--spacing)*-5)}.-mr-6{margin-right:calc(var(--spacing)*-6)}.-mr-7{margin-right:calc(var(--spacing)*-7)}.-mr-8{margin-right:calc(var(--spacing)*-8)}.-mr-9{margin-right:calc(var(--spacing)*-9)}.-mr-10{margin-right:calc(var(--spacing)*-10)}.-mr-11{margin-right:calc(var(--spacing)*-11)}.-mr-12{margin-right:calc(var(--spacing)*-12)}
.-mb-0\.5{margin-bottom:calc(var(--spacing)*-0.5)}.-mb-1{margin-bottom:calc(var(--spacing)*-1)}.-mb-1\.5{margin-bottom:calc(var(--spacing)*-1.5)}.-mb-2{margin-bottom:calc(var(--spacing)*-2)}.-mb-2\.5{margin-bottom:calc(var(--spacing)*-2.5)}.-mb-3{margin-bottom:calc(var(--spacing)*-3)}.-mb-3\.5{margin-bottom:calc(var(--spacing)*-3.5)}.-mb-4{margin-bottom:calc(var(--spacing)*-4)}.-mb-5{margin-bottom:calc(var(--spacing)*-5)}.-mb-6{margin-bottom:calc(var(--spacing)*-6)}.-mb-7{margin-bottom:calc(var(--spacing)*-7)}.-mb-8{margin-bottom:calc(var(--spacing)*-8)}.-mb-9{margin-bottom:calc(var(--spacing)*-9)}.-mb-10{margin-bottom:calc(var(--spacing)*-10)}.-mb-11{margin-bottom:calc(var(--spacing)*-11)}.-mb-12{margin-bottom:calc(var(--spacing)*-12)}
.-ml-0\.5{margin-left:calc(var(--spacing)*-0.5)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.-ml-1\.5{margin-left:calc(var(--spacing)*-1.5)}.-ml-2{margin-left:calc(var(--spacing)*-2)}.-ml-2\.5{margin-left:calc(var(--spacing)*-2.5)}.-ml-3{margin-left:calc(var(--spacing)*-3)}.-ml-3\.5{margin-left:calc(var(--spacing)*-3.5)}.-ml-4{margin-left:calc(var(--spacing)*-4)}.-ml-5{margin-left:calc(var(--spacing)*-5)}.-ml-6{margin-left:calc(var(--spacing)*-6)}.-ml-7{margin-left:calc(var(--spacing)*-7)}.-ml-8{margin-left:calc(var(--spacing)*-8)}.-ml-9{margin-left:calc(var(--spacing)*-9)}.-ml-10{margin-left:calc(var(--spacing)*-10)}.-ml-11{margin-left:calc(var(--spacing)*-11)}.-ml-12{margin-left:calc(var(--spacing)*-12)}
/* Same gap as the padding/margin/gap scale above, for width and height -
   w-7/h-7 (used by the icon-badge size correction) simply did not exist.
   Complete standard scale filled in for both. */
.w-0{width:calc(var(--spacing)*0)}.w-0\.5{width:calc(var(--spacing)*0.5)}.w-1{width:calc(var(--spacing)*1)}.w-1\.5{width:calc(var(--spacing)*1.5)}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-3{width:calc(var(--spacing)*3)}.w-3\.5{width:calc(var(--spacing)*3.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-12{width:calc(var(--spacing)*12)}
.h-0{height:calc(var(--spacing)*0)}.h-0\.5{height:calc(var(--spacing)*0.5)}.h-1{height:calc(var(--spacing)*1)}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-3{height:calc(var(--spacing)*3)}.h-3\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-12{height:calc(var(--spacing)*12)}

/* ==========================================================================
   Quotation / Invoice form — customer-select grid + line-items table.
   Custom classes (not Tailwind utilities) used deliberately here: this
   section needs one precise, guaranteed breakpoint (768px) shared by both
   the customer-select grid and the line-items table/card switch, rather
   than depending on whichever Tailwind sm:/md: variants happen to be in
   the compiled bundle (several silently aren't - see the notes throughout
   this file). Every rule below is plain, verifiable CSS.
   ========================================================================== */

/* ---- Customer / billing field grid ---- */
.qform-section {
    background: #fff;
    border: 1px solid var(--color-navy-900, #0F172A);
    border-radius: 12px;
    padding: 18px 20px;
    margin-bottom: 20px;
}
.qform-section-title {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--color-navy-400, #94a3b8);
    margin: 0 0 14px;
}
.qform-fields {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}
.qform-fields.is-2col,
.qform-fields.is-3col {
    grid-template-columns: 1fr;
}
@media (min-width: 768px) {
    .qform-fields.is-2col { grid-template-columns: 1fr 1fr; }
    .qform-fields.is-3col { grid-template-columns: 1fr 1fr 1fr; }
}
.qform-hint {
    font-size: 0.78rem;
    color: var(--color-navy-400, #94a3b8);
    margin: 12px 0 0;
}

/* ---- Line-items table (desktop, ≥768px) — "refined" style: quiet
   borders, ghost delete (red only on hover), zebra rows, and a pure-CSS
   row-number badge via a CSS counter (counter-reset on the tbody,
   counter-increment per row, content: counter() on the first cell's
   ::before) - no JavaScript involved, so it renumbers correctly on
   Add/Delete Line with zero changes to line-items.js. ---- */
.qform-table-wrap {
    background: #fff;
    border: 1px solid var(--color-navy-300, #cbd5e1);
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 16px;
}
#line-items-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}
#line-items-table thead tr {
    background: #F1F9F5;
}
#line-items-table th {
    text-align: left;
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: #5F6B66;
    padding: 10px 12px;
}
#line-items-table td {
    padding: 14px 12px;
    border-top: 1px solid var(--color-navy-300, #cbd5e1);
    vertical-align: top;
}
#line-items {
    counter-reset: lineitem;
}
#line-items tr.line-item {
    counter-increment: lineitem;
}
#line-items tr.line-item:nth-child(even) {
    background: #FAFAF8;
}
td.qf-line-num {
    text-align: center;
    padding-top: 16px !important;
}
td.qf-line-num::before {
    content: counter(lineitem);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #E1F5EE;
    color: #0F6E56;
    font-size: 11px;
    font-weight: 600;
}
#line-items-table .qf-input,
#line-items-table .qf-select,
#line-items-table .qf-textarea {
    width: 100%;
    min-height: 42px;
    border: 1px solid var(--color-navy-300, #cbd5e1);
    border-radius: 8px;
    padding: 8px 10px;
    font-size: 0.875rem;
    background: #fff;
    color: var(--color-navy-900, #0F172A);
    outline: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
#line-items-table .qf-textarea { min-height: auto; overflow: hidden; resize: none; line-height: 1.55; }
#line-items-table .qf-input:focus,
#line-items-table .qf-select:focus,
#line-items-table .qf-textarea:focus {
    border-color: var(--color-brandgreen-500, #087F4F);
    box-shadow: 0 0 0 3px rgba(8,127,79,.12);
}
.qf-line-total {
    font-weight: 600;
    font-size: 0.95rem;
    color: #0F6E56;
    display: block;
    padding-top: 9px;
}
.qf-refill-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.72rem;
    color: var(--color-navy-400, #94a3b8);
    background: none;
    border: none;
    padding: 0;
    margin-top: 6px;
    cursor: pointer;
}
.qf-refill-btn:hover { color: var(--color-brandgreen-600, #087F4F); }

/* Delete-line button - ghost/quiet by default so a multi-row table doesn't
   read as a wall of red; only turns into the danger color on hover/focus,
   the same way it would in Notion, Linear, Zoho and similar tools. On
   mobile it becomes a full labeled touch target instead (see the media
   query below) - same element, no separate button needed. */
.remove-line {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 30px;
    height: 30px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--color-navy-300, #cbd5e1);
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
    margin-top: 3px;
}
.remove-line:hover { background: var(--color-status-alert-bg, #fee2e2); color: var(--color-status-alert, #DC2626); }
.remove-line:focus-visible { outline: 2px solid var(--color-status-alert, #DC2626); outline-offset: 2px; }
.remove-line-text { display: none; }

/* "+ Add Line" — a full-width dashed affordance rather than a small link,
   so it reads as an obvious, inviting action rather than a minor button. */
.qf-add-line-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 46px;
    border: 1.5px dashed var(--color-brandgreen-500, #087F4F);
    border-radius: 10px;
    background: var(--color-brandgreen-50, #EFFBF5);
    color: var(--color-brandgreen-700, #056A44);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
    margin-bottom: 20px;
}
.qf-add-line-btn:hover {
    background: var(--color-brandgreen-100, #DCF5E9);
    border-color: var(--color-brandgreen-600, #067A50);
}

/* ---- Summary (VAT + totals) ---- */
.qform-summary-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    align-items: start;
    margin-bottom: 20px;
}
@media (min-width: 768px) {
    .qform-summary-row { grid-template-columns: 1fr 320px; }
}
.qform-vat-field {
    background: #fff;
    border: 1px solid var(--color-navy-900, #0F172A);
    border-radius: 12px;
    padding: 16px 18px;
}
.qform-summary-card {
    background: #fff;
    border: 1px solid var(--color-navy-900, #0F172A);
    border-radius: 12px;
    padding: 18px 20px;
}
.qform-summary-line {
    display: flex;
    justify-content: space-between;
    font-size: 0.875rem;
    color: var(--color-navy-500, #64748b);
    padding: 5px 0;
}
.qform-summary-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--color-navy-900, #0F172A);
    padding-top: 12px;
    margin-top: 8px;
    border-top: 2px solid var(--color-navy-900, #0F172A);
}

/* ==========================================================================
   Mobile card transform (<768px) — table structure stays identical in the
   DOM (so a dynamically cloned <tr> works with zero JS changes); CSS alone
   reflows each row into a card, using data-label attributes for the small
   field labels a table normally gets for free from its header row.
   ========================================================================== */
@media (max-width: 767px) {
    .qform-table-wrap { border: none; background: none; overflow: visible; }
    #line-items-table,
    #line-items-table thead,
    #line-items-table tbody,
    #line-items-table tr,
    #line-items-table th,
    #line-items-table td {
        display: block;
        width: 100% !important;
    }
    #line-items-table thead { display: none; }

    #line-items-table tr.line-item {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        gap: 12px;
        background: #fff;
        border: 1px solid var(--color-navy-900, #0F172A);
        border-radius: 12px;
        padding: 16px;
        margin-bottom: 14px;
        box-shadow: 0 1px 3px rgba(15,23,42,.08);
    }
    #line-items-table tr.line-item::before {
        content: "Item " counter(lineitem);
        grid-column: 1 / -1;
        font-size: 0.68rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--color-navy-400, #94a3b8);
        border-bottom: 1px solid var(--color-navy-100, #e5e9f0);
        padding-bottom: 10px;
        margin-bottom: 2px;
    }
    #line-items-table td {
        padding: 0 !important;
        border: none !important;
        grid-column: 1 / -1;
    }
    #line-items-table td.qf-line-num { display: none; }
    #line-items-table td.qf-line-num::before { content: none; }
    #line-items-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 0.68rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: .03em;
        color: var(--color-navy-400, #94a3b8);
        margin-bottom: 6px;
    }
    #line-items-table td[data-label="Qty"],
    #line-items-table td[data-label="Price"],
    #line-items-table td[data-label="Discount"] {
        grid-column: span 1;
    }
    #line-items-table td[data-label="Line Total"] {
        background: var(--surface-alt, #F1F5F9);
        border-radius: 8px !important;
        padding: 10px 12px !important;
        margin-top: 4px;
    }
    #line-items-table td[data-label="Line Total"] .qf-line-total {
        text-align: left;
        font-size: 1.15rem;
        padding-top: 0;
    }
    #line-items-table td[data-label="Action"] {
        display: flex;
        justify-content: flex-end;
        margin-top: 2px;
    }
    .remove-line {
        width: auto;
        height: 44px;
        padding: 0 18px;
    }
    .remove-line-text { display: inline; font-size: 0.85rem; font-weight: 600; }

    .qform-section { padding: 16px; }
}


/* Legal Documents tracker table (Operations > Legal Documents) - explicit
   ID-scoped border rule, since the shared .table-grid class alone wasn't
   rendering visible cell borders on this page (root cause unclear -
   possibly a build/caching gap on some deployments). Kept in addition to
   .table-grid, not instead of it, so this table also picks up any future
   shared improvements to that class. */
#legal-doc-table {
    border-collapse: collapse !important;
    border: 1px solid #0F172A !important;
}
#legal-doc-table th,
#legal-doc-table td {
    border: 1px solid #0F172A !important;
}
#legal-docs-tab-table {
    border-collapse: collapse !important;
    border: 1px solid #0F172A !important;
}
#legal-docs-tab-table th,
#legal-docs-tab-table td {
    border: 1px solid #0F172A !important;
}
#bank-accounts-tab-table {
    border-collapse: collapse !important;
    border: 1px solid #0F172A !important;
}
#bank-accounts-tab-table th,
#bank-accounts-tab-table td {
    border: 1px solid #0F172A !important;
}
