/*
  Fresh Produce Management - application shell and shared components.

  Spec section 50 UX principles:
    - operational screens are mobile-first with large tap targets and large numeric inputs
    - management and finance screens are desktop-first, dense but clear
    - three status colours do most of the work: green fine, amber attention, red blocked
    - the same data gets two treatments; a desktop table is never just shrunk onto a phone
*/

:root {
    --fp-primary: #1b5e20;
    --fp-primary-dark: #14481a;
    --fp-primary-light: #e8f5e9;
    --fp-accent: #ef6c00;

    /* Spec 23 principle 7: three status colours, and resist a fourth meaning. */
    --fp-ok: #2e7d32;
    --fp-attention: #ed6c02;
    --fp-blocked: #c62828;

    --fp-surface: #ffffff;
    --fp-canvas: #f4f6f4;
    --fp-border: #dfe3df;
    --fp-text: #1c1f1c;
    --fp-muted: #6b716b;

    --fp-sidenav-width: 248px;
    --fp-topbar-height: 56px;
    --fp-mobilenav-height: 60px;
}

html { font-size: 16px; }

body {
    background: var(--fp-canvas);
    color: var(--fp-text);
    /* Noto Sans Devanagari is required for Nepali (spec 15.2); the Latin fallbacks are
       weight-matched so a mixed-script line does not jump. */
    font-family: "Segoe UI", "Noto Sans", "Noto Sans Devanagari", system-ui, -apple-system, sans-serif;
}

:lang(ne) body,
[lang="ne"] {
    font-family: "Noto Sans Devanagari", "Segoe UI", system-ui, sans-serif;
}

.btn-primary { background-color: var(--fp-primary); border-color: var(--fp-primary); }
.btn-primary:hover, .btn-primary:focus { background-color: var(--fp-primary-dark); border-color: var(--fp-primary-dark); }
a { color: var(--fp-primary-dark); }

/* ---------- Shell ---------- */

.app-shell { display: flex; min-height: calc(100vh - var(--fp-topbar-height)); }

.app-topbar {
    position: sticky; top: 0; z-index: 1030;
    height: var(--fp-topbar-height);
    display: flex; align-items: center; gap: .5rem;
    padding: 0 .75rem;
    background: var(--fp-surface);
    border-bottom: 1px solid var(--fp-border);
}

.app-topbar-spacer { flex: 1 1 auto; }
.app-topbar-date { display: flex; align-items: center; gap: .35rem; font-size: .875rem; color: var(--fp-muted); white-space: nowrap; flex: 0 0 auto; }
.app-topbar-location select { min-width: 9rem; }

/* Everything on this bar is a tap target or a menu, and flexbox will happily shrink a 40px button
   to 18px rather than wrap. Nothing here shrinks; the bar sheds items instead. */
.app-topbar > * { flex: 0 0 auto; }
.app-topbar-spacer { flex: 1 1 auto; }

@media (max-width: 767.98px) {
    /* A phone fits the hamburger, the date, the location and four menus - but only just, and only
       once the brand mark goes. The hamburger is already the way back to the nav. */
    .app-topbar { gap: .25rem; padding: 0 .4rem; }
    .app-topbar-brand { display: none; }
    .app-topbar-date { font-size: .8125rem; }
    /* The location name is the one thing here that can be truncated without losing a control. */
    /* The location name is the one thing here that can be truncated without losing a control, so
       it takes whatever is left and shows an ellipsis rather than pushing the menus off screen. */
    .app-topbar-location { flex: 1 1 auto; min-width: 4rem; }
    .app-topbar-location select { min-width: 0; width: 100%; text-overflow: ellipsis; }
}
.app-topbar-brand { color: var(--fp-primary); font-size: 1.35rem; text-decoration: none; }

.btn-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.5rem; height: 2.5rem; padding: 0;
    border: 0; background: transparent; color: var(--fp-text); font-size: 1.15rem;
    border-radius: .5rem;
}
.btn-icon:hover { background: var(--fp-primary-light); }
.lang-toggle { font-size: .8rem; font-weight: 600; }

.btn-user { border: 0; background: transparent; display: inline-flex; align-items: center; gap: .4rem; }
/* A long display name must not be what pushes the menus off the bar. */
.btn-user > span { display: inline-block; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

.app-sidenav {
    width: var(--fp-sidenav-width); flex: 0 0 var(--fp-sidenav-width);
    background: var(--fp-surface); border-right: 1px solid var(--fp-border);
    position: sticky; top: var(--fp-topbar-height);
    height: calc(100vh - var(--fp-topbar-height));
}

.app-brand {
    display: flex; align-items: center; gap: .5rem;
    padding: 1rem; font-weight: 700; color: var(--fp-primary); border-bottom: 1px solid var(--fp-border);
}

.app-sidenav-scroll { overflow-y: auto; padding: .5rem 0 2rem; flex: 1 1 auto; }

.nav-group { padding: .35rem 0; }
.nav-group-title {
    padding: .5rem 1rem .25rem; font-size: .7rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .06em; color: var(--fp-muted);
}
.app-sidenav .nav-link, .offcanvas .nav-link {
    display: flex; align-items: center; gap: .6rem;
    padding: .5rem 1rem; color: var(--fp-text); border-radius: 0;
}
.app-sidenav .nav-link:hover, .offcanvas .nav-link:hover { background: var(--fp-primary-light); }
.app-sidenav .nav-link.active {
    background: var(--fp-primary-light); color: var(--fp-primary-dark);
    font-weight: 600; box-shadow: inset 3px 0 0 var(--fp-primary);
}

.app-main { flex: 1 1 auto; padding: 1rem; min-width: 0; padding-bottom: calc(var(--fp-mobilenav-height) + 1rem); }
@media (min-width: 992px) { .app-main { padding: 1.25rem 1.5rem; padding-bottom: 2rem; } }

.app-main-anonymous { min-height: 100vh; }

/* Mobile bottom tab bar - spec 50: large tap targets, primary action always visible. */
.app-mobilenav {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 1030;
    height: var(--fp-mobilenav-height);
    display: flex; background: var(--fp-surface); border-top: 1px solid var(--fp-border);
}
.app-mobilenav-item {
    flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .15rem; border: 0; background: transparent; color: var(--fp-muted);
    font-size: .7rem; text-decoration: none; padding: .25rem;
}
.app-mobilenav-item i { font-size: 1.25rem; }
.app-mobilenav-item.active { color: var(--fp-primary); font-weight: 600; }

.skip-link { position: absolute; left: .5rem; top: .5rem; z-index: 2000; background: #fff; padding: .5rem; }

/* ---------- Page furniture ---------- */

.page-header {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: .75rem; margin-bottom: 1rem;
}
.page-header .h4 { margin: 0; }

.card { border: 1px solid var(--fp-border); border-radius: .6rem; }
.card-header { background: var(--fp-surface); border-bottom: 1px solid var(--fp-border); font-weight: 600; }
.card-form { max-width: 46rem; }

.kpi-tile {
    display: block; padding: .75rem .5rem; border-radius: .5rem;
    background: var(--fp-canvas); text-decoration: none; color: inherit;
}
.kpi-tile:hover { background: var(--fp-primary-light); }
.kpi-value { font-size: 1.6rem; font-weight: 700; line-height: 1.15; }
.kpi-label { font-size: .75rem; color: var(--fp-muted); }
.kpi-warning { background: #fff4e5; }
.kpi-warning .kpi-value { color: var(--fp-attention); }
.kpi-blocked .kpi-value { color: var(--fp-blocked); }

/* ---------- Universal states (spec 20.1) ---------- */

.state-empty-icon { font-size: 3rem; color: var(--fp-border); }
.state-empty, .state-nopermission { color: var(--fp-muted); }
.state-blocked { border-left: 4px solid var(--fp-attention); }
.state-dayclosed { border-left: 4px solid var(--fp-muted); }
.state-pending { border-left: 4px solid var(--fp-attention); }
.state-offline { border-radius: 0; }
/* ASP.NET emits a validation summary as <ul><li style="display:none"></li></ul> even when the
   model is valid, so the element is never :empty and an alert-styled summary would show as a
   blank red bar on every fresh form. The tag helper's own class is the reliable signal. */
.d-none-if-empty:empty,
.d-none-if-empty.validation-summary-valid { display: none !important; }

/* Skeletons, never a spinner over a blank list (spec 20.1). */
.skeleton {
    background: linear-gradient(90deg, #eceeec 25%, #f5f7f5 37%, #eceeec 63%);
    background-size: 400% 100%; animation: skeleton 1.2s ease-in-out infinite;
    border-radius: .3rem; height: 1rem; margin-bottom: .5rem;
}
@keyframes skeleton { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ---------- Status badges (spec 4 badge colour convention) ---------- */

.badge-status { font-weight: 600; }
.status-draft, .status-proposed { background: #6c757d !important; }
.status-submitted, .status-inprogress { background: #0d6efd !important; }
.status-pending, .status-variance { background: var(--fp-attention) !important; color: #fff !important; }
.status-approved, .status-active, .status-closed { background: var(--fp-ok) !important; }
.status-rejected, .status-blocked, .status-exception { background: var(--fp-blocked) !important; }
.status-expired, .status-superseded { background: #6f42c1 !important; }

/* ---------- Operational screens: large numeric inputs (spec 50) ---------- */

.input-numeric-lg {
    font-size: 2rem; font-weight: 600; text-align: right;
    padding: .5rem .75rem; height: auto;
    font-variant-numeric: tabular-nums;
}
.input-numeric-md { font-size: 1.35rem; text-align: right; font-variant-numeric: tabular-nums; }

.numeric { font-variant-numeric: tabular-nums; text-align: right; }
th.numeric, td.numeric { text-align: right; }

/* Variance chip (S-11, S-45) */
.variance-chip { display: inline-flex; align-items: center; gap: .35rem; padding: .35rem .6rem; border-radius: 999px; font-weight: 600; font-size: .85rem; }
.variance-ok { background: #e8f5e9; color: var(--fp-ok); }
.variance-warn { background: #fff4e5; color: var(--fp-attention); }
.variance-block { background: #fdecea; color: var(--fp-blocked); }

/* ---------- Print (spec 58) ---------- */

@media print {
    .app-topbar, .app-sidenav, .app-mobilenav, .no-print, .offcanvas { display: none !important; }
    .app-main { padding: 0; }
    body { background: #fff; }
    .card { border: 0; }
}

/* 80 mm thermal receipt (spec 58 and 21.6). */
.receipt-80mm {
    width: 76mm; margin: 0 auto; font-family: "Noto Sans", "Noto Sans Devanagari", monospace;
    font-size: 11px; line-height: 1.35; color: #000;
}
.receipt-80mm .receipt-line { display: flex; justify-content: space-between; gap: .5rem; }
.receipt-80mm hr { border: 0; border-top: 1px dashed #000; margin: .35rem 0; }
.receipt-80mm .receipt-total { font-weight: 700; font-size: 13px; }

@page { margin: 8mm; }

/* ---------- Sign in and other anonymous screens (S-01) ---------- */

/* The anonymous shell has no side nav and no top bar, so the card has to place itself. Centred
   both ways on a desktop, but top-aligned once the viewport is short enough that centring would
   push the button under a phone keyboard. */
.auth-wrapper {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem;
    background: var(--fp-canvas);
}

@media (max-height: 640px) {
    .auth-wrapper { align-items: flex-start; }
}

.auth-card {
    width: 100%;
    max-width: 26rem;
    background: var(--fp-surface);
    border: 1px solid var(--fp-border);
    border-radius: .75rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .06), 0 8px 24px rgba(0, 0, 0, .06);
    padding: 1.75rem;
}

.auth-brand {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: 1.5rem;
}

.auth-brand > i {
    font-size: 2rem;
    line-height: 1;
    color: var(--fp-primary);
}

.auth-title { font-size: 1.125rem; font-weight: 700; line-height: 1.25; }
.auth-subtitle { font-size: .8125rem; color: var(--fp-muted); }

/* ---------- Notification panel (top bar) ---------- */

/* A dropdown that loads its contents over the wire needs a size before the contents arrive, or the
   panel snaps from spinner-width to list-width under the pointer. */
.app-notifications {
    width: 22rem;
    max-width: calc(100vw - 1rem);
    padding-bottom: 0;
}

.app-notifications-body {
    max-height: 22rem;
    overflow-y: auto;
}

/* ---------- Odds and ends ---------- */

/* Filled by script once the B-2 balance is known; reserving the height stops the card jumping. */
.balance-strip { min-height: 2rem; }

.trace-body { min-width: 0; }

/* The receipt is read on 76mm of paper: no zebra striping, no cell padding worth the ink. */
.receipt-table > :not(caption) > * > * { padding: .15rem .25rem; border-color: #000; }
.receipt-table { font-size: 11px; }
