/* ============================================================
   MISTEAMS — app-side UI layer

   The card-and-button vocabulary from the daylight POS deployment,
   ported onto this app's Bootstrap 3 chrome.

   It is written as a restyle of the markup that is already there —
   .panel, .table, .btn, .form-control — rather than a new set of
   classes, so every logged-in page picks the new look up without its
   own edit. The .mis-stat-* block at the bottom is the one addition:
   dashboards have nowhere to put a figure today.

   Loaded from _Layout.cshtml only. The public site renders under
   _LayoutBlog.cshtml and never sees this file, so the v18 redesign is
   untouched.

   ACCENT: daylight's own accent is violet #8b5cf6. This app is green,
   and its public site, account forms and navbar are all built on
   #1E9E5A, so the port keeps the green and takes daylight's structure,
   depth and motion. To follow daylight literally, change the
   --mis-accent* values in Site.css and nothing else.
   ============================================================ */

:root {
    /* The accent lives in Site.css, which every layout loads. Repeating it
       here is what let the two drift apart. */

    --mis-ink:      #111827;
    --mis-muted:    #6b7280;
    --mis-faint:    #9ca3af;
    --mis-line:     #e5e7eb;
    --mis-line-soft:#f3f4f6;
    --mis-surface:  #ffffff;
    --mis-ground:   #f4f4f4;

    /* daylight's semantic set, kept as-is: these carry meaning, not brand */
    --mis-danger:   #ef4444;
    --mis-danger-d: #dc2626;
    --mis-warn:     #f59e0b;
    --mis-warn-d:   #d97706;
    --mis-info:     #0ea5e9;
    --mis-info-d:   #0284c7;
    --mis-ok:       #10b981;
    --mis-ok-d:     #059669;

    --mis-radius:    12px;
    --mis-radius-sm: 10px;
    --mis-shadow:    0 2px 10px rgba(0, 0, 0, .07);
    --mis-shadow-up: 0 4px 10px rgba(16, 24, 40, .16);
    --mis-shadow-in: 0 1px 2px rgba(16, 24, 40, .12);
}

/* ------------------------------------------------------------
   Top bar

   The colour stays the dark green the app already wears; what
   changes is the weight of it. Site.css hangs a 6px grey blur under
   the bar (box-shadow: 0 8px 6px -4px #999) which reads as a smear
   on a light page - daylight's bar sits flat on the content instead.
   ------------------------------------------------------------ */
.navbar-fixed-top {
    box-shadow: 0 1px 3px rgba(16, 24, 40, .12) !important;
    border: 0;
}
/* The bar was `darkgreen` (#006400), patched into the flatly bundle, while the
   public site, the account cards and #blogPanelHeading all carry the brand
   #1E9E5A. One green across the app, and the hover/active states follow it
   instead of Site.css's near-black #194619. */
.navbar-default {
    background-color: var(--mis-accent);
    border-color: transparent;
}
.navbar-default .navbar-brand { color: #fff; font-weight: 600; letter-spacing: .2px; }
.navbar-default .navbar-nav > li > a { color: #fff; transition: background-color .15s ease; }
.navbar-default .navbar-nav > li > a:hover,
.navbar-default .navbar-nav > li > a:focus { background-color: var(--mis-accent-dark); color: #fff; }
.navbar-default .navbar-nav > .active > a,
.navbar-default .navbar-nav > .active > a:hover,
.navbar-default .navbar-nav > .active > a:focus,
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .open > a:hover,
.navbar-default .navbar-nav > .open > a:focus { background-color: var(--mis-accent-press); color: #fff; }

/* ------------------------------------------------------------
   Cards

   Bootstrap's .panel is a boxed block with a solid coloured header
   bar. Daylight's card is a white sheet with a quiet border, a soft
   shadow and its title set in ink - the colour goes on the content,
   not around it. .panel-primary and friends keep a 3px accent edge so
   a page that colour-codes its panels still reads.
   ------------------------------------------------------------ */
.body-content .panel {
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius);
    box-shadow: var(--mis-shadow);
    margin-bottom: 18px;
}
.body-content .panel > .panel-heading {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--mis-line);
    border-radius: var(--mis-radius) var(--mis-radius) 0 0;
    color: var(--mis-ink);
    padding: 14px 18px;
}
.body-content .panel > .panel-heading .panel-title,
.body-content .panel > .panel-heading h5,
.body-content .panel > .panel-heading h4,
.body-content .panel > .panel-heading h3 {
    color: var(--mis-ink);
    font-size: 15px;
    font-weight: 600;
    margin: 0;
}
.body-content .panel > .panel-heading a { color: var(--mis-accent); }
.body-content .panel > .panel-body { padding: 18px; }
.body-content .panel > .panel-footer {
    background: var(--mis-line-soft);
    border-top: 1px solid var(--mis-line);
    border-radius: 0 0 var(--mis-radius) var(--mis-radius);
}
/* the colour a panel used to shout with, kept as a 3px edge */
.body-content .panel-primary { border-top: 3px solid var(--mis-accent); }
.body-content .panel-success { border-top: 3px solid var(--mis-ok); }
.body-content .panel-info    { border-top: 3px solid var(--mis-info); }
.body-content .panel-warning { border-top: 3px solid var(--mis-warn); }
.body-content .panel-danger  { border-top: 3px solid var(--mis-danger); }

/* a card that holds only a table should not double its padding */
.body-content .panel > .panel-body > .table:only-child,
.body-content .panel > .table { margin-bottom: 0; }

/* ------------------------------------------------------------
   Tables

   Hairline rules, a muted header row, and a tint on hover. The heavy
   full-grid border is dropped: rows read as rows without being boxed.
   ------------------------------------------------------------ */
.body-content .table > thead > tr > th {
    background: transparent;
    border-bottom: 1px solid var(--mis-line);
    color: var(--mis-muted);
    font-size: 12px;
    font-weight: 600;
    padding: 9px 10px;
    vertical-align: middle;
}
.body-content .table > tbody > tr > td {
    border-top: 1px solid var(--mis-line-soft);
    color: var(--mis-ink);
    padding: 9px 10px;
    vertical-align: middle;
}
.body-content .table-bordered,
.body-content .table-bordered > thead > tr > th,
.body-content .table-bordered > tbody > tr > td { border-left: 0; border-right: 0; }
.body-content .table-hover > tbody > tr:hover { background-color: var(--mis-accent-tint); }
.body-content .table-striped > tbody > tr:nth-of-type(odd) { background-color: #fafbfc; }

/* ------------------------------------------------------------
   Buttons

   Daylight's finish: rounded, weighted, a soft shadow that lifts on
   hover and sinks when pressed. Every button keeps the meaning it
   already had - danger still clears, success still confirms - so
   nothing has to be re-learned; only the colour and the finish change.
   ------------------------------------------------------------ */
.body-content .btn,
.navbar .btn {
    border: 0;
    border-radius: var(--mis-radius-sm);
    font-weight: 600;
    letter-spacing: .2px;
    text-shadow: none;
    transition: background-color .15s ease, box-shadow .15s ease, transform .06s ease;
}
.body-content .btn-primary,
.body-content .btn-success,
.body-content .btn-danger,
.body-content .btn-warning,
.body-content .btn-info {
    box-shadow: 0 1px 2px rgba(16, 24, 40, .08), 0 2px 6px rgba(16, 24, 40, .10);
    color: #fff;
}
.body-content .btn-primary:hover, .body-content .btn-success:hover,
.body-content .btn-danger:hover,  .body-content .btn-warning:hover,
.body-content .btn-info:hover {
    box-shadow: var(--mis-shadow-up);
    transform: translateY(-1px);
}
.body-content .btn-primary:active, .body-content .btn-success:active,
.body-content .btn-danger:active,  .body-content .btn-warning:active,
.body-content .btn-info:active {
    box-shadow: var(--mis-shadow-in);
    transform: translateY(0);
}
.body-content .btn:focus, .body-content .btn:active:focus { outline: 0; }

.body-content .btn-primary { background-color: var(--mis-accent); }
.body-content .btn-primary:hover,
.body-content .btn-primary:focus,
.body-content .btn-primary.active { background-color: var(--mis-accent-dark); }
.body-content .btn-primary:active { background-color: var(--mis-accent-press); }

.body-content .btn-success { background-color: var(--mis-ok); }
.body-content .btn-success:hover, .body-content .btn-success:focus { background-color: var(--mis-ok-d); }

.body-content .btn-danger { background-color: var(--mis-danger); }
.body-content .btn-danger:hover, .body-content .btn-danger:focus { background-color: var(--mis-danger-d); }

.body-content .btn-warning { background-color: var(--mis-warn); }
.body-content .btn-warning:hover, .body-content .btn-warning:focus { background-color: var(--mis-warn-d); }

.body-content .btn-info { background-color: var(--mis-info); }
.body-content .btn-info:hover, .body-content .btn-info:focus { background-color: var(--mis-info-d); }

.body-content .btn-default {
    background-color: var(--mis-surface);
    border: 1px solid var(--mis-line);
    color: var(--mis-ink);
}
.body-content .btn-default:hover, .body-content .btn-default:focus {
    background-color: var(--mis-line-soft);
    border-color: #d8dee7;
    color: var(--mis-ink);
}

/* disabled must read as inert, not merely dimmed colour */
.body-content .btn[disabled],
.body-content .btn.disabled {
    background-color: #e2e8f0 !important;
    border-color: #e2e8f0 !important;
    box-shadow: none !important;
    color: #94a3b8 !important;
    opacity: 1;
    transform: none !important;
}

/* ------------------------------------------------------------
   Form controls
   ------------------------------------------------------------ */
.body-content .form-control {
    border: 1px solid var(--mis-line);
    border-radius: 8px;
    box-shadow: none;
    color: var(--mis-ink);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.body-content .form-control:focus {
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(30, 158, 90, .12);
}
.body-content label { color: var(--mis-ink); font-weight: 600; }
.body-content .input-group-addon {
    background: var(--mis-line-soft);
    border: 1px solid var(--mis-line);
    border-radius: 8px;
    color: var(--mis-muted);
}

/* ------------------------------------------------------------
   Page furniture
   ------------------------------------------------------------ */
.body-content .nav-tabs { border-bottom: 1px solid var(--mis-line); }
.body-content .nav-tabs > li > a { border: 0; color: var(--mis-muted); font-weight: 600; }
.body-content .nav-tabs > li.active > a,
.body-content .nav-tabs > li.active > a:hover,
.body-content .nav-tabs > li.active > a:focus {
    background: transparent;
    border: 0;
    border-bottom: 2px solid var(--mis-accent);
    color: var(--mis-ink);
}
.body-content .alert { border: 0; border-radius: var(--mis-radius-sm); }
.body-content .modal-content { border: 0; border-radius: var(--mis-radius); box-shadow: 0 12px 40px rgba(16, 24, 40, .18); }
.body-content .modal-header, .body-content .modal-footer { border-color: var(--mis-line); }
.body-content hr { border-top: 1px solid var(--mis-line); }
.body-content .well {
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius);
    box-shadow: none;
}

/* ------------------------------------------------------------
   Stat tiles

   The one new component: an icon chip, a quiet label and the figure.
   Straight from daylight's dashboard, for pages that want to lead
   with numbers.

       <div class="mis-stat-row row">
         <div class="col-md-3 col-sm-6 col-xs-12">
           <div class="mis-stat-card">
             <div class="mis-stat-icon"><i class="fa fa-users"></i></div>
             <div class="mis-stat-info">
               <p class="mis-stat-label">Total staff</p>
               <p class="mis-stat-value">128</p>
             </div>
           </div>
         </div>
       </div>

   Colour a tile by adding a modifier to the icon chip:
   .is-ok / .is-warn / .is-danger / .is-info. Default is the accent.
   ------------------------------------------------------------ */
.mis-stat-row { display: flex; flex-wrap: wrap; }
.mis-stat-row > [class*="col-"] { display: flex; }
.mis-stat-row .mis-stat-card { width: 100%; }

.mis-stat-card {
    align-items: center;
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius);
    box-shadow: var(--mis-shadow);
    display: flex;
    gap: 14px;
    margin-bottom: 18px;
    padding: 16px 18px;
}
.mis-stat-icon {
    align-items: center;
    background: var(--mis-accent-tint);
    border-radius: var(--mis-radius-sm);
    color: var(--mis-accent);
    display: flex;
    flex-shrink: 0;
    font-size: 22px;
    height: 54px;
    justify-content: center;
    width: 54px;
}
.mis-stat-icon.is-ok     { background: #d1fae5; color: var(--mis-ok-d); }
.mis-stat-icon.is-warn   { background: #fef3c7; color: var(--mis-warn-d); }
.mis-stat-icon.is-danger { background: #fee2e2; color: var(--mis-danger-d); }
.mis-stat-icon.is-info   { background: #e0f2fe; color: var(--mis-info-d); }

.mis-stat-info { flex: 1; min-width: 0; }
.mis-stat-info .mis-stat-label {
    color: var(--mis-muted);
    font-size: 12px;
    font-weight: 500;
    margin: 0 0 3px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mis-stat-info .mis-stat-value {
    color: var(--mis-ink);
    font-size: 20px;
    font-weight: 700;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* section heading above a group of cards */
.mis-section-title { color: var(--mis-ink); font-size: 18px; font-weight: 600; margin: 0 0 12px; }
.mis-section-title small { color: var(--mis-faint); font-size: 13px; font-weight: 400; }

/* "nothing here yet", inside a card */
.mis-empty { color: var(--mis-faint); padding: 18px 0; text-align: center; }

/* ------------------------------------------------------------
   Print: drop the chrome and the depth, keep the content
   ------------------------------------------------------------ */
@media print {
    .navbar, #footer, .no-print { display: none !important; }
    .body-content { margin-top: 0 !important; }
    .body-content .panel,
    .mis-stat-card { box-shadow: none; }
}

/* ============================================================
   The shell — dark sidebar + top header

   Used by _LayoutAdmin.cshtml. It lives here rather than in that
   file so the same chrome can be put behind every app-side page
   later by pointing _ViewStart at the admin layout; nothing below
   is specific to one screen.

   The sidebar is dark on purpose against the light workspace: it
   is chrome, not content, and the eye should skip it once the
   page is open.
   ============================================================ */
:root {
    --mis-side:        #FFFFFF;   /* a light rail: the nav is a surface, not a shadow */
    --mis-side-2:      #F2F5F8;
    --mis-side-ink:    #1F2A37;
    --mis-side-muted:  #6B7A90;
    --mis-side-line:   #E6EAF0;
    --mis-side-w:      252px;
    --mis-top-h:       60px;
}

body.mis-shell-body { padding: 0 !important; }

.mis-shell { display: grid; grid-template-columns: var(--mis-side-w) minmax(0, 1fr); min-height: 100vh; }

/* ---- sidebar ---- */
.mis-side {
    background: var(--mis-side);
    color: var(--mis-side-ink);
    display: flex;
    flex-direction: column;
    max-height: 100vh;
    overflow-y: auto;
    padding-bottom: 18px;
    position: sticky;
    top: 0;
}
.mis-side::-webkit-scrollbar { width: 8px; }
.mis-side::-webkit-scrollbar-thumb { background: var(--mis-side-line); border-radius: 4px; }

.mis-brand {
    align-items: center;
    border-bottom: 1px solid var(--mis-side-line);
    display: flex;
    gap: 11px;
    min-height: var(--mis-top-h);
    padding: 12px 16px;
    text-decoration: none;
}
.mis-brand:hover, .mis-brand:focus { text-decoration: none; }
.mis-brand-mark {
    align-items: center;
    background: var(--mis-accent);
    border-radius: 10px;
    color: #fff;
    display: flex;
    flex: none;
    font-size: 13px;
    font-weight: 700;
    height: 34px;
    justify-content: center;
    letter-spacing: .5px;
    width: 34px;
}
.mis-brand-name { color: var(--mis-side-ink); font-size: 14.5px; font-weight: 600; letter-spacing: .3px; line-height: 1.2; }
.mis-brand-sub { color: var(--mis-side-muted); font-size: 10.5px; letter-spacing: .5px; text-transform: uppercase; }

.mis-nav { padding: 0 10px; }
.mis-nav-label {
    color: var(--mis-side-muted);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
    padding: 15px 10px 6px;
    text-transform: uppercase;
}
.mis-nav a, .mis-nav .mis-nav-toggle {
    align-items: center;
    background: none;
    border: 0;
    border-radius: 9px;
    color: var(--mis-side-ink);
    cursor: pointer;
    display: flex;
    font-size: 13.5px;
    gap: 10px;
    padding: 9px 10px;
    text-align: left;
    text-decoration: none;
    transition: background-color .14s ease;
    width: 100%;
}
.mis-nav a:hover, .mis-nav .mis-nav-toggle:hover,
.mis-nav a:focus { background: var(--mis-side-2); color: var(--mis-side-ink); text-decoration: none; }
.mis-nav a.is-active { background: var(--mis-accent-tint); color: var(--mis-accent); font-weight: 600; }
.mis-nav .glyphicon { flex: none; font-size: 13px; opacity: .8; width: 16px; }
.mis-nav a.is-active .glyphicon { opacity: 1; }
.mis-nav .caret { margin-left: auto; opacity: .6; }
.mis-nav-toggle[aria-expanded="true"] .caret { transform: rotate(180deg); }

.mis-subnav { display: grid; margin: 2px 0 4px 26px; }
.mis-subnav[hidden] { display: none; }
.mis-subnav a {
    border-left: 1px solid var(--mis-side-line);
    border-radius: 0;
    color: var(--mis-side-muted);
    font-size: 13px;
    padding: 6px 0 6px 12px;
}
.mis-subnav a:hover { background: none; border-left-color: var(--mis-accent); color: var(--mis-side-ink); }

/* ---- top header ---- */
.mis-main { display: flex; flex-direction: column; min-width: 0; }

.mis-top {
    align-items: center;
    background: var(--mis-surface);
    border-bottom: 1px solid var(--mis-line);
    display: flex;
    gap: 14px;
    min-height: var(--mis-top-h);
    padding: 10px 22px;
    position: sticky;
    top: 0;
    z-index: 30;
}
.mis-top-crumb { color: var(--mis-muted); font-size: 11.5px; letter-spacing: .3px; }
.mis-top h1 { color: var(--mis-ink); font-size: 17px; font-weight: 600; letter-spacing: -.2px; margin: 1px 0 0; }
.mis-top-spacer { flex: 1 1 auto; }
.mis-top .mis-user {
    align-items: center;
    background: var(--mis-accent-tint);
    border-radius: 999px;
    color: var(--mis-accent);
    display: inline-flex;
    font-size: 12.5px;
    font-weight: 600;
    gap: 8px;
    padding: 4px 13px 4px 5px;
}
.mis-top .mis-user .mis-face {
    align-items: center;
    background: var(--mis-accent);
    border-radius: 999px;
    color: #fff;
    display: flex;
    font-size: 11px;
    height: 26px;
    justify-content: center;
    width: 26px;
}
.mis-top .mis-lang { margin: 0; }
.mis-logout {
    background: none;
    border: 1px solid var(--mis-line);
    border-radius: 999px;
    color: var(--mis-muted);
    cursor: pointer;
    font-size: 12.5px;
    padding: 5px 13px;
    transition: border-color .14s ease, color .14s ease;
}
.mis-logout:hover { border-color: var(--mis-danger); color: var(--mis-danger); }

.mis-content { padding: 22px 22px 40px; }
.mis-foot { border-top: 1px solid var(--mis-line); color: var(--mis-muted); font-size: 12px; margin-top: auto; padding: 14px 22px; }

@media (max-width: 991px) {
    .mis-shell { grid-template-columns: 1fr; }
    .mis-side { flex-direction: row; gap: 6px; max-height: none; overflow-x: auto; padding: 8px 10px; position: static; }
    .mis-side .mis-nav-label, .mis-side .mis-subnav, .mis-side .mis-brand-sub, .mis-side .caret { display: none; }
    .mis-side .mis-brand { border: 0; min-height: 0; padding: 0 8px 0 0; }
    .mis-nav { display: flex; padding: 0; }
    .mis-nav a, .mis-nav .mis-nav-toggle { white-space: nowrap; width: auto; }
    .mis-content { padding: 16px 14px 32px; }
    .mis-top { padding: 10px 14px; }
}

/* Printing goes through this shell too — AdminFormats/RenderReport and the
   report views print from inside it, so the rail and the header have to step
   out of the way and the grid has to collapse to one column. */
@media print {
    .mis-shell { display: block; }
    .mis-side, .mis-top, .mis-foot { display: none !important; }
    .mis-content { padding: 0 !important; }
}

/* ============================================================
   Button corners and density — a correction to the block above

   One radius for every button was wrong. The tables in this app are
   built from .btn-xs and .btn-sm icon buttons (48 and 56 views), and
   a 10px corner on a 22px control turns it into a blob; the lift and
   the drop shadow, fine on a real button, read as smudge under a row
   of six of them. Corner radius now scales with the control, and the
   depth is reserved for buttons big enough to carry it.

   Grouped controls get their joins back too: Bootstrap squares the
   inner corners of .input-group and .btn-group members so they read
   as one control, and the blanket radius above had broken that.
   ============================================================ */

.body-content .btn { border-radius: 8px; }
.body-content .btn-sm, .body-content .btn-group-sm > .btn { border-radius: 7px; }
.body-content .btn-xs, .body-content .btn-group-xs > .btn { border-radius: 6px; }
.body-content .btn-lg, .body-content .btn-group-lg > .btn { border-radius: 10px; }

/* small buttons sit flat: no shadow, no lift, just a colour change */
.body-content .btn-sm, .body-content .btn-xs,
.body-content .btn-group-sm > .btn, .body-content .btn-group-xs > .btn {
    box-shadow: none !important;
}
.body-content .btn-sm:hover, .body-content .btn-xs:hover,
.body-content .btn-sm:active, .body-content .btn-xs:active {
    box-shadow: none !important;
    transform: none !important;
}

/* a row of small buttons needs air between them, not a shared edge */
.body-content td .btn + .btn,
.body-content th .btn + .btn { margin-left: 4px; }

/* ---- grouped controls: square the joins, round only the outer ends ---- */
.body-content .btn-group > .btn,
.body-content .btn-group-vertical > .btn,
.body-content .input-group > .form-control,
.body-content .input-group-btn > .btn,
.body-content .input-group-addon { border-radius: 0; }

.body-content .btn-group > .btn:first-child:not(:last-child),
.body-content .input-group > .form-control:first-child,
.body-content .input-group-addon:first-child,
.body-content .input-group-btn:first-child > .btn {
    border-bottom-left-radius: 8px;
    border-top-left-radius: 8px;
}
.body-content .btn-group > .btn:last-child:not(:first-child),
.body-content .btn-group > .dropdown-toggle:not(:first-child),
.body-content .input-group > .form-control:last-child,
.body-content .input-group-addon:last-child,
.body-content .input-group-btn:last-child > .btn {
    border-bottom-right-radius: 8px;
    border-top-right-radius: 8px;
}
.body-content .btn-group > .btn:only-child { border-radius: 8px; }

.body-content .btn-group-vertical > .btn:first-child:not(:last-child) {
    border-top-left-radius: 8px; border-top-right-radius: 8px;
}
.body-content .btn-group-vertical > .btn:last-child:not(:first-child) {
    border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;
}

/* a grouped button keeps a hairline so it does not float free of its input */
.body-content .input-group-btn > .btn { border: 1px solid var(--mis-line); }
.body-content .input-group-btn > .btn-primary,
.body-content .input-group-btn > .btn-success,
.body-content .input-group-btn > .btn-danger,
.body-content .input-group-btn > .btn-warning,
.body-content .input-group-btn > .btn-info { border-color: transparent; }

/* dropdown toggles inside the content keep the same corner language */
.body-content .dropdown-menu { border: 1px solid var(--mis-line); border-radius: 10px; box-shadow: var(--mis-shadow); padding: 6px; }
.body-content .dropdown-menu > li > a { border-radius: 7px; padding: 7px 10px; }

/* ============================================================
   Rail, header search and tile grid

   The structure here follows the admin-panel convention the user
   pointed at (light rail, search in the header, a card grid with a
   status pill per item). The palette stays this app's green — the
   layout is the borrowed idea, the brand is not.
   ============================================================ */

/* the rail now sits on white, so it needs an edge rather than contrast */
.mis-side { border-right: 1px solid var(--mis-side-line); }
.mis-brand { border-bottom: 1px solid var(--mis-side-line); }
.mis-nav a .glyphicon, .mis-nav .mis-nav-toggle .glyphicon { color: var(--mis-side-muted); opacity: 1; }
.mis-nav a.is-active .glyphicon { color: var(--mis-accent); }
.mis-nav a:hover .glyphicon { color: var(--mis-side-ink); }

/* the signed-in user, pinned to the foot of the rail */
.mis-side-user {
    align-items: center;
    border-top: 1px solid var(--mis-side-line);
    display: flex;
    gap: 10px;
    margin-top: auto;
    padding: 12px 16px;
}
.mis-side-user .mis-face {
    align-items: center;
    background: var(--mis-accent);
    border-radius: 999px;
    color: #fff;
    display: flex;
    flex: none;
    font-size: 12px;
    font-weight: 600;
    height: 32px;
    justify-content: center;
    width: 32px;
}
.mis-side-user .mis-side-name { color: var(--mis-side-ink); font-size: 13px; font-weight: 600; line-height: 1.25; }
.mis-side-user .mis-side-role { color: var(--mis-side-muted); font-size: 11.5px; }

/* ---- header search ---- */
.mis-search { flex: 0 1 380px; position: relative; }
.mis-search input {
    background: var(--mis-surface-2, #FAF9FD);
    border: 1px solid var(--mis-line);
    border-radius: 10px;
    color: var(--mis-ink);
    font-size: 13.5px;
    height: 38px;
    padding: 0 62px 0 36px;
    width: 100%;
}
.mis-search input:focus {
    background: var(--mis-surface);
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(30, 158, 90, .12);
    outline: 0;
}
.mis-search .glyphicon-search {
    color: var(--mis-muted);
    font-size: 13px;
    left: 12px;
    pointer-events: none;
    position: absolute;
    top: 12px;
}
.mis-search kbd {
    background: var(--mis-line-soft);
    border: 1px solid var(--mis-line);
    border-radius: 6px;
    box-shadow: none;
    color: var(--mis-muted);
    font-size: 11px;
    padding: 2px 6px;
    position: absolute;
    right: 8px;
    top: 8px;
}
.mis-top-icon {
    background: none;
    border: 0;
    border-radius: 9px;
    color: var(--mis-muted);
    height: 34px;
    position: relative;
    width: 34px;
}
.mis-top-icon:hover { background: var(--mis-line-soft); color: var(--mis-ink); }
.mis-top-icon .mis-badge {
    background: var(--mis-danger);
    border-radius: 999px;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    padding: 2px 5px;
    position: absolute;
    right: 1px;
    top: 1px;
}
.mis-top .mis-id { align-items: center; display: flex; gap: 9px; }
.mis-top .mis-id .mis-face {
    align-items: center; background: var(--mis-accent); border-radius: 999px; color: #fff;
    display: flex; font-size: 12px; font-weight: 600; height: 34px; justify-content: center; width: 34px;
}
.mis-top .mis-id-name { color: var(--mis-ink); font-size: 13px; font-weight: 600; line-height: 1.2; }
.mis-top .mis-id-sub { color: var(--mis-muted); font-size: 11.5px; }

/* ---- page head: title, description, primary action ---- */
.mis-page-head { align-items: flex-start; display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
.mis-page-head h2 { color: var(--mis-ink); font-size: 24px; font-weight: 700; letter-spacing: -.4px; margin: 0; }
.mis-page-head p { color: var(--mis-muted); font-size: 13.5px; margin: 5px 0 0; }
.mis-page-head .mis-page-action { margin-left: auto; }

/* ---- toolbar: search + filter, on its own card ---- */
.mis-toolbar {
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius);
    box-shadow: var(--mis-shadow);
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 18px;
    padding: 14px 16px;
}
.mis-toolbar .mis-toolbar-search { flex: 1 1 260px; position: relative; }
.mis-toolbar .mis-toolbar-search input {
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: 10px;
    color: var(--mis-ink);
    height: 40px;
    padding: 0 12px 0 36px;
    width: 100%;
}
.mis-toolbar .mis-toolbar-search input:focus {
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(30, 158, 90, .12);
    outline: 0;
}
.mis-toolbar .mis-toolbar-search .glyphicon { color: var(--mis-muted); font-size: 13px; left: 13px; position: absolute; top: 13px; }

/* ---- tile grid ---- */
.mis-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); }

.mis-tile {
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius);
    box-shadow: var(--mis-shadow);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: box-shadow .16s ease, transform .16s ease;
}
.mis-tile:hover { box-shadow: var(--mis-shadow-up); transform: translateY(-2px); }
.mis-tile-media {
    align-items: center;
    background: var(--mis-line-soft);
    color: var(--mis-muted);
    display: flex;
    font-size: 34px;
    height: 132px;
    justify-content: center;
    position: relative;
}
.mis-tile-media img { height: 100%; object-fit: cover; width: 100%; }
.mis-tile-body { display: flex; flex: 1; flex-direction: column; gap: 4px; padding: 14px 15px 15px; }
.mis-tile-title { color: var(--mis-ink); font-size: 14.5px; font-weight: 600; margin: 0; }
.mis-tile-meta { color: var(--mis-muted); font-size: 12px; }
.mis-tile-foot { align-items: center; display: flex; gap: 10px; margin-top: 8px; }
.mis-tile-lead { color: var(--mis-accent); font-size: 17px; font-weight: 700; }
.mis-tile-foot .mis-pill { margin-left: auto; }
.mis-tile-rows { border-top: 1px solid var(--mis-line-soft); margin-top: 11px; padding-top: 9px; }
.mis-tile-row { color: var(--mis-muted); display: flex; font-size: 12.5px; justify-content: space-between; padding: 2px 0; }
.mis-tile-row b { color: var(--mis-ink); font-weight: 600; }

/* ---- status pill: colour plus a word, never colour alone ---- */
.mis-pill {
    border-radius: 999px;
    display: inline-block;
    font-size: 11.5px;
    font-weight: 600;
    padding: 3px 10px;
    white-space: nowrap;
}
.mis-pill.is-ok     { background: var(--mis-good-tint, #E4F6E4); color: #0B7A0B; }
.mis-pill.is-warn   { background: #FEF3D7; color: #8A5B00; }
.mis-pill.is-danger { background: #FBE7E7; color: #B02A2A; }
.mis-pill.is-muted  { background: var(--mis-line-soft); color: var(--mis-muted); }

@media (max-width: 991px) {
    .mis-side-user { border: 0; margin: 0; padding: 0 8px; }
    .mis-side-user .mis-side-name, .mis-side-user .mis-side-role { display: none; }
    .mis-search { display: none; }
}

/* ============================================================
   Shell v3 — the admin-panel reference

   A third pass over the shell, bringing it to the layout the user
   pointed at: a collapsible white rail, a header that carries only
   navigation aids (search, alerts, identity), and the page title
   moved down into the content where a breadcrumb can sit above it.

   Written as a layer on top of the two blocks above rather than an
   edit to them, so the earlier vocabulary keeps working and this
   file stays readable as a history of the passes.

   Everything here is the reference's STRUCTURE. The palette is
   still this app's green (--mis-accent); the reference's blue lives
   on as --mis-info, which is the role it fills here.
   ============================================================ */

:root {
    --mis-ground:   #F6F8FB;   /* the workspace behind the cards */
    --mis-side-w:   256px;
    --mis-side-w-c: 76px;      /* collapsed rail: icons only */
    --mis-top-h:    62px;
}

/* the rail's collapsed width is a body-level switch so the grid, the
   labels and the hover chips all read the same state */
body.mis-rail-collapsed { --mis-side-w: var(--mis-side-w-c); }

.mis-main { background: var(--mis-ground); }

/* Pace's loading bar is the hairline across the very top of the
   reference. It was a near-white #eff3f9 and invisible against the
   header; give it the accent so it reads as deliberate feedback. */
.pace .pace-progress {
    background: linear-gradient(90deg, var(--mis-accent-md, #35B872), var(--mis-accent));
    height: 3px;
}

/* ------------------------------------------------------------
   Rail — collapse, active marker, group headers
   ------------------------------------------------------------ */
.mis-brand-mark { box-shadow: 0 2px 6px rgba(30, 158, 90, .28); }

/* the active row gets a tick at the rail's edge as well as the tint,
   so the current page is findable without relying on colour alone */
.mis-nav a { position: relative; }
.mis-nav a.is-active::before {
    background: var(--mis-accent);
    border-radius: 0 3px 3px 0;
    bottom: 7px;
    content: "";
    left: -10px;
    position: absolute;
    top: 7px;
    width: 3px;
}
.mis-nav a, .mis-nav .mis-nav-toggle { margin-bottom: 2px; }

/* a group header that opens: label and chevron on one row, matching
   the reference's "Dashboards ⌄" */
.mis-nav .mis-nav-toggle { color: var(--mis-side-ink); font-weight: 500; }
.mis-nav .mis-nav-toggle[aria-expanded="true"] { color: var(--mis-accent); }
.mis-nav .mis-nav-toggle[aria-expanded="true"] .glyphicon { color: var(--mis-accent); }
.mis-nav .caret { border-top-color: currentColor; transition: transform .16s ease; }

.mis-subnav a { position: relative; }
.mis-subnav a.is-active { color: var(--mis-accent); font-weight: 600; }
.mis-subnav a.is-active::before {
    background: var(--mis-accent);
    bottom: 4px;
    content: "";
    left: -1px;
    position: absolute;
    top: 4px;
    width: 2px;
}

/* ---- collapsed rail: icons only, label restored on hover as a chip ---- */
body.mis-rail-collapsed .mis-side { overflow: visible; }
body.mis-rail-collapsed .mis-brand { justify-content: center; padding: 12px 8px; }
/* :not() on both, or the badge and the avatar go with the words —
   they are direct children of the same element as the text block. */
body.mis-rail-collapsed .mis-brand > span:not(.mis-brand-mark),
body.mis-rail-collapsed .mis-nav-label,
body.mis-rail-collapsed .mis-nav .caret,
body.mis-rail-collapsed .mis-subnav,
body.mis-rail-collapsed .mis-side-user > span:not(.mis-face) { display: none; }
body.mis-rail-collapsed .mis-nav { padding: 6px 10px 0; }
body.mis-rail-collapsed .mis-nav a,
body.mis-rail-collapsed .mis-nav .mis-nav-toggle {
    gap: 0;
    justify-content: center;
    padding: 10px 0;
    white-space: nowrap;
}
/* the row's text is a child span so it can be hidden without hiding
   the icon; markup with bare text degrades to a clipped row, not a
   broken one */
body.mis-rail-collapsed .mis-nav-text { display: none; }
body.mis-rail-collapsed .mis-nav .glyphicon { font-size: 15px; width: auto; }
body.mis-rail-collapsed .mis-side-user { justify-content: center; padding: 12px 8px; }
/* a divider stands in for each group's dropped label */
body.mis-rail-collapsed .mis-nav + .mis-nav { border-top: 1px solid var(--mis-side-line); padding-top: 10px; }

/* hover label, so a collapsed rail is still learnable */
body.mis-rail-collapsed .mis-nav .mis-nav-toggle { position: relative; }
body.mis-rail-collapsed .mis-nav a::after,
body.mis-rail-collapsed .mis-nav .mis-nav-toggle::after {
    background: var(--mis-side-ink);
    border-radius: 7px;
    color: #fff;
    content: attr(data-label);
    font-size: 12.5px;
    font-weight: 500;
    left: calc(100% + 8px);
    opacity: 0;
    padding: 5px 10px;
    pointer-events: none;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    transition: opacity .12s ease;
    white-space: nowrap;
    z-index: 60;
}
body.mis-rail-collapsed .mis-nav a:hover::after,
body.mis-rail-collapsed .mis-nav a:focus-visible::after,
body.mis-rail-collapsed .mis-nav .mis-nav-toggle:hover::after,
body.mis-rail-collapsed .mis-nav .mis-nav-toggle:focus-visible::after { opacity: 1; }

/* ------------------------------------------------------------
   Header — hamburger, then only navigation aids

   The page title moved out of here (it now leads the content, under a
   breadcrumb) so the bar reads identically on every screen and the
   search never shifts position.
   ------------------------------------------------------------ */
.mis-top { gap: 10px; padding: 10px 20px; }

.mis-icon-btn {
    align-items: center;
    background: none;
    border: 0;
    border-radius: 9px;
    color: var(--mis-muted);
    cursor: pointer;
    display: inline-flex;
    flex: none;
    height: 36px;
    justify-content: center;
    position: relative;
    transition: background-color .14s ease, color .14s ease;
    width: 36px;
}
.mis-icon-btn:hover, .mis-icon-btn:focus { background: var(--mis-line-soft); color: var(--mis-ink); outline: 0; }
.mis-icon-btn .glyphicon { font-size: 15px; }
.mis-icon-btn .mis-badge {
    background: var(--mis-danger);
    border: 2px solid var(--mis-surface);
    border-radius: 999px;
    color: #fff;
    font-family: Inter, sans-serif;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    padding: 2px 5px;
    position: absolute;
    right: -1px;
    top: -1px;
}

/* a hamburger drawn from three rules rather than an icon font, so it
   is crisp at any zoom and can animate into a close mark */
.mis-burger-bars { display: block; height: 14px; position: relative; width: 17px; }
.mis-burger-bars i {
    background: currentColor;
    border-radius: 2px;
    display: block;
    height: 2px;
    left: 0;
    position: absolute;
    transition: transform .18s ease, opacity .14s ease;
    width: 100%;
}
.mis-burger-bars i:nth-child(1) { top: 0; }
.mis-burger-bars i:nth-child(2) { top: 6px; }
.mis-burger-bars i:nth-child(3) { top: 12px; }
body.mis-drawer-open .mis-burger-bars i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.mis-drawer-open .mis-burger-bars i:nth-child(2) { opacity: 0; }
body.mis-drawer-open .mis-burger-bars i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.mis-top-sep { background: var(--mis-line); flex: none; height: 26px; width: 1px; }

/* identity block: initials, then name over the account it belongs to */
.mis-top .mis-id { flex: none; }
.mis-top .mis-id-text { line-height: 1.25; min-width: 0; }
.mis-top .mis-id-name,
.mis-top .mis-id-sub {
    display: block;
    max-width: 190px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mis-top .mis-id .mis-face { box-shadow: 0 2px 6px rgba(30, 158, 90, .3); }

/* the logout button loses its outline and joins the icon row */
.mis-logout {
    align-items: center;
    border: 0;
    border-radius: 9px;
    display: inline-flex;
    flex: none;
    gap: 6px;
    padding: 7px 11px;
    transition: background-color .14s ease, color .14s ease;
}
.mis-logout:hover { background: #FBE7E7; border: 0; color: var(--mis-danger-d); }
#logoutForm { margin: 0; }

.mis-search input { background: var(--mis-ground); }
.mis-search kbd { font-family: Inter, sans-serif; }

/* ------------------------------------------------------------
   Content head — breadcrumb, then the page's own title
   ------------------------------------------------------------ */
.mis-content { padding: 18px 22px 44px; }

.mis-crumb {
    align-items: center;
    color: var(--mis-muted);
    display: flex;
    flex-wrap: wrap;
    font-size: 12.5px;
    gap: 7px;
    margin: 0 0 14px;
}
.mis-crumb a { color: var(--mis-muted); text-decoration: none; }
.mis-crumb a:hover { color: var(--mis-accent); }
.mis-crumb .glyphicon-home { font-size: 12px; }
.mis-crumb .mis-crumb-sep { color: var(--mis-faint); font-size: 9px; }
.mis-crumb .mis-crumb-now { color: var(--mis-ink); font-weight: 600; }

.mis-page-head { margin-bottom: 20px; }
.mis-page-head h2 { font-size: 27px; line-height: 1.2; }
.mis-page-head p { font-size: 13.5px; margin-top: 6px; }

/* ------------------------------------------------------------
   KPI card

   The reference's summary tile: the figure leads, the icon is a quiet
   chip in the corner, and the change since the last period sits below
   as a badge with an arrow. Kept separate from .mis-stat-card (the
   icon-beside-figure form) because pages already use that one and its
   proportions are different.
   ------------------------------------------------------------ */
.mis-kpi-row {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
    margin-bottom: 18px;
}

.mis-kpi {
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius);
    box-shadow: var(--mis-shadow);
    display: flex;
    gap: 12px;
    padding: 17px 18px;
    transition: box-shadow .16s ease, transform .16s ease;
}
.mis-kpi:hover { box-shadow: var(--mis-shadow-up); transform: translateY(-2px); }
.mis-kpi-body { flex: 1; min-width: 0; }
.mis-kpi-label {
    color: var(--mis-muted);
    font-size: 12.5px;
    font-weight: 500;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mis-kpi-value {
    color: var(--mis-ink);
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -.6px;
    line-height: 1.15;
    margin: 6px 0 0;
}
.mis-kpi-foot {
    align-items: center;
    color: var(--mis-faint);
    display: flex;
    flex-wrap: wrap;
    font-size: 11.5px;
    gap: 7px;
    margin: 10px 0 0;
}

.mis-kpi-chip {
    align-items: center;
    background: var(--mis-accent-tint);
    border-radius: var(--mis-radius-sm);
    color: var(--mis-accent);
    display: flex;
    flex: none;
    font-size: 17px;
    height: 42px;
    justify-content: center;
    width: 42px;
}
.mis-kpi-chip.is-ok     { background: #D1FAE5; color: var(--mis-ok-d); }
.mis-kpi-chip.is-warn   { background: #FEF3C7; color: var(--mis-warn-d); }
.mis-kpi-chip.is-danger { background: #FEE2E2; color: var(--mis-danger-d); }
.mis-kpi-chip.is-info   { background: #E0F2FE; color: var(--mis-info-d); }

/* the change badge: an arrow plus the number, never colour alone */
.mis-delta {
    align-items: center;
    border-radius: 999px;
    display: inline-flex;
    font-family: Inter, sans-serif;
    font-size: 11.5px;
    font-weight: 700;
    gap: 3px;
    padding: 2px 8px;
}
.mis-delta.is-up   { background: #E4F6E4; color: #0B7A0B; }
.mis-delta.is-down { background: #FBE7E7; color: #B02A2A; }
.mis-delta.is-flat { background: var(--mis-line-soft); color: var(--mis-muted); }
.mis-delta .glyphicon { font-size: 9px; }

/* ------------------------------------------------------------
   Card head with controls, and list rows inside a card

   The reference's lower half is two cards of rows: a name over a
   subtitle on the left, a figure over a status on the right. That is
   the shape of this app's access log and of most of its "latest N"
   panels, so it gets a named component.
   ------------------------------------------------------------ */
.body-content .panel > .panel-heading { padding: 15px 18px; }
.body-content .panel > .panel-heading .panel-title { font-size: 15.5px; }

.mis-list { list-style: none; margin: 0; padding: 0; }
.mis-list > li {
    align-items: center;
    border-top: 1px solid var(--mis-line-soft);
    display: flex;
    gap: 12px;
    padding: 11px 2px;
}
.mis-list > li:first-child { border-top: 0; }
.mis-list-main { flex: 1; min-width: 0; }
.mis-list-title {
    color: var(--mis-ink);
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mis-list-sub {
    color: var(--mis-muted);
    font-size: 12px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mis-list-side { flex: none; text-align: right; }
.mis-list-lead { color: var(--mis-ink); font-size: 13.5px; font-weight: 700; }
.mis-list-side .mis-pill { margin-top: 4px; }

/* ------------------------------------------------------------
   Settings button, bottom right

   In the reference this floats over the content as a theme picker.
   Here it goes to the one settings screen this app has, so it is a
   link rather than a popover.
   ------------------------------------------------------------ */
.mis-fab {
    align-items: center;
    background: var(--mis-accent);
    border-radius: 999px;
    bottom: 22px;
    box-shadow: 0 6px 18px rgba(30, 158, 90, .38);
    color: #fff;
    display: flex;
    height: 48px;
    justify-content: center;
    position: fixed;
    right: 22px;
    transition: background-color .15s ease, box-shadow .15s ease, transform .15s ease;
    width: 48px;
    z-index: 40;
}
.mis-fab:hover, .mis-fab:focus {
    background: var(--mis-accent-dark);
    box-shadow: 0 8px 22px rgba(30, 158, 90, .46);
    color: #fff;
    text-decoration: none;
    transform: translateY(-2px);
}
.mis-fab .glyphicon { font-size: 18px; transition: transform .5s ease; }
.mis-fab:hover .glyphicon { transform: rotate(90deg); }

/* ------------------------------------------------------------
   Narrow screens — the rail becomes a drawer

   The earlier pass turned it into a horizontal scrolling strip, which
   drops the group labels and the sub-menus. A drawer keeps the whole
   navigation intact, which matters most on the screen where least of
   it is visible.
   ------------------------------------------------------------ */
@media (max-width: 991px) {
    .mis-shell { grid-template-columns: minmax(0, 1fr); }

    .mis-side {
        border-right: 1px solid var(--mis-side-line);
        bottom: 0;
        box-shadow: 0 10px 40px rgba(16, 24, 40, .18);
        flex-direction: column;
        gap: 0;
        left: 0;
        max-height: none;
        overflow-x: hidden;
        overflow-y: auto;
        padding: 0 0 18px;
        position: fixed;
        top: 0;
        transform: translateX(-100%);
        transition: transform .22s ease;
        width: 256px;
        z-index: 70;
    }
    body.mis-drawer-open .mis-side { transform: translateX(0); }

    /* the strip rules from the previous pass, undone */
    /* Spelled out rather than `revert`, which reverts to the UA stylesheet
       and would cost .caret the inline-block Bootstrap gives it — the
       triangle is drawn from borders and collapses without it. */
    .mis-side .mis-nav-label { display: block; }
    .mis-side .mis-brand-sub { display: inline; }
    .mis-side .caret { display: inline-block; }
    .mis-side .mis-subnav { display: grid; }
    .mis-side .mis-subnav[hidden] { display: none; }
    .mis-side .mis-brand {
        border-bottom: 1px solid var(--mis-side-line);
        min-height: var(--mis-top-h);
        padding: 12px 16px;
    }
    .mis-nav { display: block; padding: 0 10px; }
    .mis-nav a, .mis-nav .mis-nav-toggle { white-space: normal; width: 100%; }
    .mis-side-user {
        border-top: 1px solid var(--mis-side-line);
        margin-top: auto;
        padding: 12px 16px;
    }
    .mis-side-user .mis-side-name, .mis-side-user .mis-side-role { display: inline; }

    /* on a drawer, collapsing means nothing — the burger opens and closes it */
    body.mis-rail-collapsed .mis-brand { justify-content: flex-start; padding: 12px 16px; }
    body.mis-rail-collapsed .mis-nav-label { display: block; }
    body.mis-rail-collapsed .mis-nav .caret { display: inline-block; }
    body.mis-rail-collapsed .mis-brand > span:not(.mis-brand-mark),
    body.mis-rail-collapsed .mis-side-user > span:not(.mis-face),
    body.mis-rail-collapsed .mis-nav-text { display: inline; }
    body.mis-rail-collapsed .mis-subnav { display: grid; }
    body.mis-rail-collapsed .mis-subnav[hidden] { display: none; }
    body.mis-rail-collapsed .mis-side-user { justify-content: flex-start; padding: 12px 16px; }
    body.mis-rail-collapsed .mis-nav a,
    body.mis-rail-collapsed .mis-nav .mis-nav-toggle {
        gap: 10px;
        justify-content: flex-start;
        padding: 9px 10px;
    }
    body.mis-rail-collapsed .mis-nav a::after,
    body.mis-rail-collapsed .mis-nav .mis-nav-toggle::after { content: none; }
    body.mis-rail-collapsed .mis-nav + .mis-nav { border-top: 0; padding-top: 0; }

    .mis-scrim {
        background: rgba(16, 24, 40, .45);
        bottom: 0;
        left: 0;
        opacity: 0;
        pointer-events: none;
        position: fixed;
        right: 0;
        top: 0;
        transition: opacity .22s ease;
        z-index: 60;
    }
    body.mis-drawer-open .mis-scrim { opacity: 1; pointer-events: auto; }
    body.mis-drawer-open { overflow: hidden; }

    .mis-search { display: block; flex: 1 1 auto; }
    .mis-top .mis-id-text { display: none; }
    .mis-top-sep { display: none; }
    .mis-content { padding: 14px 14px 36px; }
    .mis-page-head h2 { font-size: 22px; }
}

@media (max-width: 600px) {
    .mis-search { display: none; }
    .mis-kpi-row { grid-template-columns: minmax(0, 1fr); }
    .mis-fab { bottom: 16px; right: 16px; }
    .mis-logout .mis-logout-text { display: none; }
}

/* the burger, the drawer's scrim and the floating button are chrome */
@media print {
    .mis-scrim, .mis-fab, .mis-burger { display: none !important; }
}

/* someone who has asked for less motion gets the layout, not the moves */
@media (prefers-reduced-motion: reduce) {
    .mis-kpi:hover, .mis-tile:hover, .mis-fab:hover { transform: none; }
    .mis-side, .mis-scrim, .mis-fab .glyphicon, .mis-burger-bars i { transition: none; }
}

/* ============================================================
   Corrections found by rendering the shell

   Three things the reference makes obvious once the layout is
   actually on screen.
   ============================================================ */

/* ---- 1. typeface ----

   Not a bug fix: bootstrap-flatly sets `'Roboto', Battambang` on the
   body and again on h1-h6, and the bundle loads both faces, so
   app-side text was already rendering in Roboto.

   This is an alignment. mis-forms.css already dresses the account
   cards in Kantumruy Pro + Inter, and so does the public site under
   _LayoutBlog; the dashboards were the last place still on Roboto.
   Kantumruy Pro covers Khmer and Latin in one face, which matters on
   screens whose labels mix the two mid-sentence.

   Headings need naming separately: Bootstrap sets a family on h1-h6
   directly, and a directly-matched declaration beats an inherited one
   whatever the specificity of the ancestor it came from. */
body.mis-shell-body,
body.mis-shell-body .mis-content,
body.mis-shell-body .mis-side,
body.mis-shell-body .mis-top,
body.mis-shell-body .mis-foot,
body.mis-shell-body h1, body.mis-shell-body h2, body.mis-shell-body h3,
body.mis-shell-body h4, body.mis-shell-body h5, body.mis-shell-body h6,
body.mis-shell-body .h1, body.mis-shell-body .h2, body.mis-shell-body .h3,
body.mis-shell-body .h4, body.mis-shell-body .h5, body.mis-shell-body .h6,
body.mis-shell-body .panel-title,
body.mis-shell-body .btn,
body.mis-shell-body .form-control {
    font-family: 'Kantumruy Pro', 'Khmer OS Battambang', 'Noto Sans Khmer', 'Battambang', system-ui, sans-serif;
}

/* Figures are read as figures, not prose: Inter, and lining digits of
   one width so a column of numbers stays in column. */
.mis-kpi-value,
.mis-stat-value,
.mis-list-lead,
.mis-delta,
.mis-search kbd {
    font-family: Inter, system-ui, sans-serif;
    font-variant-numeric: tabular-nums;
}

/* ---- 2. list rows ----
   .mis-list-title and .mis-list-sub are spans, so they ran together
   on one line ("01 Sep 202609:14") instead of stacking. */
.mis-list-title, .mis-list-sub { display: block; }

/* ---- 3. the floating button sat on the footer ----
   It is fixed to the bottom right, which is exactly where the
   "logged in as" line ends. Give the footer room to clear it. */
.mis-foot { padding-right: 84px; }

/* ============================================================
   Shell v4 — quieting the card

   Held up against the reference, the layout was right and the
   surfaces were loud. Everything below removes decoration rather
   than adding any: the reference's cards are plain white sheets, and
   ours were wearing a coloured top edge, a rule under every title
   and a shadow you could see.

   These override the v1 block near the top of this file rather than
   editing it, for the same reason as the other passes — the file
   reads as the history of the decisions.
   ============================================================ */

/* ---- the coloured top edge, dropped ----

   v1 kept the panel's old .panel-primary / -success / -danger colour
   as a 3px edge. On one card that reads as emphasis; on a page where
   every card is .panel-primary — which is how this app marks up
   nearly all of them — it is just a green stripe repeated down the
   screen, and it is the loudest thing separating our page from the
   reference. Semantic panels keep their meaning through their
   content, as the reference's do. */
.body-content .panel-primary,
.body-content .panel-success,
.body-content .panel-info,
.body-content .panel-warning,
.body-content .panel-danger {
    border-top: 1px solid var(--mis-line);
}

/* ---- the rule under every card title, dropped ----
   The reference separates title from body with space, not a line. */
.body-content .panel > .panel-heading {
    border-bottom: 0;
    padding: 18px 20px 2px;
}
.body-content .panel > .panel-heading + .panel-body { padding-top: 14px; }
.body-content .panel > .panel-body { padding: 20px; }
.body-content .panel > .panel-heading .panel-title { font-size: 16px; letter-spacing: -.1px; }

/* ---- shadow ----
   Two very short shadows read as a sheet lying on the page. One long
   soft one reads as a box floating above it. */
:root {
    --mis-shadow:    0 1px 2px rgba(16, 24, 40, .04), 0 1px 3px rgba(16, 24, 40, .06);
    --mis-shadow-up: 0 2px 4px rgba(16, 24, 40, .06), 0 6px 16px rgba(16, 24, 40, .10);
}

/* ---- KPI card ----
   The figure carries the card, so it gets the reference's size. */
.mis-kpi { padding: 18px 20px; }
.mis-kpi-value { font-size: 29px; }
.mis-kpi-label { font-size: 13px; }
.mis-kpi-chip { height: 40px; width: 40px; }

/* ---- list rows, a little more air ---- */
.mis-list > li { padding: 13px 2px; }

/* ---- section labels in the rail ----
   They earn their place — this app's groups are not self-evident the
   way "E-Commerce" is — but they should whisper. */
.mis-nav-label { font-size: 9.5px; opacity: .75; padding-top: 17px; }

/* ---- the language flag ----
   An image sitting between two monochrome glyph buttons was the one
   noisy thing left in the header. Size it to the buttons and let it
   sit in the same 36px slot. */
.mis-top .mis-lang-opt {
    align-items: center;
    border-radius: 9px;
    display: inline-flex;
    height: 36px;
    justify-content: center;
    transition: background-color .14s ease;
    width: 36px;
}
.mis-top .mis-lang-opt:hover { background: var(--mis-line-soft); }
.mis-top .mis-lang-opt img {
    border-radius: 999px;
    box-shadow: inset 0 0 0 1px rgba(16, 24, 40, .12);
    display: block;
    height: 19px;
    object-fit: cover;
    width: 19px;
}

/* ---- equal-height columns ----

   Bootstrap 3 floats its columns, so a short card beside a tall one
   leaves the dead gap under it that the dashboard had under its
   access log. Opt a row into flex and the cards in it end level.

       <div class="row mis-eq-row"> ... </div>
   ------------------------------------------------------------ */
.mis-eq-row { display: flex; flex-wrap: wrap; }
.mis-eq-row > [class*="col-"] { display: flex; flex-direction: column; }
.mis-eq-row > [class*="col-"] > .panel { display: flex; flex: 1; flex-direction: column; }
.mis-eq-row > [class*="col-"] > .panel > .panel-body { flex: 1; }

/* a card that stretched past its content should not strand the
   content at the top of a tall empty box */
.mis-eq-row .panel-body > .mis-list { height: 100%; }

@media (max-width: 767px) {
    .mis-eq-row { display: block; }
}

/* ============================================================
   Shell v5 — the Customize panel and the tokens it drives

   Every control in the panel does one thing: set an attribute on
   <html>. The blocks below are what those attributes mean. Nothing
   in the panel touches a component rule, so a new preference is a
   token swap and never a restyle.

     data-mis-accent  green | blue | indigo | violet | fuchsia | pink
                      | red | amber | teal | cyan | sky | slate
     data-mis-radius  none | sharp | default | rounded
     data-mis-width   fluid | boxed
     data-mis-theme   light | system

   Sidebar mode rides on <body> instead, because the two existing
   rail states already live there: .mis-rail-collapsed (Compact) and
   .mis-rail-overlay (Overlay).
   ============================================================ */

/* ------------------------------------------------------------
   Accent sets

   Each carries the four shades the components already ask for, plus
   --mis-accent-rgb. The rgb triplet exists because focus rings and
   the brand glow need the accent at low alpha, and rgba() cannot
   take a hex var — `rgba(var(--mis-accent-rgb), .12)` can, in every
   browser that supports custom properties at all.
   ------------------------------------------------------------ */
/* No "green" rule: green is the :root default set in Site.css, so selecting
   green means no accent override applies at all. */
:root[data-mis-accent="blue"] {
    --mis-accent: #2563EB; --mis-accent-dark: #1D4ED8; --mis-accent-press: #1E40AF;
    --mis-accent-tint: #EFF6FF; --mis-accent-rgb: 37, 99, 235;
}
:root[data-mis-accent="indigo"] {
    --mis-accent: #4F46E5; --mis-accent-dark: #4338CA; --mis-accent-press: #3730A3;
    --mis-accent-tint: #EEF2FF; --mis-accent-rgb: 79, 70, 229;
}
:root[data-mis-accent="violet"] {
    --mis-accent: #7C3AED; --mis-accent-dark: #6D28D9; --mis-accent-press: #5B21B6;
    --mis-accent-tint: #F5F3FF; --mis-accent-rgb: 124, 58, 237;
}
:root[data-mis-accent="fuchsia"] {
    --mis-accent: #C026D3; --mis-accent-dark: #A21CAF; --mis-accent-press: #86198F;
    --mis-accent-tint: #FDF4FF; --mis-accent-rgb: 192, 38, 211;
}
:root[data-mis-accent="pink"] {
    --mis-accent: #DB2777; --mis-accent-dark: #BE185D; --mis-accent-press: #9D174D;
    --mis-accent-tint: #FDF2F8; --mis-accent-rgb: 219, 39, 119;
}
:root[data-mis-accent="red"] {
    --mis-accent: #DC2626; --mis-accent-dark: #B91C1C; --mis-accent-press: #991B1B;
    --mis-accent-tint: #FEF2F2; --mis-accent-rgb: 220, 38, 38;
}
:root[data-mis-accent="amber"] {
    --mis-accent: #D97706; --mis-accent-dark: #B45309; --mis-accent-press: #92400E;
    --mis-accent-tint: #FFFBEB; --mis-accent-rgb: 217, 119, 6;
}
:root[data-mis-accent="teal"] {
    --mis-accent: #0D9488; --mis-accent-dark: #0F766E; --mis-accent-press: #115E59;
    --mis-accent-tint: #F0FDFA; --mis-accent-rgb: 13, 148, 136;
}
:root[data-mis-accent="cyan"] {
    --mis-accent: #0891B2; --mis-accent-dark: #0E7490; --mis-accent-press: #155E75;
    --mis-accent-tint: #ECFEFF; --mis-accent-rgb: 8, 145, 178;
}
:root[data-mis-accent="sky"] {
    --mis-accent: #0284C7; --mis-accent-dark: #0369A1; --mis-accent-press: #075985;
    --mis-accent-tint: #F0F9FF; --mis-accent-rgb: 2, 132, 199;
}
:root[data-mis-accent="slate"] {
    --mis-accent: #475569; --mis-accent-dark: #334155; --mis-accent-press: #1E293B;
    --mis-accent-tint: #F1F5F9; --mis-accent-rgb: 71, 85, 105;
}

/* The places that had the brand green written into an rgba(), now
   reading the accent instead. Without these, switching to violet
   left green focus rings and a green glow behind the logo. */
.body-content .form-control:focus,
.mis-search input:focus,
.mis-toolbar .mis-toolbar-search input:focus {
    box-shadow: 0 0 0 3px rgba(var(--mis-accent-rgb), .12);
}
.mis-brand-mark { box-shadow: 0 2px 6px rgba(var(--mis-accent-rgb), .28); }
.mis-top .mis-id .mis-face { box-shadow: 0 2px 6px rgba(var(--mis-accent-rgb), .3); }
.mis-fab { box-shadow: 0 6px 18px rgba(var(--mis-accent-rgb), .38); }
.mis-fab:hover, .mis-fab:focus { box-shadow: 0 8px 22px rgba(var(--mis-accent-rgb), .46); }

/* ------------------------------------------------------------
   Border radius

   The pill shapes (999px) are deliberately left alone: a status pill
   or an avatar is round because that is what it is, not because the
   theme says so. "None" squares the sheets, not the people.
   ------------------------------------------------------------ */
:root[data-mis-radius="none"]    { --mis-radius: 0;    --mis-radius-sm: 0; }
:root[data-mis-radius="sharp"]   { --mis-radius: 4px;  --mis-radius-sm: 3px; }
:root[data-mis-radius="default"] { --mis-radius: 12px; --mis-radius-sm: 10px; }
:root[data-mis-radius="rounded"] { --mis-radius: 18px; --mis-radius-sm: 14px; }

/* the handful of corners written as literals, brought under the token */
:root[data-mis-radius] .mis-icon-btn,
:root[data-mis-radius] .mis-lang-opt,
:root[data-mis-radius] .mis-nav a,
:root[data-mis-radius] .mis-nav .mis-nav-toggle,
:root[data-mis-radius] .mis-search input,
:root[data-mis-radius] .mis-logout,
:root[data-mis-radius] .body-content .dropdown-menu { border-radius: var(--mis-radius-sm); }
:root[data-mis-radius="none"] .mis-brand-mark,
:root[data-mis-radius="sharp"] .mis-brand-mark { border-radius: var(--mis-radius-sm); }

/* ------------------------------------------------------------
   Content width
   ------------------------------------------------------------ */
:root[data-mis-width="boxed"] .mis-content {
    margin: 0 auto;
    max-width: 1320px;
    width: 100%;
}
/* ------------------------------------------------------------
   Sidebar: Overlay

   Compact is the .mis-rail-collapsed state that already exists.
   Overlay lifts the rail out of the grid at every width — the same
   thing the narrow breakpoint does, promoted to a choice.
   ------------------------------------------------------------ */
body.mis-rail-overlay .mis-shell { grid-template-columns: minmax(0, 1fr); }
body.mis-rail-overlay .mis-side {
    border-right: 1px solid var(--mis-side-line);
    bottom: 0;
    box-shadow: 0 10px 40px rgba(16, 24, 40, .18);
    left: 0;
    max-height: none;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 0 0 18px;
    position: fixed;
    top: 0;
    transform: translateX(-100%);
    transition: transform .22s ease;
    width: 256px;
    z-index: 70;
}
body.mis-rail-overlay.mis-drawer-open .mis-side { transform: translateX(0); }
/* an overlay rail is never also a compact one */
body.mis-rail-overlay .mis-brand { justify-content: flex-start; padding: 12px 16px; }
body.mis-rail-overlay .mis-nav-label { display: block; }
body.mis-rail-overlay .mis-nav .caret { display: inline-block; }
body.mis-rail-overlay .mis-brand > span,
body.mis-rail-overlay .mis-side-user > span,
body.mis-rail-overlay .mis-nav-text { display: inline; }
body.mis-rail-overlay .mis-subnav { display: grid; }
body.mis-rail-overlay .mis-subnav[hidden] { display: none; }
body.mis-rail-overlay .mis-side-user { justify-content: flex-start; padding: 12px 16px; }
body.mis-rail-overlay .mis-nav a,
body.mis-rail-overlay .mis-nav .mis-nav-toggle { gap: 10px; justify-content: flex-start; padding: 9px 10px; }
body.mis-rail-overlay .mis-nav a::after,
body.mis-rail-overlay .mis-nav .mis-nav-toggle::after { content: none; }
body.mis-rail-overlay .mis-nav + .mis-nav { border-top: 0; padding-top: 0; }
body.mis-rail-overlay .mis-scrim {
    background: rgba(16, 24, 40, .45);
    bottom: 0;
    left: 0;
    opacity: 0;
    pointer-events: none;
    position: fixed;
    right: 0;
    top: 0;
    transition: opacity .22s ease;
    z-index: 60;
}
body.mis-rail-overlay.mis-drawer-open .mis-scrim { opacity: 1; pointer-events: auto; }

/* ------------------------------------------------------------
   The Customize panel itself

   A right-hand sheet. It is chrome for the chrome, so it is the one
   thing in the app that does not care about --mis-radius: a panel
   whose own corners changed while you were choosing corners would
   be impossible to judge against.
   ------------------------------------------------------------ */
.mis-cust {
    background: var(--mis-surface);
    border-left: 1px solid var(--mis-line);
    bottom: 0;
    box-shadow: -8px 0 32px rgba(16, 24, 40, .16);
    display: flex;
    flex-direction: column;
    max-width: 100vw;
    position: fixed;
    right: 0;
    top: 0;
    transform: translateX(100%);
    transition: transform .24s ease;
    width: 340px;
    z-index: 90;
}
body.mis-cust-open .mis-cust { transform: translateX(0); }
.mis-cust[hidden] { display: flex; }   /* hidden only gates a11y, the transform hides it */

.mis-cust-head {
    align-items: flex-start;
    border-bottom: 1px solid var(--mis-line);
    display: flex;
    flex: none;
    gap: 10px;
    padding: 18px 20px 16px;
}
.mis-cust-head h2 { color: var(--mis-ink); font-size: 17px; font-weight: 700; margin: 0; }
.mis-cust-head p { color: var(--mis-muted); font-size: 12px; margin: 4px 0 0; }
.mis-cust-head .mis-cust-x { margin-left: auto; }
.mis-cust-x {
    background: none;
    border: 0;
    border-radius: 8px;
    color: var(--mis-muted);
    cursor: pointer;
    flex: none;
    height: 30px;
    width: 30px;
}
.mis-cust-x:hover { background: var(--mis-line-soft); color: var(--mis-ink); }

.mis-cust-body { flex: 1; overflow-y: auto; padding: 4px 20px 20px; }
.mis-cust-group { padding-top: 18px; }
.mis-cust-label {
    color: var(--mis-faint);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
    margin: 0 0 9px;
    text-transform: uppercase;
}
.mis-cust-note { color: var(--mis-faint); font-size: 11.5px; margin: 8px 0 0; }

/* segmented control — Layout, Theme, Sidebar, Width, Radius all use it */
.mis-seg { display: grid; gap: 8px; grid-auto-flow: column; }
.mis-seg-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-flow: row; }
.mis-seg-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-flow: row; }
.mis-seg button {
    align-items: center;
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: 9px;
    color: var(--mis-muted);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    font-size: 12px;
    font-weight: 500;
    gap: 5px;
    justify-content: center;
    min-height: 56px;
    padding: 9px 6px;
    transition: border-color .14s ease, background-color .14s ease, color .14s ease;
}
.mis-seg button:hover:not([disabled]) { border-color: var(--mis-faint); color: var(--mis-ink); }
.mis-seg button[aria-pressed="true"] {
    background: rgba(var(--mis-accent-rgb), .07);
    border-color: var(--mis-accent);
    color: var(--mis-accent);
}
.mis-seg button[disabled] { cursor: not-allowed; opacity: .45; }
.mis-seg .glyphicon { font-size: 14px; }

/* preset row */
.mis-preset { display: grid; gap: 8px; grid-template-columns: repeat(5, minmax(0, 1fr)); }
.mis-preset button {
    align-items: center;
    background: var(--mis-surface);
    border: 1px solid var(--mis-line);
    border-radius: 9px;
    color: var(--mis-muted);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    font-size: 10px;
    gap: 6px;
    padding: 9px 2px 7px;
    transition: border-color .14s ease;
}
.mis-preset button:hover { border-color: var(--mis-faint); color: var(--mis-ink); }
.mis-preset i {
    border-radius: 999px;
    display: block;
    height: 18px;
    width: 18px;
}

/* colour swatches */
.mis-swatch { display: grid; gap: 9px; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.mis-swatch button {
    background: none;
    border: 2px solid transparent;
    border-radius: 9px;
    cursor: pointer;
    height: 38px;
    padding: 3px;
    transition: border-color .14s ease;
}
.mis-swatch button i { border-radius: 6px; display: block; height: 100%; width: 100%; }
.mis-swatch button:hover { border-color: var(--mis-line); }
.mis-swatch button[aria-pressed="true"] { border-color: var(--mis-ink); }

.mis-cust-foot {
    border-top: 1px solid var(--mis-line);
    display: grid;
    flex: none;
    gap: 10px;
    grid-template-columns: 1fr 1fr;
    padding: 14px 20px;
}
.mis-cust-foot button {
    align-items: center;
    border: 1px solid var(--mis-line);
    border-radius: 9px;
    cursor: pointer;
    display: inline-flex;
    font-size: 13px;
    font-weight: 600;
    gap: 7px;
    justify-content: center;
    padding: 10px 12px;
    transition: background-color .14s ease, border-color .14s ease;
}
.mis-cust-reset { background: var(--mis-surface); color: var(--mis-muted); }
.mis-cust-reset:hover { border-color: var(--mis-danger); color: var(--mis-danger); }
.mis-cust-copy { background: var(--mis-accent); border-color: var(--mis-accent); color: #fff; }
.mis-cust-copy:hover { background: var(--mis-accent-dark); border-color: var(--mis-accent-dark); color: #fff; }

/* the panel's own backdrop, separate from the rail drawer's */
.mis-cust-scrim {
    background: rgba(16, 24, 40, .32);
    bottom: 0;
    left: 0;
    opacity: 0;
    pointer-events: none;
    position: fixed;
    right: 0;
    top: 0;
    transition: opacity .24s ease;
    z-index: 85;
}
body.mis-cust-open .mis-cust-scrim { opacity: 1; pointer-events: auto; }

/* the gear turns into the open panel's anchor */
body.mis-cust-open .mis-fab { opacity: 0; pointer-events: none; }
.mis-fab { transition: background-color .15s ease, box-shadow .15s ease, transform .15s ease, opacity .2s ease; }

@media (max-width: 420px) {
    .mis-cust { width: 100%; }
    .mis-preset { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media print {
    .mis-cust, .mis-cust-scrim { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
    .mis-cust, .mis-cust-scrim, body.mis-rail-overlay .mis-side { transition: none; }
}

/* The gear became a <button> when it stopped being a link to Change Password
   and started opening the appearance panel. */
.mis-fab { border: 0; cursor: pointer; padding: 0; }

/* ============================================================
   Shell v6 — every rail group is a collapsible group

   Before this, two of the five groups (Tools, Setting) were
   collapsible .mis-nav-toggle headers and the other three
   (Monitoring, Document, Accounting) were static .mis-nav-label
   captions. Tools had both at once, so the rail read "TOOLS" as a
   caption and "Tools" as a toggle immediately under it.

   Now all five are toggles and .mis-nav-label is no longer rendered
   anywhere. Its rules are left in place above rather than unpicked
   from the four responsive blocks that reference them — they match
   nothing and cost nothing.

   .mis-subnav keeps its name: it is still the container of a group's
   children, which is exactly what it was. Reusing it means the
   compact, overlay and print passes above keep working untouched.
   What changes is what its children look like — full nav rows with
   an icon, rather than the indented text list they used to be, since
   they are now the whole navigation and not a footnote to it.
   ============================================================ */

/* ---- the group header ---- */
.mis-nav .mis-nav-toggle {
    color: var(--mis-side-ink);
    font-weight: 600;
    margin-top: 2px;
}
.mis-nav .mis-nav-toggle .glyphicon { color: var(--mis-side-muted); }
.mis-nav + .mis-nav { margin-top: 2px; }

/* An open group is not "active" — only the page you are on is. Keep the
   header quiet when open so it does not compete with the current item. */
.mis-nav .mis-nav-toggle[aria-expanded="true"] { color: var(--mis-side-ink); }
.mis-nav .mis-nav-toggle[aria-expanded="true"] .glyphicon { color: var(--mis-side-muted); }
/* ...unless the page you are on lives inside it, which is worth showing */
.mis-nav .mis-nav-toggle.has-current,
.mis-nav .mis-nav-toggle.has-current .glyphicon { color: var(--mis-accent); }

/* ---- the group body ---- */
.mis-subnav {
    display: grid;
    margin: 0 0 2px;          /* the indent moves onto the rows themselves */
}
.mis-subnav[hidden] { display: none; }

/* Children are ordinary nav rows again: icon, label, hover, active pill.
   Undoes the bordered text-list treatment from the first pass. */
.mis-subnav a {
    align-items: center;
    border-left: 0;
    border-radius: 9px;
    color: var(--mis-side-ink);
    display: flex;
    font-size: 13.5px;
    gap: 10px;
    margin-bottom: 2px;
    padding: 9px 10px 9px 22px;   /* 12px deeper than a group header */
    text-decoration: none;
}
.mis-subnav a:hover, .mis-subnav a:focus {
    background: var(--mis-side-2);
    border-left: 0;
    color: var(--mis-side-ink);
    text-decoration: none;
}
.mis-subnav a.is-active {
    background: var(--mis-accent-tint);
    color: var(--mis-accent);
    font-weight: 600;
}
.mis-subnav a .glyphicon { color: var(--mis-side-muted); flex: none; font-size: 13px; width: 16px; }
.mis-subnav a:hover .glyphicon { color: var(--mis-side-ink); }
.mis-subnav a.is-active .glyphicon { color: var(--mis-accent); }

/* the tick sits at the rail's edge, same as a top-level row's */
.mis-subnav a.is-active::before {
    background: var(--mis-accent);
    border-radius: 0 3px 3px 0;
    bottom: 7px;
    content: "";
    left: -10px;
    position: absolute;
    top: 7px;
    width: 3px;
}

/* ------------------------------------------------------------
   Compact rail

   The earlier passes hid .mis-subnav when the rail collapsed, which
   was right when it held only Tools and Settings. Now it holds every
   destination in the app, so hiding it would leave a rail of five
   group icons and no way to reach anything.

   Collapsed therefore drops the grouping instead of the items: the
   headers go, and every child shows as an icon — which is exactly
   what the compact rail looked like before groups existed.
   ------------------------------------------------------------ */
body.mis-rail-collapsed .mis-nav .mis-nav-toggle { display: none; }
body.mis-rail-collapsed .mis-subnav,
body.mis-rail-collapsed .mis-subnav[hidden] { display: grid; margin-left: 0; }
body.mis-rail-collapsed .mis-subnav a {
    gap: 0;
    justify-content: center;
    padding: 10px 0;
    position: relative;
}
body.mis-rail-collapsed .mis-subnav a .glyphicon { font-size: 15px; width: auto; }
body.mis-rail-collapsed .mis-subnav a.is-active::before { left: -10px; }

/* the hover chip the collapsed rail uses to name an icon */
body.mis-rail-collapsed .mis-subnav a::after {
    background: var(--mis-side-ink);
    border-radius: 7px;
    color: #fff;
    content: attr(data-label);
    font-size: 12.5px;
    font-weight: 500;
    left: calc(100% + 8px);
    opacity: 0;
    padding: 5px 10px;
    pointer-events: none;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    transition: opacity .12s ease;
    white-space: nowrap;
    z-index: 60;
}
body.mis-rail-collapsed .mis-subnav a:hover::after,
body.mis-rail-collapsed .mis-subnav a:focus-visible::after { opacity: 1; }

/* ------------------------------------------------------------
   Drawer and overlay: full grouping, like the expanded rail
   ------------------------------------------------------------ */
@media (max-width: 991px) {
    body.mis-rail-collapsed .mis-nav .mis-nav-toggle { display: flex; }
    body.mis-rail-collapsed .mis-subnav[hidden] { display: none; }
    body.mis-rail-collapsed .mis-subnav a {
        gap: 10px;
        justify-content: flex-start;
        padding: 9px 10px 9px 22px;
    }
    body.mis-rail-collapsed .mis-subnav a::after { content: none; }
}

body.mis-rail-overlay .mis-nav .mis-nav-toggle { display: flex; }
body.mis-rail-overlay .mis-subnav[hidden] { display: none; }
body.mis-rail-overlay .mis-subnav a {
    gap: 10px;
    justify-content: flex-start;
    padding: 9px 10px 9px 22px;
}
body.mis-rail-overlay .mis-subnav a::after { content: none; }

/* printing takes the whole rail out anyway, but be explicit */
@media print {
    .mis-nav-toggle { display: none !important; }
}

/* ------------------------------------------------------------
   Signed-out pages (Login, AccessDenied, Error)

   Site.css line 2 puts padding-top:50px on the body, left over from
   the old fixed navbar. .mis-shell-body cancels it for the signed-in
   shell, but the signed-out body carried no class at all — so the
   sign-in screen sat under a 50px grey band, and its headings missed
   the typeface rule for the same reason.
   ------------------------------------------------------------ */
body.mis-plain-body { padding: 0 !important; }
body.mis-plain-body,
body.mis-plain-body h1, body.mis-plain-body h2, body.mis-plain-body h3,
body.mis-plain-body h4, body.mis-plain-body h5, body.mis-plain-body h6,
body.mis-plain-body .btn,
body.mis-plain-body .form-control,
body.mis-plain-body a {
    font-family: 'Kantumruy Pro', 'Khmer OS Battambang', 'Noto Sans Khmer', 'Battambang', system-ui, sans-serif;
}


/* ============================================================
   Forms — the app-side pass

   Sixty-six views carry form controls and twenty-seven of them are
   modal partials, all written straight against Bootstrap 3: a
   .form-group, a bare <label>, and a .form-control.input-sm. The
   earlier "Form controls" block near the top of this file gave them a
   border, a radius and a focus ring and stopped there, which left the
   app with two form languages — the considered one in mis-forms.css
   (.mis-form, used by sign-in and the account pages) and Bootstrap's
   defaults everywhere else.

   This section closes that gap. It is a restyle of the markup that is
   already in the views, in the same spirit as the rest of this file:
   no view has to change, and a new form written the ordinary
   Bootstrap way comes out looking like the rest of the app.

   The target is the .mis-form language: 1.5px hairline, 10px corner,
   a resting fill just off white, and the accent only on focus.
   ============================================================ */

/* ---- fields ---------------------------------------------------- */

.body-content .form-control {
    background: #FCFDFE;
    border: 1.5px solid var(--mis-line);
    border-radius: var(--mis-radius-sm);
    box-shadow: none;
    color: var(--mis-ink);
    font-size: 14.5px;
    height: auto;
    line-height: 1.5;
    min-height: 40px;
    padding: 9px 13px;
    transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.body-content .form-control:hover { background: #fff; border-color: #CBD5E1; }
.body-content .form-control:focus {
    background: #fff;
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(var(--mis-accent-rgb), .14);
    outline: none;
}
.body-content .form-control::placeholder { color: var(--mis-faint); opacity: 1; }

/* .input-sm is on fifty-two views — mostly modal fields and table
   filters. It keeps a smaller footprint than the default, but as a
   deliberate second size rather than Bootstrap's cramped 30px. */
.body-content .form-control.input-sm,
.body-content .input-sm .form-control {
    border-radius: 9px;
    font-size: 13.5px;
    min-height: 34px;
    padding: 6px 11px;
}
.body-content .form-control.input-lg { font-size: 16px; min-height: 48px; padding: 12px 16px; }

.body-content textarea.form-control { line-height: 1.65; min-height: 84px; padding: 10px 13px; resize: vertical; }

/* A disabled field should look inert, not merely greyer. */
.body-content .form-control[disabled],
.body-content .form-control[readonly],
.body-content fieldset[disabled] .form-control {
    background: var(--mis-line-soft);
    border-color: var(--mis-line);
    color: var(--mis-muted);
    cursor: not-allowed;
}
.body-content .form-control[readonly] { cursor: default; }

/* ---- selects ---------------------------------------------------- */

/* Bootstrap 3 leaves a select as the operating system draws it, which
   next to these fields reads as an unstyled control that someone
   forgot. One chevron, drawn to match the hairline. Multi-selects and
   size>1 lists keep the native affordance — they are lists, not
   pickers, and an arrow on them would be a lie. */
.body-content select.form-control:not([multiple]):not([size]) {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%236b7280' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-position: right 13px center;
    background-repeat: no-repeat;
    background-size: 12px 8px;
    padding-right: 34px;
}
.body-content select.form-control.input-sm:not([multiple]):not([size]) {
    background-position: right 11px center;
    padding-right: 30px;
}
.body-content select.form-control[multiple],
.body-content select.form-control[size] { min-height: 0; padding: 6px; }

/* ---- labels and help text ---------------------------------------- */

.body-content label {
    color: var(--mis-ink);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1.5;
    margin-bottom: 6px;
    /* Khmer labels run considerably longer than their English
       counterparts; without this they collide with the control. */
    white-space: normal;
}
.body-content .form-group { margin-bottom: 16px; }
.body-content .help-block { color: var(--mis-muted); font-size: 12.5px; line-height: 1.6; margin: 6px 0 0; }

/* .form-horizontal puts the label in a column beside the field, so it
   needs the vertical alignment back that the margin above removes. */
.body-content .form-horizontal .control-label { margin-bottom: 0; padding-top: 10px; }
@media (max-width: 767px) {
    .body-content .form-horizontal .control-label { padding-top: 0; margin-bottom: 6px; text-align: left; }
}

/* ---- checkboxes and radios --------------------------------------- */

/* accent-color keeps the real control — and with it every keyboard and
   screen-reader behaviour — while painting it in the brand colour. */
.body-content .checkbox label,
.body-content .radio label {
    font-size: 14px;
    font-weight: 500;
    line-height: 1.6;
    margin-bottom: 0;
}
.body-content .checkbox input[type="checkbox"],
.body-content .radio input[type="radio"],
.body-content input[type="checkbox"],
.body-content input[type="radio"] {
    accent-color: var(--mis-accent);
    cursor: pointer;
}
.body-content .checkbox + .checkbox,
.body-content .radio + .radio { margin-top: 6px; }

/* ---- file inputs -------------------------------------------------- */

/* Thirty views take an upload. A bare file input is the least
   considered control on any of these screens, and it sits right next
   to fields that now have a hairline and a corner. */
.body-content input[type="file"] {
    background: #FCFDFE;
    border: 1.5px dashed var(--mis-line);
    border-radius: var(--mis-radius-sm);
    color: var(--mis-muted);
    font-size: 13.5px;
    line-height: 1.5;
    padding: 9px 12px;
    transition: background-color .15s ease, border-color .15s ease;
    width: 100%;
}
.body-content input[type="file"]:hover { background: #fff; border-color: var(--mis-accent); }
.body-content input[type="file"]:focus {
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(var(--mis-accent-rgb), .14);
    outline: none;
}
/* the -webkit- pseudo is still what older Safari and pre-89 Chrome
   understand; both are declared because a browser that knows neither
   simply keeps its own button */
.body-content input[type="file"]::-webkit-file-upload-button,
.body-content input[type="file"]::file-selector-button {
    background: var(--mis-accent-tint);
    border: 0;
    border-radius: 7px;
    color: var(--mis-accent-dark);
    cursor: pointer;
    font-weight: 600;
    margin-right: 12px;
    padding: 6px 12px;
}
.body-content input[type="file"]::-webkit-file-upload-button:hover,
.body-content input[type="file"]::file-selector-button:hover { background: #DCEFE4; }

/* ---- validation ---------------------------------------------------- */

/* Only the validation message becomes a block. .text-danger is also
   the required-field asterisk inside a label — <span class="text-danger">*</span>
   in seven views — and blocking that would drop the star onto its own
   line under every label it marks. */
.body-content .text-danger { color: var(--mis-danger-d); }
.body-content .field-validation-error,
.body-content .has-error .help-block {
    color: var(--mis-danger-d);
    display: block;
    font-size: 12.5px;
    line-height: 1.55;
    margin-top: 5px;
}
.body-content .validation-summary-errors {
    background: #FCEDED;
    border: 1px solid #F5C6CB;
    border-radius: var(--mis-radius-sm);
    color: #B33232;
    font-size: 13px;
    margin: 0 0 16px;
    padding: 11px 14px;
}
.body-content .validation-summary-errors ul { margin: 0; padding-left: 18px; }
.body-content .validation-summary-errors ul:empty,
.body-content .validation-summary-valid { display: none; }

.body-content .has-error .form-control,
.body-content .form-control.input-validation-error {
    background: #FFFBFB;
    border-color: var(--mis-danger);
}
.body-content .has-error .form-control:focus,
.body-content .form-control.input-validation-error:focus {
    border-color: var(--mis-danger);
    box-shadow: 0 0 0 3px rgba(239, 68, 68, .14);
}
.body-content .has-error .control-label,
.body-content .has-error label { color: var(--mis-danger-d); }

/* ---- grouped controls: match the field corner --------------------- */

/* The block further up rounds these to 8px, from when the fields were
   8px too. Only the input groups move — the button groups were tuned
   against the tables and are left alone. */
.body-content .input-group > .form-control:first-child,
.body-content .input-group-addon:first-child,
.body-content .input-group-btn:first-child > .btn {
    border-bottom-left-radius: var(--mis-radius-sm);
    border-top-left-radius: var(--mis-radius-sm);
}
.body-content .input-group > .form-control:last-child,
.body-content .input-group-addon:last-child,
.body-content .input-group-btn:last-child > .btn {
    border-bottom-right-radius: var(--mis-radius-sm);
    border-top-right-radius: var(--mis-radius-sm);
}
.body-content .input-group-addon { border-width: 1.5px; font-size: 13.5px; }

/* ---- Chosen ---------------------------------------------------------- */

/* Eight views swap a select for Chosen, which draws its own box. Left
   alone it is the one control on the page still wearing 2012. */
.body-content .chosen-container-single .chosen-single {
    background: #FCFDFE;
    border: 1.5px solid var(--mis-line);
    border-radius: var(--mis-radius-sm);
    box-shadow: none;
    color: var(--mis-ink);
    height: auto;
    line-height: 1.5;
    padding: 8px 13px;
}
.body-content .chosen-container-active.chosen-with-drop .chosen-single,
.body-content .chosen-container-active .chosen-single {
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(var(--mis-accent-rgb), .14);
}
.body-content .chosen-container .chosen-drop {
    border: 1px solid var(--mis-line);
    border-radius: var(--mis-radius-sm);
    box-shadow: var(--mis-shadow);
    margin-top: 4px;
}
.body-content .chosen-container .chosen-results li.highlighted { background: var(--mis-accent); }

/* ============================================================
   Modals — where most of these forms actually live

   Twenty-seven modal partials, all to one template: a header with the
   title in inline `color: darkblue`, a red btn-danger close on the
   right, and a body of .form-groups. The inline colour is why the
   rules below need !important — it is on thirty-seven elements across
   the views, and one line here is a better trade than thirty-seven
   edits to remove a colour that should never have been inline.
   ============================================================ */

.body-content .modal-content {
    border: 0;
    border-radius: 14px;
    box-shadow: 0 24px 60px rgba(16, 24, 40, .22), 0 4px 12px rgba(16, 24, 40, .1);
}
/* Left on floats rather than switched to flex. The close control is
   written BEFORE the title in every one of these headers and floated
   right; under flex it would need an order, and any third element a
   header happens to carry would silently jump in front of the title.
   Floats already place these two correctly. */
.body-content .modal-header {
    border-bottom: 1px solid var(--mis-line);
    padding: 15px 20px;
}
.body-content .modal-title {
    color: var(--mis-ink) !important;
    display: block;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.45;
    margin: 0;
    overflow-wrap: break-word;
    /* .modal-title is a <b> in most of these, so the weight has to be
       stated rather than inherited from a heading. */
}
.body-content .modal-body { padding: 20px; }
.body-content .modal-footer { border-top: 1px solid var(--mis-line); padding: 14px 20px; }

/* The close control is a red danger button in forty-six views. Red is
   this app's colour for destructive actions, and dismissing a dialog
   is not one — it reads as a warning on every modal that opens. This
   turns it into a quiet ghost button and keeps red for real deletes.

   Matched on the attribute, not on .btn: eleven of these are written
   `class="btn-danger btn-xs pull-right"` with no .btn at all, so they
   were picking up Bootstrap's danger colours over a native button. */
.body-content .modal-header [data-dismiss="modal"]:not(.close) {
    background: transparent;
    border: 1.5px solid var(--mis-line);
    border-radius: 8px;
    box-shadow: none;
    color: var(--mis-muted);
    cursor: pointer;
    display: inline-block;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.5;
    padding: 5px 12px;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.body-content .modal-header [data-dismiss="modal"]:not(.close):hover,
.body-content .modal-header [data-dismiss="modal"]:not(.close):focus {
    background: var(--mis-line-soft);
    border-color: #CBD5E1;
    color: var(--mis-ink);
    outline: none;
}

/* the three headers that use Bootstrap's own × instead */
.body-content .modal-header .close {
    color: var(--mis-muted);
    font-size: 24px;
    line-height: 1;
    margin-top: -2px;
    opacity: 1;
    text-shadow: none;
}
.body-content .modal-header .close:hover { color: var(--mis-ink); }

@media (max-width: 767px) {
    .body-content .modal-header { padding: 13px 15px; }
    .body-content .modal-body { padding: 15px; }
    .body-content .modal-footer { padding: 12px 15px; }
}

/* ============================================================
   Responsive — the wide-table problem

   Scripts/mis-responsive.js puts every table in a
   .table-responsive.mis-scroll-x box at runtime. Bootstrap already
   defines .table-responsive; what it does not do is match this app,
   so the rules below finish the job:

     * Bootstrap only stops the cells wrapping below 768px. The admin
       shell turns into a drawer at 991px, and a ten-column table is
       just as unreadable at 900px as at 600px, so the treatment now
       runs to the same 991px the rest of the shell uses.

     * Bootstrap's box border is #ecf0f1 from the flatly theme. This
       one uses the app's own line token and corner radius, so the
       scrolling table reads as one of this app's panels rather than
       a stray Bootstrap default.

   Deliberately not a card-per-row transform. Staff read these grids
   on a desktop all day; the same grid, scrolled, is something they
   can already use. A phone-only layout would be a second thing to
   learn and a second thing to keep correct.
   ============================================================ */

@media (max-width: 991px) {
    .table-responsive {
        border: 1px solid var(--mis-line);
        border-radius: var(--mis-radius-sm);
        margin-bottom: 16px;
        overflow-x: auto;
        overflow-y: hidden;
        -ms-overflow-style: -ms-autohiding-scrollbar;
        -webkit-overflow-scrolling: touch;
        width: 100%;
    }

    /* Natural column widths are what give the box something to scroll.
       Without this the table obeys width:100%, squeezes ten columns
       into 360px and turns every cell into a column of single
       characters — which is the failure this is meant to fix. */
    .table-responsive > .table > thead > tr > th,
    .table-responsive > .table > tbody > tr > th,
    .table-responsive > .table > tfoot > tr > th,
    .table-responsive > .table > thead > tr > td,
    .table-responsive > .table > tbody > tr > td,
    .table-responsive > .table > tfoot > tr > td { white-space: nowrap; }

    .table-responsive > .table { margin-bottom: 0; }
    .table-responsive > .table-bordered { border: 0; }

    /* The panel already draws a line where the table starts, so the box
       inside it would be a second border around the same edge. */
    .body-content .panel-body > .table-responsive:only-child {
        border: 0;
        border-radius: 0;
        margin-bottom: 0;
    }
}

/* Scroll shadows: the two outer gradients are painted in local
   coordinates so they scroll away with the content, the two inner ones
   are fixed to the box. The result is a shadow at whichever edge has
   more table behind it, and none at the ends — the only honest way to
   say "this scrolls" without adding a permanent arrow to every table. */
.mis-scroll-x {
    background:
        linear-gradient(to right, var(--mis-surface) 30%, rgba(255, 255, 255, 0)) left center,
        linear-gradient(to left, var(--mis-surface) 30%, rgba(255, 255, 255, 0)) right center,
        radial-gradient(farthest-side at 0 50%, rgba(16, 24, 40, .16), rgba(16, 24, 40, 0)) left center,
        radial-gradient(farthest-side at 100% 50%, rgba(16, 24, 40, .16), rgba(16, 24, 40, 0)) right center;
    background-attachment: local, local, scroll, scroll;
    background-color: var(--mis-surface);
    background-repeat: no-repeat;
    background-size: 34px 100%, 34px 100%, 15px 100%, 15px 100%;
}

/* ------------------------------------------------------------
   Panel toolbars

   Index pages put their filters in a .form-inline on the left and
   their buttons in a stack of .pull-right on the right. Bootstrap
   already un-inlines the filters below 768px, but the floats stay:
   two or three floated buttons on a 360px screen land beside each
   other, overlap the filter above them and push past the panel edge.

   Unfloating them lets them flow and wrap like the block elements
   they have effectively become, and full-width is the standard phone
   treatment for what is now a stack of primary actions.
   ------------------------------------------------------------ */
@media (max-width: 767px) {
    /* Every selector below stops at the column's direct children. The
       obvious shorter version — .panel-body .btn — also matches the
       edit and delete buttons rendered into table cells further down
       the same panel, and turning those into full-width blocks would
       stack them inside the Action column and stretch it. Toolbar
       buttons are direct children of the column; cell buttons never
       are. */
    .body-content .panel-heading > .pull-right,
    .body-content .panel-body > .row > [class*="col-"] > .pull-right { float: none !important; }

    .body-content .panel-body > .row > [class*="col-"] + [class*="col-"] { margin-top: 10px; }

    .body-content .panel-body > .row > [class*="col-"] > .btn,
    .body-content .panel-body > .row > [class*="col-"] > .dropdown,
    .body-content .panel-body > .row > [class*="col-"] > .btn-group { display: block; margin-left: 0; width: 100%; }
    .body-content .panel-body > .row > [class*="col-"] > .btn-group > .btn { width: auto; }
    .body-content .panel-body > .row > [class*="col-"] > .dropdown > .btn { width: 100%; }
    .body-content .panel-body > .row > [class*="col-"] > .btn + .btn,
    .body-content .panel-body > .row > [class*="col-"] > .dropdown + .dropdown,
    .body-content .panel-body > .row > [class*="col-"] > .dropdown + .btn,
    .body-content .panel-body > .row > [class*="col-"] > .btn + .dropdown { margin-top: 8px; }

    /* A right-anchored menu hanging off a now-full-width trigger has
       nothing to sit against and would run past the screen edge. */
    .body-content .panel-body > .row > [class*="col-"] > .dropdown > .dropdown-menu {
        left: 0;
        right: auto;
        width: 100%;
    }

    /* Bootstrap already un-inlines .form-inline below 768px; all it
       leaves out is the gap between the stacked filters. */
    .body-content .form-inline .form-group + .form-group { margin-top: 8px; }
}

/* ------------------------------------------------------------
   Overflow guards

   Two things routinely set a minimum width no breakpoint can undo: a
   long unbroken string (an email, a file name, a pasted URL) outside
   a scrolling table, and a fixed pixel width in a view's inline
   style. The first is fixable here; the second is not, so the shell
   simply stops it dragging the whole page sideways.
   ------------------------------------------------------------ */
.mis-main,
.body-content { min-width: 0; }

@media (max-width: 767px) {
    .body-content .panel-title,
    .body-content .list-group-item,
    .body-content dd,
    .body-content .form-control-static { overflow-wrap: break-word; word-wrap: break-word; }

    /* Modals are 10px from each edge on a phone in Bootstrap, but their
       bodies still inherit desktop padding. */
    .modal-body { padding: 14px; }
    .modal-header, .modal-footer { padding: 12px 14px; }
    .modal-footer .btn { display: block; margin-left: 0; width: 100%; }
    .modal-footer .btn + .btn { margin-top: 8px; }
}

/* Printing wants the whole grid, not the slice that happened to be
   scrolled into view — and the scroll shadows would print as grey
   smudges down both edges of every table. */
@media print {
    .table-responsive {
        border: 0 !important;
        overflow: visible !important;
    }
    .mis-scroll-x { background: none !important; }
    .table-responsive > .table > thead > tr > th,
    .table-responsive > .table > tbody > tr > td { white-space: normal !important; }
}

/* ============================================================
   SREYPICH ADMIN THEME (mis-shell-body pace-done)
   Matches reference design: Purple top header, clean white sidebar,
   vibrant KPI cards, sales & donut charts, 10 quick action buttons.
   ============================================================ */

body.mis-shell-body {
    background-color: #F4F6F9 !important;
    margin: 0;
    padding: 0 !important;
    font-family: 'Kantumruy Pro', 'Khmer OS Battambang', 'Noto Sans Khmer', 'Battambang', system-ui, sans-serif !important;
    color: #1E293B;
}

.mis-shell {
    display: flex !important;
    flex-direction: column !important;
    min-height: 100vh;
    background-color: #F4F6F9;
}

/* ---- TOP HEADER BAR (Full width across top) ---- */
.mis-top {
    height: 52px !important;
    min-height: 52px !important;
    /* Accent green, replacing the old purple. Kept as a gradient so the bar
       keeps its depth, and built from the accent tokens rather than a literal
       #1E9E5A: the Customize panel can switch the accent, and a hard-coded
       green would stay green under every other choice. */
    background: linear-gradient(90deg, var(--mis-accent) 0%, var(--mis-accent-dark) 100%) !important;
    color: #FFFFFF !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    padding: 0 16px !important;
    position: sticky !important;
    top: 0 !important;
    z-index: 1000 !important;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.08) !important;
    border: 0 !important;
}

.mis-top-left {
    display: flex;
    align-items: center;
    gap: 12px;
}

.mis-top-brand {
    text-decoration: none !important;
    display: flex;
    align-items: center;
    margin-right: 6px;
}

.mis-top-brand-text {
    color: #FFFFFF !important;
    font-size: 15.5px;
    font-weight: 700;
    letter-spacing: 0.2px;
    font-family: 'Kantumruy Pro', sans-serif;
    white-space: nowrap;
}

.mis-burger {
    background: transparent !important;
    border: 0 !important;
    cursor: pointer;
    padding: 6px 8px;
    display: flex;
    align-items: center;
    border-radius: 4px;
}

.mis-burger:hover {
    background: rgba(255, 255, 255, 0.12) !important;
}

.mis-burger-bars {
    display: flex;
    flex-direction: column;
    gap: 3px;
    width: 17px;
}

.mis-burger-bars i {
    display: block;
    width: 17px;
    height: 2px;
    background: #FFFFFF !important;
    border-radius: 1px;
}

.mis-top-flag-box {
    display: flex;
    align-items: center;
    border-radius: 3px;
    overflow: hidden;
    height: 15px;
    width: 22px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
    margin-left: 2px;
}

.mis-top-flag-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The flag box is a language toggle in the admin topbar, so it needs a
   pointer and a visible hover/keyboard-focus state. */
a.mis-top-flag-box {
    cursor: pointer;
    transition: box-shadow .16s ease, transform .16s ease;
}

a.mis-top-flag-box:hover,
a.mis-top-flag-box:focus-visible {
    box-shadow: 0 0 0 2px rgba(255,255,255,0.65);
    transform: translateY(-1px);
}

.mis-top-right {
    display: flex;
    align-items: center;
    gap: 12px;
}

.mis-top-clock {
    font-size: 12px;
    color: #E2E8F0;
    font-weight: 500;
    letter-spacing: 0.3px;
    white-space: nowrap;
    margin-right: 4px;
}

.mis-top-btn {
    background: transparent !important;
    border: 0 !important;
    color: #E2E8F0 !important;
    cursor: pointer;
    font-size: 13.5px;
    padding: 6px 7px;
    border-radius: 5px;
    transition: all 0.15s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.mis-top-btn:hover {
    color: #FFFFFF !important;
    background-color: rgba(255, 255, 255, 0.14) !important;
}

.mis-top-notif-wrap {
    position: relative;
}

.mis-top-badge {
    position: absolute;
    top: 5px;
    right: 5px;
    width: 6px;
    height: 6px;
    background-color: #EF4444;
    border-radius: 50%;
    border: 1px solid var(--mis-accent);
}

.mis-user-dropdown {
    position: relative;
    margin-left: 4px;
}

.mis-user-btn {
    display: flex !important;
    align-items: center;
    gap: 8px;
    text-decoration: none !important;
    color: #FFFFFF !important;
    padding: 4px 6px;
    border-radius: 6px;
    transition: background 0.15s;
}

.mis-user-btn:hover, .mis-user-btn:focus {
    background-color: rgba(255, 255, 255, 0.12) !important;
}

.mis-user-avatar {
    width: 27px;
    height: 27px;
    border-radius: 50%;
    object-fit: cover;
    border: 1.5px solid rgba(255,255,255,0.8);
    background-color: #FFFFFF;
}

.mis-user-name {
    font-size: 12.5px;
    font-weight: 600;
    color: #FFFFFF;
    white-space: nowrap;
}

.mis-profile-menu {
    border-radius: 8px;
    box-shadow: 0 4px 14px rgba(0,0,0,0.12);
    border: 1px solid #E2E8F0;
    margin-top: 6px;
    min-width: 170px;
}

.mis-profile-menu > li > a {
    padding: 7px 16px;
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ---- open user menu ----------------------------------------------------
   The menu drops out of a coloured bar, so it gets a coloured head of its
   own: without it the panel reads as an unrelated white box that happens to
   be below the button. Everything is drawn from the accent tokens, so this
   follows the Customize panel rather than pinning the menu to green. */
.mis-user-dropdown.open .mis-user-btn {
    background-color: rgba(255, 255, 255, 0.18) !important;
}
.mis-profile-menu {
    overflow: hidden;      /* lets the header's square corners take the radius */
    padding-top: 0;
    min-width: 210px;
}
.mis-profile-menu > .dropdown-header {
    background: linear-gradient(90deg, var(--mis-accent) 0%, var(--mis-accent-dark) 100%);
    color: #FFFFFF;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .2px;
    margin: 0 0 6px;
    padding: 11px 16px;
    text-transform: none;   /* Bootstrap upper-cases this; Khmer must not be */
}
.mis-profile-menu > li > a:hover,
.mis-profile-menu > li > a:focus {
    background-color: var(--mis-accent-tint);
    color: var(--mis-accent-press);
}
.mis-profile-menu > li > a i {
    color: var(--mis-accent);
    width: 15px;
    text-align: center;
}
/* The sign-out row stays red: it is the one entry whose colour is about
   consequence rather than branding. */
.mis-profile-menu > li > a.text-danger,
.mis-profile-menu > li > a.text-danger i { color: #DC2626; }
.mis-profile-menu > li > a.text-danger:hover,
.mis-profile-menu > li > a.text-danger:focus {
    background-color: #FEF2F2;
    color: #B91C1C;
}
.mis-profile-menu > li > a.text-danger:hover i { color: #B91C1C; }

/* ---- SHELL CONTAINER (Sidebar + Main) ---- */
.mis-shell-container {
    display: grid !important;
    grid-template-columns: var(--mis-side-w, 240px) minmax(0, 1fr) !important;
    flex: 1;
    min-height: calc(100vh - 52px);
    background-color: #F4F6F9;
}

/* ---- SIDEBAR ---- */
.mis-side {
    background-color: #FFFFFF !important;
    border-right: 1px solid #E6EAF0 !important;
    position: sticky !important;
    top: 52px !important;
    height: calc(100vh - 52px) !important;
    overflow-y: auto !important;
    padding: 8px 0 24px !important;
    transition: width 0.2s ease;
    z-index: 90;
    max-height: none !important;
}

.mis-side::-webkit-scrollbar {
    width: 5px;
}
.mis-side::-webkit-scrollbar-thumb {
    background: #CBD5E1;
    border-radius: 4px;
}

.mis-nav-menu {
    padding: 0 8px;
}

.mis-menu-item {
    margin: 2px 0;
}

.mis-menu-link, .mis-menu-toggle {
    display: flex !important;
    align-items: center !important;
    width: 100% !important;
    padding: 8px 12px !important;
    border-radius: 6px !important;
    color: #334155 !important;
    font-size: 13.5px !important;
    text-decoration: none !important;
    background: transparent !important;
    border: 0 !important;
    cursor: pointer !important;
    text-align: left !important;
    transition: all 0.15s ease !important;
    box-sizing: border-box;
}

.mis-menu-link:hover, .mis-menu-toggle:hover {
    background-color: #F1F5F9 !important;
    color: #0F172A !important;
}

.mis-menu-link.is-active {
    background-color: #F8FAFC !important;
    color: #0F172A !important;
    font-weight: 700 !important;
    box-shadow: inset 3px 0 0 var(--mis-accent) !important;
}

.mis-menu-icon {
    width: 20px;
    font-size: 14px;
    margin-right: 10px;
    color: #64748B;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.mis-menu-link.is-active .mis-menu-icon {
    color: var(--mis-accent) !important;
}

.mis-menu-text {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mis-menu-caret {
    margin-left: auto;
    font-size: 12px;
    color: #94A3B8;
    transition: transform 0.2s ease;
}

.mis-menu-toggle[aria-expanded="true"] .mis-menu-caret {
    transform: rotate(90deg);
}

.mis-menu-sub {
    padding-left: 28px;
    padding-top: 2px;
    padding-bottom: 4px;
}

.mis-menu-sub a {
    display: flex !important;
    align-items: center !important;
    padding: 6px 10px !important;
    font-size: 12.5px !important;
    color: #64748B !important;
    text-decoration: none !important;
    border-radius: 4px !important;
    transition: all 0.15s !important;
}

.mis-menu-sub a:hover, .mis-menu-sub a.is-active {
    color: #0F172A !important;
    background-color: #F1F5F9 !important;
    font-weight: 600 !important;
}

.mis-sub-bullet {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: #CBD5E1;
    margin-right: 8px;
    display: inline-block;
    flex-shrink: 0;
}

.mis-menu-sub a.is-active .mis-sub-bullet {
    background-color: var(--mis-accent);
}

/* ---- MAIN AREA & FOOTER ---- */
.mis-main {
    display: flex !important;
    flex-direction: column !important;
    min-width: 0 !important;
    background-color: #F4F6F9 !important;
}

.mis-content {
    flex: 1;
    padding: 16px 20px 28px !important;
}

.mis-foot {
    background-color: #FFFFFF !important;
    border-top: 1px solid #E6EAF0 !important;
    padding: 12px 22px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    font-size: 12px !important;
    color: #64748B !important;
    margin-top: auto;
}

.mis-foot-left strong {
    font-weight: 600;
    color: #334155;
}

.mis-foot-right {
    font-weight: 500;
    color: #64748B;
}

/* ---- COLLAPSED SIDEBAR (mis-rail-collapsed) ---- */
body.mis-rail-collapsed .mis-shell-container {
    grid-template-columns: 66px minmax(0, 1fr) !important;
}

body.mis-rail-collapsed .mis-side {
    width: 66px !important;
}

body.mis-rail-collapsed .mis-menu-text,
body.mis-rail-collapsed .mis-menu-caret,
body.mis-rail-collapsed .mis-menu-sub {
    display: none !important;
}

body.mis-rail-collapsed .mis-menu-icon {
    margin-right: 0 !important;
    width: 100% !important;
}

/* ============================================================
   SREYPICH DASHBOARD VIEW STYLES
   ============================================================ */
.sreypich-dashboard {
    max-width: 1400px;
    margin: 0 auto;
}

/* Header Row */
.dash-header-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 16px;
    flex-wrap: wrap;
    gap: 8px;
}

.dash-page-title {
    font-size: 21px;
    font-weight: 700;
    color: #0F172A;
    margin: 0 0 4px 0;
    font-family: 'Kantumruy Pro', sans-serif;
}

.dash-page-subtitle {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 13.5px;
    color: #0F172A;
    font-weight: 600;
}

.dash-page-subtitle i {
    font-size: 13px;
    color: #0F172A;
}

.dash-page-subtitle .sub-period {
    color: #64748B;
    font-weight: 400;
    font-size: 12px;
}

.dash-breadcrumb-block {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #64748B;
    padding-top: 4px;
}

.dash-crumb-link {
    color: #64748B;
    text-decoration: none !important;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.dash-crumb-link:hover {
    color: #2563EB;
}

.dash-crumb-sep {
    color: #CBD5E1;
}

.dash-crumb-current {
    color: #334155;
    font-weight: 600;
}

/* 3 KPI Summary Cards */
.dash-kpi-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-bottom: 18px;
}

.dash-kpi-box {
    background: #FFFFFF;
    border: 1px solid #E6EAF0;
    border-radius: 12px;
    padding: 18px 20px;
    display: flex;
    align-items: center;
    gap: 16px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.03);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.dash-kpi-box:hover {
    box-shadow: 0 4px 10px rgba(0,0,0,0.05);
}

.kpi-icon-wrap {
    width: 50px;
    height: 50px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    flex-shrink: 0;
}

/* These three figures carry meaning, so they stay distinguishable rather than
   all going green. But money coming in is the one number on this dashboard
   that the brand colour genuinely belongs to, and it was a generic blue that
   appears nowhere else in the product. Amber and rose are kept as they are:
   they read as "going out" and "taken off". */
.kpi-income {
    background-color: var(--mis-accent-tint);
    color: var(--mis-accent-dark);
}

.kpi-expense {
    background-color: #FEF8E7;
    color: #D97706;
}

.kpi-discount {
    background-color: #FEECEE;
    color: #E11D48;
}

.kpi-label {
    font-size: 12.5px;
    color: #64748B;
    font-weight: 500;
    margin-bottom: 2px;
}

.kpi-val {
    font-size: 20px;
    font-weight: 700;
    color: #0F172A;
    letter-spacing: -0.2px;
    font-family: 'Inter', sans-serif;
}

/* Middle Charts Row */
.dash-charts-row {
    display: grid;
    grid-template-columns: 66% minmax(0, 1fr);
    gap: 16px;
    margin-bottom: 18px;
    /* Each card takes the height of what is in it. Grid stretches its children
       by default, so whichever card had less to show grew a matching area of
       white -- the taller the neighbour, the bigger the void. Uneven bottom
       edges read better than a card padded out with nothing. */
    align-items: start;
}

.dash-chart-card {
    background: #FFFFFF;
    border: 1px solid #E6EAF0;
    border-radius: 12px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.03);
    overflow: hidden;
}

.dash-card-header {
    padding: 14px 18px;
    border-bottom: 1px solid #F1F5F9;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.dash-card-title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: #1E293B;
}

/* The period a card covers, sitting quietly opposite its title. */
.dash-card-note {
    font-size: 12px;
    color: #94A3B8;
}

/* Shown instead of an axis with nothing on it. A chart drawn over no rows
   reads as "business was flat", which is a different claim from "nothing has
   been entered yet". */
/* ---- Activity panels ----
   Three small components the dashboard needed once it started showing the
   things the system actually records: a list of recent enquiries, a set of
   proportional bars for job statuses, and a ranked list for tool usage.
   Ranked rather than plotted, because the tool counts span five orders of
   magnitude and anything to scale is one full bar and five empty ones. */
.dash-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.dash-list > li {
    padding: 10px 2px;
    border-bottom: 1px solid #F1F4F8;
}

.dash-list > li:last-child { border-bottom: 0; }

.dash-list-main {
    display: block;
    font-size: 13.5px;
    font-weight: 600;
    color: #2F3D54;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-list-sub {
    display: block;
    margin-top: 2px;
    font-size: 11.5px;
    color: #8A97A8;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Divides two kinds of content inside one card -- the status bars above from
   the jobs they count below. */
.dash-subhead {
    border-top: 1px solid #F1F4F8;
    color: #8A97A8;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    margin: 14px 0 2px;
    padding-top: 14px;
    text-transform: uppercase;
}

.dash-list-tight > li { padding: 8px 2px; }

.dash-bars {
    list-style: none;
    margin: 0;
    padding: 6px 0;
}

.dash-bars > li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 2px;
}

.dash-bar-label {
    flex: 0 0 34%;
    font-size: 13px;
    color: #2F3D54;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-bar-track {
    flex: 1 1 auto;
    height: 9px;
    border-radius: 100px;
    background: #EEF1F5;
    overflow: hidden;
}

.dash-bar-fill {
    display: block;
    height: 100%;
    border-radius: 100px;
    background: var(--mis-accent);
}

.dash-bar-val {
    flex: 0 0 auto;
    font-size: 12.5px;
    font-weight: 700;
    color: #45526B;
    font-variant-numeric: tabular-nums;
}

.dash-rank {
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: rank;
}

.dash-rank > li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 2px;
    border-bottom: 1px solid #F1F4F8;
    counter-increment: rank;
}

.dash-rank > li:last-child { border-bottom: 0; }

.dash-rank > li::before {
    content: counter(rank);
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--mis-accent-tint);
    color: var(--mis-accent-dark);
    font-size: 11px;
    font-weight: 700;
    display: grid;
    place-items: center;
}

.dash-rank-name {
    flex: 1 1 auto;
    font-size: 13px;
    color: #2F3D54;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-rank-val {
    flex: 0 0 auto;
    font-size: 12.5px;
    font-weight: 700;
    color: #45526B;
    font-variant-numeric: tabular-nums;
}

/* The period's money totals, sitting above the chart that plots them. */
.dash-money-strip {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    padding: 2px 0 16px;
    border-bottom: 1px solid #F1F4F8;
    margin-bottom: 14px;
}

.dash-money-strip span {
    display: block;
    font-size: 11.5px;
    color: #8A97A8;
}

.dash-money-strip b {
    display: block;
    margin-top: 2px;
    font-size: 15px;
    color: #2F3D54;
    font-variant-numeric: tabular-nums;
}

.dash-money-strip b.is-in  { color: var(--mis-accent-dark); }
.dash-money-strip b.is-out { color: #D97706; }

@media (max-width: 620px) {
    .dash-money-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* KPI tiles are links now, so they must not pick up link styling. */
a.dash-kpi-box,
a.dash-kpi-box:hover,
a.dash-kpi-box:focus {
    text-decoration: none;
    color: inherit;
}

a.dash-kpi-box:hover {
    border-color: rgba(var(--mis-accent-rgb), 0.35);
    box-shadow: 0 4px 14px rgba(14, 32, 56, 0.08);
}

.kpi-sub {
    font-size: 11.5px;
    font-weight: 500;
    color: #8A97A8;
    margin-left: 6px;
}

.dash-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* Was 220px, which turned "nothing recorded this month" into a half-metre
       of white. An empty state should be legible, not monumental. */
    min-height: 150px;
    padding: 20px 16px;
    text-align: center;
}

.dash-empty i {
    font-size: 30px;
    color: #CBD5E1;
}

.dash-empty p {
    margin: 0;
    font-size: 13px;
    color: #64748B;
}

.dash-empty-link {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--mis-accent);
}

.dash-empty-link:hover,
.dash-empty-link:focus {
    text-decoration: underline;
}

.dash-pill-group {
    display: flex;
    gap: 6px;
}

.dash-pill {
    border: 1px solid #E2E8F0;
    background: #FFFFFF;
    color: #64748B;
    font-size: 11px;
    font-weight: 500;
    padding: 4px 12px;
    border-radius: 20px;
    cursor: pointer;
    transition: all 0.15s;
}

.dash-pill:hover {
    background-color: #F8FAFC;
}

.dash-pill.active {
    background: #2563EB;
    color: #FFFFFF;
    border-color: #2563EB;
}

.dash-card-body {
    padding: 18px;
}

.sales-chart-container {
    width: 100%;
}

.sales-bar-svg {
    width: 100%;
    height: 220px;
}

.chart-legend-row {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin-top: 10px;
    font-size: 11px;
    color: #64748B;
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 5px;
}

.legend-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}

/* Donut Chart */
.donut-body {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 22px;
    flex-wrap: wrap;
    min-height: 250px;
}

.donut-chart-box {
    width: 190px;
    height: 190px;
    flex: none;
}

/* The ring is rotated in the markup, on a group around the arcs alone: doing
   it here turned the centre total on its side along with them. */
.donut-svg {
    width: 100%;
    height: 100%;
}

/* Which colour is which product. The ring alone could not say. */
.donut-legend {
    list-style: none;
    margin: 0;
    padding: 0;
    min-width: 150px;
    flex: 1 1 150px;
}

.donut-legend li {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 0;
    font-size: 12.5px;
    color: #475569;
}

.donut-legend-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.donut-legend-val {
    font-weight: 600;
    color: #1E293B;
}

/* Bottom Quick Actions (ážŠáŸ†ážŽáž¾ážšáž€áž¶ážšážšáž áŸážŸ) */
.dash-quick-actions-card {
    background: #FFFFFF;
    border: 1px solid #E6EAF0;
    border-radius: 12px;
    padding: 18px 20px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.03);
}

.quick-act-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 18px;
}

.quick-act-icon {
    color: #2563EB;
    font-size: 14px;
}

.quick-act-title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: #1E293B;
}

/* A grid, not flex with space-between. The old rule sized every tile at a
   fixed 78px and then pushed them apart to fill the row, so on a wide screen
   eleven tiles sat in one cramped line with ragged gaps, and the last row of
   any wrap spread itself across the full width. auto-fill lays them out in
   even columns and wraps into tidy rows at any width. */
/* Five to a row rather than auto-fill. auto-fill packed as many as would fit
   -- nine across on a wide screen and the tenth alone on its own row, which is
   the ragged thing this grid was meant to stop. A fixed count gives even rows,
   and the step-downs below keep them even as the window narrows. */
.quick-act-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 22px 12px;
    align-items: start;
}

@media (max-width: 1400px) {
    .quick-act-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 1024px) {
    .quick-act-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.quick-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 9px;
    text-decoration: none !important;
    padding: 4px 2px;
    transition: transform 0.15s ease;
}

.quick-tile:hover {
    transform: translateY(-3px);
}

/* One tile treatment, in the brand's own colour.
   There were twelve hardcoded hues here -- purple, sky, orange, pink, crimson,
   indigo, slate -- none of which appear anywhere else in MISTEAMS and none of
   which meant anything: the colour was decoration, assigned in the order the
   tiles happened to be written. Site.css declares --mis-accent as the single
   place the product's colour is defined, and this grid was the largest thing
   on the dashboard ignoring it. The icon and the label carry the meaning now,
   which is what was distinguishing the tiles in practice anyway. */
.tile-icon-box {
    width: 52px;
    height: 52px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--mis-accent-tint);
    color: var(--mis-accent-dark);
    font-size: 18px;
    border: 1px solid rgba(var(--mis-accent-rgb), 0.16);
    transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.quick-tile:hover .tile-icon-box {
    background: var(--mis-accent);
    border-color: var(--mis-accent);
    color: #FFFFFF;
    box-shadow: 0 5px 14px rgba(var(--mis-accent-rgb), 0.30);
}

.tile-label {
    font-size: 12px;
    color: #334155;
    text-align: center;
    /* Was nowrap, which is why the long Khmer labels forced the row wider than
       its container instead of running onto a second line. */
    line-height: 1.45;
    font-weight: 500;
}

.quick-tile:hover .tile-label {
    color: var(--mis-accent-dark);
}

/* Responsive Breakpoints */
@media (max-width: 1200px) {
    .dash-charts-row {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 991px) {
    .mis-shell-container {
        grid-template-columns: 1fr !important;
    }
    .mis-side {
        position: fixed !important;
        left: -260px;
        top: 52px !important;
        bottom: 0;
        width: 250px !important;
        transition: left 0.25s ease;
        z-index: 1050 !important;
    }
    body.mis-rail-open .mis-side {
        left: 0 !important;
    }
    .dash-kpi-grid {
        grid-template-columns: 1fr;
    }
    /* justify-content did nothing once this became a grid. Two even columns on
       a phone; the labels are long enough in Khmer that three would wrap to
       three lines each. */
    .quick-act-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 18px 10px;
    }
}

/* ============================================================
   CLEAN PAGE BANNER, BREADCRUMBS, BRAND & SIDEBAR POLISH
   ============================================================ */
.mis-brand-icon {
    width: 30px;
    height: 30px;
    background: rgba(255, 255, 255, 0.18);
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #FFFFFF;
    font-size: 15px;
    margin-right: 8px;
}
.mis-top-brand-text {
    font-size: 16px !important;
    font-weight: 800 !important;
    letter-spacing: 0.5px !important;
    color: #FFFFFF !important;
}
.mis-user-avatar-circle {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    /* Was a hardcoded pale blue on a blue-grey scheme. Inverted against the
       bar instead: white disc, accent initials -- so it stays legible whichever
       accent the Customize panel is set to. */
    background: #FFFFFF;
    color: var(--mis-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    font-weight: 700;
}

.mis-page-banner {
    margin-bottom: 18px;
}
.mis-crumb {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    color: #64748B;
    margin-bottom: 6px;
}
.mis-crumb a {
    color: #64748B;
    text-decoration: none !important;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.mis-crumb a:hover {
    color: var(--mis-accent);
}
.mis-crumb-sep {
    color: #CBD5E1;
}
.mis-crumb-now {
    color: #1E293B;
    font-weight: 600;
}
.mis-page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.mis-page-heading {
    font-size: 20px;
    font-weight: 700;
    color: #0F172A;
    margin: 0 0 2px 0;
    font-family: 'Kantumruy Pro', sans-serif;
}
.mis-page-subheading {
    font-size: 13px;
    color: #64748B;
    margin: 0;
}

.mis-sub-icon {
    width: 16px;
    font-size: 12.5px;
    margin-right: 8px;
    color: #64748B;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.mis-menu-sub a.is-active .mis-sub-icon {
    color: var(--mis-accent) !important;
}
.mis-menu-toggle.is-parent-active {
    background-color: #F8FAFC !important;
    color: #0F172A !important;
    font-weight: 600 !important;
}

/* Cleaner Card & DataTables */
.mis-card {
    background: #FFFFFF;
    border: 1px solid #E6EAF0;
    border-radius: 12px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03);
    margin-bottom: 20px;
}
.dataTables_wrapper .dataTables_filter input {
    height: 34px;
    border-radius: 6px;
    border: 1px solid #CBD5E1;
    padding: 4px 10px;
    font-size: 13px;
}
.dataTables_wrapper .dataTables_length select {
    height: 34px;
    border-radius: 6px;
    border: 1px solid #CBD5E1;
    padding: 4px 8px;
    font-size: 13px;
}

/* ------------------------------------------------------------
   Rail: third level

   The six section groups now sit inside the "Manage Website" group,
   so a .mis-menu-item.has-sub can appear inside a .mis-menu-sub --
   a depth the rail was never styled for. Without these the nested
   toggles inherit the top-level button's padding and sit at the same
   indent as their own children, so the tree reads flat.

   The rule is one step in, one step quieter, at each level.
   ------------------------------------------------------------ */
.mis-menu-sub .mis-menu-item.has-sub { margin: 0; }

.mis-menu-sub .mis-menu-toggle {
    background: transparent !important;
    border: 0 !important;
    border-radius: 6px !important;
    color: #475569 !important;
    display: flex;
    font-size: 12.8px;
    font-weight: 600;
    gap: 9px;
    padding: 7px 10px !important;
    width: 100%;
}
.mis-menu-sub .mis-menu-toggle:hover,
.mis-menu-sub .mis-menu-toggle.is-parent-active {
    background-color: #F1F5F9 !important;
    color: #0F172A !important;
}
.mis-menu-sub .mis-menu-toggle .mis-menu-icon i { font-size: 13px; width: 16px; text-align: center; }

/* The innermost list steps in again and picks up a guide rule, so the
   three levels are distinguishable without counting indents. */
.mis-menu-sub .mis-menu-sub {
    border-left: 1px solid var(--mis-line);
    margin-left: 14px;
    padding-left: 8px;
}
.mis-menu-sub .mis-menu-sub a { font-size: 12.5px; padding: 6px 9px; }

/* ------------------------------------------------------------
   Rail: fourth level -- a shop's POS menu

   Store Types > category > shop > page. The rail was styled three
   deep; a shop with a till now has fourteen pages under it, which
   is the depth the POS module's own menu has in the system it was
   ported from.

   Four levels of indent would leave the deepest labels squeezed
   against the right edge, so this level does NOT step in again.
   It marks itself with a heavier guide rule and a tighter row
   instead -- the nesting is already legible from the rule the
   third level drew, and the fourth reads as that list's contents
   rather than as another branch.
   ------------------------------------------------------------ */
.mis-menu-sub .mis-menu-sub .mis-menu-sub {
    border-left: 2px solid var(--mis-line);
    margin-left: 10px;
    padding-left: 6px;
}
.mis-menu-sub .mis-menu-sub .mis-menu-sub a {
    font-size: 12px;
    padding: 5px 8px;
}
/* The shop's own toggle carries its name, which is the longest label
   at this depth -- it wraps rather than being clipped. */
.mis-menu-sub .mis-menu-sub .mis-menu-toggle .mis-menu-text {
    white-space: normal;
    line-height: 1.25;
}

/* ------------------------------------------------------------
   Rail: fifth level -- the Products group inside a shop's menu

   Store Types > category > shop > Products > page. Only one group
   goes this deep, and only because the catalogue is five jobs in
   the POS this module was ported from rather than one.

   Like the fourth level, this one does NOT step in again -- there
   is no horizontal room left, and the labels here ("Promotion By
   Period") are the longest in the rail. It separates itself with a
   dotted rule in the accent instead, which reads as "inside the
   list above" rather than as another branch, and it is the only
   dotted rule in the rail so there is nothing to confuse it with.
   ------------------------------------------------------------ */
.mis-menu-sub .mis-menu-sub .mis-menu-sub .mis-menu-sub {
    border-left: 1px dotted var(--mis-accent);
    margin-left: 8px;
    padding-left: 6px;
}
.mis-menu-sub .mis-menu-sub .mis-menu-sub .mis-menu-sub a {
    font-size: 11.5px;
    padding: 4px 8px;
}
.mis-menu-sub .mis-menu-sub .mis-menu-sub .mis-menu-sub .mis-sub-icon {
    width: 14px;
    font-size: 11px;
    margin-right: 6px;
}
/* The group's own toggle sits among the page rows rather than above
   them, so it takes their size and not the shop toggle's. */
.mis-menu-sub .mis-menu-sub .mis-menu-sub .mis-menu-toggle {
    font-size: 12px;
    padding: 5px 8px !important;
}

/* An entry with no screen behind it: visible, inert, and saying so.
   Rendered as an <a> with no href, which is already unfocusable and
   unclickable; this is only the part the eye needs. Keyed on the
   attribute rather than on .is-muted alone, because .is-muted also
   marks a closed shop or a retired category -- those are real links
   and must stay clickable. */
.mis-menu-sub a.is-muted[aria-disabled="true"] {
    cursor: default;
    font-style: normal;
    opacity: .55;
}
.mis-menu-sub a.is-muted[aria-disabled="true"]:hover {
    background: transparent !important;
    color: #94A3B8 !important;
}

/* The caret belongs on the right at every level. */
.mis-menu-sub .mis-menu-toggle .mis-menu-caret { margin-left: auto; font-size: 11px; opacity: .7; }

/* The outermost rail group shows and hides by class, not by Bootstrap
   collapse -- see the comment beside its markup in _LayoutAdmin.cshtml.
   No height animation, so nothing for a child's transitionend to disturb. */
.mis-root-sub { display: none; }
.mis-menu-item.is-open > .mis-root-sub { display: block; }


/* A rail entry for something switched off: still listed, visibly not in use.
   Opacity alone would fade the icon and the label unevenly, so the colour is
   set directly and the label italicised. */
.mis-menu-sub a.is-muted { color: #94A3B8 !important; font-style: italic; }
.mis-menu-sub a.is-muted i { color: #CBD5E1 !important; }
.mis-menu-sub a.is-muted:hover { color: #64748B !important; }

/* ============================================================
   The till (/stores/{id}/pos)

   Four panes -- form, list, sum, cat -- placed by grid-template-areas,
   one arrangement per breakpoint. The form fields stand on their own
   side; the item list and the money (totals + buttons) stand side by
   side; the catalogue takes whatever is left. See Views/Pos/Till.cshtml
   for why, and for the two-column layout this replaced.

   The colours are that screen's colours on purpose. A till is read
   at a glance, half-looked-at, mid-conversation with a customer --
   the red price, the green Payment button and the mint total are
   how it is read without being read.
   ============================================================ */

/* ---- the till owns the window ---------------------------------
   The shell is built out of min-heights all the way down -- 100vh on
   .mis-shell, calc(100vh - 52px) on .mis-shell-container -- so it grows to
   whatever its content asks for. That is right for a document and wrong for a
   till: with no DEFINITE height anywhere in the chain, the `overflow-y: auto`
   on the basket and on the product grid has nothing to overflow. A seventh row
   of tiles did not start the grid scrolling, it pushed the panel, the row, the
   content well and finally the page taller, and the till scrolled as one
   document -- which on a 1366x768 laptop put the total and the Payment button
   below the fold, the one thing this layout exists to prevent.

   Pinning .mis-shell to the viewport once, here, is what makes every `flex: 1`
   and `overflow-y: auto` below it mean what it says. It has to be .mis-shell
   and not the container: the container carries `flex: 1`, and a flex item's
   grow factor beats any height you give it.

   Only from 992px up. Below that the shell stops being a grid, the two columns
   stack, and a till taller than the window is the correct outcome.

   Scoped to body.mis-till-page (set from Views/Pos/Till.cshtml) rather than
   applied everywhere: every other screen in the app is a document that should
   end where its content ends. */
@media (min-width: 992px) {
    body.mis-till-page .mis-shell { height: 100vh; }
    body.mis-till-page .mis-shell-container,
    body.mis-till-page .mis-main,
    body.mis-till-page .mis-content { min-height: 0; }
    /* `auto`, not `hidden`. The grid below has minimum track sizes -- a pane of
       buttons cannot usefully be squeezed to 80px -- so on a genuinely short
       window (a 1280x600 counter PC, or a laptop with a browser toolbar and a
       taskbar eating 200px) the four panes can ask for more height than the
       window has. `hidden` would have answered that by cutting the Payment
       button off at the bottom edge with no way to reach it. `auto` shows a
       scrollbar in that one case and none in every other, because when the
       panes do fit there is nothing to scroll. */
    body.mis-till-page .mis-content { display: flex; flex-direction: column; overflow: auto; }
    body.mis-till-page .mis-content > .mis-till { flex: 1; min-height: 0; }

    /* The copyright line, for the same reason the breadcrumb, the page heading
       and the POS tab strip are already gone from this one screen: it is 42px
       the basket and the grid can use, and it says nothing to someone standing
       at a counter. !important because the theme block above sets
       `display: flex !important` on it. */
    body.mis-till-page .mis-foot { display: none !important; }
}

/* ---- the four panes -------------------------------------------
   A GRID, NOT A FLEX ROW. The old layout was `display: flex` over two
   Bootstrap columns, and a flex item will not shrink below its own content:
   the tile grid's min-content width regularly pushed the pair past 100% and
   wrapped the catalogue onto a second line, which is how a 1900px screen ended
   up showing a 700px order panel with the right third of the display empty. A
   grid track cannot do that -- `minmax(0, 1fr)` is an instruction the browser
   has to obey, and the panes divide the width exactly however wide the window
   is.

   The areas are always the same four names, so only the shape changes per
   breakpoint and the markup never does. Base case here is the phone: one
   column, and the catalogue sits directly under the form because that is the
   order of the job -- pick the customer, scan or tap the goods, check the
   list, take the money. */
.mis-till {
    display: grid;
    gap: 12px;
    grid-template-areas:
        "form"
        "cat"
        "list"
        "sum";
    grid-template-columns: minmax(0, 1fr);
    /* EACH STACKED ROW IS ITS OWN PANE'S HEIGHT, stated rather than left to
       `auto`, and this is not a nicety.

       An `auto` track's base size is the item's automatic minimum, and further
       down this file every link in the pane chain carries `min-height: 0` --
       which the scrolling basket and tile grid need. That makes the base size
       zero, so while the till is pinned to the window (992px up) the grid had
       674px of free space and four zero-height tracks to share it between:
       159.5px each, against a form pane that needs 233. The panes do not clip,
       they overflow, so what reached the screen was the catalogue card painted
       over the bottom of the form, with the search box underneath it.

       max-content sizes each row to its pane; the column then overflows into
       .mis-content, which scrolls. `start` keeps them at the top when the
       window is taller than the four of them. The two-column rule below states
       its own rows, so this governs the stacked case only. */
    align-content: start;
    grid-template-rows: repeat(4, max-content);
}
.mis-till > div { display: flex; min-width: 0; }
/* Scoped: `grid-area` on a bare `.t-list` anywhere else in the app would place
   an unrelated element into a grid it has never heard of. */
.mis-till > .t-form { grid-area: form; }
.mis-till > .t-list { grid-area: list; }
.mis-till > .t-sum  { grid-area: sum; }
.mis-till > .t-cat  { grid-area: cat; }

/* While the panes are stacked, the tile grid has nothing to overflow and would
   run to a hundred rows down the page, burying the basket and the buttons under
   it. A viewport-relative cap gives it something to scroll inside while leaving
   the page itself scrollable.

   The ceiling is 1199px, matching where the two columns begin. Between 992 and
   1199 the page is already pinned to the window but the panes are still
   stacked, which is the case that most needs this: a grid with no cap, inside a
   container that cannot grow. */
@media (max-width: 1199px) {
    .mis-till-grid { max-height: 58vh; }
    .mis-till-basket { max-height: 46vh; }
}

/* Desktop: TWO COLUMNS. The order on the left -- form fields, then the item
   list, then the totals and the buttons, in the order a sale is worked through
   -- and the catalogue beside it on the right, both the full height of the
   window with nothing stacked below.

   The left column is three rows rather than one pane, which is what lets the
   item list take the height: `auto` for the form and `auto` for the money mean
   each is exactly as tall as its content, and the `1fr` between them hands the
   list everything else. That is also what keeps the Payment button still --
   it is measured from the bottom of the column, not pushed down from the top by
   whatever the basket is doing.

   ONE BREAKPOINT, at 1200px, and it is measured. Below it the two columns stop
   being worth having: at 1000px a 240px rail and the page padding leave 732px,
   the order takes its 440px floor, and the catalogue is left with 280px -- one
   tile per row, which is a list with pictures, not a catalogue. At 1200 it gets
   three, at 1366 four, at 1920 seven. Under 1200 the panes stack instead, and
   the tile grid gets the whole width for as long as it needs.

   The left column's floor is 440px and its ceiling 620px, and between the two
   it takes 38% of whatever is there. The floor is set by the basket: its five
   narrow columns are tightened to 288px in this layout (see .mis-till-basket
   .c-* below), and 440 is what leaves the product name the ~130px it needs to
   wrap an ordinary Khmer name in two lines rather than three. The ceiling is
   where the order stops gaining anything and is only holding whitespace the
   tiles would use. */
@media (min-width: 1200px) {
    .mis-till {
        grid-template-areas:
            "form cat"
            "list cat"
            "sum  cat";
        grid-template-columns: clamp(440px, 38%, 620px) minmax(0, 1fr);
        grid-template-rows: auto minmax(160px, 1fr) auto;
    }

    /* A grid item stretches to its area, but the .panel inside it is a separate
       box: without this it sizes to its own content and the card stops short of
       the bottom of its area, leaving a band of grey inside the pane. An
       explicit 100% -- resolved against the area's now-definite height -- is
       also what hands `flex: 1` on .panel-body a real number to divide up.

       IT BELONGS WITH THE TWO COLUMNS, not up in the pinned-height block where
       it was written. That block starts at 992px, and between 992 and 1199 the
       page is pinned but the panes are stacked in auto-sized rows -- a height of
       100% against a row that has no definite height of its own resolved to
       something shorter than the card, and the form pane was cut off through the
       middle of the search box. */
    body.mis-till-page .mis-till > div,
    body.mis-till-page .mis-till .panel { height: 100%; }
}

.mis-till .panel {
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
    width: 100%;
}
/* Prefixed with .body-content to match the specificity of the app-wide
   `.body-content .panel > .panel-body { padding: 18px }` and beat it on source
   order. The panes used to carry `style="padding:10px"` inline, which is what
   was outranking that rule before; the padding belongs here, not on four
   elements in the view. */
.body-content .mis-till .panel-body {
    background: #fff;
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 10px;
}

/* Every link in that chain needs min-height: 0, or the `overflow-y: auto` on
   the basket and the product grid never fires.

   A flex item defaults to `min-height: auto`, which refuses to shrink below
   its own content -- so a seventh row of tiles did not start the grid
   scrolling, it pushed the panel, the row, the content well and finally the
   page taller, and the whole till scrolled as one document. On a 1366x768
   laptop that put the Payment button and the total below the fold, which is
   the one thing this layout exists to prevent. The shell's
   `min-height: calc(100vh - 52px)` then resolves to exactly that, because
   nothing below demands more. */
.mis-till > div,
.mis-till .panel,
.mis-till .panel-body { min-height: 0; }

/* --- the form pane -------------------------------------------- */

/* One class instead of the `style="margin-bottom:6px"` that used to sit on
   every control. There are five of them across two panes now, and the gap
   between them is a property of the layout, not of each field. */
.mis-till-field { margin-bottom: 8px; }
.mis-till-pane .panel-body > .mis-till-field:last-child { margin-bottom: 0; }

.mis-till .form-control {
    border-color: #CCD3DA;
    border-radius: 2px;
    box-shadow: none;
    font-size: 13.5px;
    height: 38px;
}
.mis-till .form-control:focus { border-color: #10B981; box-shadow: 0 0 0 2px rgba(16,185,129,.12); }

/* The add-customer button sits against the select as one control. */
.mis-till .input-group-btn .btn {
    border-radius: 0 2px 2px 0;
    height: 38px;
    padding: 0 12px;
}
.mis-till-add {
    background: #2D8CF0 !important;
    border-color: #2D8CF0 !important;
    color: #fff !important;
    font-size: 15px;
}
.mis-till-add:hover { background: #1C7AE0 !important; }

/* What the customer owes. Styled as a readonly field rather than a
   badge: it is a figure you read off, not a state you act on. */
.mis-till-balance {
    background: #FAFBFC;
    border: 1px solid #CCD3DA;
    border-radius: 2px;
    color: #334155;
    font-size: 14px;
    line-height: 22px;
    min-height: 38px;
    padding: 7px 12px;
}
.mis-till-balance.is-owing { color: #B45309; font-weight: 600; }

/* --- the list pane -------------------------------------------- */

/* The basket is the whole pane now -- nothing above it and nothing below it --
   so it takes the pane's full height and scrolls inside itself. That is the
   change that stops a long order pushing the Payment button off the screen:
   the buttons are in a different pane entirely, and rows can only ever grow
   into this box. */
.mis-till-basket {
    border: 1px solid #E2E8F0;
    border-radius: 2px;
    flex: 1;
    margin-bottom: 0;
    min-height: 120px;
    overflow-y: auto;
}
.mis-till-basket table { margin: 0; }
/* The five narrow columns. Held here rather than inline in the view because an
   inline width cannot be answered by a media query, and this pane's width is
   not one number -- it is a third of the row on a laptop and half of it on a
   wide screen. The product name takes whatever is left over, which is the right
   way round: it is the only column whose content has no fixed size. */
.mis-till-basket .c-qty   { width: 74px; }
.mis-till-basket .c-price { width: 74px; }
.mis-till-basket .c-disc  { width: 74px; }
.mis-till-basket .c-sub   { width: 84px; }
.mis-till-basket .c-del   { width: 30px; }

/* In the two-column layout the order pane is 440-620px rather than the width of
   the screen, and 336px of fixed columns is a share it can afford at one and
   not the other -- at 440 it left the product name 84px, which is three lines
   for an ordinary Khmer name. 288px, with the cell padding down from 8px to
   6px, buys back about 60px of it. Nothing is clipped: the narrowest of these,
   Price at 72px, still holds "1000.00" with its input padding.

   Placed here, below the widths it overrides, because a media query carries no
   specificity of its own -- up with the grid rules it would simply lose. */
@media (min-width: 1200px) {
    .mis-till-basket .c-qty   { width: 58px; }
    .mis-till-basket .c-price { width: 72px; }
    .mis-till-basket .c-disc  { width: 58px; }
    .mis-till-basket .c-sub   { width: 76px; }
    .mis-till-basket .c-del   { width: 24px; }
    .body-content .mis-till-basket .table > thead > tr > th,
    .mis-till-basket td { padding-left: 6px !important; padding-right: 6px !important; }
}
/* Written long-hand, and prefixed with .body-content, so it outranks the
   app-wide `.body-content .table > thead > tr > th` further up this file.
   That rule forces `background: transparent` and a muted 12px grey, and at the
   plain `.mis-till-basket thead th` specificity it was winning -- the green
   band never reached the screen.

   The band is not decoration. It is the line between what has been rung up and
   the controls above it; without it the whole left panel reads as one
   undifferentiated white box. */
.body-content .mis-till-basket .table > thead > tr > th {
    background: #DFF3E4;
    border: 0 !important;
    color: #1F2937;
    font-size: 13px;
    font-weight: 600;
    padding: 9px 8px !important;
    position: sticky;            /* the header stays while a long order scrolls */
    top: 0;
    z-index: 1;
}
.body-content .mis-till-basket .table > thead > tr > th a { color: #4B5563; }
.mis-till-basket td {
    border-top: 1px solid #F1F5F9 !important;
    font-size: 12.5px;
    padding: 5px 8px !important;
    vertical-align: middle !important;
}
.mis-till-basket input {
    border: 1px solid #CBD5E1;
    border-radius: 2px;
    font-size: 12.5px;
    padding: 2px 5px;
    text-align: right;
    width: 100%;
}
.mis-till-basket input:focus { border-color: #10B981; outline: 0; }

/* --- the sum pane: totals and actions -------------------------- */
/* Four cells per row, label-value label-value, the way the source
   lays them out -- it fits twice the information in the same height,
   which is what buys the buttons below their size. */
.mis-till-totals { margin: 0 0 10px !important; }
.mis-till-totals td {
    border: 0 !important;
    font-size: 13px;
    padding: 8px 12px !important;
}
/* In the pane the four cells share about 300px rather than 680, so the
   horizontal padding comes down and the labels are allowed to wrap. Nothing is
   dropped: a counter needs the item count and the discount as much as the
   total, and hiding either to save 40px is how a miskeyed discount reaches a
   receipt unnoticed. */
.mis-till .t-sum .mis-till-totals td {
    padding: 8px 7px !important;
    word-break: break-word;
}
/* The pane's own safety valve. The totals block and the buttons have a real
   minimum height between them, and on a short window the pane can be shorter
   than that; this scrolls the pane rather than clipping the Payment button. */
.mis-till .t-sum .panel-body { overflow-y: auto; }
.mis-till-totals .num { text-align: right; }
.mis-till-totals tr.t-a td { background: #E7F2FB; }
.mis-till-totals tr.t-b td { background: #fff; }
.mis-till-totals tr.t-b td.lbl { color: #2D8CF0; }
.mis-till-totals tr.t-pay td {
    background: #DFF3E4;
    font-size: 15px;
    font-weight: 700;
}

/* --- the sum pane: the actions -------------------------------- */
/* THE SAME THREE GROUPS, TURNED THROUGH NINETY DEGREES. The markup is
   untouched -- quote/clear, DN/bill, payment, same ids and same handlers -- but
   the pane they now live in is a ~320px rail rather than a 680px panel, and
   three columns of it left "បោះពុម្ពវិក្កយបត្រដឹក" four words deep in a 95px
   button. Stacking the groups and running each group across gives two
   comfortable buttons per row, with Payment the full width of the pane below
   them: it is pressed on every sale, so it should be the one you cannot miss
   and the one you cannot hit by accident.

   The block sits directly under the totals rather than being pushed to the foot
   of the pane. `margin-top: auto` was the first instinct -- a button in a fixed
   corner is a button you can hit without looking -- but the pane is as tall as
   the order beside it, and on a 1080p screen that put 600px of white between
   the amount and the button you press having read it. Read the total, press the
   green one underneath it. */
.mis-till-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.mis-till-actions > div { display: flex; flex-direction: row; gap: 6px; }
.mis-till-actions > div > .btn { flex: 1; min-width: 0; }
.mis-till-actions .btn {
    border: 0;
    border-radius: 2px;
    color: #fff;
    font-size: 13px;
    padding: 11px 4px;
    white-space: normal;
}
.mis-till-actions .btn:hover { color: #fff; filter: brightness(.94); }
.t-quote { background: #F0A030; }
.t-clear { background: #E04B45; }
.t-dn    { background: #9A96D8; }
.t-bill  { background: #4B5A68; }
/* Scoped to the action block. `t-pay` is also the class on the Total Payable
   ROW of the totals table, here and in the payment modal, and that row wants
   none of this -- its cells are styled by `.mis-till-totals tr.t-pay td` a few
   rules up. The background was landing behind those cells harmlessly; a height
   would not have.

   `flex: 1` in a row makes the button the full width of the pane, and the
   min-height keeps it the tallest thing in the block now that it no longer
   spans two rows of buttons. */
.mis-till-actions .t-pay {
    background: #1FA75C;
    flex: 1;
    font-size: 17px !important;
    font-weight: 700;
    min-height: 56px;
}

/* In the two-column layout, back to the source's block: two narrow columns of
   secondary actions and Payment across the height of both. The stacked version
   above exists because a 300px rail cannot hold two Khmer labels side by side;
   the order column is 400px at its narrowest, it can, and the block is about
   110px shorter this way -- 110px the basket above it gets instead.

   THIS HAS TO SIT BELOW THE RULES IT OVERRIDES, not up with the grid at 992px
   where it was first written. A media query adds no specificity, so `@media …
   { .mis-till-actions { flex-direction: row } }` placed before
   `.mis-till-actions { flex-direction: column }` simply loses to it, and the
   buttons stayed stacked on every screen. */
@media (min-width: 1200px) {
    .mis-till-actions { flex-direction: row; }
    .mis-till-actions > div { flex: 1; flex-direction: column; }
    .mis-till-actions .t-pay { min-height: 0; }
}

/* --- the cat pane: the product grid --------------------------- */

/* `auto-fill` rather than a fixed column count with a ladder of max-width
   media queries. The catalogue pane is no longer a fixed fraction of the
   window -- it spans all four columns below 1600px and one of them above -- so
   a rule written against the WINDOW's width now guesses wrong in both
   directions: five columns squeezed into a 600px pane, or four stretched
   across 1400px. `minmax(134px, 1fr)` asks the question of the pane instead,
   which is the only box that ever knew the answer. */
.mis-till-grid {
    align-content: start;
    display: grid;
    flex: 1;
    gap: 5px;
    grid-auto-rows: max-content; /* see below */
    grid-template-columns: repeat(auto-fill, minmax(134px, 1fr));
    min-height: 0;               /* see the note on the panel chain above */
    overflow-y: auto;
}
/* `grid-auto-rows: auto` let the rows collapse to share out whatever height
   the pane had, instead of keeping their own and letting the pane scroll: on a
   1366x768 screen the seven rows of tiles each shrank to 71px and every
   photograph was squeezed to an 8px sliver. max-content fixes each row at the
   tile's own height, so the pane overflows and scrolls, which is what the
   `overflow-y: auto` above was always for. The image box is held out of the
   same negotiation -- a photograph you cannot see is not a smaller tile, it is
   a broken one. */
.mis-till-tile .mis-till-img { flex: 0 0 auto; }
/* A phone is the one width where auto-fill's own answer is wrong: 134px would
   leave two columns and a ragged margin on a 360px screen, and a tile you tap
   with a thumb wants to be as wide as it can be. */
@media (max-width: 480px) { .mis-till-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.mis-till-tile {
    background: #fff;
    border: 1px solid #E2E8F0;
    border-radius: 2px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
    text-align: center;
    transition: border-color .12s, box-shadow .12s;
}
.mis-till-tile:hover { border-color: #1FA75C; box-shadow: 0 2px 8px rgba(31,167,92,.22); }
.mis-till-tile:active { transform: translateY(1px); }

/* Fixed-height image box. These photographs are every shape there is,
   and letting each tile size itself gives a ragged grid. */
.mis-till-tile .mis-till-img {
    align-items: center;
    background: #fff;
    display: flex;
    height: 104px;
    justify-content: center;
    overflow: hidden;
    padding: 4px;
}
.mis-till-tile .mis-till-img img { max-height: 100%; max-width: 100%; object-fit: contain; }
.mis-till-tile .mis-till-noimg { color: #D1D5DB; font-size: 30px; }

.mis-till-tile .mis-till-foot {
    background: #F4F6F8;
    border-top: 1px solid #E8ECF0;
    flex: 1;
    padding: 5px 4px 6px;
}
/* Two lines, clamped -- not a 32px box with the overflow sheared off.
   `line-height: 1.3` was set for Latin; Khmer stacks subscripts and vowel
   signs above and below the base glyph, so "អំពូលសូឬា" lost its
   descenders mid-stroke rather than wrapping. 1.45 clears them, and a
   min-height of the same two lines keeps every price in a row on one
   baseline whether the name above it ran to one line or two. */
.mis-till-tile .mis-till-name {
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    color: #1F2937;
    display: -webkit-box;
    font-size: 12px;
    line-height: 1.45;
    min-height: 2.9em;
    overflow: hidden;
    word-break: break-word;
}
.mis-till-tile .mis-till-price {
    color: #D32F2F;               /* the source prices in red; staff scan for it */
    display: block;
    font-size: 13px;
    font-weight: 700;
    margin-top: 2px;
}
/* Out of stock is dimmed, not hidden: the shop still sells it, the
   count is simply wrong or the goods are on order. */
.mis-till-tile.is-out { opacity: .5; }

/* --- right: the pager ------------------------------------------ */
/* Two wide bars. At a counter these are tapped, often one-handed and
   sometimes without looking, so they are as large as the grid allows.
   Previous is the paler of the two -- forward is the common direction. */
.mis-till-pager { display: flex; gap: 4px; margin-top: 5px; }
.mis-till-pager .btn {
    border: 0;
    border-radius: 2px;
    color: #fff;
    flex: 1;
    font-size: 16px;
    padding: 9px;
}
.mis-till-pager .btn-prev { background: #F6C98A; }
.mis-till-pager .btn-next { background: #F0932B; }
.mis-till-pager .btn:disabled { opacity: .45; }
.mis-till-pager .mis-till-pageinfo {
    align-self: center;
    color: #64748B;
    font-size: 12px;
    min-width: 96px;
    text-align: center;
}

/* --- the closed-shop notice ------------------------------------ */
/* The till renders no header. This is the one thing that can appear
   above it, and only when the shop is closed -- it is the only
   explanation for the missing Payment and print buttons, so it is
   loud rather than subtle. */
.mis-till-closed {
    background: #FEF3C7;
    border: 1px solid #FCD34D;
    border-radius: 4px;
    color: #92400E;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 8px;
    padding: 8px 12px;
}

/* --- printing --------------------------------------------------- */
/* The print area is built in the browser from the basket, so a
   quotation can be printed for an order that was never recorded. */
.mis-till-print { display: none; }
.mis-till-print h3 { font-size: 15px; margin: 0 0 2px; }
.mis-till-print table { border-collapse: collapse; width: 100%; }
.mis-till-print th, .mis-till-print td { border-bottom: 1px solid #ddd; font-size: 12px; padding: 4px 3px; text-align: left; }
.mis-till-print .num { text-align: right; }

@media print {
    /* Hide the application, show only the document. Chrome prints a
       position:fixed sidebar on every page otherwise, which is how a
       one-page receipt becomes four.

       SCOPED TO body.mis-till-page, and that qualifier is load-bearing.
       Unscoped, `body * { visibility: hidden !important }` is a rule that
       reaches every print in the application, from a stylesheet every
       page loads, and wins wherever it lands because of the !important.
       It is what blanked the product label: the label is not
       .mis-till-print, so the first declaration hid it and the second
       never matched it. Nothing about a blank sticker points at the
       till's receipt CSS, which is why it took two wrong diagnoses.

       Only Till.cshtml sets this body class (ViewBag.BodyClass), and
       .mis-till-print exists only on that page, so the scope costs
       nothing here and confines the rule to the screen that wants it.
       Anything else printing from this app now starts from a clean sheet
       rather than from "everything is hidden, work out why". */
    body.mis-till-page * { visibility: hidden !important; }
    body.mis-till-page .mis-till-print,
    body.mis-till-page .mis-till-print * { visibility: visible !important; }
    body.mis-till-page .mis-till-print {
        display: block !important;
        left: 0;
        position: absolute;
        top: 0;
        width: 100%;
    }
    body.mis-till-page .mis-rail,
    body.mis-till-page .mis-header,
    body.mis-till-page .mis-menu,
    body.mis-till-page aside,
    body.mis-till-page nav,
    body.mis-till-page .modal,
    body.mis-till-page .modal-backdrop { display: none !important; }

    /* @page takes no selector -- it applies to the document, not to a
       body class -- so this was never scoped to the till even though it
       sat inside a block that read as though it were. Left here because
       8mm is a reasonable default for the app's other prints (the
       catalogue's own Print button), and the label overrides it in its
       print iframe. */
    @page { margin: 8mm; }
}

/* ============================================================
   The POS dashboard (/stores/{id}/dashboard)

   A banner, eight figures, two lines and two panels. Laid out with
   CSS grid throughout: this page is bands of equal cells, which is
   what grid is for, and auto-fit means the eight cards find their
   own column count instead of being told one per breakpoint.
   ============================================================ */

/* ---- the banner ------------------------------------------------ */
/* The greeting on the left, the period on the right, and on a narrow
   screen the period drops under the greeting rather than squeezing
   beside it -- three date controls at 150px each are unusable. */
.mis-posdash-hero {
    align-items: center;
    background: linear-gradient(135deg, #1D4ED8 0%, #2D8CF0 100%);
    border-radius: 10px;
    color: #fff;
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    justify-content: space-between;
    margin-bottom: 18px;
    padding: 20px 24px;
}
.mis-posdash-hello h2 {
    color: #fff;
    font-size: 26px;
    font-weight: 700;
    margin: 0;
}
.mis-posdash-hello p {
    color: rgba(255, 255, 255, .85);
    font-size: 13px;
    margin: 6px 0 0;
}
.mis-posdash-hello p i { margin-right: 6px; }

.mis-posdash-range { align-items: flex-end; display: flex; flex-wrap: wrap; gap: 10px; }
.mis-posdash-field { display: flex; flex-direction: column; }
.mis-posdash-field label {
    color: rgba(255, 255, 255, .85);
    font-size: 11px;
    font-weight: 500;
    margin: 0 0 4px 2px;
}
/* Prefixed to beat the theme's own .form-control, which paints a white
   field with a grey border -- invisible furniture on a blue banner. */
.body-content .mis-posdash-field .form-control {
    background: rgba(255, 255, 255, .14);
    border: 1px solid rgba(255, 255, 255, .35);
    border-radius: 6px;
    box-shadow: none;
    color: #fff;
    height: 38px;
    width: 160px;
}
.body-content .mis-posdash-field .form-control:focus {
    background: rgba(255, 255, 255, .22);
    border-color: #fff;
}
/* Chrome paints the date picker's calendar glyph near-black, which on
   this background is a smudge. */
.mis-posdash-field input[type="date"]::-webkit-calendar-picker-indicator {
    filter: invert(1);
    opacity: .8;
}
.mis-posdash-go {
    background: rgba(255, 255, 255, .18);
    border: 1px solid rgba(255, 255, 255, .35);
    border-radius: 6px;
    color: #fff;
    height: 38px;
    padding: 0 16px;
}
.mis-posdash-go:hover, .mis-posdash-go:focus { background: rgba(255, 255, 255, .3); color: #fff; }

/* ---- the eight cards ------------------------------------------- */
/* auto-fit rather than a column count per breakpoint: the cards are all
   the same size and the row knows its own width, so it can work out how
   many fit without being told. Four across on a desktop, two on a
   tablet, one on a phone -- and nothing to maintain in between. */
.mis-posdash-cards {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    margin-bottom: 18px;
}
.mis-posdash-card {
    align-items: center;
    background: #fff;
    border: 1px solid var(--mis-line, #E6EAF0);
    border-radius: 10px;
    box-shadow: var(--mis-shadow, 0 1px 2px rgba(16, 24, 40, .05));
    display: flex;
    gap: 14px;
    padding: 16px 18px;
}
/* The icon tint is decoration, not data: these eight figures are not a
   series and nothing is encoded by which colour a card wears. Its job is
   to make a card findable at a glance once you know where yours is. */
.mis-posdash-ico {
    align-items: center;
    border-radius: 10px;
    display: flex;
    flex: 0 0 auto;
    font-size: 18px;
    height: 46px;
    justify-content: center;
    width: 46px;
}
.mis-posdash-ico.is-blue  { background: #E8F1FE; color: #2D8CF0; }
.mis-posdash-ico.is-green { background: #E6F7EF; color: #10B981; }
.mis-posdash-ico.is-amber { background: #FEF3C7; color: #D97706; }
.mis-posdash-ico.is-red   { background: #FDECEC; color: #EF4444; }

.mis-posdash-label {
    color: #64748B;
    display: block;
    font-size: 12.5px;
    line-height: 1.35;
}
.mis-posdash-label i {
    color: #94A3B8;
    cursor: help;
    font-size: 11px;
}
/* The figure is ink, never the card's colour -- a number painted in the
   tint reads as an encoding, and none of these are one. */
.mis-posdash-value {
    color: #1F2937;
    display: block;
    font-size: 22px;
    font-weight: 700;
    margin-top: 2px;
}

/* ---- the two-panel bands --------------------------------------- */
.mis-posdash-split {
    display: grid;
    gap: 14px;
    grid-template-columns: minmax(0, 1fr);
    margin-bottom: 18px;
}
@media (min-width: 992px) {
    .mis-posdash-split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.mis-posdash-split > .panel { margin-bottom: 0; }

.mis-posdash-h {
    color: #1F2937;
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 14px;
}
.mis-posdash-h small { color: #94A3B8; font-size: 12px; font-weight: 400; margin-left: 4px; }

/* A stated height, because Google Charts draws to pixels and a host with
   none collapses to nothing. 300px shows a month of daily figures without
   the line becoming a flat smear. */
.mis-posdash-chart { height: 300px; width: 100%; }
.mis-posdash-empty {
    color: #94A3B8;
    font-size: 13px;
    margin: 0;
    padding: 120px 0;
    text-align: center;
}

/* ---- the payment-due table ------------------------------------- */
.mis-posdash-table { margin: 0; }
.body-content .mis-posdash-table > thead > tr > th {
    border-bottom: 1px solid #E6EAF0;
    color: #64748B;
    font-size: 12px;
    font-weight: 600;
    padding: 8px 10px;
}
.mis-posdash-table > tbody > tr > td {
    border-top: 1px solid #F1F5F9;
    font-size: 13px;
    padding: 8px 10px !important;
}
.mis-posdash-table .is-due { color: #B45309; font-weight: 600; }
.mis-posdash-table .mis-posdash-none {
    color: #94A3B8;
    padding: 28px 0 !important;
    text-align: center;
}

/* ---- the net income panel -------------------------------------- */
/* Four rows that have to add up in front of someone: three inputs and
   the answer, with the answer given a rule above it and weight on it. */
.mis-posdash-net { margin: 0; }
.mis-posdash-net > tbody > tr > td {
    border: 0;
    font-size: 13.5px;
    padding: 10px 4px !important;
}
.mis-posdash-net td small { color: #94A3B8; margin-left: 4px; }
.mis-posdash-net .num { font-weight: 600; text-align: right; }
.mis-posdash-net .num.is-minus { color: #EF4444; }
.mis-posdash-net tr.is-total > td {
    border-top: 1px solid #E6EAF0 !important;
    font-size: 15px;
    font-weight: 700;
}
.mis-posdash-net tr.is-total .num { color: #10B981; }
.mis-posdash-note {
    color: #94A3B8;
    font-size: 11.5px;
    margin: 12px 0 0;
}

/* ---- product table thumbnails (/stores/{id}/products) ----------
   A fixed box rather than a max-width, so 140 rows of photographs of
   every shape do not give 140 different row heights. contain, not
   cover: a product cropped to a square is a product you cannot
   identify, which is the only thing this column is for. */
.mis-prod-thumb {
    background: #fff;
    border: 1px solid #EDF1F5;
    border-radius: 3px;
    height: 38px;
    object-fit: contain;
    width: 38px;
}
.mis-prod-noimg {
    color: #D1D5DB;
    font-size: 18px;
    line-height: 38px;
}
/* ---- the products table toolbar -------------------------------
   One line: length menu, category filter and search on the left,
   the export buttons on the right, wrapping to a second line only
   when the window is too narrow to hold both groups.

   These are OUR containers, not Bootstrap rows, and that is the
   point. A .row carries -15px side margins; inside the scroll box
   that used to wrap this whole area, that measured 30px wider than
   the box and drew a horizontal scrollbar under a table that fitted
   the screen exactly. Nothing here has a negative margin. */
.mis-dt-bar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 12px;
    justify-content: space-between;
    margin-bottom: 12px;
}
.mis-dt-bar.mis-dt-foot { margin: 12px 0 0; }
.mis-dt-group {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
/* DataTables wraps the length menu and the search in blocks with
   their own margins; flattened so the gap above is the only spacing
   rule in play. */
.mis-dt-bar .dataTables_length,
.mis-dt-bar .dataTables_filter,
.mis-dt-bar .dataTables_info,
.mis-dt-bar .dataTables_paginate { float: none; margin: 0; padding: 0; text-align: left; }
.mis-dt-bar .dataTables_filter input { margin: 0; width: 220px; }
.mis-dt-bar .dataTables_length select { width: auto; }
.mis-dt-bar #productCategoryFilter { width: auto; min-width: 160px; }
.mis-dt-bar .dataTables_info { color: #64748B; font-size: 12.5px; }
.mis-dt-bar .pagination { margin: 0; }
.dt-buttons .btn { margin-left: 4px; }

/* The table, and only the table, scrolls -- never the toolbar. */
.mis-prod-scroll { overflow-x: auto; }

/* ---- the products table ---------------------------------------
   Horizontal rules only. A full grid draws 11 vertical lines per row
   and makes a catalogue look like a spreadsheet; the eye follows a
   row perfectly well without them. */
.mis-prod-table {
    margin-bottom: 0;
    /* A FLOOR, so the table scrolls inside .mis-prod-scroll rather than
       compressing. DataTables sets width:100% on it, and eleven columns told to
       fit an 800px panel do not overflow -- they squeeze, and a Khmer product
       name shreds into five lines of two syllables. Below this width, scrolling
       sideways past a column is the better of two bad options: every row stays
       one line and stays legible. */
    min-width: 1020px;
}
.body-content .mis-prod-table > thead > tr > th {
    border-bottom: 2px solid #E6EAF0;
    color: #64748B;
    font-size: 12px;
    font-weight: 600;
    vertical-align: bottom;
    white-space: nowrap;
}
.body-content .mis-prod-table > thead > tr > th small { color: #94A3B8; font-weight: 400; }
.mis-prod-table > tbody > tr > td {
    border-top: 1px solid #F1F5F9;
    font-size: 13px;
    vertical-align: middle !important;
}
/* Figures must not wrap: a price broken over two lines stops the
   decimal points lining up down the column, which is the only reason
   they are right-aligned in the first place. */
.mis-nowrap { white-space: nowrap; }

/* The totals row reads as an answer, not as another product. */
.mis-prod-table > tfoot > tr.mis-prod-total > th {
    background: #F8FAFC;
    border-top: 2px solid #E6EAF0;
    color: #1F2937;
    font-size: 13px;
}

/* ======================================================================
   The POS page header (Views/Pos/_PosHeader.cshtml)

   Fourteen screens open with a breadcrumb, a heading, the shop's code and
   category, the till button, and a strip of grouped links. The banner half
   reuses .mis-page-banner / .mis-crumb / .mis-page-head from the layout --
   deliberately, so a POS screen and a Stores screen have the same first
   inch -- and only the parts with no equivalent are defined here.

   THE STRIP IS NOT .nav-tabs. Bootstrap's tabs draw a raised folder tab
   joined to a 1px line that has nothing under it here, which read as the top
   edge of a panel that was not there. These are pills on the page ground,
   and the open one is filled with the accent.

   BOOTSTRAP STILL OPENS THE DROPDOWNS. .dropdown / .dropdown-toggle /
   .dropdown-menu stay on the markup and keep their behaviour; what follows
   only restyles them.
   ====================================================================== */

.mis-pos-sub {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.mis-pos-code { font-weight: 600; color: #475569; }
.mis-pos-code i { margin-right: 4px; color: #94A3B8; }

/* Read-only rather than broken: the same message the till shows, sized to
   sit on the subheading line instead of above the page. */
.mis-pos-closed {
    align-items: center;
    background: #FEF3C7;
    border: 1px solid #FDE68A;
    border-radius: 999px;
    color: #92400E;
    display: inline-flex;
    font-size: 11.5px;
    font-weight: 600;
    gap: 5px;
    margin-left: 4px;
    padding: 2px 9px;
}

.mis-pos-actions {
    align-items: center;
    display: flex;
    flex-shrink: 0;
    gap: 8px;
}

/* The till, as the page's primary action. It is the only accent-filled
   control in the header, because it is the only one staff press by reflex. */
.mis-pos-cta {
    align-items: center;
    background: var(--mis-accent);
    border-radius: 9px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .12);
    color: #FFFFFF !important;
    display: inline-flex;
    font-size: 13.5px;
    font-weight: 600;
    gap: 8px;
    padding: 9px 16px;
    text-decoration: none !important;
    transition: background .15s ease, transform .1s ease;
}
.mis-pos-cta:hover, .mis-pos-cta:focus { background: var(--mis-accent-dark); color: #FFFFFF !important; }
.mis-pos-cta:active { transform: translateY(1px); }

.mis-pos-gear {
    align-items: center;
    background: #FFFFFF;
    border: 1px solid #E2E8F0;
    border-radius: 9px;
    color: #64748B !important;
    display: inline-flex;
    height: 36px;
    justify-content: center;
    text-decoration: none !important;
    transition: border-color .15s ease, color .15s ease;
    width: 36px;
}
.mis-pos-gear:hover, .mis-pos-gear:focus { border-color: var(--mis-accent); color: var(--mis-accent) !important; }
.mis-pos-gear.is-active {
    background: var(--mis-accent-tint);
    border-color: var(--mis-accent);
    color: var(--mis-accent) !important;
}

/* ---------------------------------------------------------------- strip */

/* Scrolls sideways rather than wrapping: six pills wrap to a second line at
   about 420px, and a strip that changes height as you move between screens
   shifts the content under it every time. */
.mis-postabs {
    align-items: center;
    display: flex;
    flex-wrap: nowrap;
    gap: 4px;
    margin-bottom: 16px;
    overflow-x: auto;
    padding-bottom: 2px;
    -webkit-overflow-scrolling: touch;
}
.mis-postabs::-webkit-scrollbar { height: 4px; }
.mis-postabs::-webkit-scrollbar-thumb { background: #E2E8F0; border-radius: 4px; }

.mis-postab-group { position: relative; }

.mis-postab {
    align-items: center;
    border: 1px solid transparent;
    border-radius: 8px;
    color: #475569 !important;
    cursor: pointer;
    display: inline-flex;
    font-size: 13px;
    font-weight: 600;
    gap: 7px;
    padding: 8px 13px;
    text-decoration: none !important;
    transition: background .15s ease, color .15s ease;
    white-space: nowrap;
}
.mis-postab i { color: #94A3B8; font-size: 13px; }
.mis-postab:hover, .mis-postab:focus { background: #F1F5F9; color: #0F172A !important; }
.mis-postab:hover i, .mis-postab:focus i { color: #64748B; }

/* The open page, and the group holding it, are filled rather than
   underlined: an underline is invisible on a strip that scrolls. */
.mis-postab.is-active,
.mis-postab-group.is-active > .mis-postab,
.mis-postab-group.open > .mis-postab {
    background: var(--mis-accent-tint);
    border-color: rgba(var(--mis-accent-rgb), .25);
    color: var(--mis-accent) !important;
}
.mis-postab.is-active i,
.mis-postab-group.is-active > .mis-postab i,
.mis-postab-group.open > .mis-postab i { color: var(--mis-accent); }

.mis-postab .caret { margin-left: 1px; opacity: .6; }

.mis-postab-menu.dropdown-menu {
    border: 1px solid #E6EAF0;
    border-radius: 10px;
    box-shadow: 0 6px 20px rgba(16, 24, 40, .10);
    margin-top: 6px;
    min-width: 210px;
    padding: 6px;
}
.mis-postab-menu > li > a {
    align-items: center;
    border-radius: 7px;
    color: #334155;
    display: flex;
    font-size: 13px;
    gap: 9px;
    padding: 8px 10px;
    white-space: nowrap;
}
.mis-postab-menu > li > a > i { color: #94A3B8; width: 15px; text-align: center; }
.mis-postab-menu > li > a:hover,
.mis-postab-menu > li > a:focus { background: #F1F5F9; color: #0F172A; }
.mis-postab-menu > li.active > a,
.mis-postab-menu > li.active > a:hover,
.mis-postab-menu > li.active > a:focus {
    background: var(--mis-accent-tint);
    color: var(--mis-accent);
    font-weight: 600;
}
.mis-postab-menu > li.active > a > i { color: var(--mis-accent); }

/* On a phone the heading and the till button stack, and the pills lose their
   labels only where there is genuinely no room -- the icons alone are not
   enough to tell Stock from Money, so the labels go last. */
@media (max-width: 767px) {
    .mis-pos-actions { margin-left: 0; width: 100%; }
    .mis-pos-cta { flex: 1 1 auto; justify-content: center; }
    .mis-postab { padding: 8px 11px; }
}

/* ======================================================================
   Products: row actions, column filters, the details modal and the label

   Added when this screen was brought in line with the POS it was ported
   from -- five buttons a row instead of two, filters under the columns
   they filter, and a printable label.
   ====================================================================== */

/* Five buttons on a row that is already eleven columns wide. They are
   glyph-only and tight, and the column is fixed at 172px in the view so
   the table does not reflow as rows draw. */
.mis-prod-actions .btn-xs {
    padding: 2px 6px;
    line-height: 1.4;
}
.mis-prod-actions .btn-xs + .btn-xs { margin-left: 2px; }

/* The two read-only actions are quieter than the three that write. Looking
   at a product and printing its label are not the same kind of act as
   editing or deleting one, and the colours should not suggest they are. */
.mis-prod-actions .btn-default {
    background: #FFFFFF;
    border-color: #CBD5E1;
    color: #64748B;
}
.mis-prod-actions .btn-default:hover { border-color: var(--mis-accent); color: var(--mis-accent); }

/* ---- the footer filter row ------------------------------------------ */

/* Sits under the totals, inside the same tfoot. Lighter than the totals
   row above it: that row is an answer, this one is a control. */
.mis-prod-table > tfoot > tr.mis-prod-filters > th {
    background: #FFFFFF;
    border-top: 1px solid #F1F5F9;
    font-weight: 400;
    padding: 6px 4px;
}
.mis-prod-table > tfoot > tr.mis-prod-filters input {
    font-size: 12px;
    height: 28px;
    width: 100%;
}
/* No sort cursor on these cells. DataTables puts its sort affordance on
   every th in the table, including these, and a text box that looks
   sortable is a text box people click expecting something else. */
.mis-prod-table > tfoot > tr.mis-prod-filters > th { cursor: default; }

/* ---- the details modal ---------------------------------------------- */

.mis-prod-view { display: flex; gap: 16px; align-items: flex-start; }
.mis-prod-view-img {
    flex: 0 0 96px;
    text-align: center;
}
.mis-prod-view-img img {
    border: 1px solid #E6EAF0;
    border-radius: 8px;
    max-width: 96px;
}
.mis-prod-view-table { margin: 0; width: 100%; }
.mis-prod-view-table > tbody > tr > th {
    color: #64748B;
    font-size: 12px;
    font-weight: 600;
    padding: 5px 8px 5px 0;
    white-space: nowrap;
    width: 42%;
}
.mis-prod-view-table > tbody > tr > td {
    color: #0F172A;
    font-size: 13px;
    padding: 5px 0;
    word-break: break-word;
}

/* ---- the product label ---------------------------------------------- */

/* ONE ELEMENT, TWO CONTEXTS. This is the preview inside the modal AND the
   thing that goes on the sticker -- the print rules below show exactly
   this node and hide the rest of the page. There is deliberately no
   second copy of the markup for printing: two copies drift, and the drift
   is only discovered on stock that has already been bought. */
/* The stock picker above the preview. Small and out of the way: it is
   set once when a roll is changed and then ignored for a hundred labels,
   so it should not compete with the thing being previewed. */
.mis-prod-label-size {
    align-items: center;
    display: flex;
    gap: 8px;
    justify-content: center;
    margin: 0 0 12px;
}
.mis-prod-label-size label {
    color: #64748B;
    font-size: 12px;
    font-weight: 600;
    margin: 0;
}
.mis-prod-label-size select { width: auto; }

/* WIDTH, HEIGHT AND FONT SIZE ARE NOT HERE. They come from the size
   picker (defaulting to pos_settings' label_width / label_height, with
   label_fontsize for the type) and are written on as an inline style --
   see applyLabelSize in pos-products.js. They have to be inline rather
   than in this file because printLabelNow copies this element's
   outerHTML into the print document, and only inline styles make that
   trip. A size in this file would style the preview and quietly not
   style the sticker.

   What is here is everything that does not depend on the stock: the
   sticker is a fixed box that its contents fit INTO, centred on the
   cross axis, clipped rather than allowed to grow. A label that pushes
   itself taller than the stock does not print larger, it prints cut
   off -- on the next sticker along. */
.mis-prod-label {
    background: #FFFFFF;
    border: 1px dashed #CBD5E1;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin: 0 auto;
    overflow: hidden;
    padding: 1.5mm 2mm;
    text-align: center;
}

/* Dollars left, riel right, on one line -- the arrangement the source
   label uses. Sized in em so the whole sticker scales with the one font
   size the settings row carries, rather than each part needing its own. */
.mis-prod-label-prices {
    align-items: baseline;
    color: #0F172A;
    display: flex;
    font-size: 1.15em;
    font-weight: 700;
    justify-content: space-between;
    line-height: 1.2;
}
/* One price, no exchange rate configured. space-between with an empty
   second span pins the lone price to the left edge and leaves the rest
   of the sticker blank, which reads as a misprint rather than a choice. */
.mis-prod-label-prices.is-single { justify-content: center; }

/* The line most likely to be too long for the stock. Two lines at most,
   then clipped: a third line pushes the barcode off the sticker, and a
   barcode that does not fit is the one part of this that has a job to
   do. line-clamp is webkit-prefixed and unsupported in print in some
   engines, so overflow: hidden on the label is the real guarantee and
   this is the tidy version of the same thing. */
.mis-prod-label-name {
    color: #0F172A;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    font-size: 0.95em;
    line-height: 1.25;
    margin: 0.5mm 0 1mm;
    overflow: hidden;
}

/* Fluid, not fixed. makeBarcodeFluid in pos-products.js strips the width
   and height JsBarcode writes on the <svg> and gives it a viewBox, so it
   scales to the sticker at the right aspect ratio instead of overflowing
   a narrow one. Without that this rule would squash it. */
.mis-prod-label-barcode {
    display: block;
    height: auto;
    margin: 0 auto;
    max-width: 100%;
    width: 100%;
}

/* The text-only fallback, for a code no symbology would encode. */
.mis-prod-label-fallback {
    font-family: monospace;
    font-size: 14px;
    letter-spacing: 2px;
    padding: 10px 0 4px;
}

/* THERE IS NO @media print RULE FOR THE LABEL, and that is deliberate.

   Printing it used to work by hiding the whole application and revealing
   the label; two versions of that printed a blank page, for two different
   reasons -- see the comment on printLabelNow in pos-products.js. It now
   prints through an iframe containing only the label, so the main
   document is never hidden and there is nothing here left to express.

   Weigh anything added back under a `body.printing-something` selector
   against that. A rule that hides the application depends on the code
   that unhides it running, and on a print dialog that blocks while the
   user decides, which Chrome's no longer does. */

/* ======================================================================
   Import Products (/stores/{id}/products/import)

   A three-step form on the left, the file's contract on the right.

   NOTE THE PAGE USES .panel, NOT .mis-card. mis-forms.css also defines
   .mis-card -- as the centred, max-width 460px card the sign-in and
   account forms are built from -- and it loads after this file, so it
   wins. Anything full-width on the admin side wants .panel.
   ====================================================================== */

.mis-import-grid {
    display: grid;
    gap: 28px;
    grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
}
/* One column below the width where the two would start fighting. The
   form comes first in the markup, so it stays first when they stack --
   the action before the reference. */
@media (max-width: 991px) {
    .mis-import-grid { grid-template-columns: minmax(0, 1fr); gap: 20px; }
}

/* ---- the steps ------------------------------------------------------ */

.mis-import-step {
    display: flex;
    gap: 12px;
    padding: 0 0 20px;
}
.mis-import-step:last-child { padding-bottom: 0; }
.mis-import-step strong { color: #0F172A; display: block; font-size: 13.5px; }
.mis-import-step p { color: #64748B; font-size: 12.5px; margin: 2px 0 8px; }

/* The step number. A counter would be tidier, but these are read aloud
   between two people looking at one screen ("you're on step 2"), so the
   number is in the markup where it can be selected and searched. */
.mis-import-num {
    align-items: center;
    background: var(--mis-accent-tint);
    border-radius: 999px;
    color: var(--mis-accent);
    display: inline-flex;
    flex: 0 0 26px;
    font-size: 12px;
    font-weight: 700;
    height: 26px;
    justify-content: center;
    margin-top: 1px;
    width: 26px;
}

/* ---- the file picker ------------------------------------------------ */

.mis-file-pick { align-items: center; display: flex; flex-wrap: wrap; gap: 10px; }

/* Hidden but still focusable and still clickable through its <label>.
   display: none would take it out of the tab order and break keyboard
   use; this keeps the control real and only removes it from view. */
.mis-file-input {
    height: 0;
    opacity: 0;
    position: absolute;
    width: 0;
}
.mis-file-input:focus + label {
    border-color: var(--mis-accent);
    box-shadow: 0 0 0 3px rgba(var(--mis-accent-rgb), .18);
}
.mis-file-pick label { margin: 0; }

.mis-file-name {
    color: #94A3B8;
    font-size: 12.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* A chosen file is a fact, not a placeholder, so it stops being grey. */
.mis-file-name.is-set { color: #0F172A; font-weight: 600; }

/* ---- the format panel ----------------------------------------------- */

.mis-import-help {
    background: #F8FAFC;
    border: 1px solid #E6EAF0;
    border-radius: 10px;
    padding: 16px 18px;
}
.mis-import-help h4 {
    color: #0F172A;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
    margin: 0 0 8px;
    text-transform: uppercase;
}
.mis-import-help p { color: #475569; font-size: 12.5px; margin: 0 0 12px; }

/* Numbered, because position is the contract: the header row's text is
   ignored on import, so column 3 is Purchase Price whatever it is
   called. An ordered list says that; a row of chips did not. */
.mis-import-cols {
    counter-reset: mis-col;
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
}
.mis-import-cols li {
    align-items: center;
    border-top: 1px solid #E6EAF0;
    counter-increment: mis-col;
    display: flex;
    gap: 10px;
    padding: 5px 0;
}
.mis-import-cols li:first-child { border-top: 0; }
.mis-import-cols li::before {
    color: #94A3B8;
    content: counter(mis-col);
    flex: 0 0 16px;
    font-size: 11.5px;
    font-weight: 700;
    text-align: right;
}
.mis-import-cols code {
    background: #FFFFFF;
    border: 1px solid #CBD5E1;
    border-radius: 5px;
    color: #0F172A;
    font-size: 12px;
    padding: 2px 8px;
    white-space: nowrap;
}

.mis-import-notes { color: #475569; font-size: 12px; margin: 0; padding-left: 16px; }
.mis-import-notes li { margin-bottom: 5px; }
.mis-import-notes li:last-child { margin-bottom: 0; }

/* ---- the report ----------------------------------------------------- */

.mis-import-result { margin-top: 24px; }
.mis-import-busy { color: #64748B; font-size: 13px; }
.mis-import-busy .glyphicon { margin-right: 6px; }

/* The error table sits inside an .alert, which styles its own text; the
   table needs to stay readable on that background without inheriting the
   alert's colour for every cell. */
.mis-import-errors { margin: 0; }
.mis-import-errors table { background: #FFFFFF; border-radius: 6px; }
.mis-import-errors th { color: #64748B; font-size: 12px; }
.mis-import-errors td { color: #0F172A; font-size: 12.5px; }

/* ======================================================================
   Promotion By Period (/stores/{id}/products/promotion)

   A period, two ways to gather products, a staging table, and below it
   the promotions already on file.
   ====================================================================== */

/* The period sits above everything because it applies to everything in
   the batch. Two fields side by side, narrow: they are dates, not a
   layout. */
.mis-promo-period { display: flex; flex-wrap: wrap; gap: 16px; }
.mis-promo-period .form-group { margin: 0; min-width: 220px; }
.mis-promo-period label,
.mis-promo-pick label {
    color: #475569;
    font-size: 12.5px;
    font-weight: 600;
    margin-bottom: 4px;
}

.mis-promo-pick {
    display: grid;
    gap: 16px;
    grid-template-columns: minmax(200px, 1fr) minmax(220px, 1.4fr) minmax(200px, 1fr);
    margin-bottom: 18px;
}
@media (max-width: 991px) {
    .mis-promo-pick { grid-template-columns: minmax(0, 1fr); }
}
.mis-promo-pick .form-group { margin: 0; }
.mis-promo-pick .help-block { font-size: 11px; margin: 4px 0 0; }

/* ---- the staging table ---------------------------------------------- */

.mis-promo-table > thead > tr > th {
    background: #F8FAFC;
    border-bottom: 2px solid #E6EAF0;
    color: #64748B;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
.mis-promo-table > tbody > tr > td {
    border-top: 1px solid #F1F5F9;
    font-size: 13px;
    vertical-align: middle !important;
}
/* The two columns you type in, marked in the header so they read as
   inputs before anyone reaches a row. */
.mis-promo-table th.mis-promo-edit { color: var(--mis-accent); }
.mis-promo-table input.form-control {
    display: inline-block;
    height: 28px;
    padding: 2px 6px;
    text-align: right;
    width: 92px;
}

/* A promo price above the normal price. The server refuses it; this is
   so the refusal is not the first anyone hears of it. */
.mis-promo-over { color: var(--mis-danger); font-size: 12px; font-weight: 600; }

.mis-promo-empty {
    background: #F8FAFC;
    border: 1px dashed #CBD5E1;
    border-radius: 8px;
    color: #64748B;
    font-size: 12.5px;
    margin: 0;
    padding: 18px;
    text-align: center;
}

.mis-promo-actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}
.mis-promo-count { color: #64748B; font-size: 12.5px; }

/* ======================================================================
   Update Price (/stores/{id}/products/update-price)

   Four fields, a compulsory preview, and a deliberately red Apply.
   ====================================================================== */

/* Narrow. These are four short controls, and stretching them across a
   wide screen makes a two-second form look like a long one. */
.mis-price-form { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); max-width: 1000px; }
.mis-price-form .form-group { margin: 0; }
.mis-price-form label { color: #475569; font-size: 12.5px; font-weight: 600; margin-bottom: 4px; }
.mis-price-form .help-block { font-size: 11px; margin: 4px 0 0; }

.mis-price-actions { align-items: center; display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.mis-price-note { color: #64748B; font-size: 12.5px; }

/* Apply is btn-danger, not btn-success. It is not a destructive action
   in the delete sense, but it is irreversible and it changes what
   customers are charged -- the colour should not say "go ahead". */
.mis-price-actions .btn-danger[disabled] { opacity: .45; }

.mis-price-result { margin-top: 22px; }

.mis-price-summary {
    background: #F8FAFC;
    border: 1px solid #E6EAF0;
    border-radius: 8px;
    font-size: 13px;
    margin-bottom: 14px;
    padding: 12px 14px;
}
.mis-price-summary strong { color: #0F172A; }
.mis-price-skipped { color: var(--mis-warn-d); font-weight: 600; }

.mis-price-table > thead > tr > th {
    background: #F8FAFC;
    border-bottom: 2px solid #E6EAF0;
    color: #64748B;
    font-size: 12px;
    white-space: nowrap;
}
.mis-price-table > tbody > tr > td { border-top: 1px solid #F1F5F9; font-size: 12.5px; }

/* A skipped row is still listed -- see the note in the DTO -- but it
   should not read as a price that is about to change. */
.mis-price-row-skipped { background: #FFFBEB; }
.mis-price-why { color: var(--mis-warn-d); font-size: 11.5px; }

.mis-price-up   { color: var(--mis-danger); font-weight: 600; }
.mis-price-down { color: var(--mis-ok-d);   font-weight: 600; }

/* ======================================================================
   List Products: table presentation

   Appended after the .mis-prod-table rules above and deliberately at
   the same specificity, so these win on source order. Kept separate
   rather than edited in place because this block is presentation --
   density, case, colour -- while the block above is structure, and the
   two get changed for different reasons.
   ====================================================================== */

/* UPPERCASE, TRACKED, SMALL. A column heading is a label for what is
   under it, not a line to read; setting it apart in case and size
   stops it competing with the first row. */
.body-content .mis-prod-table > thead > tr > th {
    color: #94A3B8;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    padding: 12px 8px;
    text-transform: uppercase;
}
/* The currency hints in the headers are not part of the label. */
.body-content .mis-prod-table > thead > tr > th small {
    font-size: 10px;
    letter-spacing: 0;
    text-transform: none;
}

/* Room to breathe. The catalogue is read by scanning down one column,
   and rows packed to the condensed default make that hard work. */
.mis-prod-table > tbody > tr > td {
    border-top: 1px solid #F1F5F9;
    padding: 11px 8px !important;
}
.mis-prod-table > tbody > tr:hover > td { background: #F8FAFC; }

/* ---- stock, as a dot in the margin ---------------------------------- */

.mis-stock { align-items: center; display: inline-flex; gap: 7px; justify-content: flex-end; }
.mis-stock-dot {
    border-radius: 50%;
    display: inline-block;
    flex: 0 0 7px;
    height: 7px;
    width: 7px;
}
.mis-stock-dot.is-ok  { background: var(--mis-ok); }
.mis-stock-dot.is-low { background: var(--mis-warn); }
.mis-stock-dot.is-out { background: var(--mis-danger); }

/* ---- the row menu --------------------------------------------------- */

.mis-row-menu .dropdown-toggle {
    border-color: #E2E8F0;
    color: #475569;
    font-size: 12px;
    padding: 4px 10px;
}
.mis-row-menu.open .dropdown-toggle,
.mis-row-menu .dropdown-toggle:hover {
    border-color: var(--mis-accent);
    color: var(--mis-accent);
}
.mis-row-menu .dropdown-menu {
    border: 1px solid #E6EAF0;
    border-radius: 10px;
    box-shadow: 0 6px 20px rgba(16, 24, 40, .12);
    min-width: 176px;
    padding: 6px;
}
.mis-row-menu .dropdown-menu > li > a {
    align-items: center;
    border-radius: 6px;
    color: #334155;
    display: flex;
    font-size: 12.5px;
    gap: 9px;
    padding: 7px 10px;
}
.mis-row-menu .dropdown-menu > li > a:hover { background: #F1F5F9; color: #0F172A; }
.mis-row-menu .dropdown-menu .glyphicon { color: #94A3B8; width: 14px; }

/* Delete reads as delete before it is pressed, not after. */
.mis-row-menu .dropdown-menu > li > a.mis-menu-danger { color: var(--mis-danger); }
.mis-row-menu .dropdown-menu > li > a.mis-menu-danger:hover {
    background: #FEF2F2;
    color: var(--mis-danger-d);
}
.mis-row-menu .dropdown-menu > li > a.mis-menu-danger .glyphicon { color: var(--mis-danger); }

/* See the shown.bs.dropdown handler in pos-products.js: the scroll box
   clips on both axes, so it has to stop clipping while a menu is open. */
.mis-prod-scroll.is-menu-open { overflow: visible; }

/* ---- pagination ----------------------------------------------------- */

.mis-dt-bar .pagination > li > a,
.mis-dt-bar .pagination > li > span {
    border: 1px solid #E6EAF0;
    border-radius: 8px !important;
    color: #475569;
    font-size: 12.5px;
    margin-left: 4px;
    min-width: 32px;
    padding: 6px 10px;
    text-align: center;
}
.mis-dt-bar .pagination > li > a:hover { background: #F1F5F9; color: #0F172A; }
.mis-dt-bar .pagination > .active > a,
.mis-dt-bar .pagination > .active > a:hover,
.mis-dt-bar .pagination > .active > span {
    background: var(--mis-accent);
    border-color: var(--mis-accent);
    color: #FFFFFF;
}
.mis-dt-bar .pagination > .disabled > a,
.mis-dt-bar .pagination > .disabled > span { border-color: #F1F5F9; color: #CBD5E1; }

/* ======================================================================
   The list card (List Products, and anything that follows it)

   A named card with a title bar, a hairline, then the table. Replaces
   .panel for list screens: the panel put an explanation, a button and
   an <hr> in front of the first row, which is three pieces of furniture
   before the thing people opened the page for.

   NOT called .mis-card -- mis-forms.css owns that name for the centred
   460px account-form card and loads after this file.
   ====================================================================== */

.mis-list-card {
    background: #FFFFFF;
    border: 1px solid #EEF1F6;
    border-radius: 14px;
    /* Shadow rather than a strong border. The reference reads as a sheet
       lying on the page; a 1px grey box reads as a fieldset. */
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 8px 24px rgba(16, 24, 40, .05);
    margin-bottom: 22px;
    overflow: hidden;
}

.mis-list-head {
    align-items: flex-start;
    border-bottom: 1px solid #F1F5F9;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: space-between;
    padding: 18px 22px;
}
.mis-list-head h3 {
    color: #0F172A;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.01em;
    margin: 0;
}
/* The note under the title is context, read once. It should not have the
   weight of an alert box, which is what it had as a .text-muted paragraph
   above a horizontal rule. */
.mis-list-head p {
    color: #94A3B8;
    font-size: 12px;
    margin: 4px 0 0;
    max-width: 62ch;
}

.mis-list-body { padding: 18px 22px 20px; }

/* ---- the toolbar, quieter -------------------------------------------- */

/* The length menu and the search sit on the left with the category
   filter; Export and Columns on the right. Both sides are controls, so
   neither should look like a call to action. */
.mis-dt-bar .btn-default,
.mis-dt-bar .dt-button {
    background: #FFFFFF;
    border: 1px solid #E2E8F0;
    border-radius: 8px;
    color: #475569;
    font-size: 12.5px;
    padding: 6px 12px;
}
.mis-dt-bar .btn-default:hover,
.mis-dt-bar .dt-button:hover { background: #F8FAFC; border-color: #CBD5E1; color: #0F172A; }

.mis-dt-bar .dataTables_filter input,
.mis-dt-bar .dataTables_length select,
.mis-dt-bar #productCategoryFilter {
    border: 1px solid #E2E8F0;
    border-radius: 8px;
    box-shadow: none;
    font-size: 12.5px;
    height: 34px;
}
.mis-dt-bar .dataTables_filter label,
.mis-dt-bar .dataTables_length label {
    color: #64748B;
    font-size: 12.5px;
    font-weight: 400;
    margin: 0;
}

/* The Export collection menu. DataTables draws it detached at the end of
   <body>, so it cannot be styled through .mis-dt-bar. */
.dt-button-collection {
    background: #FFFFFF;
    border: 1px solid #E6EAF0 !important;
    border-radius: 10px !important;
    box-shadow: 0 6px 20px rgba(16, 24, 40, .12) !important;
    padding: 6px !important;
}
.dt-button-collection .dt-button {
    border: 0 !important;
    border-radius: 6px !important;
    color: #334155 !important;
    display: block;
    font-size: 12.5px !important;
    padding: 7px 12px !important;
    text-align: left;
    width: 100%;
}
.dt-button-collection .dt-button:hover { background: #F1F5F9 !important; color: #0F172A !important; }

/* ---- table, inside the card ------------------------------------------ */

/* The head row is the only tinted band on the table now that the zebra
   striping is gone -- it separates labels from data without drawing a
   line through every other row. */
.body-content .mis-prod-table > thead > tr > th { background: #FBFCFD; }

/* The card already has padding; the table should reach its edges rather
   than sit in a second box inside it. */
.mis-list-body .mis-prod-scroll { margin: 0 -6px; padding: 0 6px; }
