/* =====================================================================
   Bakery System — design system
   Layout and component structure modelled on a modern dashboard shell:
   fixed left sidebar with grouped nav, white topbar, soft card grid.
   Palette is the warm bakery identity (browns + toasted amber).
   ===================================================================== */

:root {
    /* Brand — warm browns */
    --brand-900: #3B2314;   /* sidebar */
    --brand-800: #4A2C18;
    --brand-700: #6B3E26;   /* headings */
    --brand-600: #8A5433;

    /* Accent — toasted crust amber */
    --accent:     #D98E3F;
    --accent-600: #C17C30;
    --accent-100: #FCEEDC;
    --gold-700:   #A9762A;  /* eyebrow labels */

    /* Ink */
    --ink-900: #2A1D14;
    --ink-700: #4B3A2F;
    --ink-500: #7A6A5E;
    --ink-400: #9C8E83;

    /* Surfaces */
    --bg:   #F8F4EF;
    --card: #FFFFFF;
    --line: #EADFD3;

    /* Semantic */
    --success: #2F7A4F;  --success-bg: #E6F4EC;
    --danger:  #C0392B;  --danger-bg:  #FBEAE7;
    --warning: #B7791F;  --warning-bg: #FDF3DC;
    --info:    #2B6CB0;  --info-bg:    #E7F0FA;

    /* Shape */
    --r-sm: 8px;
    --r:    12px;
    --r-lg: 16px;
    --r-xl: 20px;

    --shadow-sm: 0 1px 2px rgba(59,35,20,.06);
    --shadow:    0 4px 16px rgba(59,35,20,.07);
    --shadow-lg: 0 12px 32px rgba(59,35,20,.10);

    --sidebar-w: 264px;
    --topbar-h:  74px;
    /* One source of truth: the bar's height AND the padding that keeps
       page content clear of it must never drift apart. */
    --bottom-nav-h: 74px;
}

/* ---------------------------------------------------------------- base */

* { -webkit-font-smoothing: antialiased; }

body {
    font-family: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    background-color: var(--bg);
    color: var(--ink-700);
    font-size: 15px;
}

h1, h2, h3, h4, h5, h6 { color: var(--brand-700); font-weight: 700; }
a { text-decoration: none; }
.text-muted { color: var(--ink-500) !important; }

/* Small uppercase label above a heading */
.eyebrow {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--gold-700);
    display: flex;
    align-items: center;
    gap: .4rem;
}

/* ------------------------------------------------------------- shell */

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

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

/* ----------------------------------------------------------- sidebar */

/* Bootstrap's .offcanvas / .offcanvas-lg force a transparent background and
   `position: static` at the lg breakpoint, so these rules deliberately carry
   extra specificity (and !important on the background) to win. */
.app-sidebar {
    background: var(--brand-900) !important;
    color: #fff;
    width: var(--sidebar-w);
}

.app-sidebar .offcanvas-body {
    padding: 0;
    display: flex;
    flex-direction: column;
    background: var(--brand-900) !important;
    overflow: hidden;
}

/* White logo strip, aligned with the topbar */
.sidebar-brand {
    background: #fff;
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: 0 1.1rem;
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
}

.sidebar-brand .mark {
    width: 38px; height: 38px;
    border-radius: 11px;
    background: linear-gradient(135deg, var(--brand-700), var(--accent));
    color: #fff;
    display: grid; place-items: center;
    font-size: 1.15rem;
    flex-shrink: 0;
}

.sidebar-brand .name {
    line-height: 1.05;
    font-weight: 800;
    color: var(--brand-700);
    letter-spacing: .02em;
    font-size: .95rem;
}
.sidebar-brand .name small {
    display: block;
    font-size: .62rem;
    letter-spacing: .18em;
    color: var(--accent-600);
    font-weight: 700;
}

.sidebar-scroll { flex: 1 1 auto; overflow-y: auto; padding: 1.1rem .75rem; }

.nav-group + .nav-group { margin-top: .3rem; }

/* Collapsible group header. Replaces the old static .nav-group-label so a
   phone shows ~6 rows instead of ~16 links. */
.nav-group-toggle {
    display: flex;
    align-items: center;
    gap: .7rem;
    width: 100%;
    padding: .62rem .75rem;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: rgba(255,255,255,.62);
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    text-align: left;
    transition: background-color .15s ease, color .15s ease;
}
.nav-group-toggle:hover { background: rgba(255,255,255,.07); color: #fff; }
.nav-group-toggle .grp-ic { font-size: 1rem; width: 1.25rem; text-align: center; }
.nav-group-toggle .chev {
    margin-left: auto;
    font-size: .75rem;
    transition: transform .2s ease;
}
/* Bootstrap sets aria-expanded on the toggle; drive the chevron off it. */
.nav-group-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
.nav-group-toggle[aria-expanded="true"] { color: rgba(255,255,255,.85); }
/* Group containing the current page stays visibly marked even when closed. */
.nav-group-toggle.current { color: #fff; }
.nav-group-toggle.current .grp-ic { color: var(--accent); }

.nav-group .collapse .nav, .nav-group .collapsing .nav { padding-left: .35rem; }

/* Logout: an action, not a section — separated by a rule instead of a
   group header, so it never reads as another collapsible category. */
.nav-signout {
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid rgba(255,255,255,.1);
}

.app-sidebar .nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: .62rem .75rem;
    margin-bottom: .15rem;
    border-radius: 10px;
    color: rgba(255,255,255,.78);
    font-size: .9rem;
    font-weight: 500;
    transition: background-color .15s ease, color .15s ease;
}
.app-sidebar .nav-link i { font-size: 1.05rem; width: 1.25rem; text-align: center; }

.app-sidebar .nav-link:hover { background: rgba(255,255,255,.07); color: #fff; }

.app-sidebar .nav-link.active {
    background: rgba(255,255,255,.13);
    color: #fff;
    font-weight: 700;
}
.app-sidebar .nav-link.active::before {
    content: '';
    position: absolute;
    left: -.75rem; top: 50%;
    transform: translateY(-50%);
    width: 4px; height: 26px;
    border-radius: 0 4px 4px 0;
    background: var(--accent);
}

.sidebar-foot {
    padding: 1rem 1.25rem;
    border-top: 1px solid rgba(255,255,255,.1);
    font-size: .72rem;
    color: rgba(255,255,255,.4);
    flex-shrink: 0;
}

@media (min-width: 992px) {
    /* Specificity must beat `.offcanvas-lg:not(.offcanvas-lg .offcanvas-lg)` */
    .app-shell .app-sidebar.offcanvas-lg {
        background: var(--brand-900) !important;
        position: sticky;
        top: 0;
        height: 100vh;
        flex: 0 0 var(--sidebar-w);
        width: var(--sidebar-w);
        visibility: visible;
        transform: none !important;
    }
    .app-shell .app-sidebar.offcanvas-lg .offcanvas-body {
        background: var(--brand-900) !important;
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        overflow: hidden;
        padding: 0;
    }
}

/* ------------------------------------------------------------ topbar */

.topbar {
    height: var(--topbar-h);
    background: #fff;
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.25rem;
    position: sticky;
    top: 0;
    z-index: 1020;
}

.topbar-title {
    font-weight: 800;
    color: var(--brand-700);
    font-size: 1.08rem;
    margin: 0;
}

.icon-btn {
    position: relative;
    width: 42px; height: 42px;
    border-radius: 12px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--ink-700);
    display: grid; place-items: center;
    font-size: 1.2rem;
    transition: background-color .15s ease;
}
.icon-btn:hover { background: var(--bg); color: var(--brand-700); }

.icon-btn .count {
    position: absolute;
    top: 3px; right: 3px;
    min-width: 18px; height: 18px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--danger);
    color: #fff;
    font-size: .66rem;
    font-weight: 700;
    display: grid; place-items: center;
    border: 2px solid #fff;
}

.topbar-user { display: flex; align-items: center; gap: .6rem; }
.avatar {
    width: 40px; height: 40px;
    border-radius: 50%;
    background: var(--brand-700);
    color: #fff;
    display: grid; place-items: center;
    font-weight: 700;
    flex-shrink: 0;
}
.topbar-user .who { font-size: .88rem; font-weight: 600; color: var(--ink-900); }
.topbar-user .role { font-size: .7rem; color: var(--ink-400); text-transform: uppercase; letter-spacing: .06em; }

/* Alerts dropdown */
.alert-menu { width: 340px; padding: 0; border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); }
.alert-menu .head { padding: .85rem 1rem; border-bottom: 1px solid var(--line); font-weight: 700; color: var(--brand-700); }
.alert-menu .item { display: flex; gap: .7rem; padding: .75rem 1rem; border-bottom: 1px solid var(--line); color: var(--ink-700); }
.alert-menu .item:last-child { border-bottom: 0; }
.alert-menu .item:hover { background: var(--bg); }
.alert-menu .item .ic { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; flex-shrink: 0; }
.alert-menu .item .t { font-size: .85rem; font-weight: 600; color: var(--ink-900); }
.alert-menu .item .s { font-size: .76rem; color: var(--ink-500); }
.alert-menu .empty { padding: 1.5rem 1rem; text-align: center; color: var(--ink-500); font-size: .85rem; }

/* Profile dropdown (topbar avatar) */
.profile-menu { width: 260px; padding: 0; border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); overflow: hidden; }
.profile-menu .head { display: flex; align-items: center; gap: .7rem; padding: .9rem 1rem; border-bottom: 1px solid var(--line); }
.profile-menu .head .t { font-size: .88rem; font-weight: 700; color: var(--ink-900); }
.profile-menu .head .s { font-size: .75rem; color: var(--ink-500); word-break: break-word; }
.profile-menu .dropdown-item { padding: .65rem 1rem; font-size: .87rem; }
.profile-menu .dropdown-item:hover { background: var(--bg); }
.profile-menu .dropdown-divider { margin: 0; }
button.topbar-user { cursor: pointer; }

/* -------------------------------------------------------------- page */

.page { flex: 1 1 auto; padding: 1.5rem; }
@media (min-width: 992px) { .page { padding: 1.75rem 2rem; } }

.page-foot {
    padding: 1.1rem 2rem;
    border-top: 1px solid var(--line);
    background: #fff;
    font-size: .78rem;
    color: var(--ink-400);
    text-align: center;
}

/* Section heading with an action on the right */
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.section-head h2 { font-size: 1.22rem; margin: 0 0 .15rem; }
.section-head p  { margin: 0; font-size: .88rem; color: var(--ink-500); }
.section-head a  { font-weight: 600; color: var(--accent-600); font-size: .88rem; white-space: nowrap; }
.section-head a:hover { color: var(--brand-700); }

.page-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: .9rem; flex-wrap: wrap; }
.page-head h1 { font-size: 1.35rem; margin: 0; }

/* -------------------------------------------------------------- cards */

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
}
.card-body { padding: 1rem 1.1rem; }

/* Hero welcome banner */
.hero {
    position: relative;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-sm);
    padding: 1.75rem 2rem;
    margin-bottom: 1.75rem;
    overflow: hidden;
}
.hero h1 { font-size: 1.85rem; margin: .3rem 0 .5rem; letter-spacing: -.02em; }
.hero p  { color: var(--ink-500); max-width: 46rem; margin: 0; }
.hero .glyph {
    position: absolute;
    right: 2rem; top: 50%;
    transform: translateY(-50%);
    width: 86px; height: 86px;
    border-radius: 50%;
    background: var(--brand-700);
    color: #fff;
    display: grid; place-items: center;
    font-size: 2.1rem;
    box-shadow: 0 0 0 10px rgba(107,62,38,.07);
}
@media (max-width: 767px) { .hero .glyph { display: none; } .hero { padding: 1.35rem; } .hero h1 { font-size: 1.4rem; } }

/* Split feature card: visual panel + detail panel.
   flex-direction is set explicitly because Bootstrap's .card is a column. */
.feature-card { display: flex; flex-direction: row; flex-wrap: wrap; overflow: hidden; padding: 0; }
.feature-visual {
    position: relative;
    flex: 0 0 320px;
    min-height: 220px;
    background: linear-gradient(140deg, var(--brand-900), var(--brand-700) 60%, var(--brand-600));
    color: #fff;
    display: grid; place-items: center;
    padding: 1.5rem;
    text-align: center;
}
/* Order numbers are alphanumeric codes (e.g. "ORD000123"), not short
   numerals, so this is sized down from a typical "big stat" figure to
   keep the whole code readable on one line without overflowing/wrapping. */
.feature-visual .big { font-size: 1.6rem; font-weight: 800; line-height: 1.15; word-break: break-word; }
.feature-visual .cap { font-size: .8rem; opacity: .75; letter-spacing: .04em; }
.feature-visual .pill {
    position: absolute;
    left: 1rem; bottom: 1rem;
    background: var(--accent);
    color: #3B2314;
    font-size: .76rem;
    font-weight: 700;
    padding: .35rem .7rem;
    border-radius: 999px;
    display: inline-flex; align-items: center; gap: .35rem;
}
.feature-body { flex: 1 1 340px; padding: 1.5rem 1.75rem; }
.feature-body h3 { font-size: 1.4rem; margin: .35rem 0 1rem; }
@media (max-width: 640px) { .feature-visual { flex: 1 1 100%; min-height: 160px; } }

/* Stat tiles */
.stat-card {
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: 1.1rem 1.25rem;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    height: 100%;
    transition: transform .15s ease, box-shadow .15s ease;
}
a.stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.stat-card .ic {
    width: 48px; height: 48px;
    border-radius: 14px;
    display: grid; place-items: center;
    font-size: 1.3rem;
    flex-shrink: 0;
}
.stat-card .num {
    font-size: 1.7rem; font-weight: 800; color: var(--brand-700); line-height: 1.15;
    min-width: 0; overflow-wrap: break-word;
}
/* Money values run much longer than plain counts ("KSh 125,430.00" vs "12") —
   a fixed 1.7rem overflows the card's fixed padding, so money tiles get a
   smaller, still-legible size instead of letting the figure spill out. */
.stat-card .num.num-money { font-size: 1.25rem; }
@media (max-width: 420px) {
    .stat-card .num.num-money { font-size: 1.05rem; }
}
.stat-card > span:not(.ic) { min-width: 0; flex: 1 1 auto; }
.stat-card .lbl { font-size: .82rem; color: var(--ink-500); }
.stat-card .go  { margin-left: auto; color: var(--ink-400); font-size: 1.1rem; }
a.stat-card:hover .go { color: var(--accent-600); }

/* Password show/hide toggle — wraps every password input site-wide (see
   script.js). A plain icon button inside the field, not a separate control,
   so it works with existing .form-control widths and validation states. */
.pw-toggle-wrap { position: relative; }
.pw-toggle-wrap input[type="password"],
.pw-toggle-wrap input[type="text"] { padding-right: 2.6rem; }
.pw-toggle-btn {
    position: absolute; top: 50%; right: .35rem; transform: translateY(-50%);
    width: 2rem; height: 2rem; display: grid; place-items: center;
    border: none; background: transparent; color: var(--ink-500);
    border-radius: 8px; cursor: pointer;
}
.pw-toggle-btn:hover { background: var(--bg); color: var(--ink-700); }
.pw-toggle-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.ic-amber  { background: var(--accent-100); color: var(--accent-600); }
.ic-green  { background: var(--success-bg); color: var(--success); }
.ic-red    { background: var(--danger-bg);  color: var(--danger); }
.ic-blue   { background: var(--info-bg);    color: var(--info); }
.ic-gold   { background: var(--warning-bg); color: var(--warning); }

/* Quick action tile */
.action-tile { display: block; padding: 1.25rem; background: #fff; border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); height: 100%; transition: transform .15s ease, box-shadow .15s ease; }
.action-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.action-tile h5 { font-size: 1rem; margin: 0 0 .3rem; display: flex; align-items: center; gap: .5rem; }
.action-tile p { margin: 0; font-size: .83rem; color: var(--ink-500); }

/* ------------------------------------------------------------ pieces */

.progress { height: 9px; border-radius: 999px; background: #F0E6DA; }
.progress-bar { background: var(--accent); border-radius: 999px; }
.progress-bar.low  { background: var(--danger); }
.progress-bar.good { background: var(--success); }

.btn { border-radius: 10px; font-weight: 600; font-size: .9rem; padding: .55rem 1.1rem; }
/* Declared after .btn so Bootstrap's size modifiers aren't flattened by it. */
.btn-sm { padding: .35rem .7rem; font-size: .79rem; border-radius: 8px; }
.btn-lg { padding: .75rem 1.5rem; font-size: 1rem; border-radius: 12px; }
/* Keep row action buttons on one line */
td.text-end .btn, td.text-end form { vertical-align: middle; }
td.text-end { white-space: nowrap; }
.btn-brand { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-brand:hover, .btn-brand:focus { background: var(--accent-600); border-color: var(--accent-600); color: #fff; }
.btn-dark-brand { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }
.btn-dark-brand:hover { background: var(--brand-800); border-color: var(--brand-800); color: #fff; }
.btn-outline-secondary { border-color: var(--line); color: var(--ink-700); }
.btn-outline-secondary:hover { background: var(--bg); border-color: var(--ink-400); color: var(--brand-700); }
.btn-link-arrow { font-weight: 700; color: var(--brand-700); display: inline-flex; align-items: center; gap: .4rem; padding: .55rem .25rem; }
.btn-link-arrow:hover { color: var(--accent-600); }

.badge { font-weight: 600; border-radius: 999px; padding: .35em .7em; font-size: .72rem; letter-spacing: .02em; }
.badge.bg-success { background: var(--success-bg) !important; color: var(--success) !important; }
.badge.bg-danger  { background: var(--danger-bg)  !important; color: var(--danger)  !important; }
.badge.bg-warning { background: var(--warning-bg) !important; color: var(--warning) !important; }
.badge.bg-info    { background: var(--info-bg)    !important; color: var(--info)    !important; }
.badge.bg-secondary, .badge.bg-secondary-subtle { background: #F0E9E1 !important; color: var(--ink-500) !important; }
.badge.bg-light   { background: #F0E9E1 !important; color: var(--ink-700) !important; }

/* Status tabs (Orders page): a horizontally-scrollable pill row rather than
   Bootstrap nav-pills, so it degrades gracefully on a phone (swipe instead
   of wrapping into a tall stack) and carries a live count badge per status. */
.status-tabs {
    display: flex;
    gap: .5rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: .25rem;
    scrollbar-width: thin;
}
.status-tab {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    flex-shrink: 0;
    padding: .5rem .9rem;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: #fff;
    color: var(--ink-700);
    font-weight: 600;
    font-size: .85rem;
    text-decoration: none;
    white-space: nowrap;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.status-tab:hover { border-color: var(--accent); color: var(--brand-700); }
.status-tab.active { background: var(--brand-700); border-color: var(--brand-700); color: #fff; }
.status-tab-count {
    background: rgba(0,0,0,.06);
    border-radius: 999px;
    padding: .1rem .5rem;
    font-size: .74rem;
    font-weight: 700;
}
.status-tab.active .status-tab-count { background: rgba(255,255,255,.22); }
/* Tint the icon per status while inactive, so the row reads at a glance
   even before the label is parsed. */
.status-tab-draft i     { color: var(--ink-400); }
.status-tab-confirmed i { color: var(--info); }
.status-tab-completed i { color: var(--success); }
.status-tab-cancelled i { color: var(--danger); }
.status-tab.active i    { color: inherit; }

/* Order cards (mobile list, replacing the table below md breakpoint) */
.order-card { color: inherit; transition: transform .15s ease, box-shadow .15s ease; }
.order-card:hover, .order-card:active { transform: translateY(-1px); box-shadow: var(--shadow); }

/* Tables — kept compact so order/report tables with many rows fit without
   excessive scrolling; row height comes from padding, not font-size, so
   text stays readable while rows take up noticeably less vertical space. */
.table { margin: 0; color: var(--ink-700); font-size: .88rem; }
.table > :not(caption) > * > * { padding: .5rem .75rem; border-bottom-color: var(--line); }
.table thead th {
    background: #FBF8F4;
    color: var(--ink-500);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--line);
    padding-top: .55rem;
    padding-bottom: .55rem;
}
.table-hover > tbody > tr:hover > * { background-color: #FCF9F5; }
.table td { vertical-align: middle; }
/* .table-sm (used throughout order/payment/report line tables) goes even
   tighter — these are working tables the user scans and edits quantities
   in, not prose to read at leisure. */
.table-sm > :not(caption) > * > * { padding: .3rem .5rem; }

/* Forms */
.form-label { font-size: .78rem; font-weight: 600; color: var(--ink-700); margin-bottom: .25rem; }
.form-control, .form-select {
    border-radius: 8px;
    border-color: var(--line);
    padding: .4rem .65rem;
    font-size: .85rem;
    color: var(--ink-900);
}
.form-control-sm, .form-select-sm {
    padding: .25rem .5rem;
    font-size: .82rem;
}
.form-control:focus, .form-select:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 .2rem rgba(217,142,63,.16);
}
.form-text { font-size: .76rem; color: var(--ink-400); }
.form-check-input:checked { background-color: var(--accent); border-color: var(--accent); }

/* Alerts */
.alert { border-radius: var(--r); border: 1px solid transparent; font-size: .89rem; }
.alert-success { background: var(--success-bg); color: var(--success); border-color: rgba(47,122,79,.2); }
.alert-danger  { background: var(--danger-bg);  color: var(--danger);  border-color: rgba(192,57,43,.2); }
.alert-warning { background: var(--warning-bg); color: var(--warning); border-color: rgba(183,121,31,.25); }
.alert-info    { background: var(--info-bg);    color: var(--info);    border-color: rgba(43,108,176,.2); }

/* Empty state */
.empty-state { text-align: center; padding: 3rem 1rem; color: var(--ink-500); }
.empty-state i { font-size: 2.6rem; color: var(--ink-400); display: block; margin-bottom: .75rem; }

/* Product grid */
.product-card { overflow: hidden; height: 100%; transition: transform .15s ease, box-shadow .15s ease; }
.product-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.product-card img { height: 170px; object-fit: cover; width: 100%; }

/* Placeholder shown when a product has no uploaded image. */
.product-thumb {
    position: relative;
    height: 170px;
    display: grid;
    place-items: center;
    background: linear-gradient(140deg, var(--brand-900), var(--brand-700) 60%, var(--brand-600));
    color: rgba(255,255,255,.9);
}
.product-thumb i { font-size: 2.2rem; opacity: .35; }
.product-thumb span {
    position: absolute;
    font-size: 2.4rem;
    font-weight: 800;
    letter-spacing: -.02em;
    color: rgba(255,255,255,.92);
}

/* ------------------------------------------------------- auth screens */

.auth-wrap {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 2rem 1rem;
    background:
        linear-gradient(180deg, rgba(15,9,6,.5), rgba(10,6,4,.68)),
        url('../img/bakery-bg.jpg') center center / cover no-repeat fixed,
        var(--bg);
}
.auth-card { width: 100%; max-width: 420px; }
.auth-card .card {
    border-radius: var(--r-xl);
    box-shadow: 0 25px 60px -15px rgba(0,0,0,.55), var(--shadow-lg);
    border: 1px solid rgba(255,255,255,.08);
}
.auth-brand { text-align: center; margin-bottom: 1.75rem; }
.auth-brand .mark {
    width: 56px; height: 56px;
    border-radius: 16px;
    background: linear-gradient(135deg, var(--brand-700), var(--accent));
    color: #fff;
    display: grid; place-items: center;
    font-size: 1.6rem;
    margin: 0 auto .8rem;
    box-shadow: 0 10px 25px -6px rgba(0,0,0,.6);
}
.auth-brand h1 {
    font-size: 1.5rem;
    margin: 0;
    color: #fff;
    text-shadow: 0 2px 10px rgba(0,0,0,.65), 0 1px 2px rgba(0,0,0,.5);
}
.auth-brand p {
    font-size: .85rem;
    color: rgba(255,255,255,.85);
    margin: .3rem 0 0;
    text-shadow: 0 1px 6px rgba(0,0,0,.6);
}

/* --------------------------------------------- mobile bottom navigation */

/* Fixed thumb bar for the 4 most-used screens + More. Only below lg —
   from lg up the sidebar is permanently visible and this is redundant. */
.bottom-nav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 1030;
    display: flex;
    background: #fff;
    border-top: 1px solid var(--line);
    box-shadow: 0 -4px 18px -6px rgba(45,28,18,.16);
    min-height: var(--bottom-nav-h);
    /* Keeps the bar clear of the iPhone home indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
}
.bottom-nav .bn-item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .15rem;
    padding: .5rem .25rem .55rem;
    border: 0;
    background: transparent;
    color: var(--ink-500);
    font-size: .68rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    /* Full-height targets, comfortably above the 44px minimum. */
    min-height: var(--bottom-nav-h);
    transition: color .15s ease, background-color .15s ease;
}
.bottom-nav .bn-item i { font-size: 1.2rem; }
.bottom-nav .bn-item:active { background: var(--bg); }
.bottom-nav .bn-item.active { color: var(--brand-700); }
.bottom-nav .bn-item.active i { color: var(--accent); }
/* Small bar above the active item, mirroring the sidebar's active marker. */
.bottom-nav .bn-item.active::before {
    content: '';
    position: absolute;
    top: 0;
    width: 28px; height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--accent);
}
.bottom-nav .bn-item { position: relative; }

/* Stop the fixed bar covering the last rows of content / the footer. */
@media (max-width: 991.98px) {
    .app-main { padding-bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px)); }
}

/* ------------------------------------------------------- distribution ---
   Scoped to admin/distribution.php. Office staff work down a list of
   orders fast — every extra pixel of padding between the item table and
   its action row (Save Delivery / rider select / Collect Payment) is a
   pixel where a rushed click lands on the wrong control. Tighter card
   padding and an explicit gap here fixes buttons that were reported as
   visually touching the table above them. */

.dist-page .page-head { margin-bottom: .75rem; }

.dist-order-list { gap: .75rem; }

.dist-order-card .card-body {
    padding: .85rem 1rem;
}

.dist-order-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: .6rem;
    padding-bottom: .6rem;
    border-bottom: 1px solid var(--line);
}

.dist-line-table {
    margin-bottom: .75rem;
}
.dist-line-table .table > :not(caption) > * > * { padding: .35rem .5rem; }
.dist-line-table input.form-control-sm { min-height: 32px; }

/* The row of buttons under the table — explicit top border + padding so it
   never reads as part of the table above it, whatever content wraps. */
.dist-order-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem;
    padding-top: .65rem;
    border-top: 1px dashed var(--line);
}

/* Filter bar: one compact row of controls above the order list, wrapping
   to two rows on narrow screens rather than stacking one-per-line. */
.dist-filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .6rem;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: .75rem .9rem;
    margin: .75rem 0 1rem;
}
.dist-filter-bar .df-field {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    min-width: 9rem;
}
.dist-filter-bar .df-field.df-grow { flex: 1 1 14rem; min-width: 12rem; }
.dist-filter-bar .df-field label {
    font-size: .72rem;
    font-weight: 700;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: .03em;
}
.dist-filter-bar .df-actions {
    display: flex;
    gap: .5rem;
    align-items: center;
}
@media (max-width: 576px) {
    .dist-filter-bar .df-field { min-width: calc(50% - .3rem); flex: 1 1 calc(50% - .3rem); }
    .dist-filter-bar .df-field.df-grow { flex-basis: 100%; }
}

/* ------------------------------------------------------ kitchen flow ---
   Scoped to admin/batches.php and admin/batch_view.php: the screens a
   kitchen worker actually touches while producing. Everywhere else in the
   app stays compact (see .table-sm etc. above — office staff scan a lot of
   rows at once); this scope deliberately goes the other way — big text,
   big tap targets, one clear action at a time, since it's read and filled
   in standing at a counter, often on a phone, mid-task. */

.kitchen-flow { font-size: 1rem; }

.kitchen-flow .page-head h1 { font-size: 1.5rem; }

/* Big centred call-to-action card — used for "confirm you've received
   this batch" and the finished/closed summary, where there's one message
   and (at most) one button, not a form to fill in. */
.kitchen-cta-card {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-sm);
    padding: 1.5rem 1.25rem;
    text-align: center;
}
.kitchen-cta-card i.cta-icon {
    font-size: 2.5rem;
    color: var(--accent-600);
    display: block;
    margin-bottom: .6rem;
}
.kitchen-cta-card h2 { font-size: 1.25rem; margin: 0 0 .35rem; }
.kitchen-cta-card p { color: var(--ink-500); max-width: 32rem; margin: 0 auto 1rem; font-size: .96rem; }

/* Section headers inside the work screen — plainer than .section-head,
   since there's no "view all" link, just a label and maybe a hint. */
.kitchen-section {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    padding: 1rem 1.1rem;
    margin-bottom: 1rem;
}
.kitchen-section h2 {
    font-size: 1.05rem;
    margin: 0 0 .2rem;
    display: flex;
    align-items: center;
    gap: .5rem;
}
.kitchen-section > p.hint { color: var(--ink-500); font-size: .84rem; margin: 0 0 .75rem; }

/* One product/ingredient line — a stacked card row instead of a dense
   table, so labels and inputs never shrink below comfortable tap size. */
.kitchen-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem 1.1rem;
    padding: .65rem 0;
    border-bottom: 1px solid var(--line);
}
.kitchen-line:last-child { border-bottom: 0; padding-bottom: 0; }
.kitchen-line:first-child { padding-top: 0; }
.kitchen-line .li-name { flex: 1 1 220px; min-width: 0; }
.kitchen-line .li-name .nm { font-weight: 700; color: var(--ink-900); font-size: 1.02rem; display: block; }
.kitchen-line .li-name .planned { color: var(--ink-500); font-size: .88rem; }
.kitchen-line .li-fields { display: flex; flex-wrap: wrap; gap: .6rem; }
.kitchen-line .li-field { display: flex; flex-direction: column; gap: .25rem; }
.kitchen-line .li-field label { font-size: .74rem; font-weight: 700; color: var(--ink-500); text-transform: uppercase; letter-spacing: .04em; }
.kitchen-line .li-field input {
    width: 108px;
    min-height: 46px;
    font-size: 1.05rem;
    text-align: center;
    border-radius: 10px;
    border: 1px solid var(--line);
    padding: .4rem .5rem;
}
.kitchen-line .li-field input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 .2rem rgba(217,142,63,.16);
    outline: none;
}
@media (max-width: 480px) {
    .kitchen-line .li-field input { width: 88px; }
}

/* Compact table layout for product/output rows — used where a batch has
   several lines and scanning down columns (Planned/Actual/Good/Rejected)
   beats a stacked card per line. Denser than .kitchen-line but still
   generously sized inputs, since it's used on the same screens. */
.kitchen-table-wrap {
    overflow-x: auto;
    margin: 0 -1.1rem;
    padding: 0 1.1rem;
}
table.kitchen-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .95rem;
}
table.kitchen-table th {
    text-align: left;
    font-size: .72rem;
    font-weight: 700;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: 0 .6rem .5rem;
    white-space: nowrap;
}
table.kitchen-table th.num, table.kitchen-table td.num { text-align: center; }
table.kitchen-table td {
    padding: .55rem .6rem;
    border-top: 1px solid var(--line);
    vertical-align: middle;
}
table.kitchen-table tbody tr:hover { background: var(--bg-soft, #f8f7f5); }
table.kitchen-table td.name-cell .nm { font-weight: 700; color: var(--ink-900); display: block; line-height: 1.2; }
table.kitchen-table td.name-cell .sub { color: var(--ink-500); font-size: .8rem; }
table.kitchen-table td .stat {
    display: inline-flex;
    min-width: 3.2rem;
    justify-content: center;
    font-weight: 700;
}
table.kitchen-table td .stat.stat-good { color: var(--success); }
table.kitchen-table td .stat.stat-reject { color: var(--danger); }
table.kitchen-table input[type="number"] {
    width: 100%;
    min-width: 78px;
    max-width: 108px;
    min-height: 42px;
    font-size: 1rem;
    text-align: center;
    border-radius: 10px;
    border: 1px solid var(--line);
    padding: .35rem .4rem;
    margin: 0 auto;
    display: block;
}
table.kitchen-table input[type="number"]:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 .2rem rgba(217,142,63,.16);
    outline: none;
}
table.kitchen-table tfoot td {
    border-top: 2px solid var(--line);
    font-weight: 700;
    padding-top: .6rem;
}
@media (max-width: 576px) {
    table.kitchen-table { font-size: .88rem; }
    table.kitchen-table input[type="number"] { min-width: 62px; }
}

/* Per-product recipe card — one small self-contained block per product
   inside a grid, since a batch with several products needs its recipes
   visually separated rather than one long undifferentiated table. */
.recipe-card {
    border: 1px solid var(--line);
    border-radius: var(--r-md, 10px);
    padding: .75rem .9rem;
    height: 100%;
}
.recipe-card-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
    margin-bottom: .4rem;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--line);
}
.recipe-card-head .nm { font-weight: 700; color: var(--ink-900); }
.recipe-card table.kitchen-table td { padding: .4rem .1rem; }
.recipe-card table.kitchen-table tr:first-child td { border-top: 0; }

/* Simple button-style tabs for switching between a few independent forms
   on one page (Release / Wastage / Expenses) — plain links so each tab
   is its own page load, no JS tab-panel state to manage. */
.kitchen-tabs {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}
.kitchen-tab {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .6rem 1.1rem;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: #fff;
    color: var(--ink-700, var(--ink-900));
    font-weight: 700;
    font-size: .95rem;
    text-decoration: none;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.kitchen-tab:hover { border-color: var(--accent); color: var(--accent-600); text-decoration: none; }
.kitchen-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* NOTE: a previous version of this file had a `.kitchen-form-grid` custom
   CSS-grid wrapper here, used to lay out the release/wastage/expense forms
   on admin/releases.php. It was removed after it caused native <select>
   dropdown popups to render in the wrong place in some browsers. Those
   forms now use plain Bootstrap `.row`/`.col-*`, same as orders.php and
   payments.php — don't reintroduce a custom grid/flex wrapper around a
   <select> element. */

/* Full-width, extra-large primary action — the single next step, never
   competing with a row of smaller buttons. */
.btn-kitchen-primary {
    display: block;
    width: 100%;
    padding: 1rem 1.5rem;
    font-size: 1.1rem;
    font-weight: 700;
    border-radius: 14px;
    background: var(--accent);
    border: 1px solid var(--accent);
    color: #fff;
    text-align: center;
}
.btn-kitchen-primary:hover, .btn-kitchen-primary:focus { background: var(--accent-600); border-color: var(--accent-600); color: #fff; }
.btn-kitchen-primary i { margin-right: .5rem; }

/* Kitchen batch list — bigger, friendlier cards than the generic .card
   grid used elsewhere, with a status-coloured left edge so the day's
   batches read at a glance without parsing badge text first. */
.kitchen-batch-card {
    display: block;
    background: #fff;
    border: 1px solid var(--line);
    border-left: 5px solid var(--ink-400);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    padding: 1.1rem 1.25rem;
    transition: transform .15s ease, box-shadow .15s ease;
    color: inherit;
}
.kitchen-batch-card:hover, .kitchen-batch-card:active { transform: translateY(-2px); box-shadow: var(--shadow); color: inherit; }
.kitchen-batch-card.bs-planned          { border-left-color: var(--ink-400); }
.kitchen-batch-card.bs-materials_issued,
.kitchen-batch-card.bs-in_progress      { border-left-color: var(--info); }
.kitchen-batch-card.bs-completed        { border-left-color: var(--warning); }
.kitchen-batch-card.bs-qc_passed        { border-left-color: var(--success); }
.kitchen-batch-card.bs-closed           { border-left-color: var(--ink-700); }
.kitchen-batch-card.bs-cancelled        { border-left-color: var(--danger); }
/* Purchase-order statuses (admin/purchases.php) share this same card —
   'received'/'cancelled' reuse the production-batch color meanings above
   (success/danger) since they mean the same thing here (done / voided). */
.kitchen-batch-card.bs-draft              { border-left-color: var(--ink-400); }
.kitchen-batch-card.bs-sent               { border-left-color: var(--info); }
.kitchen-batch-card.bs-partially_received { border-left-color: var(--warning); }
.kitchen-batch-card.bs-received           { border-left-color: var(--success); }
.kitchen-batch-card .kb-no { font-size: 1.1rem; font-weight: 800; color: var(--brand-700); }
.kitchen-batch-card .kb-meta { color: var(--ink-500); font-size: .88rem; margin-top: .15rem; }
.kitchen-batch-card .kb-cta { font-weight: 700; color: var(--accent-600); font-size: .9rem; margin-top: .6rem; display: flex; align-items: center; gap: .4rem; }

.kitchen-group-title {
    font-size: .82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--ink-500);
    margin: 1.5rem 0 .75rem;
}
.kitchen-group-title:first-child { margin-top: 0; }

/* ------------------------------------------------------------- printing */

/* Everything chrome-like disappears; the report itself goes full width on
   white. .print-only blocks (letterhead, signature line) are hidden on
   screen and revealed here — see includes/report.php. */
.print-only { display: none; }

@media print {
    @page { size: A4; margin: 14mm 12mm; }

    body { background: #fff !important; font-size: 11pt; }

    .app-sidebar, .topbar, .bottom-nav, .page-foot,
    .no-print, .btn, .nav-pills, .alert-dismissible .btn-close,
    .offcanvas-backdrop, .modal, .modal-backdrop { display: none !important; }

    .app-shell { display: block !important; }
    .app-main  { margin: 0 !important; padding: 0 !important; }
    .page      { padding: 0 !important; }

    .print-only { display: block !important; }

    /* Cards become plain sections — borders and shadows waste toner and
       fragment tables across page breaks. */
    .card {
        border: 0 !important;
        box-shadow: none !important;
        break-inside: auto;
    }
    .card-body { padding: 0 !important; }
    .table-responsive { overflow: visible !important; }

    table { width: 100% !important; border-collapse: collapse !important; }
    thead { display: table-header-group; }  /* repeat headers on every page */
    tr, img { break-inside: avoid; }
    .table > :not(caption) > * > * { padding: .35rem .4rem !important; }
    .table th {
        background: #f2ede7 !important;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
        border-bottom: 1.5px solid #8a6a4f !important;
    }
    .table td { border-bottom: 1px solid #ddd !important; }

    /* Badges print as plain text — coloured pills are unreadable in mono. */
    .badge {
        background: transparent !important;
        color: #000 !important;
        border: 1px solid #999;
        font-weight: 600;
    }

    a[href]::after { content: ''; }  /* don't append raw URLs */

    .report-letterhead {
        display: flex !important;
        justify-content: space-between;
        align-items: flex-start;
        border-bottom: 2.5px solid #6B3E26;
        padding-bottom: 8pt;
        margin-bottom: 12pt;
    }
    .report-letterhead .biz-name { font-size: 17pt; font-weight: 800; color: #6B3E26; margin: 0; }
    .report-letterhead .biz-meta { font-size: 8.5pt; color: #555; margin: 2pt 0 0; line-height: 1.45; }
    .report-letterhead .doc-title { font-size: 12.5pt; font-weight: 700; text-align: right; margin: 0; }
    .report-letterhead .doc-meta  { font-size: 8.5pt; color: #555; text-align: right; margin: 2pt 0 0; }

    .report-signature {
        display: flex !important;
        justify-content: space-between;
        gap: 30pt;
        margin-top: 26pt;
        break-inside: avoid;
    }
    .report-signature div { flex: 1; border-top: 1px solid #333; padding-top: 4pt; font-size: 9pt; }

    .report-foot {
        display: block !important;
        margin-top: 14pt;
        padding-top: 5pt;
        border-top: 1px solid #ccc;
        font-size: 8pt;
        color: #666;
        text-align: center;
    }
}

/*
 * Root cause of the "dropdowns opening in the wrong place" bug reported
 * across orders.php, releases.php, distribution.php etc: EVERY create/edit
 * form here is a Bootstrap modal (see includes/modal.php), and Bootstrap's
 * own .modal.fade .modal-dialog rule applies `transform: translate(0,-50px)`
 * while the modal opens/closes. A `transform` on any ancestor creates a new
 * containing block for that subtree, and on many Chromium/WebKit builds it
 * also throws off the browser's anchor calculation for NATIVE <select>
 * popups (this app uses plain HTML <select> everywhere — no select2/
 * choices.js/etc). That's why the popup panel renders far from the actual
 * dropdown: the browser is anchoring to the dialog's pre-transform position.
 *
 * Fix: neutralize the transform so the dialog only fades (opacity), never
 * translates. Do NOT reintroduce a transform/translate on .modal-dialog.
 */
.modal.fade .modal-dialog {
    transform: none !important;
    transition: opacity .15s linear !important;
}

/*
 * Tom Select theming — brought in to replace both the native <select>
 * (whose popup mis-positions inside a transformed/animated Bootstrap
 * modal) and an earlier hand-rolled custom dropdown that had its own
 * positioning bugs. Tom Select is a well-tested third-party library
 * (self-hosted under assets/vendor/tom-select/, no CDN dependency) that
 * handles anchoring, search, keyboard nav and dynamic option lists
 * itself — see assets/js/select-init.js for the wire-up. These rules
 * only adjust sizing/spacing to match this app's form controls; do not
 * fight Tom Select's own positioning logic with custom transforms here.
 */
/* Tom Select's wrapper is display:flex by default, which — unlike the
   block-level native <select> it replaces — will shrink to its content's
   width inside a flexible container like a <table> cell instead of
   filling it. Force full width explicitly so it always matches the space
   the original <select> occupied (this was the cause of the dropdown
   rendering as a narrow, clipped strip instead of spanning its column). */
.ts-wrapper { width: 100%; }
.ts-wrapper.form-select { padding: 0; border: 0; background: transparent; }
.ts-wrapper .ts-control {
    width: 100%;
    box-sizing: border-box;
    min-height: calc(1.5em + .8rem + 2px);
    border-radius: 8px;
    border-color: var(--line);
    padding: .4rem .65rem;
    font-size: .85rem;
    color: var(--ink-900);
}
.ts-wrapper.form-select-sm .ts-control,
.form-select-sm .ts-control {
    min-height: calc(1.5em + .5rem + 2px);
    padding: .25rem .5rem;
    font-size: .82rem;
}
.ts-wrapper.single .ts-control { background: #fff; }
.ts-wrapper.focus .ts-control {
    border-color: var(--accent);
    box-shadow: 0 0 0 .2rem rgba(217,142,63,.16);
}
.ts-dropdown {
    border-color: var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    font-size: .85rem;
    z-index: 3000; /* above Bootstrap's modal (1055) and backdrop */
}
.ts-dropdown .ts-dropdown-content { padding: .25rem; }
.ts-dropdown .option { padding: .4rem .65rem; border-radius: 8px; }
.ts-dropdown .active { background: rgba(217,142,63,.12); color: var(--ink-900); }
.ts-dropdown .option:hover { background: var(--brand-50, #FAF3EC); }

/* Assign Riders dispatch board (admin/assign_riders.php) */
.dispatch-col { display: flex; flex-direction: column; gap: .6rem; max-height: 70vh; overflow-y: auto; }
.dispatch-card {
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: .65rem .75rem;
    background: #fff;
}

/* --------------------------------------------------- order status cards ---
   Solid, full-colour cards used for orders on both the customer ("My
   Orders") and admin (Orders) pages on mobile. Each order's status picks
   the card's entire background (not just an accent bar) so a long list
   reads as a strip of colour a customer/staff member can scan without
   opening anything — mirrors the bold colour-block card style used
   elsewhere for at-a-glance status. Payment status (paid/unpaid/partial/
   overpaid) is shown as its own pill since it's a second, independent
   axis from the order's workflow status. */

.order-card-list {
    display: flex;
    flex-direction: column;
    gap: .75rem;
}

.order-card {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    border-radius: var(--r);
    padding: 1rem 1.1rem;
    box-shadow: var(--shadow);
    cursor: pointer;
    transition: box-shadow .15s ease, transform .1s ease;
    color: #fff;
}
.order-card:active { transform: scale(.99); }

.order-card .oc-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .4rem;
}
.order-card .oc-id {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-width: 0;
}
.order-card .oc-id i { font-size: 1.05rem; flex: 0 0 auto; opacity: .9; }
.order-card .oc-no {
    font-weight: 800;
    font-size: 1.05rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #fff;
}
.order-card .oc-status {
    flex: 0 0 auto;
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .3rem .65rem;
    border-radius: 999px;
    white-space: nowrap;
    background: rgba(255,255,255,.22);
    color: #fff;
}

.order-card .oc-items {
    font-size: .87rem;
    color: rgba(255,255,255,.85);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: .55rem;
}

.order-card .oc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1rem;
    font-size: .74rem;
    color: rgba(255,255,255,.75);
    margin-bottom: .7rem;
}
.order-card .oc-meta i { margin-right: .25rem; }

/* Glance-level "what's in this order" line — Vanilla Cake ×2, White Bread
   ×5, +1 more — shown before expanding the card, same muted treatment as
   .oc-meta but its own line since item text can run long. */
.order-card .oc-items-preview {
    font-size: .74rem;
    color: rgba(255,255,255,.75);
    margin-bottom: .7rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.order-card .oc-items-preview i { margin-right: .3rem; }

.order-card .oc-bottom {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: .5rem;
    padding-top: .65rem;
    border-top: 1px solid rgba(255,255,255,.22);
}

.order-card .oc-amounts {
    display: flex;
    gap: 1.4rem;
}
.order-card .oc-label {
    display: block;
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: rgba(255,255,255,.7);
    font-weight: 700;
    margin-bottom: .1rem;
}
.order-card .oc-value {
    display: block;
    font-size: 1.05rem;
    font-weight: 800;
    color: #fff;
}
.order-card .oc-value--due { color: #FFE29A; }

/* Payment-status pill — its own small colour language layered on top of
   the card's status colour, so "who owes what" reads at a glance even
   though it isn't the card's main colour. Solid, high-contrast fills
   rather than the card's translucent-white pills, since this one carries
   its own meaning independent of the status colour underneath it. */
.order-card .oc-pay {
    flex: 0 0 auto;
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .3rem .65rem;
    border-radius: 999px;
    white-space: nowrap;
    color: #fff;
}
.order-card .oc-pay--unpaid    { background: #7A1F17; }
.order-card .oc-pay--partial   { background: #7A5710; }
.order-card .oc-pay--paid      { background: #1E5C38; }
.order-card .oc-pay--overpaid  { background: #1D4E80; }
.order-card .oc-pay--refunded  { background: rgba(255,255,255,.22); }

.order-card .oc-view {
    display: flex;
    justify-content: flex-end;
    font-size: .78rem;
    font-weight: 700;
    color: rgba(255,255,255,.9);
    align-items: center;
    gap: .2rem;
    white-space: nowrap;
    margin-top: .5rem;
}

/* Status colours — solid full-card backgrounds, one per order status.
   Customer-facing statuses (sent/confirmed/completed/cancelled). */
.order-card--sent      { background: #5B5147; }
.order-card--confirmed { background: #1D4E80; }
.order-card--completed { background: #1E5C38; }
.order-card--cancelled { background: #7A1F17; }
.order-card--cancelled .oc-value { text-decoration: line-through; opacity: .8; }

/* Admin order cards reuse the same status backgrounds but put the
   customer's name in the position the order number takes on the
   customer's own page — staff scan by "whose order is this" first, the
   order number second. */
.order-card .oc-customer {
    font-weight: 800;
    font-size: 1.08rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #fff;
}
.order-card .oc-subno {
    font-size: .74rem;
    color: rgba(255,255,255,.75);
    font-weight: 600;
}

/* Admin order card's inline call-to-action row (Release / Deliver) —
   styled as a pill button sitting on the card's own solid colour rather
   than a standalone Bootstrap button, so it reads as part of the card. */
.order-card .oc-action {
    margin-top: .7rem;
    padding-top: .7rem;
    border-top: 1px solid rgba(255,255,255,.22);
}
.order-card .oc-action-btn {
    display: block;
    text-align: center;
    width: 100%;
    padding: .5rem .75rem;
    border-radius: var(--r-sm);
    background: rgba(255,255,255,.16);
    color: #fff;
    font-weight: 700;
    font-size: .85rem;
}

/* ----------------------------------------- admin order card, rebuilt ---
   Customer name + phone lead, a row of quick-action buttons sits under
   the summary, and the expandable panel flips to a light inset card so a
   product table and figures stay easy to read against the card's bold
   solid status colour. */

.order-card .oc-header {
    cursor: pointer;
    border-radius: var(--r-sm);
    margin: -.25rem -.35rem 0;
    padding: .25rem .35rem 0;
    transition: background .12s ease;
}
.order-card .oc-header:hover,
.order-card .oc-header:focus-visible {
    background: rgba(255,255,255,.08);
    outline: none;
}
.order-card .oc-header:active { transform: scale(.995); }

.order-card .oc-phone {
    font-size: .78rem;
    font-weight: 600;
    color: rgba(255,255,255,.82);
    margin-top: .1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.order-card .oc-phone i { margin-right: .3rem; font-size: .72rem; }

.order-card .oc-header-right {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: 0 0 auto;
}
.order-card .oc-chevron {
    font-size: .85rem;
    color: rgba(255,255,255,.75);
    transition: transform .2s ease;
}
.order-card .oc-header[aria-expanded="true"] .oc-chevron,
.order-card .oc-header:not(.collapsed) .oc-chevron { transform: rotate(180deg); }

/* Select-for-production/sales checkbox — only rendered on confirmed
   orders, sits above the (separately clickable) collapse header so
   ticking it never toggles the card open/closed. */
.order-card .oc-select {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin-bottom: .6rem;
    cursor: pointer;
}
.order-card .oc-select input[type="checkbox"] {
    width: 1.1rem;
    height: 1.1rem;
    cursor: pointer;
}
.order-card .oc-select span { color: rgba(255,255,255,.8); }

/* Quick actions: History / Order / Allocate / Release — a row of small
   pill buttons directly on the card's own colour, so common next-steps
   never require opening the order first. */
.order-card .oc-quick-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: .75rem;
    padding-top: .7rem;
    border-top: 1px solid rgba(255,255,255,.22);
}
.order-card .oc-qa-btn {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .4rem .7rem;
    border-radius: 999px;
    background: rgba(255,255,255,.16);
    color: #fff;
    font-weight: 700;
    font-size: .76rem;
    white-space: nowrap;
    border: 0;
    line-height: 1.1;
}
.order-card .oc-qa-btn:hover,
.order-card .oc-qa-btn:focus-visible { background: rgba(255,255,255,.28); color: #fff; }
.order-card .oc-qa-btn--brand {
    background: var(--accent);
}
.order-card .oc-qa-btn--brand:hover { background: var(--accent-600); }

/* The expandable panel: a light inset card, not the dark status colour,
   so a product table and numbers stay legible without inventing a whole
   second white-on-colour text system. */
.order-card .oc-collapse { margin-top: .7rem; }
.order-card .oc-details {
    background: #fff;
    color: var(--ink-900);
    border-radius: var(--r-sm);
    padding: .85rem .9rem;
}
.order-card .oc-details-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .82rem;
    margin-bottom: .7rem;
}
.order-card .oc-details-table th {
    text-align: left;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--ink-500);
    font-weight: 700;
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--line);
}
.order-card .oc-details-table td {
    padding: .4rem 0;
    border-bottom: 1px solid var(--line);
    color: var(--ink-900);
}
.order-card .oc-details-table tr:last-child td { border-bottom: 0; }

.order-card .oc-details-totals {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem 1rem;
    font-size: .8rem;
    color: var(--ink-700);
    padding-top: .6rem;
    border-top: 1px dashed var(--line);
    margin-bottom: .6rem;
}
.order-card .oc-details-totals strong { color: var(--ink-900); margin-left: .25rem; }

.order-card .oc-details-meta {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem 1rem;
    font-size: .78rem;
    color: var(--ink-500);
    margin-bottom: .5rem;
}
.order-card .oc-details-meta i { margin-right: .3rem; }

.order-card .oc-recent-changes {
    padding-top: .6rem;
    border-top: 1px dashed var(--line);
}
.order-card .oc-rc-title {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    font-weight: 700;
    color: var(--ink-500);
    margin-bottom: .35rem;
}
.order-card .oc-rc-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
    font-size: .78rem;
    color: var(--ink-700);
    padding: .3rem 0;
    border-bottom: 1px solid var(--line);
}
.order-card .oc-rc-item:last-child { border-bottom: 0; }
.order-card .oc-rc-time {
    flex: 0 0 auto;
    color: var(--ink-500);
    font-size: .72rem;
    white-space: nowrap;
}

/* Edit-history modal list (History quick action) — plain light modal
   content, no card-colour styling needed since it's outside the card. */
.oc-history-list li { color: var(--ink-900); }

/* --------------------------------------------------- customer dashboard ---
   Money-summary stat cards and the "what you've received" delivered-by-
   item breakdown on customer/dashboard.php. */

/* A stat card that's carrying a balance owed gets a subtle red wash so it
   reads as "needs attention" without shouting as loud as a full-red card
   would in a row of otherwise neutral stat tiles. */
.stat-card.stat-card--warn {
    background: var(--danger-bg);
    border: 1px solid rgba(192,57,43,.18);
}
.stat-card.stat-card--warn .lbl { color: var(--danger); }

.delivered-list {
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: .85rem;
}
.delivered-row .dr-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
    margin-bottom: .3rem;
}
.delivered-row .dr-name {
    font-weight: 700;
    color: var(--ink-900);
    font-size: .92rem;
}
.delivered-row .dr-qty {
    font-weight: 800;
    color: var(--brand-700);
    font-size: .92rem;
    white-space: nowrap;
}
.delivered-row .dr-bar {
    height: 8px;
    border-radius: 999px;
    background: var(--bg);
    overflow: hidden;
}
.delivered-row .dr-bar-fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent), var(--brand-700));
}

/* Full item list + qty total inside the customer order card (replaces the
   earlier truncated one-line item summary) — sits on the card's solid
   status-colour background, so it uses translucent-white text/dividers
   like the rest of the card rather than the app's normal ink colours. */
.order-card .oc-item-list {
    margin-bottom: .4rem;
}
.order-card .oc-item-row {
    display: flex;
    justify-content: space-between;
    gap: .5rem;
    padding: .18rem 0;
    font-size: .85rem;
    color: rgba(255,255,255,.92);
    border-bottom: 1px dashed rgba(255,255,255,.14);
}
.order-card .oc-item-row:last-child { border-bottom: 0; }
.order-card .oc-item-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.order-card .oc-item-qty {
    flex: 0 0 auto;
    font-weight: 700;
    color: #fff;
}
.order-card .oc-qty-total {
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: rgba(255,255,255,.7);
    margin-bottom: .65rem;
}

/* Two-tone price panel — the whole point of this request: paid portion in
   yellow/amber, balance owed in red, side by side and sized by their
   share of the order total, so "how much of this is still owed" reads
   as a proportion at a glance, not just two numbers. Fully-settled
   orders (paid/overpaid/refunded) get a single green panel instead. */
.order-card .oc-price-split {
    display: flex;
    border-radius: var(--r-sm);
    overflow: hidden;
    margin: .55rem 0;
}
.order-card .oc-price-half {
    padding: .55rem .7rem;
    min-width: 0;
}
.order-card .oc-price-half .oc-label {
    display: block;
    font-size: .64rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    font-weight: 800;
    margin-bottom: .15rem;
    opacity: .85;
}
.order-card .oc-price-half .oc-value {
    display: block;
    font-size: .95rem;
    font-weight: 800;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.order-card .oc-price-half--paid  { background: #7A5710; color: #fff; }
.order-card .oc-price-half--due   { background: #7A1F17; color: #fff; }
.order-card .oc-price-half--settled { background: #1E5C38; color: #fff; }

/* ===================================================================
   Item cards (admin/items.php) — one card per raw material / product,
   a stock number front and center, and a colour cue (ok/warning/danger)
   so what needs attention is visible without reading every card.
   =================================================================== */
.item-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 1rem;
}
.item-card {
    background: #fff;
    border: 1px solid var(--line);
    border-left: 5px solid var(--line);
    border-radius: var(--r);
    padding: 1rem 1.1rem;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: .6rem;
    transition: box-shadow .15s ease, transform .1s ease;
}
.item-card:hover { box-shadow: var(--shadow); transform: translateY(-1px); }

.item-card-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: .5rem;
}
.item-card-name { font-weight: 700; color: var(--ink-900); font-size: 1rem; line-height: 1.25; }
.item-card-sku { font-size: .72rem; color: var(--ink-400); }

.item-card-badge {
    flex: 0 0 auto;
    font-size: .66rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: .3rem .55rem;
    border-radius: 999px;
    white-space: nowrap;
}

.item-card-stock {
    display: flex;
    align-items: baseline;
    gap: .35rem;
}
.item-card-stock-qty { font-size: 1.9rem; font-weight: 800; color: var(--ink-900); line-height: 1; }
.item-card-stock-unit { font-size: .85rem; color: var(--ink-500); font-weight: 600; }

.item-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1rem;
    font-size: .78rem;
    color: var(--ink-500);
}

.item-card-actions {
    display: flex;
    gap: .5rem;
    margin-top: .2rem;
    padding-top: .6rem;
    border-top: 1px solid var(--line);
}

/* Status variants — border colour + badge colour carry the signal, card
   body stays white/legible either way rather than tinting the whole card,
   which would make the stock number harder to read at a glance. */
.item-card--ok { border-left-color: var(--success); }
.item-card--ok .item-card-badge { background: var(--success-bg); color: var(--success); }

.item-card--warning { border-left-color: var(--warning); background: var(--warning-bg); }
.item-card--warning .item-card-badge { background: #fff; color: var(--warning); }

.item-card--danger { border-left-color: var(--danger); background: var(--danger-bg); }
.item-card--danger .item-card-badge { background: #fff; color: var(--danger); }
.item-card--danger .item-card-stock-qty { color: var(--danger); }

/* ===================================================================
   Ledger cards (admin/inventory.php "Recent movements", storekeeper's
   itemized view of every stock-in/stock-out) — one card per transaction,
   replacing the old ledger table. Kept compact/dense since there can be
   many rows: a left accent stripe (green=in, red=out) is the fastest cue.
   =================================================================== */
.ledger-card {
    background: #fff;
    border: 1px solid var(--line);
    border-left: 4px solid var(--line);
    border-radius: var(--r);
    padding: .65rem .9rem;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .3rem 1rem;
    margin-bottom: .5rem;
}
.ledger-card--in  { border-left-color: var(--success); }
.ledger-card--out { border-left-color: var(--danger); }

.ledger-card-main { display: flex; flex-direction: column; gap: .1rem; }
.ledger-card-item { font-weight: 700; color: var(--ink-900); font-size: .92rem; }
.ledger-card-type { font-size: .72rem; color: var(--ink-500); }

.ledger-card-qty { font-weight: 800; font-size: 1rem; white-space: nowrap; }

.ledger-card-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .1rem;
    font-size: .72rem;
    color: var(--ink-400);
    text-align: right;
    margin-left: auto;
}

/* =====================================================================
   WORKER CARDS (admin/workers.php)
   One card per person instead of a roster table row: a worker's identity,
   rate, attendance, pay state and pay action all live in their own box,
   which expands in place to reveal their details and history. The grid is
   intrinsic (auto-fill/minmax), so it goes from three columns on a desk
   monitor to one on a phone with no breakpoints of its own.
   ===================================================================== */

.worker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 1rem;
    align-items: start;
}
@media (max-width: 400px) {
    .worker-grid { grid-template-columns: 1fr; }
}

.worker-card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: box-shadow .16s ease, border-color .16s ease;
}
.worker-card:hover { box-shadow: var(--shadow); }
/* An expanded card is the one being worked on — lift it out of the grid
   visually so it reads as a panel, not just a taller tile. */
.worker-card--open { box-shadow: var(--shadow-lg); border-color: var(--accent); }
.worker-card--inactive { background: #FBF8F4; }
.worker-card--inactive .wc-name { color: var(--ink-500); }

.wc-head {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .95rem 1rem .6rem;
}
.wc-avatar {
    flex: 0 0 auto;
    width: 44px; height: 44px;
    border-radius: 13px;
    display: grid; place-items: center;
    font-weight: 800; font-size: .95rem;
    letter-spacing: .02em;
}
.wc-avatar--day   { background: var(--accent-100); color: var(--gold-700); }
.wc-avatar--night { background: #E8E3DD;           color: var(--brand-800); }
.wc-ident { min-width: 0; flex: 1 1 auto; }
.wc-name {
    font-size: 1.02rem; font-weight: 800; line-height: 1.25;
    color: var(--brand-700); margin: 0;
    overflow-wrap: break-word;
}
.wc-sub { font-size: .78rem; color: var(--ink-500); margin-top: .1rem; }
.wc-sub code { font-size: .74rem; color: var(--ink-500); background: transparent; padding: 0; }
.wc-badges { display: flex; flex-direction: column; align-items: flex-end; gap: .25rem; flex: 0 0 auto; }
.wc-badges .badge { font-size: .66rem; font-weight: 700; }

/* Four facts, always in the same four places, so a wall of cards can be
   scanned down a column instead of read one card at a time. */
.wc-facts {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: .4rem;
    padding: .2rem 1rem .8rem;
}
.wc-facts > div { display: flex; flex-direction: column; min-width: 0; }
.wc-lbl {
    font-size: .63rem; text-transform: uppercase; letter-spacing: .05em;
    color: var(--ink-400); font-weight: 700;
}
.wc-val { font-size: .92rem; font-weight: 700; color: var(--ink-900); overflow-wrap: break-word; }
.wc-val small { font-size: .68rem; font-weight: 500; color: var(--ink-400); }
.wc-val--sm { font-size: .78rem; font-weight: 600; }

/* The pay strip carries its own colour because it is the answer to the
   only urgent question on the card: can this person be paid right now? */
.wc-strip {
    display: flex; align-items: flex-start; gap: .45rem;
    padding: .55rem 1rem;
    font-size: .8rem; line-height: 1.35;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}
.wc-strip i { flex: 0 0 auto; margin-top: .1rem; }
.wc-strip a { font-weight: 700; }
.wc-strip--payable     { background: var(--warning-bg); color: #7A5410; }
.wc-strip--settled     { background: var(--success-bg); color: #1E5C3A; }
.wc-strip--draft       { background: var(--info-bg);    color: #1E4E80; }
.wc-strip--closed      { background: #EFEAE4;           color: var(--ink-700); }
.wc-strip--nothing_due,
.wc-strip--inactive    { background: #F6F2ED;           color: var(--ink-500); }

.wc-actions {
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    padding: .6rem 1rem;
}
.wc-actions .btn { font-size: .78rem; }

/* --- expanded half ------------------------------------------------- */

.wc-collapse-inner {
    border-top: 1px dashed var(--line);
    background: #FDFBF9;
    padding: .25rem 1rem .9rem;
}
.wc-sec { padding: .8rem 0; border-bottom: 1px solid var(--line); }
.wc-sec:last-child { border-bottom: 0; padding-bottom: .2rem; }
.wc-sec-title {
    font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
    color: var(--gold-700); font-weight: 800; margin: 0 0 .5rem;
}

/* Label/value pairs in two columns, wrapping to one on a narrow card. */
.wc-dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .25rem .75rem;
    margin: 0; font-size: .82rem;
}
.wc-dl dt { font-weight: 600; color: var(--ink-500); }
.wc-dl dd { margin: 0; color: var(--ink-900); overflow-wrap: anywhere; }

.wc-note {
    margin: .6rem 0 0; padding: .45rem .6rem;
    background: var(--accent-100); border-radius: var(--r-sm);
    font-size: .8rem; color: var(--brand-800);
}
.wc-absences { list-style: none; margin: 0 0 .4rem; padding: 0; font-size: .8rem; }
.wc-absences li { padding: .12rem 0; }
.wc-pay-table { font-size: .78rem; }
.wc-pay-table th { font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-400); }
.wc-pay-table .badge { font-size: .62rem; }

.wc-sec--pay { background: transparent; }
.wc-pay-form { display: flex; align-items: flex-end; gap: .5rem; flex-wrap: wrap; }
.wc-pay-form > div { flex: 1 1 110px; min-width: 110px; }
.wc-pay-form .form-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-400); margin-bottom: .15rem; }

/* --- filter bar ---------------------------------------------------- */

.worker-filter-bar {
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
}
.wf-search { position: relative; flex: 1 1 260px; min-width: 200px; }
.wf-search i {
    position: absolute; left: .7rem; top: 50%; transform: translateY(-50%);
    color: var(--ink-400); pointer-events: none; font-size: .9rem;
}
.wf-search input { padding-left: 2.1rem; }
.wf-chips .btn { white-space: nowrap; }

/* --- period closing panel ------------------------------------------ */

.period-close-card .pc-title {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 800; color: var(--gold-700);
}
.pc-chip {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .76rem; padding: .25rem .6rem;
    border-radius: 999px; border: 1px solid var(--line);
}
.pc-chip strong { font-weight: 800; text-transform: uppercase; font-size: .66rem; letter-spacing: .04em; }
.pc-chip--open   { background: #fff;              color: var(--ink-700); }
.pc-chip--open strong   { color: var(--warning); }
.pc-chip--closed { background: var(--success-bg); color: #1E5C3A; border-color: #CBE6D7; }
.pc-chip--closed strong { color: var(--success); }
.closed-period-list li { padding: .25rem 0; border-top: 1px solid var(--line); }
.closed-period-list li:first-child { border-top: 0; }

.worker-fieldset {
    border: 1px solid var(--line); border-radius: var(--r);
    padding: .5rem .85rem .85rem;
}
.worker-fieldset legend {
    float: none; width: auto; padding: 0 .35rem; margin: 0;
    font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 800; color: var(--gold-700);
}

/* A closed day on the attendance sheet: locked, not merely uninteresting,
   so it gets a filled column rather than a greyed checkbox alone. */
.att-day-closed { background: #F1ECE6; }

/* =====================================================================
   RESTOCK PREVIEW + ITEM MOVEMENT (admin/items.php, admin/item_movement.php)
   ===================================================================== */

/* "In stock now -> after adding", live as the quantity is typed. The
   arrow makes it read as a transition rather than two unrelated figures. */
.restock-preview {
    display: flex; align-items: center; gap: .75rem;
    padding: .7rem .9rem;
    background: var(--accent-100);
    border-radius: var(--r);
}
.restock-preview .rp-cell { display: flex; flex-direction: column; min-width: 0; }
.restock-preview .rp-lbl {
    font-size: .63rem; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 700; color: var(--gold-700);
}
.restock-preview .rp-val { font-size: 1.1rem; font-weight: 800; color: var(--brand-700); }
.restock-preview .rp-val--changed { color: var(--success); }
.restock-preview .rp-arrow { color: var(--ink-400); }
.restock-preview .rp-cell--after { margin-left: auto; text-align: right; }

.movement-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: .75rem;
}
.ms-tile {
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--r); padding: .8rem 1rem;
    display: flex; flex-direction: column;
}
.ms-lbl {
    font-size: .63rem; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 700; color: var(--ink-400);
}
.ms-val { font-size: 1.3rem; font-weight: 800; color: var(--brand-700); }
.ms-val small { font-size: .7rem; font-weight: 500; color: var(--ink-400); }

/* Each movement type is also a filter — clicking "Used in production"
   narrows the table below to exactly those rows. */
.movement-breakdown { display: flex; flex-wrap: wrap; gap: .5rem; }
.mb-chip {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .35rem .7rem; border-radius: 999px;
    border: 1px solid var(--line); background: #fff;
    font-size: .78rem; color: var(--ink-700); text-decoration: none;
}
.mb-chip:hover { border-color: var(--accent); color: var(--brand-700); }
.mb-chip--on { border-color: var(--accent); background: var(--accent-100); }
.mb-chip--clear { color: var(--ink-500); }
.mb-chip .mb-qty { font-weight: 800; }

.movement-filter .form-label {
    font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
    color: var(--ink-400); margin-bottom: .15rem;
}
.movement-table th {
    font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-400);
}

/* =====================================================================
   ORDERS — CUSTOMER-FIRST (admin/orders.php)
   The page is organised by who the order is for, then by where it is in
   the day's flow. Three visual languages, one per tab: a customer card
   (identity + money + history), a production row (scannable queue), and a
   ready card (what to hand over).
   ===================================================================== */

.order-tabs {
    display: flex; gap: .4rem; flex-wrap: wrap;
    border-bottom: 1px solid var(--line);
    padding-bottom: .1rem;
}
.ot-tab {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .6rem 1rem;
    border-radius: var(--r) var(--r) 0 0;
    font-size: .88rem; font-weight: 700;
    color: var(--ink-500); text-decoration: none;
    border: 1px solid transparent; border-bottom: 0;
    position: relative; top: 1px;
}
.ot-tab:hover { color: var(--brand-700); background: #FDFBF9; }
.ot-tab--on {
    color: var(--brand-700); background: var(--card);
    border-color: var(--line);
}
.ot-tab .ot-count {
    font-style: normal; font-size: .68rem; font-weight: 800;
    padding: .1rem .42rem; border-radius: 999px;
    background: var(--warning-bg); color: var(--warning);
}
.ot-tab .ot-count--go { background: var(--info-bg); color: var(--info); }

/* ------------------------------------------------ customer cards ---- */

.customer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 1rem;
    align-items: start;
}
@media (max-width: 400px) { .customer-grid { grid-template-columns: 1fr; } }

.customer-card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    transition: box-shadow .16s ease, border-color .16s ease;
}
.customer-card:hover { box-shadow: var(--shadow); }
.customer-card--open { box-shadow: var(--shadow-lg); border-color: var(--accent); }
.customer-card--walkin { background: #FBF8F4; }

.cc-head { display: flex; align-items: flex-start; gap: .7rem; padding: .95rem 1rem .6rem; }
.cc-avatar {
    flex: 0 0 auto; width: 44px; height: 44px;
    border-radius: 13px; display: grid; place-items: center;
    background: var(--accent-100); color: var(--gold-700);
    font-weight: 800; font-size: .95rem;
}
.cc-ident { min-width: 0; flex: 1 1 auto; }
.cc-name {
    font-size: 1.02rem; font-weight: 800; line-height: 1.25;
    color: var(--brand-700); margin: 0; overflow-wrap: break-word;
}
.cc-sub { font-size: .78rem; color: var(--ink-500); margin-top: .1rem; display: flex; gap: .5rem; flex-wrap: wrap; }
.cc-sub code { font-size: .74rem; color: var(--ink-500); background: transparent; padding: 0; }
.cc-phone { color: var(--ink-500); text-decoration: none; }
.cc-phone:hover { color: var(--accent-600); }

/* The + is the page's primary verb, so it gets brand colour and a target
   big enough for a thumb. */
.cc-new {
    flex: 0 0 auto;
    width: 38px; height: 38px;
    border: 0; border-radius: 12px;
    background: var(--accent); color: #fff;
    font-size: 1.05rem; line-height: 1;
    display: grid; place-items: center;
    transition: background .15s ease, transform .15s ease;
}
.cc-new:hover { background: var(--accent-600); transform: translateY(-1px); }

.cc-facts {
    display: grid; grid-template-columns: repeat(4, 1fr);
    gap: .4rem; padding: .2rem 1rem .8rem;
}
.cc-facts > div { display: flex; flex-direction: column; min-width: 0; }
.cc-lbl {
    font-size: .63rem; text-transform: uppercase; letter-spacing: .05em;
    color: var(--ink-400); font-weight: 700;
}
.cc-val { font-size: 1rem; font-weight: 800; color: var(--ink-900); overflow-wrap: break-word; }
.cc-val--money { font-size: .82rem; }
.cc-val--sm { font-size: .76rem; font-weight: 600; }
.text-brand { color: var(--brand-700); }

.cc-flags { display: flex; flex-wrap: wrap; gap: .4rem; padding: 0 1rem .7rem; }
.cc-flag {
    display: inline-flex; align-items: center; gap: .3rem;
    font-size: .74rem; font-weight: 700; text-decoration: none;
    padding: .25rem .6rem; border-radius: 999px;
}
.cc-flag--pending { background: var(--warning-bg); color: #7A5410; }
.cc-flag--ready   { background: var(--info-bg);    color: #1E4E80; }

.cc-actions {
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    padding: .6rem 1rem; border-top: 1px solid var(--line);
}
.cc-actions .btn { font-size: .78rem; }

.cc-collapse-inner {
    border-top: 1px dashed var(--line);
    background: #FDFBF9;
    padding: .8rem 1rem;
}
.cc-order-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.cc-order {
    display: flex; flex-direction: column; gap: .2rem;
    padding: .55rem .7rem;
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--r); text-decoration: none; color: inherit;
}
.cc-order:hover { border-color: var(--accent); }
.cc-order .cco-top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.cc-order .cco-no { font-weight: 800; font-size: .82rem; color: var(--brand-700); }
.cc-order .cco-items { font-size: .78rem; color: var(--ink-500); }
.cc-order .cco-bottom { display: flex; align-items: center; gap: .6rem; font-size: .76rem; color: var(--ink-500); }
.cc-order .cco-total { font-weight: 800; color: var(--ink-900); margin-left: auto; }
.cc-order .badge { font-size: .62rem; }

/* ----------------------------------------------- production queue ---- */

.section-head {
    font-size: .8rem; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 800; color: var(--gold-700);
    margin: 1.4rem 0 .6rem;
}
.section-head:first-of-type { margin-top: 0; }

.prod-summary { display: flex; flex-wrap: wrap; gap: .5rem; }
.ps-chip {
    display: inline-flex; align-items: baseline; gap: .3rem;
    padding: .35rem .7rem; border-radius: 999px;
    background: var(--accent-100); color: var(--brand-800);
    font-size: .8rem;
}
.ps-chip .ps-qty { font-weight: 800; font-size: .95rem; }
.ps-chip .ps-unit { font-size: .68rem; color: var(--gold-700); }

.prod-order-list { display: flex; flex-direction: column; gap: .5rem; }
.prod-order {
    display: flex; gap: .6rem; align-items: flex-start;
    background: var(--card); border: 1px solid var(--line);
    border-left: 3px solid var(--info);
    border-radius: var(--r); padding: .7rem .9rem;
}
.prod-order--pending { border-left-color: var(--warning); background: #FFFDF8; }
.prod-order .po-select { padding-top: .15rem; }
.prod-order .po-main { min-width: 0; flex: 1 1 auto; }
.prod-order .po-top { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.prod-order .po-customer { font-weight: 800; color: var(--brand-700); text-decoration: none; font-size: .95rem; }
.prod-order .po-no { font-size: .74rem; color: var(--ink-400); }
.prod-order .po-items { font-size: .8rem; color: var(--ink-700); margin-top: .2rem; }
.prod-order .po-meta {
    display: flex; gap: .8rem; flex-wrap: wrap; align-items: center;
    font-size: .76rem; color: var(--ink-500); margin-top: .35rem;
}
.prod-order .po-total { font-weight: 800; color: var(--ink-900); margin-left: auto; }
.prod-order .po-batches { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .45rem; }
.prod-order .po-hint { font-size: .74rem; color: var(--warning); margin-top: .35rem; }

/* A batch chip carries its own state, so the order row answers "is it out
   of the oven yet" without opening the batch. */
.po-batch {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .25rem .6rem; border-radius: 999px;
    font-size: .72rem; text-decoration: none;
    border: 1px solid var(--line); background: #fff; color: var(--ink-700);
}
.po-batch:hover { border-color: var(--accent); }
.po-batch .pb-no { font-weight: 800; }
.po-batch .pb-status { color: var(--ink-400); }
.po-batch--in_progress { background: var(--warning-bg); border-color: #F0DFB5; }
.po-batch--completed,
.po-batch--qc_passed,
.po-batch--closed { background: var(--success-bg); border-color: #CBE6D7; }
.po-batch--completed .pb-status,
.po-batch--qc_passed .pb-status,
.po-batch--closed .pb-status { color: var(--success); }

/* -------------------------------------------- ready for release ------ */

.ready-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1rem;
    align-items: start;
}
.ready-card {
    background: var(--card);
    border: 1px solid var(--line);
    border-top: 3px solid var(--info);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    padding: .9rem 1rem;
}
.rc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.rc-customer { font-size: 1rem; font-weight: 800; color: var(--brand-700); margin: 0; }
.rc-sub { font-size: .76rem; color: var(--ink-500); }
.rc-items { list-style: none; margin: .7rem 0; padding: 0; font-size: .84rem; }
.rc-items li {
    display: flex; justify-content: space-between; gap: .5rem;
    padding: .25rem 0; border-bottom: 1px dashed var(--line);
}
.rc-items li:last-child { border-bottom: 0; }
.rc-foot { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.rc-money { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.rc-total { font-size: 1.05rem; font-weight: 800; color: var(--ink-900); }
.rc-balance { font-size: .72rem; color: var(--danger); font-weight: 700; }

/* Customer order cards gained two stages when production started driving
   'preparing' and 'ready' — amber for "being made", blue-green for "ready
   to collect", so the card's colour alone answers "is my order done". */
.order-card--preparing { background: #8A5A12; }
.order-card--ready     { background: #14625C; }

/* =====================================================================
   MIXERS + ORDER COLOUR CODE + RELEASE FROM STORE
   ===================================================================== */

/* A mixer count is a physical fact about the kitchen, not a quantity, so it
   reads as a badge rather than another number in the row. */
.mixer-pill {
    display: inline-flex; align-items: baseline; gap: .3rem;
    padding: .22rem .55rem; border-radius: 999px;
    background: var(--info-bg); color: #1E4E80;
    font-size: .74rem; font-weight: 800; white-space: nowrap;
}
.mixer-pill i { font-size: .8rem; }
.mixer-pill .mp-sub { font-weight: 500; font-size: .66rem; opacity: .75; }

.ps-chip .ps-mixer {
    display: inline-flex; align-items: baseline; gap: .25rem;
    margin-left: .4rem; padding: .1rem .45rem;
    border-radius: 999px; background: #fff; color: #1E4E80;
    font-size: .68rem; font-weight: 800;
}
.ps-chip .ps-mixer em { font-style: normal; font-weight: 500; opacity: .8; }

/* ---------------------------------------------------- the colour key ---- */

/* ONE COLOUR PER STAGE — nine stages, nine hues, no two alike. Released and
   delivered used to share Bootstrap's green, which made the two states that
   matter most (has it left the store / has the customer got it) impossible to
   tell apart. Each hue is set once here and reused by the badge, the key and
   the stripe on an order row, so a colour always means the same thing.

   Hues are ordered as the journey runs: neutral grey while it is only a
   request, blue once it is agreed, amber while it is being made, teal when it
   is baked, violet when it leaves the store, green when the customer has it,
   olive when collected, brand brown when the books close, red if cancelled. */
:root {
    --st-draft:     #6B7280;   /* grey   — sent, nothing agreed yet */
    --st-confirmed: #2B6CB0;   /* blue   — agreed */
    --st-preparing: #B7791F;   /* amber  — being made */
    --st-ready:     #0F766E;   /* teal   — baked, waiting in store */
    --st-released:  #6D28D9;   /* violet — out of store */
    --st-delivered: #2F7A4F;   /* green  — customer has it */
    --st-collected: #4D7C0F;   /* olive  — picked up */
    --st-completed: #6B3E26;   /* brown  — closed and cleared */
    --st-cancelled: #C0392B;   /* red    — cancelled */
}

.st-badge {
    display: inline-flex; align-items: center; gap: .3rem;
    font-size: .68rem; font-weight: 800;
    padding: .18rem .55rem; border-radius: 999px;
    color: #fff; white-space: nowrap;
    background: var(--st-draft);
}
.st-badge i { font-size: .72rem; }
.st-draft     { background: var(--st-draft); }
.st-confirmed { background: var(--st-confirmed); }
.st-preparing { background: var(--st-preparing); }
.st-ready     { background: var(--st-ready); }
.st-released  { background: var(--st-released); }
.st-delivered { background: var(--st-delivered); }
.st-collected { background: var(--st-collected); }
.st-completed { background: var(--st-completed); }
.st-cancelled { background: var(--st-cancelled); }

.order-key {
    display: flex; flex-wrap: wrap; align-items: center; gap: .35rem;
    padding: .5rem .7rem;
    background: #fff; border: 1px solid var(--line); border-radius: var(--r);
}
.order-key .ok-label {
    font-size: .63rem; text-transform: uppercase; letter-spacing: .05em;
    font-weight: 800; color: var(--ink-400); margin-right: .15rem;
}

/* Each order in a customer's history carries its stage as a left stripe, in
   the same colour as its badge — that is what makes the key worth reading. */
.cc-order { border-left-width: 3px; border-left-style: solid; }
.cc-order--draft     { border-left-color: var(--st-draft); }
.cc-order--confirmed { border-left-color: var(--st-confirmed); }
.cc-order--preparing { border-left-color: var(--st-preparing); }
.cc-order--ready     { border-left-color: var(--st-ready); }
.cc-order--released  { border-left-color: var(--st-released); }
.cc-order--delivered { border-left-color: var(--st-delivered); }
.cc-order--collected { border-left-color: var(--st-collected); }
.cc-order--completed { border-left-color: var(--st-completed); }
.cc-order--cancelled { border-left-color: var(--st-cancelled); }
.cc-order--cancelled .cco-no { text-decoration: line-through; opacity: .7; }

/* The Edit link sits under the order, outside the card-wide link, so tapping
   the row still opens the order and only Edit opens the editor. */
.cco-edit {
    display: inline-flex; align-items: center; gap: .25rem;
    margin: .15rem 0 0 .1rem; font-size: .7rem; font-weight: 700;
    color: var(--accent-600); text-decoration: none;
}
.cco-edit:hover { text-decoration: underline; }

/* Production and Ready borrow the same hues so the tabs agree with the key. */
.prod-order              { border-left-color: var(--st-confirmed); }
.prod-order--pending     { border-left-color: var(--st-preparing); }
.ready-card              { border-top-color: var(--st-ready); }
.ready-card--released    { border-top-color: var(--st-released); }

.rc-note {
    font-size: .68rem; color: var(--warning); font-weight: 700;
    margin-top: .3rem; text-align: center;
}

/* ------------------------------------------- release from store -------- */


.rc-release .rc-items li {
    display: flex; align-items: center; justify-content: space-between;
    gap: .5rem; padding: .3rem 0;
}
.rc-release .rc-item-name { display: flex; flex-direction: column; min-width: 0; }
.rc-release .rc-released { font-style: normal; font-size: .68rem; color: var(--success); font-weight: 700; }
.rc-release .rc-short    { font-style: normal; font-size: .68rem; color: var(--danger);  font-weight: 700; }
.rc-release .rc-qty { display: flex; align-items: center; gap: .3rem; flex: 0 0 auto; }
.rc-release .rc-qty input { width: 5.5rem; text-align: right; }
.rc-release .rc-qty small { font-size: .64rem; color: var(--ink-400); white-space: nowrap; }
.rc-line--done { opacity: .65; }
.rc-alldone {
    font-size: .76rem; font-weight: 700; color: var(--success);
    background: var(--success-bg); border-radius: var(--r-sm);
    padding: .4rem .6rem; text-align: center;
}
