/* =====================================================================
 * ARMANN :: Medical design system
 * ---------------------------------------------------------------------
 * A pharmacy counter is not a marketing site. Staff read this screen for
 * eight hours under fluorescent light, often at a glance while a patient
 * waits, and the numbers on it decide what medicine leaves the shelf.
 * So the design is built for legibility and calm, not personality:
 *
 *   - One saturated colour, used only where it means something. Green is
 *     reserved for identity and "in stock"; every other accent earns its
 *     place semantically (amber = running low, red = out or destructive,
 *     clinical blue = informational).
 *   - Neutrals carry a slight green bias so they sit with the brand
 *     rather than looking like a default grey admin panel.
 *   - Dense by intent. Staff scan tables; generous marketing whitespace
 *     would mean scrolling for stock they need to see at once.
 *   - Contrast targets AAA where it is achievable, AA everywhere. Focus
 *     rings are 3px and never removed -- half the counter staff drive
 *     this by keyboard.
 *
 * Loaded LAST so its tokens win over Bootstrap and the older sheets.
 * ===================================================================== */

/* ---------------------------------------------------------------------
 * TOKENS
 * ------------------------------------------------------------------- */
:root {
    /* Brand -- deep pharmacy green. Dark enough to carry white text at
       AAA, which the old brighter green could not. */
    --arm-primary:        #0f6b4e;
    --arm-primary-hover:  #0c563f;
    --arm-primary-soft:   #e6f2ed;
    --arm-primary-line:   #b9dccd;
    --arm-on-primary:     #ffffff;

    /* Clinical blue -- informational only, never decorative. */
    --arm-info:           #0369a1;
    --arm-info-soft:      #e4f0f8;

    /* Semantic stock states. These three do the real work on this app. */
    --arm-ok:             #0f6b4e;
    --arm-ok-soft:        #e6f2ed;
    --arm-warn:           #8a5208;   /* 5.6:1 on --arm-warn-soft; #a2610a measured 4.38 */
    --arm-warn-soft:      #fbf0dd;
    --arm-danger:         #b42318;
    --arm-danger-soft:    #fbe9e7;

    /* Neutrals, biased a few degrees toward the brand green so the grey
       reads as chosen rather than inherited. */
    --arm-bg:             #f4f7f5;
    --arm-surface:        #ffffff;
    --arm-surface-2:      #eef3f0;
    --arm-surface-3:      #e4ebe7;
    --arm-ink:            #11241d;
    --arm-ink-2:          #40554d;
    --arm-ink-3:          #5c6f68;   /* 5.3:1 on white; #6b8078 measured 4.21 */
    --arm-line:           #d7e2dc;
    --arm-line-strong:    #b9c8c1;

    /* Dense dashboard spacing: 4px rhythm. */
    --arm-s1: 4px;  --arm-s2: 8px;  --arm-s3: 12px;
    --arm-s4: 16px; --arm-s5: 24px; --arm-s6: 32px; --arm-s7: 48px;

    --arm-r-sm: 6px;
    --arm-r:    10px;
    --arm-r-lg: 14px;

    /* Shadows stay shallow. Deep drop shadows read as consumer-app
       styling and muddy the page under overhead lighting. */
    --arm-shadow-1: 0 1px 2px rgba(17, 36, 29, .06);
    --arm-shadow-2: 0 1px 3px rgba(17, 36, 29, .07), 0 6px 16px -10px rgba(17, 36, 29, .28);

    --arm-focus: 0 0 0 3px rgba(15, 107, 78, .32);

    --arm-font-ui:   "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
    --arm-font-body: "Noto Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
    --arm-font-num:  "Figtree", system-ui, sans-serif;
}

/* ---------------------------------------------------------------------
 * BASE
 * ------------------------------------------------------------------- */
body {
    background: var(--arm-bg);
    color: var(--arm-ink);
    font-family: var(--arm-font-body);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.sidebar-brand, .btn, .nav-link, .form-label, .badge {
    font-family: var(--arm-font-ui);
}

h1, h2, h3, h4, h5 { color: var(--arm-ink); letter-spacing: -.01em; }

/* Every figure in this app is money or a piece count and sits in a
   column. Tabular figures stop the columns dancing as values change. */
.num, .text-end, td.num, .stat-number, .stat-value,
table td, table th {
    font-variant-numeric: tabular-nums;
}

a { color: var(--arm-primary); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--arm-primary-hover); }

/* Never remove the focus ring -- keyboard is the fast path at a counter. */
:focus-visible {
    outline: 2px solid var(--arm-primary);
    outline-offset: 2px;
    border-radius: var(--arm-r-sm);
}

/* ---------------------------------------------------------------------
 * SIDEBAR
 * ------------------------------------------------------------------- */
.sidebar {
    background: linear-gradient(178deg, #103d30 0%, #0b2a22 100%);
    color: #dbe8e2;
    min-height: 100vh;
    padding: 0;
    box-shadow: inset -1px 0 0 rgba(255, 255, 255, .06);
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: var(--arm-s3);
    padding: var(--arm-s4) var(--arm-s4) var(--arm-s3);
    border-bottom: 1px solid rgba(255, 255, 255, .09);
    text-decoration: none;
}



.sidebar-section {
    padding: var(--arm-s4) var(--arm-s4) var(--arm-s1);
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #7ba392;
}

.sidebar a,
.sidebar-link,
.sidebar-submenu a,
.sidebar-dropdown-toggle {
    display: flex;
    align-items: center;
    gap: var(--arm-s3);
    /* 44px minimum touch target. */
    min-height: 44px;
    padding: var(--arm-s2) var(--arm-s4);
    color: #cfe0d9;
    text-decoration: none;
    font-size: .875rem;
    font-weight: 500;
    border-left: 3px solid transparent;
    transition: background .16s ease, color .16s ease, border-color .16s ease;
}

.sidebar a i,
.sidebar-link i,
.sidebar-dropdown-toggle i:first-child {
    width: 18px;
    text-align: center;
    font-size: .95rem;
    opacity: .82;
    flex: 0 0 auto;
}

.sidebar a:hover,
.sidebar-link:hover,
.sidebar-submenu a:hover,
.sidebar-dropdown-toggle:hover {
    background: rgba(255, 255, 255, .07);
    color: #fff;
}

.sidebar a.active,
.sidebar-link.active,
.sidebar-submenu a.active {
    background: rgba(255, 255, 255, .11);
    color: #fff;
    border-left-color: #4ade80;
    font-weight: 600;
}

.sidebar-dropdown-toggle {
    width: 100%;
    background: none;
    border: 0;
    justify-content: space-between;
    text-align: left;
}
.sidebar-dropdown-toggle > span {
    display: flex;
    align-items: center;
    gap: var(--arm-s3);
}
.dropdown-chevron { transition: transform .2s ease; font-size: .7rem; opacity: .6; }
.sidebar-dropdown.open .dropdown-chevron { transform: rotate(180deg); }

.sidebar-submenu {
    display: none;
    background: rgba(0, 0, 0, .18);
}
.sidebar-dropdown.open .sidebar-submenu { display: block; }
.sidebar-submenu a {
    padding-left: 46px;
    font-size: .83rem;
    min-height: 40px;
}

/* ---------------------------------------------------------------------
 * PAGE HEADER
 * ------------------------------------------------------------------- */
.hero, .welcome-panel, .page-hero {
    background: linear-gradient(120deg, var(--arm-primary) 0%, #0b3f30 100%);
    color: #fff;
    border-radius: var(--arm-r-lg);
    padding: var(--arm-s5) var(--arm-s5);
    margin-bottom: var(--arm-s5);
    box-shadow: var(--arm-shadow-2);
}
.hero h2, .hero h3, .welcome-panel h3, .page-hero h2 {
    color: #fff;
    font-weight: 700;
    font-size: 1.4rem;
    margin: 0 0 4px;
    letter-spacing: -.015em;
}
.hero .kicker, .hero-kicker, .page-hero .kicker {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .13em;
    color: rgba(255, 255, 255, .72);
    font-weight: 600;
    margin-bottom: var(--arm-s2);
}
.hero p, .welcome-panel p { color: rgba(255, 255, 255, .84); margin: 0; font-size: .92rem; }

/* ---------------------------------------------------------------------
 * STAT TILES -- the row staff read first
 * ------------------------------------------------------------------- */
.stat-card, .kpi {
    background: var(--arm-surface);
    border: 1px solid var(--arm-line);
    border-radius: var(--arm-r);
    padding: var(--arm-s4);
    box-shadow: var(--arm-shadow-1);
    height: 100%;
    position: relative;
    overflow: hidden;
}

/* A 3px stripe encodes the state in FORM as well as colour, so it still
   reads for a colour-blind user and in a black-and-white printout. */
.stat-card::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: var(--arm-line-strong);
}
.stat-card.is-ok::before     { background: var(--arm-ok); }
.stat-card.is-warn::before   { background: var(--arm-warn); }
.stat-card.is-danger::before { background: var(--arm-danger); }
.stat-card.is-info::before   { background: var(--arm-info); }

.stat-label {
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--arm-ink-3);
    margin-bottom: 2px;
}
.stat-number, .stat-value {
    font-family: var(--arm-font-num);
    font-size: 1.65rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--arm-ink);
}
.stat-sub { font-size: .74rem; color: var(--arm-ink-3); margin-top: 2px; }

/* ---------------------------------------------------------------------
 * CARDS AND PANELS
 * ------------------------------------------------------------------- */
.card, .panel, .content-card, .records-card, .fin-paper {
    background: var(--arm-surface);
    border: 1px solid var(--arm-line);
    border-radius: var(--arm-r);
    box-shadow: var(--arm-shadow-1);
}
.card-header, .panel-head, .content-head, .records-header {
    background: var(--arm-surface-2);
    border-bottom: 1px solid var(--arm-line);
    padding: var(--arm-s3) var(--arm-s4);
    font-weight: 600;
    color: var(--arm-ink);
}

/* ---------------------------------------------------------------------
 * TABLES -- the densest surface in the app
 * ------------------------------------------------------------------- */
.table > :not(caption) > * > * { padding: 10px 14px; }

.table thead th,
table thead th,
.table-dark th,
thead.table-dark th {
    background: var(--arm-surface-2) !important;
    color: var(--arm-ink-2) !important;
    font-family: var(--arm-font-ui);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--arm-line-strong) !important;
    white-space: nowrap;
    vertical-align: middle;
}

.table tbody td { border-bottom: 1px solid var(--arm-line); color: var(--arm-ink-2); vertical-align: middle; }
.table tbody tr:hover > * { background: var(--arm-primary-soft); }
.table > :not(:first-child) { border-top: 0; }

/* Zebra striping is off by default: at this density the alternating
   bands fight the semantic row colours below. */
.table-striped > tbody > tr:nth-of-type(odd) > * { background: transparent; }

code, .product-code {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: .82em;
    background: var(--arm-surface-2);
    color: var(--arm-ink-2);
    padding: 2px 6px;
    border-radius: 5px;
}

/* ---------------------------------------------------------------------
 * BADGES -- state must survive greyscale, so each carries a shape cue
 * ------------------------------------------------------------------- */
.badge {
    font-family: var(--arm-font-ui);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    padding: 4px 9px;
    border-radius: 999px;
    border: 1px solid transparent;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
.badge::before {
    content: "";
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}
.badge.bg-success, .badge-state.bg-success { background: var(--arm-ok-soft) !important;     color: var(--arm-ok) !important;     border-color: var(--arm-primary-line); }
.badge.bg-warning, .badge-state.bg-warning { background: var(--arm-warn-soft) !important;   color: var(--arm-warn) !important;   border-color: #ecd5a8; }
.badge.bg-danger,  .badge-state.bg-danger  { background: var(--arm-danger-soft) !important; color: var(--arm-danger) !important; border-color: #f0c4bf; }
.badge.bg-info,    .badge.bg-primary       { background: var(--arm-info-soft) !important;   color: var(--arm-info) !important;   border-color: #bcd9ec; }
.badge.bg-secondary, .badge.bg-light       { background: var(--arm-surface-3) !important;   color: var(--arm-ink-2) !important;  border-color: var(--arm-line-strong); }

/* ---------------------------------------------------------------------
 * BUTTONS
 * ------------------------------------------------------------------- */
.btn {
    font-weight: 600;
    font-size: .875rem;
    border-radius: var(--arm-r-sm);
    padding: 9px 16px;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    transition: background .16s ease, border-color .16s ease, box-shadow .16s ease;
    cursor: pointer;
}
.btn-sm { min-height: 34px; padding: 5px 11px; font-size: .8rem; }
.btn:focus-visible { box-shadow: var(--arm-focus); outline: none; }

.btn-primary, .btn-success {
    background: var(--arm-primary);
    border-color: var(--arm-primary);
    color: var(--arm-on-primary);
}
.btn-primary:hover, .btn-success:hover {
    background: var(--arm-primary-hover);
    border-color: var(--arm-primary-hover);
    color: #fff;
}
.btn-outline-secondary {
    border-color: var(--arm-line-strong);
    color: var(--arm-ink-2);
    background: var(--arm-surface);
}
.btn-outline-secondary:hover { background: var(--arm-surface-2); color: var(--arm-ink); border-color: var(--arm-ink-3); }

.btn-danger, .btn-outline-danger:hover { background: var(--arm-danger); border-color: var(--arm-danger); color: #fff; }
.btn-outline-danger { color: var(--arm-danger); border-color: #e8b4ae; }

.btn:disabled, .btn.disabled { opacity: .45; cursor: not-allowed; }

/* ---------------------------------------------------------------------
 * FORMS
 * ------------------------------------------------------------------- */
.form-label {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--arm-ink-3);
    margin-bottom: 5px;
}
.form-control, .form-select, .record-input, .record-select {
    border: 1px solid var(--arm-line-strong);
    border-radius: var(--arm-r-sm);
    /* 16px stops iOS zooming the page when a field is focused. */
    font-size: 16px;
    padding: 8px 12px;
    min-height: 42px;
    color: var(--arm-ink);
    background: var(--arm-surface);
    transition: border-color .16s ease, box-shadow .16s ease;
}
.form-control:focus, .form-select:focus, .record-input:focus, .record-select:focus {
    border-color: var(--arm-primary);
    box-shadow: var(--arm-focus);
    outline: none;
}
.form-control::placeholder { color: var(--arm-ink-3); }

/* ---------------------------------------------------------------------
 * ALERTS
 * ------------------------------------------------------------------- */
.alert {
    border-radius: var(--arm-r);
    border: 1px solid transparent;
    border-left-width: 3px;
    padding: var(--arm-s3) var(--arm-s4);
    font-size: .9rem;
}
.alert-success { background: var(--arm-ok-soft);     border-color: var(--arm-primary-line); border-left-color: var(--arm-ok);     color: #0b4a36; }
.alert-danger  { background: var(--arm-danger-soft); border-color: #f0c4bf;                 border-left-color: var(--arm-danger); color: #8c1c14; }
.alert-warning { background: var(--arm-warn-soft);   border-color: #ecd5a8;                 border-left-color: var(--arm-warn);   color: #74450a; }
.alert-info    { background: var(--arm-info-soft);   border-color: #bcd9ec;                 border-left-color: var(--arm-info);   color: #084c73; }

/* ---------------------------------------------------------------------
 * TABS
 * ------------------------------------------------------------------- */
.nav-tabs { border-bottom: 1px solid var(--arm-line); gap: 2px; }
.nav-tabs .nav-link {
    border: 0;
    border-bottom: 2px solid transparent;
    color: var(--arm-ink-3);
    font-weight: 600;
    font-size: .84rem;
    letter-spacing: .03em;
    padding: 10px 14px;
    border-radius: 0;
    min-height: 44px;
}
.nav-tabs .nav-link:hover { color: var(--arm-ink); background: var(--arm-surface-2); }
.nav-tabs .nav-link.active {
    color: var(--arm-primary);
    background: transparent;
    border-bottom-color: var(--arm-primary);
}

/* ---------------------------------------------------------------------
 * EMPTY STATES
 * ------------------------------------------------------------------- */
.empty-state, .empty-products, .empty-fetch {
    text-align: center;
    padding: var(--arm-s7) var(--arm-s4);
    color: var(--arm-ink-3);
}
.empty-state i, .empty-products i { font-size: 1.9rem; color: var(--arm-line-strong); display: block; margin-bottom: var(--arm-s3); }
.empty-state strong, .empty-products strong { display: block; color: var(--arm-ink-2); font-weight: 600; margin-bottom: 3px; }

/* ---------------------------------------------------------------------
 * PAGE FRAME
 * ------------------------------------------------------------------- */
.page-wrap { padding: var(--arm-s5) var(--arm-s5) var(--arm-s7); }
@media (max-width: 768px) {
    .page-wrap { padding: var(--arm-s4) var(--arm-s3) var(--arm-s6); }
    .hero, .welcome-panel { padding: var(--arm-s4); }
}

.table-responsive, .table-wrap { border-radius: var(--arm-r); }

/* Motion stays subtle, and stops entirely when the viewer asks. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Icon inside a stat label sits with the text, muted so the number stays
   the thing the eye lands on. */
.stat-label i {
    margin-right: 5px;
    opacity: .55;
    font-size: .78rem;
}
.stat-card.is-ok     .stat-label i { color: var(--arm-ok); opacity: .8; }
.stat-card.is-warn   .stat-label i { color: var(--arm-warn); opacity: .9; }
.stat-card.is-danger .stat-label i { color: var(--arm-danger); opacity: .9; }
.stat-card.is-info   .stat-label i { color: var(--arm-info); opacity: .8; }

/* ---------------------------------------------------------------------
 * CASHIER DASHBOARD
 * ---------------------------------------------------------------------
 * The stat tiles shipped with a violet and an orange icon chip, which
 * belong to no part of this system's meaning: violet says nothing about
 * a drug count, and orange is the colour this app uses for "running
 * low". Both are re-pointed at the semantic palette so the only colours
 * on a pharmacy screen are ones that carry information.
 * ------------------------------------------------------------------- */
.cashier-stat-icon {
    width: 44px !important;
    height: 44px !important;
    border-radius: var(--arm-r-sm) !important;
    font-size: 19px !important;
}
.cashier-stat-icon.icon-products {
    background: var(--arm-primary-soft) !important;
    color: var(--arm-primary) !important;
}
.cashier-stat-icon.icon-category {
    background: var(--arm-info-soft) !important;
    color: var(--arm-info) !important;
}

.cashier-stat-label {
    font-size: .68rem !important;
    font-weight: 700 !important;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--arm-ink-3) !important;
}
.cashier-stat-value {
    font-family: var(--arm-font-num);
    font-size: 1.75rem;
    font-weight: 700 !important;
    color: var(--arm-ink) !important;
}

/* A saturated green bar across a panel header competes with the hero and
   with the "in stock" badges below it. Panels are containers, not
   announcements -- they get the neutral surface. */
.cashier-panel-head,
.card-header.bg-success,
.panel-head.bg-success {
    background: var(--arm-surface-2) !important;
    color: var(--arm-ink) !important;
    border-bottom: 1px solid var(--arm-line) !important;
}
.cashier-panel-head *,
.card-header.bg-success * { color: var(--arm-ink) !important; }

/* Product tiles: one predictable card size so the grid reads as a shelf
   rather than a ransom note of different-width boxes. */
.product-tile {
    border: 1px solid var(--arm-line);
    border-radius: var(--arm-r-sm);
    padding: var(--arm-s3);
    background: var(--arm-surface);
    min-height: 84px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--arm-s2);
    transition: border-color .16s ease, box-shadow .16s ease;
}
.product-tile:hover {
    border-color: var(--arm-primary-line);
    box-shadow: var(--arm-shadow-1);
}
.product-tile .product-name {
    font-weight: 600;
    font-size: .84rem;
    color: var(--arm-ink);
    line-height: 1.3;
}
.product-tile .product-qty {
    font-family: var(--arm-font-num);
    font-size: .74rem;
    font-weight: 700;
    color: var(--arm-ok);
    background: var(--arm-ok-soft);
    border: 1px solid var(--arm-primary-line);
    border-radius: 999px;
    padding: 2px 8px;
    align-self: flex-start;
}

/* The product panel header arrived as a saturated green gradient bar.
   At a counter it competed with both the hero above it and the green
   "in stock" pills below, so the eye had three greens fighting for the
   same attention. Panels are containers; the neutral surface lets the
   stock states be the only green that means something. */
.product-panel-head {
    background: var(--arm-surface-2) !important;
    background-image: none !important;
    color: var(--arm-ink) !important;
    border-bottom: 1px solid var(--arm-line) !important;
    padding: var(--arm-s3) var(--arm-s4) !important;
}
.product-panel-head * { color: var(--arm-ink) !important; }
.product-panel-head i { color: var(--arm-primary) !important; }
.product-panel-head [class*="shown"],
.product-panel-head small { color: var(--arm-ink-3) !important; font-weight: 500; }

.product-panel { border: 1px solid var(--arm-line); border-radius: var(--arm-r); box-shadow: var(--arm-shadow-1); }

/* Dashboard stat cards were centre-aligned, which reads as a marketing
   feature grid. Staff scan a column of figures down the left edge, so
   the label, number and icon all align there instead. */
.cashier-stat-card {
    text-align: left !important;
    display: grid !important;
    grid-template-columns: auto 1fr;
    grid-template-areas: "icon label" "icon value" "icon sub";
    column-gap: var(--arm-s3);
    align-content: center;
    padding: var(--arm-s4) !important;
    border: 1px solid var(--arm-line) !important;
    border-radius: var(--arm-r) !important;
    box-shadow: var(--arm-shadow-1) !important;
}
.cashier-stat-card .cashier-stat-icon  { grid-area: icon; align-self: center; margin: 0 !important; }
.cashier-stat-card .cashier-stat-label { grid-area: label; }
.cashier-stat-card .cashier-stat-value { grid-area: value; }
.cashier-stat-card .cashier-stat-sub,
.cashier-stat-card small               { grid-area: sub; font-size: .72rem; color: var(--arm-ink-3); }

/* The shelf grid: even columns that reflow, instead of tiles sized by
   the length of the drug name. */
.product-grid,
.product-tiles,
[class*="product-list-grid"] {
    display: grid !important;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)) !important;
    gap: var(--arm-s3) !important;
}

/* ---------------------------------------------------------------------
 * FINAL CORRECTIONS
 * ------------------------------------------------------------------- */

/* Clinical blue is reserved for information. A submit button is an
   action, so it takes the brand green like every other primary control
   -- otherwise the page teaches staff two different "press this"
   colours. */
.cashier-search-btn,
.product-panel .btn-primary,
.input-group .btn-primary {
    background: var(--arm-primary) !important;
    border-color: var(--arm-primary) !important;
    color: #fff !important;
}
.cashier-search-btn:hover,
.product-panel .btn-primary:hover,
.input-group .btn-primary:hover {
    background: var(--arm-primary-hover) !important;
    border-color: var(--arm-primary-hover) !important;
}

/* The hero carried a mottled photographic texture. Under fluorescent
   light it reads as smudged, it lowers the contrast of the white text
   sitting on it, and it costs an image request on every page load. A
   flat two-stop gradient does the same job and holds AAA contrast. */
/* Non-shader heroes keep the flat gradient; .aa-hero is handled below. */
.hero:not(.aa-hero), .cashier-hero, .welcome-panel, .page-hero {
    background-image: linear-gradient(118deg, #0f6b4e 0%, #0a3b2d 100%) !important;
}

/* Product tiles: text reads from the left. Centred names in a scan list
   make the eye hunt for where each one starts. */
.product-tile,
.product-tile .product-name,
.product-tile .product-qty {
    text-align: left !important;
}

/* The clock in the hero was set in a monospace face at display size,
   which read as a terminal readout rather than part of the page. */
.aa-hero .hero-clock,
.hero .hero-clock,
[class*="hero"] [class*="clock"] {
    font-family: var(--arm-font-num) !important;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.01em !important;
    font-weight: 600 !important;
}

/* Top bar sits with the page rather than floating above it. */
.aa-topbar, .topbar, .app-topbar {
    background: var(--arm-surface) !important;
    border-bottom: 1px solid var(--arm-line) !important;
    box-shadow: none !important;
}

/* ---------------------------------------------------------------------
 * ANIMATED HERO
 * ---------------------------------------------------------------------
 * The hero runs a WebGL aurora shader. It is the system's signature and
 * it stays -- what changes is that the text on top is now guaranteed
 * readable regardless of where the bright bands drift.
 *
 * The shader already declines to start under prefers-reduced-motion or
 * on a low-power device, and caps its pixel ratio at 1.25, so the cost
 * on a counter terminal is bounded.
 *
 * The problem was contrast: white text sat directly on a moving
 * gradient, so as a bright band swept under the title it dropped below
 * AA. A fixed scrim under the text -- opaque at the left where the
 * copy is, clearing to nothing at the right where the animation is
 * meant to be seen -- fixes that without hiding the effect.
 * ------------------------------------------------------------------- */
.aa-hero canvas.aa-hero-canvas {
    display: block !important;
    /* Starts transparent; armann-ui.js fades it in on the shader's first
       painted frame. The context is opaque (alpha:false), so without this
       the banner is a black rectangle until that frame lands -- which on
       a page opened in a background tab may be a long time. */
    opacity: 0;
}

.aa-hero::after {
    /* Just enough to anchor the copy. The first stop covers the text
       column; by 45% it has cleared so the aurora reads at full strength
       across the right two thirds of the banner, which is where the eye
       goes anyway. */
    background: linear-gradient(
        100deg,
        rgba(3, 32, 24, .74) 0%,
        rgba(3, 32, 24, .46) 26%,
        rgba(3, 32, 24, .12) 48%,
        rgba(3, 32, 24, 0) 68%
    ) !important;
}

/* A soft shadow on the headline itself means the title survives even a
   bright band passing directly beneath it, without darkening the whole
   banner to achieve it. */
.aa-hero h1, .aa-hero h2, .aa-hero h3,
.aa-hero .hero-title, .aa-hero .welcome-title {
    text-shadow: 0 1px 10px rgba(2, 24, 18, .75), 0 1px 2px rgba(2, 24, 18, .55);
}
.aa-hero p, .aa-hero small, .aa-hero .aa-hero-sub,
.aa-hero .aa-hero-eyebrow {
    text-shadow: 0 1px 8px rgba(2, 24, 18, .7);
}

/* No background override here on purpose. armann-ds.css already sets the
   hero's own gradient (#044e3b -> #047857 -> #0b6f52), which is both the
   WebGL fallback and what shows between the shader's brighter bands. An
   earlier near-black override sat over it and made the whole banner read
   as a flat dark slab with the aurora invisible behind it. */

/* Hero text sits above both the canvas and the scrim. */
.aa-hero > *:not(canvas) { position: relative; z-index: 1; }

/* Unclassed submit buttons inside panels were picking up a raw blue.
   Actions are green in this system; blue means information only. */
.product-search button[type="submit"],
.product-panel-body form button[type="submit"],
.aa-card form button[type="submit"] {
    background: var(--arm-primary) !important;
    border: 1px solid var(--arm-primary) !important;
    color: #fff !important;
    border-radius: var(--arm-r-sm) !important;
    min-width: 44px;
    min-height: 44px;
    cursor: pointer;
}
.product-search button[type="submit"]:hover,
.product-panel-body form button[type="submit"]:hover {
    background: var(--arm-primary-hover) !important;
    border-color: var(--arm-primary-hover) !important;
}

/* ---------------------------------------------------------------------
 * CONTRAST CORRECTIONS
 * ---------------------------------------------------------------------
 * Bootstrap's text utilities are tuned for coloured backgrounds. On the
 * white cards this app uses, two of them are unreadable, measured in the
 * browser against white:
 *
 *     .text-info    #0dcaf0   1.96 : 1   (needs 4.5)
 *     .text-warning #ffc107   1.63 : 1   (needs 4.5)
 *
 * At a pharmacy counter these were being used for stock alerts -- the
 * numbers staff most need to catch were the hardest to read. Repointed
 * at the semantic palette, which is chosen to clear 4.5:1 on white.
 * ------------------------------------------------------------------- */
.text-info    { color: var(--arm-info)    !important; }  /* 6.4:1  */
.text-warning { color: var(--arm-warn)    !important; }  /* 5.9:1  */
.text-success { color: var(--arm-ok)      !important; }  /* 6.9:1  */
.text-danger  { color: var(--arm-danger)  !important; }  /* 6.6:1  */
.text-primary { color: var(--arm-primary) !important; }  /* 6.9:1  */
.text-secondary,
.text-muted   { color: var(--arm-ink-3)   !important; }  /* 4.6:1  */

/* Stat figures read as one column of numbers. Colouring each one
   differently implies a difference that is not there -- "6 items" is
   not more urgent than "3 wholesale". The number stays ink; the stripe
   on the tile carries the state. */
.stat-card .stat-number,
.stat-card .stat-value,
.aa-stat .stat-number {
    color: var(--arm-ink) !important;
}

/* Genuinely urgent counts keep their colour, and only when non-zero --
   handled by the is-warn / is-danger modifiers on the tile. */
.stat-card.is-warn   .stat-number { color: var(--arm-warn)   !important; }
.stat-card.is-danger .stat-number { color: var(--arm-danger) !important; }

/* The stat grid was spending a lot of vertical space on six numbers.
   Tighten it so the whole row is visible without scrolling. */
.stat-card, .aa-stat { padding: var(--arm-s4) !important; }
.stat-card .stat-number, .aa-stat .stat-number { font-size: 1.55rem; }


/* The keyboard-shortcut chip in the search bar printed white on a pale
   grey -- 1.1:1, effectively invisible. */
kbd, .kbd, .aa-kbd {
    background: var(--arm-surface-3) !important;
    color: var(--arm-ink-2) !important;
    border: 1px solid var(--arm-line-strong) !important;
    box-shadow: none !important;
    font-size: .7rem;
    padding: 1px 5px;
    border-radius: 4px;
}


/* ---------------------------------------------------------------------
 * STAT GRID
 * ---------------------------------------------------------------------
 * Six tiles forced across a 1250px content area left each one 146px
 * wide, which broke labels mid-word ("DRUGSTOR / E", "WHOLESAL / E")
 * and truncated the figures they exist to show ("443,..." and "P16...").
 * A fluid grid wraps to a sensible number of columns instead of
 * squeezing to whatever the row count demands.
 * ------------------------------------------------------------------- */
.row:has(> [class*="col"] > .stat-card),
.row:has(> [class*="col"] > .aa-stat) {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--arm-s3);
    margin: 0 0 var(--arm-s4) !important;
}
.row:has(> [class*="col"] > .stat-card) > [class*="col"],
.row:has(> [class*="col"] > .aa-stat)  > [class*="col"] {
    width: auto !important;
    max-width: none !important;
    flex: none !important;
    padding: 0 !important;
    margin: 0 !important;
}

/* Labels never break a word; they wrap or they shrink. */
.stat-label, .cashier-stat-label, .aa-stat .stat-label {
    overflow-wrap: normal;
    word-break: keep-all;
    hyphens: none;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

/* Long money figures shrink to fit rather than being cut off -- a
   truncated peso total is worse than a slightly smaller one.
   NOTE: no !important on font-size. armann-ui.js measures each value and
   steps an inline font-size down until it fits; an !important here beats
   that inline style and the value gets clipped instead of shrunk, which
   is exactly what "P168,799,800...." was. */
.stat-number, .stat-value, .cashier-stat-value {
    white-space: nowrap;
    font-size: clamp(1.05rem, 1.9vw, 1.55rem);
    overflow-wrap: normal;
    overflow: visible;
    text-overflow: clip;
}


/* =====================================================================
 * BRAND BLOCK
 * ---------------------------------------------------------------------
 * Back on the dark panel, with the logo given room to actually be seen.
 *
 * On the wordmark colours there is a physical limit worth stating: the
 * logo's own inks are #020AC7 and #008301, and against this near-black
 * panel the blue measures about 1.2:1 -- it is not dim, it is invisible.
 * The hues below are those same two colours lifted in lightness only,
 * which is the closest a dark ground allows:
 *
 *     #6C8CFF  blue   6.1 : 1
 *     #3DD68C  green  8.4 : 1
 *
 * The mark itself keeps a white chip, so the true logo inks are always
 * on screen at full strength right beside the text.
 * ===================================================================== */
.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 14px;
    background: transparent;
    border-bottom: 1px solid rgba(255, 255, 255, .1);
    text-decoration: none;
}

/* ---------------------------------------------------------------------
 * THE MARK
 * ---------------------------------------------------------------------
 * The logo exactly as supplied -- whole, uncropped, unshifted. It is
 * only given a round white plate to sit on and a fixed size, because the
 * file ships at 500x500 with no intrinsic sizing and renders at natural
 * size otherwise, shoving the page sideways.
 * ------------------------------------------------------------------- */
.sidebar-logo-chip {
    width: 68px;
    height: 68px;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: #fff;
    padding: 4px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
}

.sidebar-brand .sidebar-logo,
.sidebar-logo-chip .sidebar-logo,
.sidebar-logo {
    width: 100% !important;
    height: 100% !important;
    min-width: 0 !important;
    max-width: 100% !important;
    min-height: 0 !important;
    max-height: 100% !important;
    object-fit: contain;
    transform: none;
    position: static;
    background: none;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
}

/* The strapline is the wider of the two lines, so the name is centred
   over it rather than left-aligned against it. */
.sidebar-brand-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1px;
}

.sidebar-wordmark {
    margin: 0;
    font-family: var(--arm-font-ui);
    font-size: 1.32rem !important;
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: .01em;
    white-space: nowrap;
}

/* The logo's own inks are #020AC7 and #008301. Against this near-black
   panel the blue measures about 1.2:1 -- not dim, invisible. These are
   the same two hues lifted in lightness only, which is the closest a
   dark ground allows:  blue 6.1:1, green 8.4:1. The mark beside them
   carries the true inks at full strength. */
.sidebar-wordmark .wm-arm { color: #6c8cff; }
.sidebar-wordmark .wm-ann { color: #3dd68c; }

.sidebar-brand-sub {
    display: block;
    margin: 0;
    font-size: .625rem !important;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #9dbcb0 !important;   /* 7.2:1 on the sidebar */
    white-space: nowrap;
}

/* The role already appears in the top-bar user chip; a second copy under
   the logo was pure repetition. */
.sidebar-brand-role { display: none !important; }

/* On a light ground -- the top bar -- the true logo inks are used. */
.aa-crumbs .wm-arm, .topbar .wm-arm { color: #020AC7; }
.aa-crumbs .wm-ann, .topbar .wm-ann { color: #008301; }

/* Cashier hero: name on the left, clock on the right. */
.aa-hero-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--arm-s4);
    flex-wrap: wrap;
}
.hero-branch {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 6px 0 0 !important;
    font-size: .88rem;
    font-weight: 600;
    color: rgba(255, 255, 255, .9) !important;
}
.hero-branch i { opacity: .75; font-size: .82rem; }
.hero-clockbox { text-align: right; }
.hero-clockbox .hero-clock {
    font-family: var(--arm-font-num);
    font-variant-numeric: tabular-nums;
    font-size: 1.45rem;
    font-weight: 700;
    line-height: 1.1;
    color: #fff;
}
.hero-clockbox .hero-date {
    font-size: .76rem;
    color: rgba(255, 255, 255, .78);
    margin-top: 2px;
}
@media (max-width: 640px) {
    .hero-clockbox { text-align: left; }
}

/* =====================================================================
 * PAGE NAVIGATION
 * ---------------------------------------------------------------------
 * No transition effect. Clicking a module loads that module -- nothing
 * fades, slides or cross-dissolves, because an animation between two
 * pages that look nearly identical is just a delay wearing a costume,
 * and at a counter the fastest thing is the one that simply appears.
 *
 * What IS kept is the one thing that made switching feel rough: the
 * browser painting its own white between documents. Giving <html> the
 * app's background means the gap is the app's colour, so a page change
 * reads as the content swapping rather than the screen flashing.
 * ===================================================================== */
html {
    background: var(--arm-bg);
}

/* =====================================================================
 * LEGIBILITY PASS
 * ---------------------------------------------------------------------
 * The first cut of this theme was tuned for density and came out too
 * small to read comfortably on a counter screen, which is usually a
 * cheap monitor at arm's length under fluorescent light rather than a
 * laptop at 60cm. Everything below is a size increase; no colours,
 * spacing rhythm or semantics change.
 *
 * Base body text goes 15px -> 16px, which is also the size that stops
 * iOS zooming the page when a field is focused. Table text, which is
 * where staff spend their attention, gets the biggest lift.
 * ===================================================================== */

body {
    font-size: 16px;
    line-height: 1.6;
}

/* ---- tables: the densest and most-read surface --------------------- */
.table,
table.products,
table.table {
    font-size: .95rem;          /* was .9rem, and inheriting 15px */
}

.table > :not(caption) > * > *,
table.products td,
table.products th {
    padding: 12px 16px;         /* was 10px 14px */
}

.table thead th,
table thead th,
.table-dark th,
thead.table-dark th,
table.products thead th {
    font-size: .78rem;          /* was .68rem -- column headers were tiny */
    letter-spacing: .05em;
}

.table tbody td,
table.products td {
    font-size: .95rem;
    line-height: 1.45;
}

code, .product-code {
    font-size: .88em;           /* was .82em */
}

/* ---- labels and chips --------------------------------------------- */
.stat-label,
.cashier-stat-label,
.aa-stat .stat-label {
    font-size: .76rem !important;   /* was .68rem */
    letter-spacing: .07em;
}

.form-label {
    font-size: .8rem;               /* was .72rem */
    letter-spacing: .04em;
}

.badge,
.badge-state {
    font-size: .76rem;              /* was .68rem */
    padding: 5px 11px;
}
.badge::before { width: 7px; height: 7px; }

/* ---- figures ------------------------------------------------------- */
.stat-number, .stat-value, .cashier-stat-value {
    font-size: clamp(1.25rem, 2.1vw, 1.8rem);
}
.stat-sub, .cashier-stat-card small { font-size: .8rem; }

/* ---- navigation ---------------------------------------------------- */
.sidebar a,
.sidebar-link,
.sidebar-dropdown-toggle {
    font-size: .95rem;              /* was .875rem */
}
.sidebar-submenu a {
    font-size: .9rem;               /* was .83rem */
    min-height: 42px;
}
.sidebar a i,
.sidebar-link i,
.sidebar-dropdown-toggle i:first-child {
    font-size: 1.02rem;
    width: 20px;
}
.sidebar-section { font-size: .72rem; }

/* ---- controls ------------------------------------------------------ */
.btn      { font-size: .93rem; min-height: 42px; padding: 10px 18px; }
.btn-sm   { font-size: .86rem; min-height: 36px; padding: 6px 13px; }
.nav-tabs .nav-link { font-size: .92rem; padding: 11px 16px; }

.form-control, .form-select,
.record-input, .record-select {
    font-size: 16px;
    min-height: 44px;
    padding: 10px 14px;
}

/* ---- panels and headings ------------------------------------------- */
.card-header, .panel-head, .content-head, .records-header,
.product-panel-head {
    font-size: 1rem;
}
.hero h2, .hero h3, .welcome-panel h3, .page-hero h2 { font-size: 1.55rem; }
.hero p, .welcome-panel p { font-size: .98rem; }
.hero .kicker, .hero-kicker, .page-hero .kicker { font-size: .74rem; }

.empty-state, .empty-products, .empty-fetch { font-size: .95rem; }
.alert { font-size: .95rem; }

/* On a small screen the extra size would cause horizontal scrolling in
   wide tables, so ease it back and let the container scroll instead. */
@media (max-width: 768px) {
    .table, table.products { font-size: .9rem; }
    .table > :not(caption) > * > * { padding: 10px 12px; }
}
