/* ============ Camel Toddy — design tokens ============
   Light is the default theme (issue #40). Dark stays available as a
   session-scoped toggle — see ThemeToggle.razor / wwwroot/js/theme.js.
   Both themes share the same emerald accent; only surfaces/text invert. */
:root {
    --bg: #f9f9f9;
    --bg-alt: #f1f2f0;
    --surface: #ffffff;
    --surface-raised: #ffffff;
    --ink: #1c211f;
    --ink-bright: #10140f;
    --muted: rgba(28, 33, 31, 0.64);
    --faint: rgba(28, 33, 31, 0.42);
    --accent: #1f7a63;
    --accent-soft: #185f4c;
    --accent-rgb: 31, 122, 99;
    --hairline: rgba(31, 122, 99, 0.16);
    --accent-border: rgba(31, 122, 99, 0.35);
    --accent-border-strong: rgba(31, 122, 99, 0.55);
    /* Label colour for anything sitting ON a filled accent/semantic swatch.
       Light theme fills are dark, so the label is near-white (4.96:1). */
    --on-accent: #f9f9f9;
    --color-success: #1f7a46;
    --color-success-rgb: 31, 122, 70;
    --color-danger: #b3413c;
    --color-danger-rgb: 179, 65, 60;
    --color-info: #2f6f8c;
    --color-info-rgb: 47, 111, 140;
    /* Dark enough to read on white: 5.92:1, where Bootstrap's #ffc107 is 1.63:1. */
    --color-warning: #8a5a0c;
    --color-warning-rgb: 138, 90, 12;
    --serif: 'Cormorant Garamond', Georgia, serif;
    --sans: 'Jost', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    color-scheme: light;
}

/* Dark theme — opted into per browser tab via the toggle, never the
   default on a fresh load (see the blocking script in App.razor). */
:root[data-theme="dark"] {
    --bg: #0a0c0b;
    --bg-alt: #0e100e;
    --surface: #121412;
    --surface-raised: #161916;
    --ink: #f1ede3;
    --ink-bright: #f6f2e8;
    --muted: rgba(241, 237, 227, 0.66);
    --faint: rgba(241, 237, 227, 0.4);
    --accent: #2bab8c;
    --accent-soft: #48c7a8;
    --accent-rgb: 43, 171, 140;
    --hairline: rgba(43, 171, 140, 0.18);
    --accent-border: rgba(43, 171, 140, 0.42);
    --accent-border-strong: rgba(43, 171, 140, 0.55);
    /* Dark-theme fills are LIGHT tints, so a near-white label on them measured
       2.73:1 — below AA on every primary button in the app. The ground colour
       reads as near-black ink on the mint instead: 6.98:1 on --accent and
       9.47:1 on --accent-soft. */
    --on-accent: #0a0c0b;
    --color-success: #a4cc9f;
    --color-success-rgb: 164, 204, 159;
    --color-danger: #e0a3a3;
    --color-danger-rgb: 224, 163, 163;
    --color-info: #a8c6d6;
    --color-info-rgb: 168, 198, 214;
    /* Lifted for the near-black ground, mirroring the other dark tokens: 10.3:1. */
    --color-warning: #e0bd7a;
    --color-warning-rgb: 224, 189, 122;
    color-scheme: dark;
}

html, body {
    font-family: var(--sans);
    font-weight: 300;
    background: var(--bg);
    color: var(--ink);
}

/* ---------- typography ---------- */
h1, .h1, h2, .h2 {
    font-family: var(--serif);
    font-weight: 400;
    color: var(--ink-bright);
    letter-spacing: -0.01em;
}

h1.h3, h2.h5 {
    font-family: var(--serif);
    font-weight: 500;
}

.lead {
    color: var(--muted);
}

.text-muted {
    color: var(--muted) !important;
}

.form-text {
    color: var(--faint);
}

a, .btn-link {
    color: var(--accent);
    text-decoration: none;
}

    a:hover, .btn-link:hover {
        color: var(--accent-soft);
    }

code {
    color: var(--accent);
    background: rgba(var(--accent-rgb), 0.08);
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
    font-size: 0.85em;
    /* Batch codes are the primary identifier and carry two hyphens, so a
       narrow table column broke "C3-26-0005" across three lines. The table
       already scrolls horizontally on phones; the code should not fold. */
    white-space: nowrap;
}

hr {
    border-color: var(--hairline);
    opacity: 1;
}

/* ---------- theme toggle ---------- */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: transparent;
    border: 1px solid var(--accent-border);
    color: var(--muted);
    border-radius: 999px;
    padding: 0.3rem 0.8rem;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    line-height: 1.4;
}

    .theme-toggle:hover {
        color: var(--ink-bright);
        border-color: var(--accent-border-strong);
        background: rgba(var(--accent-rgb), 0.08);
    }

/* ---------- buttons ---------- */
.btn {
    font-family: var(--sans);
    letter-spacing: 0.08em;
    border-radius: 999px;
    font-weight: 400;
}

.btn-primary {
    color: var(--on-accent);
    background-color: var(--accent);
    border-color: var(--accent);
}

    .btn-primary:hover, .btn-primary:focus, .btn-primary:active,
    .btn-primary:disabled {
        color: var(--on-accent);
        background-color: var(--accent-soft);
        border-color: var(--accent-soft);
    }

.btn-outline-primary {
    color: var(--accent);
    border-color: var(--accent-border);
}

    .btn-outline-primary:hover {
        color: var(--on-accent);
        background-color: var(--accent);
        border-color: var(--accent);
    }

.btn-outline-secondary {
    color: var(--muted);
    border-color: rgba(28, 33, 31, 0.25);
}

:root[data-theme="dark"] .btn-outline-secondary {
    border-color: rgba(241, 237, 227, 0.25);
}

    .btn-outline-secondary:hover {
        color: var(--bg);
        background-color: var(--ink);
        border-color: var(--ink);
    }

/* Was a hard-coded #4a9a5c that ignored the theme entirely and measured
   3.31:1 under a near-white label in BOTH themes. It drives the single
   "Cleared bank" button on Cheques, which only renders for a deposited
   cheque — which is why a page sweep never caught it. */
.btn-success {
    color: var(--on-accent);
    background-color: var(--color-success);
    border-color: var(--color-success);
}

.btn-outline-danger {
    color: var(--color-danger);
    border-color: rgba(var(--color-danger-rgb), 0.5);
}

    .btn-outline-danger:hover {
        color: var(--on-accent);
        background-color: var(--color-danger);
        border-color: var(--color-danger);
    }

/* The only outline variant the theme had never claimed, so the "Restore"
   buttons on Configuration rendered in stock Bootstrap green (#198754)
   against the app's emerald everywhere else. */
.btn-outline-success {
    color: var(--color-success);
    border-color: rgba(var(--color-success-rgb), 0.5);
}

    .btn-outline-success:hover {
        color: var(--on-accent);
        background-color: var(--color-success);
        border-color: var(--color-success);
    }

/* Bootstrap sets a per-variant --bs-btn-disabled-color and applies it through
   `.btn:disabled`, which outranks the single-class variant rules above. Left
   alone, every outline button reverts to stock blue, grey or red the moment it
   is disabled — which is how "Split across another batch" came to render
   Bootstrap blue on the live site whenever there was no second batch to offer.
   Each variant has to state its own disabled colour to keep it. */
.btn-outline-primary:disabled, .btn-outline-primary.disabled {
    color: var(--accent-soft);
    border-color: var(--accent-border);
}

.btn-outline-secondary:disabled, .btn-outline-secondary.disabled {
    color: var(--faint);
    border-color: rgba(28, 33, 31, 0.15);
}

:root[data-theme="dark"] .btn-outline-secondary:disabled,
:root[data-theme="dark"] .btn-outline-secondary.disabled {
    border-color: rgba(241, 237, 227, 0.15);
}

.btn-outline-danger:disabled, .btn-outline-danger.disabled {
    color: rgba(var(--color-danger-rgb), 0.55);
    border-color: rgba(var(--color-danger-rgb), 0.3);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus,
.form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.2rem rgba(var(--accent-rgb), 0.25);
}

/* ---------- cards ---------- */
.card {
    background-color: var(--surface);
    border: 1px solid var(--hairline);
    color: var(--ink);
}

.card-header {
    background-color: var(--bg-alt);
    border-bottom: 1px solid var(--hairline);
    color: var(--accent);
    font-size: 0.72rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    font-weight: 400;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
}

/* ---------- modals ---------- */
/* Bootstrap's modal defaults to a white .modal-content (--bs-modal-bg falls
   back to --bs-body-bg, #fff) with no color of its own (--bs-modal-color is
   blank), so it inherited this theme's cream body text straight onto that
   white background — cream-on-white, which reads as invisible. Themed the
   same way .card already is. */
.modal-content {
    background-color: var(--surface);
    border: 1px solid var(--hairline);
    color: var(--ink);
}

.modal-header, .modal-footer {
    border-color: var(--hairline);
}

.modal-title {
    color: var(--accent);
}

/* The close icon is a dark SVG baked in as a background image. That reads
   fine on the light theme's white header, but disappears on the dark
   theme's dark one — inverted only there, matching Bootstrap's own
   `[data-bs-theme=dark] .btn-close` treatment. */
:root[data-theme="dark"] .modal .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* When an EditForm wraps .modal-body/.modal-footer, that <form> sits between
   .modal-content (a flex column) and those two panels. Bootstrap's
   scrollable-modal CSS gives the body/footer the right flex-shrink and
   overflow rules, but knows nothing about the form in between: with no flex
   layout of its own and default overflow:visible, the form just grows to its
   full content height instead of shrinking to fit, pushing the footer (and
   its Save button) off-screen with nothing left to scroll. Making the form
   itself a flex column with overflow:hidden lets it shrink to the space
   .modal-content gives it, so .modal-body can scroll internally as intended. */
.modal-dialog-scrollable .modal-content > form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

/* ---------- tables ---------- */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--ink);
    --bs-table-border-color: var(--hairline);
    --bs-table-hover-bg: rgba(var(--accent-rgb), 0.06);
    --bs-table-hover-color: var(--ink-bright);
}

    .table thead th {
        color: var(--accent);
        font-size: 0.72rem;
        letter-spacing: 0.18em;
        text-transform: uppercase;
        font-weight: 400;
        border-bottom: 1px solid var(--accent-border);
    }

/* ---------- forms ---------- */
.form-control, .form-select {
    background-color: var(--bg-alt);
    border: 1px solid rgba(28, 33, 31, 0.18);
    color: var(--ink);
}

:root[data-theme="dark"] .form-control, :root[data-theme="dark"] .form-select {
    border-color: rgba(241, 237, 227, 0.18);
}

    .form-control:focus, .form-select:focus {
        background-color: var(--bg-alt);
        border-color: var(--accent-border-strong);
        color: var(--ink-bright);
    }

    .form-control::placeholder {
        color: var(--faint);
    }

    .form-control:disabled, .form-select:disabled {
        background-color: var(--surface);
        color: var(--faint);
    }

.form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%231f7a63' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

:root[data-theme="dark"] .form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%232bab8c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* Bootstrap's default addon is a light grey slab, which reads as a white
   block against this theme. It sits flush against .form-control, so it
   borrows the same surface and keeps only its unit label quiet. */
.input-group-text {
    background-color: var(--surface-raised);
    border: 1px solid rgba(28, 33, 31, 0.18);
    color: var(--muted);
}

:root[data-theme="dark"] .input-group-text {
    border-color: rgba(241, 237, 227, 0.18);
}

.form-label {
    color: var(--muted);
    font-size: 0.85rem;
}

.form-check-input {
    background-color: var(--bg-alt);
    border-color: rgba(28, 33, 31, 0.3);
}

:root[data-theme="dark"] .form-check-input {
    border-color: rgba(241, 237, 227, 0.3);
}

    .form-check-input:checked {
        background-color: var(--accent);
        border-color: var(--accent);
    }

input[type="file"].form-control::file-selector-button {
    background-color: var(--surface-raised);
    color: var(--ink);
    border-color: transparent;
}

/* ---------- badges (status pills) ---------- */
.badge {
    font-weight: 400;
    letter-spacing: 0.06em;
    border-radius: 999px;
    padding: 0.4em 0.85em;
}

    .badge.bg-success {
        background-color: rgba(var(--color-success-rgb), 0.16) !important;
        color: var(--color-success);
        border: 1px solid rgba(var(--color-success-rgb), 0.4);
    }

    .badge.bg-danger {
        background-color: rgba(var(--color-danger-rgb), 0.14) !important;
        color: var(--color-danger);
        border: 1px solid rgba(var(--color-danger-rgb), 0.45);
    }

    .badge.bg-warning {
        background-color: rgba(var(--accent-rgb), 0.14) !important;
        color: var(--accent) !important;
        border: 1px solid var(--accent-border);
    }

    .badge.bg-info {
        background-color: rgba(var(--color-info-rgb), 0.15) !important;
        color: var(--color-info) !important;
        border: 1px solid rgba(var(--color-info-rgb), 0.45);
    }

    .badge.bg-primary {
        background-color: rgba(var(--accent-rgb), 0.16) !important;
        color: var(--accent);
        border: 1px solid var(--accent-border-strong);
    }

    .badge.bg-secondary {
        background-color: rgba(28, 33, 31, 0.06) !important;
        color: var(--muted);
        border: 1px solid rgba(28, 33, 31, 0.15);
    }

    .badge.bg-light {
        background-color: var(--bg-alt) !important;
        color: var(--muted) !important;
        border: 1px solid var(--hairline);
    }

:root[data-theme="dark"] .badge.bg-secondary {
    background-color: rgba(241, 237, 227, 0.08) !important;
    border-color: rgba(241, 237, 227, 0.2);
}

/* ---------- alerts ---------- */
.alert-danger {
    background-color: rgba(var(--color-danger-rgb), 0.12);
    border: 1px solid rgba(var(--color-danger-rgb), 0.4);
    color: var(--color-danger);
}

.alert-warning {
    background-color: rgba(var(--accent-rgb), 0.1);
    border: 1px solid var(--accent-border);
    color: var(--accent);
}

.alert-info {
    background-color: rgba(28, 33, 31, 0.04);
    border: 1px solid var(--hairline);
    color: var(--muted);
}

:root[data-theme="dark"] .alert-info {
    background-color: rgba(241, 237, 227, 0.05);
}

/* ---------- misc ---------- */
.content {
    padding-top: 1.6rem;
    padding-bottom: 3rem;
}

dl.row dt {
    color: var(--muted);
    font-weight: 400;
}

.border-top {
    border-color: var(--hairline) !important;
}

.display-6 {
    font-family: var(--serif);
    color: var(--accent);
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid rgba(var(--color-success-rgb), 0.7);
}

.invalid {
    outline: 1px solid rgba(var(--color-danger-rgb), 0.7);
}

.validation-message, .text-danger {
    color: var(--color-danger) !important;
}

.blazor-error-boundary {
    background: #3a1515;
    padding: 1rem;
    color: #f1ede3;
    border: 1px solid rgba(196, 90, 90, 0.5);
}

    .blazor-error-boundary::after {
        content: "An error has occurred.";
    }

/* ---------- dashboard KPI tiles ---------- */
.kpi-label {
    font-size: 0.68rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--accent);
}

.kpi-unit {
    font-size: 0.8rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--faint);
    margin-bottom: 0.75rem;
}

.kpi-note {
    font-size: 0.8rem;
    color: var(--muted);
    margin-bottom: 0;
}

.text-success {
    color: var(--color-success) !important;
}

/* Bootstrap's warning is #ffc107, which on the light theme's white surfaces
   measures 1.63:1 — below the 4.5:1 minimum and genuinely hard to read. The
   counter warning on Configuration was the one piece of unreadable text in
   the app. --color-warning is an amber dark enough to carry on white and
   light enough to carry on the dark theme's near-black. */
.text-warning {
    color: var(--color-warning) !important;
}

/* ---------- print (reports → paper/PDF in light) ---------- */
@media print {
    :root { color-scheme: light; }
    html, body { background: #fff !important; color: #111 !important; }
    .sidebar, .top-row, .d-print-none, #blazor-error-ui { display: none !important; }
    .top-row, article { padding-left: 0 !important; }
    h1, h2, .display-6 { color: #111 !important; }
    .text-muted, .form-text, dl.row dt { color: #555 !important; }
    .card { background: #fff !important; border-color: #ccc !important; color: #111 !important; }
    .card-header { background: #f4f4f4 !important; color: #1f7a63 !important; }
    .kpi-label { color: #1f7a63 !important; }
    .kpi-unit, .kpi-note { color: #666 !important; }
    .table { --bs-table-color: #111; --bs-table-border-color: #ddd; }
    .table thead th { color: #1f7a63 !important; border-bottom-color: #bbb !important; }
    code { color: #1a6553 !important; background: #eaf4f1 !important; }
    .badge { border-color: #999 !important; }
    .badge.bg-success { color: #2c6b2f !important; }
    .badge.bg-danger { color: #a33 !important; }
    a { color: #111 !important; }
}

/* Live invoice preview on New order — compact, following the PDF layout. */
.invoice-preview .card-body {
    font-size: 0.8rem;
}

.invoice-preview-logo {
    width: 40px;
    height: 40px;
    object-fit: contain;
}

.invoice-preview-title {
    font-size: 1.15rem;
    font-weight: 700;
    border-bottom: 1px solid var(--bs-border-color);
    margin: 0.5rem 0;
    padding-bottom: 0.25rem;
}

.invoice-preview .table {
    font-size: 0.75rem;
}

.invoice-preview-total {
    font-size: 0.95rem;
}

/* An empty date field is drawn by Safari as today's date in grey, and by
   Chrome as mm/dd/yyyy — both read as a value. Hidden until focused. */
input[type="date"].date-empty:not(:focus)::-webkit-datetime-edit {
    color: transparent;
}

/* Table rows that open a detail page when clicked. */
tr.row-link {
    cursor: pointer;
}

/* Voided invoice: a translucent diagonal VOID over the whole view, matching
   the watermark on the printed copies. Click-through, so nothing is blocked. */
.invoice-voided {
    position: relative;
    /* The rotated word is wider than a phone screen; clip, never scroll. */
    overflow: clip;
}

.void-watermark {
    position: absolute;
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(-35deg);
    font-size: clamp(6rem, 22vw, 16rem);
    font-weight: 800;
    letter-spacing: 0.1em;
    color: rgba(198, 40, 40, 0.14);
    pointer-events: none;
    user-select: none;
    z-index: 5;
    white-space: nowrap;
}
