/* ==========================================================================
   JG-CMS — Design system
   Derived from the ArFa admin template design language:
   airy grey canvas, borderless white cards on soft shadows, one confident
   colour expressed through gradients and glows, small Montserrat type,
   here the school crest green rather than the template blue,
   0.3-0.4s easing on every state change.
   Plain CSS on purpose — no build step (SRS 6).
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500;1,600&display=swap');

:root {
  /* Brand palette — the hue is taken from the school crest (#a1c93b).
     That lime is far too light to carry white text (1.95:1), so the
     interactive colour is the same hue walked down in lightness until it
     clears WCAG AA at 4.89:1. The crest lime itself is kept as --jg-brand for
     the places nothing sits on top: the login wash and the focus glow. */
  --jg-primary:        #5c7b14;
  --jg-primary-rgb:    92 123 20;
  --jg-primary-dark:   #46600d;
  /* The light end of every gradient. White nav labels and the KPI glyphs sit
     on it, so it is held at 3.7:1 — the ArFa blue it replaces was 3.5:1.
     The crest lime itself (--jg-brand) is only used where nothing sits on top. */
  --jg-primary-fade:   #689117;
  --jg-brand:          #a1c93b;
  --jg-brand-rgb:      161 201 59;
  --jg-secondary:      #82868b;
  /* Emerald, deliberately a different hue from the lime primary — on the
     canteen queue a "Served" button sits beside primary actions and the two
     must not read as the same colour. */
  --jg-success:        #12b76a;
  --jg-info:           #00cfe8;
  --jg-warning:        #ff9f43;
  --jg-danger:         #ea5455;
  --jg-dark:           #191f30;

  /* Neutrals — these carry the whole interface */
  --jg-gray:            #b8c2cc;
  --jg-gray-medium:     #d8d8d8;
  --jg-gray-dark:       #625f6e;
  --jg-gray-light:      #f1f1f1;
  --jg-gray-xlight:     #f7f7f7;
  --jg-white:           #ffffff;
  --jg-canvas:          #f8f8f8;
  --jg-dark-lighter:    #1e222b;
  --jg-dark-secondary:  #1e273d;
  --jg-focus-ring:      rgb(var(--jg-brand-rgb) / .55);
  --jg-nav-active:      #f6f6f6;

  /* Surfaces — remapped wholesale in dark mode.
     The canvas is deliberately a cool grey rather than near-white: at only 3%
     apart from the cards nothing read as raised, and the whole interface
     looked washed out. */
  --jg-surface:         #ffffff;
  --jg-surface-alt:     #f4f6fb;
  --jg-body-bg:         #eceff6;
  --jg-text:            #5b5867;
  --jg-text-muted:      #98a2b3;
  --jg-border:          #e2e7f0;
  --jg-border-soft:     #edf1f7;
  /* Two layers: a tight contact shadow plus a wide ambient one, both tinted
     toward navy so they sit in the palette instead of muddying it. */
  --jg-card-shadow:     0 1px 2px rgba(16, 24, 40, .04),
                        0 10px 28px -12px rgba(16, 24, 40, .16);
  --jg-card-shadow-lift:0 2px 4px rgba(16, 24, 40, .05),
                        0 18px 38px -14px rgba(16, 24, 40, .22);

  --jg-sidebar-w:       260px;
  --jg-sidebar-mini:    80px;
  --jg-radius:          4px;

  /* Bridge to Bootstrap's own tokens. Everything this file styles explicitly
     already uses --jg-primary; this catches components we have not themed by
     hand (accordion, list-group active, btn-check) so none of them can fall
     back to stock Bootstrap blue. --bs-*-rgb wants comma-separated channels. */
  --bs-primary:          var(--jg-primary);
  --bs-primary-rgb:      92, 123, 20;
  --bs-link-color:       var(--jg-primary);
  --bs-link-color-rgb:   92, 123, 20;
  --bs-link-hover-color: var(--jg-primary-dark);
}

* { margin: 0; padding: 0; box-sizing: border-box; font-family: "Montserrat", sans-serif; }

html, body {
  height: 100%;
  background: var(--jg-body-bg);
  color: var(--jg-text);
  font-size: 15px;
  /* The sidebar is fixed and the content is offset by padding; nothing should
     ever push the page sideways. Wide content scrolls inside its own
     .table-responsive instead. */
  max-width: 100%;
  overflow-x: hidden;
}

ul { padding: 0; margin: 0; }
a { text-decoration: none; }

/* ============================================================ typography = */
.text-small   { font-size: .75em; }
.fs-big       { font-size: 6em; }
.fw-medium    { font-weight: 500; }
.text-mono    { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; }
.cursor-pointer { cursor: pointer; }

/* ================================================================ layout = */
#app { min-height: 100%; }

/* Fades scrolled content out beneath the floating header bar. Tracks the
   canvas colour, so it must be updated alongside --jg-body-bg. */
.shadow-header {
  display: block;
  background: linear-gradient(180deg,
    rgba(236, 239, 246, .97), rgba(236, 239, 246, .55), rgba(236, 239, 246, 0));
  padding-top: 2.2rem;
  width: 100%; height: 54px;
  position: fixed; top: 0; left: 0; z-index: 9;
}
body.dark .shadow-header {
  background: linear-gradient(180deg,
    rgba(20, 25, 38, .97), rgba(20, 25, 38, .55), rgba(20, 25, 38, 0));
}

/* --------------------------------------------------------------- sidebar */
.main-sidebar {
  z-index: 998;
  display: block;
  height: 100%;
  width: var(--jg-sidebar-w);
  position: fixed;
  top: 0; left: 0;
  background-color: var(--jg-sidebar-bg, #fbfcfe);
  border-right: 1px solid var(--jg-border);
  box-shadow: 1px 0 3px rgba(16, 24, 40, .03);
  transition: width .4s ease, margin-left .4s ease;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}
.main-sidebar::-webkit-scrollbar { width: 5px; }
.main-sidebar::-webkit-scrollbar-thumb { background: var(--jg-gray-medium); border-radius: 5px; }

.sidebar-header {
  display: flex; flex-direction: row;
  justify-content: space-between; align-items: center;
  margin: 20px; margin-bottom: 25px;
}
.sidebar-header .brand { display: flex; align-items: center; gap: 10px; overflow: hidden; }
.sidebar-header .brand-mark {
  min-width: 40px; height: 40px; border-radius: var(--jg-radius);
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--jg-primary-dark), var(--jg-primary-fade));
  box-shadow: 0 0 8px 1px rgb(var(--jg-primary-rgb) / .55);
  color: #fff; font-weight: 600; font-size: 15px; letter-spacing: .5px;
}
.sidebar-header .brand-text { line-height: 1.1; white-space: nowrap; }
.sidebar-header .brand-text .t1 { font-size: 15px; font-weight: 600; color: var(--jg-gray-dark); }
.sidebar-header .brand-text .t2 { font-size: 11px; color: var(--jg-text-muted); }

.menu-category {
  display: block; margin: 15px 25px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu-category span { color: #a3a3a7; font-size: 12px; letter-spacing: .6px; }

.sidebar-content { position: relative; padding-bottom: 40px; }
.sidebar-content ul { background: transparent; width: 100%; list-style: none; }
.sidebar-content > ul > li > a,
.sidebar-content .sub-menu li a {
  color: var(--jg-gray-dark);
  font-size: .93rem; font-weight: 400;
  padding: 10px 0 10px 50px;
  display: block; width: 230px; position: relative;
  margin: 2px 15px; border-radius: var(--jg-radius);
  transition: margin .35s ease, background .2s ease;
  white-space: nowrap; overflow: hidden;
}
.sidebar-content > ul > li > a i {
  position: absolute; left: 15px; top: 50%;
  font-size: 1.05rem; line-height: 0; width: 20px; text-align: center;
}
.sidebar-content a.has-dropdown::after {
  content: "\f054"; font-family: "Font Awesome 6 Free"; font-weight: 900;
  position: absolute; top: 50%; right: 18px;
  transform: translateY(-50%) rotate(0deg);
  font-size: 10px; transition: transform .25s ease-in-out;
}
.sidebar-content li:not(.active) > a:hover span { margin-left: 7px; }
.sidebar-content li span { transition: margin .3s ease-out; }

.sidebar-content .sub-menu {
  max-height: 0; overflow: hidden;
  transition: max-height .3s ease;
  list-style: none;
}
.sidebar-content li.open > .sub-menu { max-height: 900px; }
.sidebar-content li.open > a.has-dropdown::after { transform: translateY(-50%) rotate(90deg); }
.sidebar-content li.open > a { background: var(--jg-nav-active); }

.sidebar-content .sub-menu li a { font-size: .88rem; }
.sidebar-content .sub-menu li a::before {
  content: ""; position: absolute; left: 22px; top: calc(50% - 4px);
  height: 8px; width: 8px; border-radius: 5px;
  background: var(--jg-secondary);
  box-shadow: 0 0 6px var(--jg-secondary);
}
.sidebar-content .sub-menu li.active a {
  color: var(--jg-dark-secondary);
  background: var(--jg-nav-active);
  font-weight: 500;
}
.sidebar-content .sub-menu li.active a::before {
  background: var(--jg-primary);
  box-shadow: 0 0 6px var(--jg-primary);
}

/* The signature active state: blue gradient + blue glow, never a border */
.sidebar-content > ul > li.active > a {
  color: #fff;
  background: linear-gradient(90deg, var(--jg-primary-dark), var(--jg-primary-fade));
  box-shadow: 0 0 6px 1px rgb(var(--jg-primary-rgb));
}
.sidebar-content > ul > li.active > a i { color: #fff; }

.close-sidebar {
  display: none; cursor: pointer;
  height: 30px; width: 30px;
  align-items: center; justify-content: center;
  border-radius: 5px; color: var(--jg-gray-dark);
  box-shadow: 0 2px 8px 3px var(--jg-gray-light);
}

/* ---------------------------------------------------------------- header */
.header-navbar {
  position: fixed; top: 0; left: 0;
  width: 100%;
  padding-left: calc(var(--jg-sidebar-w) + 25px);
  padding-right: 25px;
  transition: padding-left .4s;
  z-index: 10;
}
.header-navbar .header-wrapper {
  margin-top: 18px; padding: 5px; height: 60px;
  background: var(--jg-surface);
  border: 1px solid var(--jg-border-soft);
  box-shadow: var(--jg-card-shadow);
  border-radius: 8px;
  display: flex; align-items: center; justify-content: space-between;
}
.header-navbar .header-left {
  display: flex; align-items: center; gap: 12px;
  margin-left: .8em; height: 100%;
  font-size: 1.25em; cursor: pointer; color: var(--jg-gray-dark);
}
.header-navbar .header-left .page-context {
  font-size: .72rem; color: var(--jg-text-muted); cursor: default;
  border-left: 1px solid var(--jg-border); padding-left: 12px; line-height: 1.3;
}
.header-navbar .header-left .page-context strong { display: block; color: var(--jg-gray-dark); font-size: .8rem; font-weight: 500; }
.header-navbar .header-content {
  display: flex; align-items: center; gap: .7em;
  margin-right: .6em;
}
.theme-switch-icon { cursor: pointer; font-size: 1.15em; color: var(--jg-gray-dark); }
.theme-switch-icon::before { content: "\f186"; font-family: "Font Awesome 6 Free"; font-weight: 900; }
body.dark .theme-switch-icon::before { content: "\f185"; color: rgb(196,166,32); }

.header-navbar .notification {
  position: relative;
  font-size: 1.15rem;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.header-navbar .notification > a { display: block; line-height: 1; }
.header-navbar .notification > a > i { color: #6e6b7b; }
/* Anchored to the icon's top-right corner rather than an arbitrary offset,
   so it never sits on top of the bell or spills into the name beside it. */
.header-navbar .notification span.badge {
  position: absolute;
  top: -7px; right: -9px; left: auto;
  min-width: 17px; height: 17px;
  padding: 0 4px;
  font-size: .6rem; font-weight: 500;
  line-height: 17px; text-align: center;
  border-radius: 9px;
  background: var(--jg-danger); color: #fff;
  box-shadow: 0 0 0 2px var(--jg-surface);   /* separates it from the icon */
  animation: pulsebadge 2s linear infinite;
}
@keyframes pulsebadge {
  0%   { box-shadow: 0 0 0 var(--jg-danger); }
  50%  { box-shadow: 0 0 12px var(--jg-danger); }
}

.header-navbar .user-dropdown {
  display: flex; align-items: center; height: 50px;
  margin-right: 6px; text-decoration: none;
  min-width: 0;                      /* lets the label truncate instead of pushing */
}
.header-navbar .user-dropdown .label {
  text-align: right; margin-right: 8px; line-height: 1.25; color: #6e6b7b;
  min-width: 0; max-width: 200px;
}
/* A long name ellipsises rather than shoving the avatar off the bar. */
.header-navbar .user-dropdown .label div,
.header-navbar .user-dropdown .label span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.header-navbar .user-dropdown .label div  { font-size: .88rem; font-weight: 500; }
.header-navbar .user-dropdown .label span { font-size: .7rem; font-weight: 300; color: var(--jg-text-muted); }
.header-navbar .user-dropdown .img-user,
.header-navbar .user-dropdown .avatar-fallback { flex: 0 0 auto; }
.header-navbar .user-dropdown .img-user {
  width: 38px; height: 38px; border-radius: 50%; object-fit: cover;
  box-shadow: 0 0 6px var(--jg-gray-medium);
}
.avatar-fallback {
  width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--jg-primary-dark), var(--jg-primary-fade));
  color: #fff; font-weight: 600; font-size: .85rem;
}

/* ---------------------------------------------------------- main content */
.main-content {
  padding-left: calc(var(--jg-sidebar-w) + 20px);
  padding-right: 20px;
  padding-top: 100px; padding-bottom: 30px;
  transition: padding-left .4s;
  width: 100%;
  min-height: calc(100vh - 60px);
}
/* Descendant, not child: the heading sits inside a flex row alongside the
   page actions, so `>` never matched and the subtitle ran on inline. */
.main-content .title {
  font-size: 1.4em; color: var(--jg-gray-dark);
  margin-left: 5px; margin-bottom: .5em; font-weight: 500;
  line-height: 1.25; min-width: 0;
}
.main-content .title small {
  display: block;
  font-size: .92rem;
  color: var(--jg-text-muted);
  font-weight: 400;
  margin-top: 3px;
}
.content-wrapper { padding: 0 5px; }

footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 25px 0 calc(var(--jg-sidebar-w) + 25px);
  height: 50px; font-size: .8rem; color: var(--jg-text-muted);
  transition: padding-left .4s;
}
footer a { color: var(--jg-primary); }

/* -------------------------------------------------- collapsed / mobile */
body.collapse-sidebar .main-sidebar { width: var(--jg-sidebar-mini); }
body.collapse-sidebar .main-sidebar .menu-category,
body.collapse-sidebar .main-sidebar .brand-text { display: none; }
body.collapse-sidebar .main-sidebar li > a { width: 44px; }
body.collapse-sidebar .main-sidebar li > a.has-dropdown::after { display: none; }
body.collapse-sidebar .main-sidebar li.open > .sub-menu { max-height: 0; }
body.collapse-sidebar .main-sidebar:hover { width: var(--jg-sidebar-w); }
body.collapse-sidebar .main-sidebar:hover .menu-category,
body.collapse-sidebar .main-sidebar:hover .brand-text { display: block; }
body.collapse-sidebar .main-sidebar:hover li > a { width: 230px; }
body.collapse-sidebar .main-sidebar:hover li > a.has-dropdown::after { display: block; }
body.collapse-sidebar .main-sidebar:hover li.open > .sub-menu { max-height: 900px; }
body.collapse-sidebar .header-navbar { padding-left: calc(var(--jg-sidebar-mini) + 30px); }
body.collapse-sidebar .main-content  { padding-left: calc(var(--jg-sidebar-mini) + 25px); }
body.collapse-sidebar footer         { padding-left: calc(var(--jg-sidebar-mini) + 25px); }

.overlay {
  position: fixed; top: 0; left: 0; right: 0; height: 120vh;
  background-color: rgba(34,41,47,.5); z-index: 100;
  visibility: hidden; opacity: 0; transition: all .5s ease;
}

@media only screen and (max-width: 900px) {
  .main-sidebar { margin-left: -280px; }
  body.expand-sidebar .main-sidebar { margin-left: 0; }
  body.expand-sidebar .overlay { visibility: visible; opacity: 1; }
  .close-sidebar { display: flex; }
  .header-navbar { padding-left: 15px; padding-right: 15px; }
  .main-content  { padding-left: 12px; padding-right: 12px; }
  footer { padding: 0 15px; justify-content: center; }
  footer .footer-right { display: none; }
  body.collapse-sidebar .header-navbar,
  body.collapse-sidebar .main-content,
  body.collapse-sidebar footer { padding-left: 12px; }
  .header-navbar .user-dropdown .label,
  .header-navbar .header-left .page-context { display: none; }
}

/* ============================================================ components = */

/* Cards: a hairline plus a layered shadow, so they sit clearly above the
   canvas rather than dissolving into it. */
.card {
  box-shadow: var(--jg-card-shadow);
  margin-bottom: 1.35rem;
  background: var(--jg-surface);
  border-radius: 8px;
  border: 1px solid var(--jg-border-soft);
}
.card:not([class*="border"]) { border: 1px solid var(--jg-border-soft); }
/* A faint tint separates the header from the body without a hard rule, and
   keeps a tall card from reading as one undifferentiated white block. */
.card .card-header {
  border-bottom: 1px solid var(--jg-border-soft);
  padding: .85em 1.1em;
  background: color-mix(in srgb, var(--jg-surface-alt) 55%, var(--jg-surface));
  border-radius: 8px 8px 0 0;
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.card .card-header h4 { margin-bottom: 0; font-size: 1rem; font-weight: 600; color: var(--jg-gray-dark); }
.card .card-body { padding: 1.1em; }
.card .card-footer { border-top: none; background: transparent; }
.card-body.small-padding { padding: 0; }
.same-height > [class*="col"] { display: flex; flex-flow: column; }
.same-height > [class*="col"] > .card { flex: 1 1 auto; }

/* Section band inside a card (ArFa .header-statistics) */
.header-statistics {
  display: flex; align-items: center; justify-content: center; flex-direction: column;
  background: linear-gradient(180deg, var(--jg-surface-alt), color-mix(in srgb, var(--jg-surface-alt) 45%, var(--jg-surface)));
  border-bottom: 1px solid var(--jg-border-soft);
  padding: 15px; margin-bottom: 15px;
  border-radius: 8px 8px 0 0;
}
.header-statistics h5 { font-size: 1.05rem; font-weight: 500; margin: 0; }
.header-statistics p  { color: var(--jg-text-muted); font-size: .78em; margin: 4px 0 0; }

/* Buttons: every variant glows in its own hue */
.btn { vertical-align: middle; font-size: .875rem; border-radius: var(--jg-radius); }
.btn i { font-size: .9em; }
.btn.icon-left i  { margin-right: .35em; }
.btn.icon-right i { margin-left: .35em; }
/* Driving Bootstrap's own per-button variables rather than background-color:
   .btn:disabled and .btn.active are more specific than .btn-primary, so a
   plain background-color override leaves disabled and pressed buttons showing
   Bootstrap's stock blue. The POS "Confirm sale" button starts disabled, which
   is exactly where that showed. */
.btn-primary {
  --bs-btn-bg: var(--jg-primary);
  --bs-btn-border-color: var(--jg-primary);
  --bs-btn-hover-bg: var(--jg-primary-dark);
  --bs-btn-hover-border-color: var(--jg-primary-dark);
  --bs-btn-active-bg: var(--jg-primary-dark);
  --bs-btn-active-border-color: var(--jg-primary-dark);
  --bs-btn-disabled-bg: var(--jg-primary);
  --bs-btn-disabled-border-color: var(--jg-primary);
  box-shadow: 0 0 4px var(--jg-primary);
}
.btn-success {
  --bs-btn-bg: var(--jg-success);
  --bs-btn-border-color: var(--jg-success);
  --bs-btn-hover-bg: #0e9455;
  --bs-btn-hover-border-color: #0e9455;
  --bs-btn-active-bg: #0e9455;
  --bs-btn-active-border-color: #0e9455;
  --bs-btn-disabled-bg: var(--jg-success);
  --bs-btn-disabled-border-color: var(--jg-success);
  box-shadow: 0 0 4px var(--jg-success);
}
.btn-danger    { background-color: var(--jg-danger);    border-color: var(--jg-danger);    box-shadow: 0 0 4px var(--jg-danger); }
.btn-warning   { background-color: var(--jg-warning);   border-color: var(--jg-warning);   box-shadow: 0 0 4px var(--jg-warning); color: #fff; }
.btn-info      { background-color: var(--jg-info);      border-color: var(--jg-info);      box-shadow: 0 0 4px var(--jg-info);    color: #fff; }
.btn-secondary { background-color: var(--jg-secondary); border-color: var(--jg-secondary); box-shadow: 0 0 4px var(--jg-secondary); }
.btn-dark      { background-color: var(--jg-dark);      border-color: var(--jg-dark);      box-shadow: 0 0 4px var(--jg-dark); }
.btn-danger:hover    { background-color: #e33638; border-color: #e33638; }
.btn-warning:hover   { background-color: #ff8b1f; border-color: #ff8b1f; color: #fff; }
.btn-info:hover      { background-color: #00b4c9; border-color: #00b4c9; color: #fff; }
.btn-light { background: var(--jg-surface-alt); border-color: var(--jg-border); color: var(--jg-gray-dark); }
.btn-outline-primary { color: var(--jg-primary); border-color: var(--jg-primary); }
.btn-outline-primary:hover { background: var(--jg-primary); border-color: var(--jg-primary); box-shadow: 0 0 4px var(--jg-primary); color: #fff; }
.btn-outline-danger  { color: var(--jg-danger); border-color: var(--jg-danger); }
.btn-outline-danger:hover { background: var(--jg-danger); border-color: var(--jg-danger); box-shadow: 0 0 4px var(--jg-danger); color: #fff; }
.btn-outline-secondary { color: var(--jg-secondary); border-color: var(--jg-secondary); }
.btn-outline-secondary:hover { background: var(--jg-secondary); box-shadow: 0 0 4px var(--jg-secondary); color: #fff; }
.btn:focus, .btn:active:focus { box-shadow: none !important; }

/* Forms: focus is a blue glow, not a ring */
.form-control, .form-select, .form-control-plaintext {
  color: var(--jg-text); font-size: .875rem;
  background-color: var(--jg-surface); border-color: var(--jg-border);
}
.form-control-sm, .form-select-sm { font-size: .8rem; }
.form-control:focus, .form-select:focus, .form-check-input:focus {
  box-shadow: 0 0 6px var(--jg-focus-ring);
  border-color: var(--jg-primary);
  background-color: var(--jg-surface); color: var(--jg-text);
}
.form-label, .form-text { color: var(--jg-gray-dark); font-size: .78rem; margin-bottom: .25em; font-weight: 500; }
.form-check-input:checked {
  background-color: var(--jg-primary); border-color: var(--jg-primary);
  box-shadow: 0 0 6px var(--jg-primary);
}
.input-group-text { background: var(--jg-surface); color: var(--jg-text); border-color: var(--jg-border); font-size: .85rem; }
.input-group-text.light { background: var(--jg-surface-alt); }
/* Joined input + addon that highlight together */
.input-group-join .form-control { border-right: none; transition: .1s border; }
.input-group-join .input-group-text { border-left-width: 0 !important; transition: .1s border; }
.input-group-join:focus-within .form-control,
.input-group-join:focus-within .input-group-text {
  box-shadow: none; border-color: var(--jg-primary);
}
.form-switch.lg { padding: 0; margin: 0; display: flex; align-items: center; justify-content: space-between; width: 100%; }
.form-switch.lg .form-check-input { margin: 0; height: 25px; width: 40px; background-color: var(--jg-surface-alt); }
.form-switch.lg .form-check-input:checked { background-color: var(--jg-primary); }

/* Tables */
table.table { color: var(--jg-text); font-size: .875rem; margin-bottom: 0; }
table.table thead { background-color: var(--jg-surface-alt); }
table.table thead tr th {
  font-weight: 600; font-size: .7rem; text-transform: uppercase;
  letter-spacing: .5px; color: var(--jg-text-muted); white-space: nowrap;
  padding-top: .7rem; padding-bottom: .7rem;
  border-bottom: 1px solid var(--jg-border);
}
table.table > :not(:last-child) > :last-child > * { border-bottom-color: var(--jg-border); }
table.table td, table.table th { vertical-align: middle; border-color: var(--jg-border-soft); }
.table-hover > tbody > tr { transition: background-color .12s ease; }
.table-hover > tbody > tr:hover > * { background-color: var(--jg-surface-alt); color: var(--jg-text); }
.table-striped > tbody > tr:nth-of-type(odd) > * { background-color: rgba(16, 24, 40, .016); color: var(--jg-text); }
.table-active > * { background-color: rgb(var(--jg-primary-rgb) / .06) !important; }
.table-empty { padding: 40px 15px; text-align: center; color: var(--jg-text-muted); }
.table-empty i { font-size: 2.2rem; display: block; margin-bottom: 10px; opacity: .5; }

/* Badges — soft tinted chips rather than solid blocks */
.badge { font-weight: 500; font-size: .7rem; padding: .38em .65em; border-radius: var(--jg-radius); }
.badge-soft-primary { background: rgb(var(--jg-primary-rgb) / .12);  color: var(--jg-primary); }
.badge-soft-success { background: rgba(40,199,111,.12); color: var(--jg-success); }
.badge-soft-danger  { background: rgba(234,84,85,.12);  color: var(--jg-danger); }
.badge-soft-warning { background: rgba(255,159,67,.14); color: #e8862b; }
.badge-soft-info    { background: rgba(0,207,232,.12);  color: #039fb3; }
.badge-soft-dark    { background: rgba(25,31,48,.08);   color: var(--jg-gray-dark); }

/* KPI tile */
.kpi {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 14px;
  background: var(--jg-surface); border-radius: 8px;
  border: 1px solid var(--jg-border-soft);
  padding: 16px 18px; box-shadow: var(--jg-card-shadow);
  height: 100%; min-width: 0;
  transition: transform .25s ease, box-shadow .25s ease;
}
/* min-width:0 on the text column is what lets it ellipsise rather than
   forcing the tile wider than its grid cell. */
.kpi > span { min-width: 0; }
a.kpi { color: inherit; }
a.kpi:hover { transform: translateY(-2px); box-shadow: var(--jg-card-shadow-lift); }
.kpi .kpi-icon {
  min-width: 46px; height: 46px; border-radius: var(--jg-radius);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.15rem; color: #fff;
}
.kpi .kpi-icon.c-primary { background: linear-gradient(135deg, var(--jg-primary-dark), var(--jg-primary-fade)); box-shadow: 0 0 8px rgb(var(--jg-primary-rgb) / .5); }
.kpi .kpi-icon.c-success { background: linear-gradient(135deg, var(--jg-success), #6bdd9f); box-shadow: 0 0 8px rgba(40,199,111,.5); }
.kpi .kpi-icon.c-warning { background: linear-gradient(135deg, var(--jg-warning), #ffc38a); box-shadow: 0 0 8px rgba(255,159,67,.5); }
.kpi .kpi-icon.c-danger  { background: linear-gradient(135deg, var(--jg-danger),  #f39294); box-shadow: 0 0 8px rgba(234,84,85,.5); }
.kpi .kpi-icon.c-info    { background: linear-gradient(135deg, var(--jg-info),    #7ee6f4); box-shadow: 0 0 8px rgba(0,207,232,.5); }
.kpi .kpi-icon.c-dark    { background: linear-gradient(135deg, var(--jg-dark),    #3c4763); box-shadow: 0 0 8px rgba(25,31,48,.4); }
.kpi .kpi-value {
  font-size: 1.28rem; font-weight: 600; color: var(--jg-gray-dark); line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The figure must never wrap; its caption may, so "Transactions today" stays
   readable in a narrow tile instead of being cut to "Transactions tod…". */
.kpi .kpi-label {
  display: block;
  font-size: .72rem; color: var(--jg-text-muted); letter-spacing: .3px;
  line-height: 1.25;
}
/* Six tiles across leaves each one narrow, and a float like GH₵ 12,345.67 has
   to fit whole. Scale the figure with the viewport rather than clipping it. */
@media (min-width: 1200px) and (max-width: 1699px) {
  .kpi { padding: 14px; gap: 10px; }
  .kpi .kpi-value { font-size: clamp(.9rem, 1vw, 1.28rem); }
  .kpi .kpi-label { font-size: .68rem; }
  .kpi .kpi-icon  { min-width: 38px; height: 38px; font-size: .95rem; }
}

/* Alerts */
.alert { border: none; border-radius: var(--jg-radius); font-size: .875rem; }
.alert-success { background: rgba(40,199,111,.12); color: #1f9c56; }
.alert-danger  { background: rgba(234,84,85,.12);  color: #c93d3e; }
.alert-warning { background: rgba(255,159,67,.14); color: #d9781f; }
.alert-info    { background: rgb(var(--jg-primary-rgb) / .10);  color: var(--jg-primary-dark); }

/* Allergy banner — deliberately loud, this is the child-safety surface */
.allergy-banner {
  border-radius: var(--jg-radius); padding: 12px 15px; margin-bottom: 12px;
  display: flex; gap: 12px; align-items: flex-start; font-size: .85rem;
}
.allergy-banner.severe {
  background: rgba(234,84,85,.14); color: #b93335;
  box-shadow: 0 0 10px rgba(234,84,85,.45);
  animation: allergypulse 2.2s ease-in-out infinite;
}
.allergy-banner.moderate { background: rgba(255,159,67,.16); color: #c96d17; }
.allergy-banner.mild     { background: rgba(0,207,232,.12);  color: #0b93a4; }
.allergy-banner i { font-size: 1.3rem; margin-top: 2px; }
@keyframes allergypulse {
  0%,100% { box-shadow: 0 0 6px rgba(234,84,85,.35); }
  50%     { box-shadow: 0 0 18px rgba(234,84,85,.65); }
}

/* Dropdown menus */
.dropdown-menu {
  border: none; border-radius: var(--jg-radius);
  box-shadow: 0 4px 24px 0 var(--jg-gray-medium);
  font-size: .875rem; background: var(--jg-surface); padding: 6px;
}
.dropdown-item { border-radius: var(--jg-radius); color: var(--jg-text); padding: .45rem .7rem; }
.dropdown-item:hover, .dropdown-item:focus { background: var(--jg-surface-alt); color: var(--jg-primary); }
.dropdown-item i { width: 18px; }
.dropdown-menu .menu-header {
  padding: 8px 10px; font-size: .78rem; font-weight: 500;
  color: var(--jg-gray-dark); border-bottom: 1px solid var(--jg-border); margin-bottom: 4px;
}
.dropdown-notice { display: flex; gap: 10px; padding: 8px 10px; border-radius: var(--jg-radius); color: var(--jg-text); }
.dropdown-notice:hover { background: var(--jg-surface-alt); }
.dropdown-notice .body { font-size: .8rem; }
.dropdown-notice .time { font-size: .7rem; color: var(--jg-text-muted); }

/* Progress */
.progress { background: var(--jg-gray-light); border-radius: 10px; height: 8px; }
.progress-bar { background: var(--jg-primary); border-radius: 10px; }

/* Modals */
.modal-content { border: none; border-radius: var(--jg-radius); box-shadow: 0 4px 34px 0 rgba(0,0,0,.25); background: var(--jg-surface); }
.modal-header, .modal-footer { border-color: var(--jg-border); }
.modal-title { font-size: 1.05rem; font-weight: 500; color: var(--jg-gray-dark); }

/* Nav tabs */
.nav-tabs { border-bottom-color: var(--jg-border); }
.nav-tabs .nav-link { color: var(--jg-text); font-size: .875rem; border: none; border-bottom: 2px solid transparent; }
.nav-tabs .nav-link.active {
  color: var(--jg-primary); background: transparent;
  border-bottom-color: var(--jg-primary);
}

/* Pagination */
.pagination { font-size: .85rem; margin: 0; }
.page-link { color: var(--jg-text); border-color: var(--jg-border); background: var(--jg-surface); }
.page-item.active .page-link {
  background: var(--jg-primary); border-color: var(--jg-primary);
  box-shadow: 0 0 6px var(--jg-primary);
}

/* Photo chips used across student / staff / item listings */
.photo-chip {
  width: 38px; height: 38px; border-radius: var(--jg-radius);
  object-fit: cover; box-shadow: 0 0 6px var(--jg-gray-medium); background: var(--jg-surface-alt);
}
.photo-chip.lg { width: 90px; height: 90px; }
.photo-chip.round { border-radius: 50%; }
.initials {
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--jg-primary-dark), var(--jg-primary-fade));
  color: #fff; font-weight: 600; font-size: .8rem;
}

/* Floating stat label (ArFa .float-label) */
.float-label {
  display: flex; align-items: center; justify-content: center; flex-direction: column;
  padding: 10px; position: absolute; top: -10px; left: 10px; width: 100px; z-index: 1;
  background-color: var(--jg-surface); box-shadow: 0 3px 10px var(--jg-gray); border-radius: 5px;
}

/* ------------------------------------------------------ filter toolbars - */
/* Two shapes are used across the system:
   .toolbar         — labelled controls wrapped in divs, above a table
   form[data-autosubmit] — bare controls sitting inline in a card header
   Bootstrap gives .form-control width:100%. As a *direct* flex child that
   makes every control claim a whole row, which is why date pairs stacked
   instead of sitting side by side. Size direct children to their content. */
.toolbar { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; margin-bottom: 1rem; }
.toolbar .form-control, .toolbar .form-select { min-width: 150px; }

form[data-autosubmit] {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: center;
}
form[data-autosubmit] > .form-control,
form[data-autosubmit] > .form-select {
  width: auto;
  flex: 0 1 auto;
  min-width: 130px;
}
form[data-autosubmit] > input[type="date"] {
  min-width: 150px;   /* enough for dd/mm/yyyy plus the picker glyph */
  flex: 0 0 auto;
}
form[data-autosubmit] > .btn { flex: 0 0 auto; }

/* The actions cluster beside a page heading */
.page-actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.page-actions > form { margin: 0; }

/* Footer under every list: count, page size, pager */
.pager-bar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
  padding: 14px 16px;
  border-top: 1px solid var(--jg-border);
}
.pager-bar .pagination { margin-left: auto; }

/* Auth screens */
body.auth-page { background: var(--jg-canvas); }
.auth-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; }
.auth-card { width: 100%; max-width: 430px; }
.auth-brand { text-align: center; margin-bottom: 22px; }
.auth-brand .brand-mark {
  width: 62px; height: 62px; margin: 0 auto 12px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--jg-primary-dark), var(--jg-primary-fade));
  box-shadow: 0 0 18px 2px rgb(var(--jg-primary-rgb) / .45);
  color: #fff; font-weight: 600; font-size: 20px;
}
.auth-brand h1 { font-size: 1.15rem; font-weight: 600; color: var(--jg-gray-dark); }
.auth-brand p  { font-size: .8rem; color: var(--jg-text-muted); margin: 0; }

/* ================================================================== POS = */
.pos-shell { display: grid; grid-template-columns: 1fr 380px; gap: 18px; }
@media (max-width: 1100px) { .pos-shell { grid-template-columns: 1fr; } }
/* Equal columns and equal rows: every tile is the same size whatever its name
   length or whether it carries a stock figure, so the grid reads as a grid. */
.pos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(134px, 1fr));
  gap: 10px;
  align-items: stretch;
}
.pos-grid-empty { grid-column: 1 / -1; }
@media (max-width: 480px) {
  .pos-grid { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }
}

.pos-item {
  --tile: var(--jg-primary);
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
  border: 1px solid var(--jg-border);
  border-radius: 10px;
  background: var(--jg-surface);
  box-shadow: 0 1px 3px rgba(16, 24, 40, .06);
  text-align: left;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.pos-item:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--tile) 45%, transparent);
  box-shadow: 0 10px 22px -6px color-mix(in srgb, var(--tile) 40%, transparent);
}
.pos-item:active { transform: translateY(-1px); }

/* Fixed-ratio media box — a photograph, or a tinted panel with the category
   icon. Both are the same height, which is what keeps the rows aligned. */
.pos-item-media {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 5 / 3;      /* shallow, so more of the menu fits on one screen */
  overflow: hidden;
  background: var(--jg-surface-alt);
}
.pos-item-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pos-item-media.placeholder-media {
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(circle at 30% 25%, color-mix(in srgb, var(--tile) 26%, transparent), transparent 62%),
    linear-gradient(135deg,
      color-mix(in srgb, var(--tile) 16%, var(--jg-surface)),
      color-mix(in srgb, var(--tile) 7%, var(--jg-surface)));
}
.pos-item-media.placeholder-media i {
  font-size: 1.7rem;
  color: color-mix(in srgb, var(--tile) 72%, transparent);
}

.pos-item-body {
  display: flex; flex-direction: column; flex: 1;
  gap: 6px; padding: 9px 10px 10px;
}
/* Two lines maximum, then ellipsis — a long name can never push the price
   out of line with its neighbours. */
.pos-item .n {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.3em;
  font-size: .8rem; font-weight: 500; line-height: 1.15;
  color: var(--jg-gray-dark);
}
.pos-item-foot {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  margin-top: auto;
}
.pos-item .p { font-size: 1rem; font-weight: 600; color: var(--tile); white-space: nowrap; }
.pos-item-stock {
  font-size: .66rem; color: var(--jg-text-muted);
  background: var(--jg-surface-alt); border-radius: 20px; padding: 1px 7px;
}
.pos-item-allergen {
  font-size: .62rem; color: var(--jg-danger); font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Corner flag for a low stock count or an allergen clash */
.pos-item-flag {
  position: absolute; top: 7px; right: 7px; z-index: 1;
  font-size: .62rem; font-weight: 600; line-height: 1;
  padding: 4px 7px; border-radius: 20px;
  backdrop-filter: blur(2px);
}
.pos-item-flag.warn   { background: rgba(255, 159, 67, .92); color: #fff; }
.pos-item-flag.danger { background: rgba(234, 84, 85, .95); color: #fff; }

.pos-item.blocked { opacity: .6; }
.pos-item.blocked .pos-item-media { filter: grayscale(.65); }
.pos-item.blocked:hover { border-color: var(--jg-danger); box-shadow: 0 6px 16px -6px rgba(234, 84, 85, .5); }

body.dark .pos-item { box-shadow: 0 1px 3px rgba(0, 0, 0, .3); }
/* ------------------------------------------- who is being served (search) - */
.pick-panel {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid var(--jg-border);
  border-radius: 8px;
  background: var(--jg-surface-alt);
}
.pick-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.pick-head .form-label { margin: 0; }

.pick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(126px, 1fr));
  gap: 8px;
  align-items: stretch;
  max-height: 340px;
  overflow-y: auto;
}
.pick-empty { grid-column: 1 / -1; }

/* Every card identical height: a two-line name can't shunt the balance out of
   alignment with its neighbours. */
.pos-person {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 8px 9px;
  border: 1px solid var(--jg-border-soft);
  border-radius: 8px;
  background: var(--jg-surface);
  text-align: center;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.pos-person:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--jg-primary) 45%, transparent);
  box-shadow: 0 8px 18px -8px rgb(var(--jg-primary-rgb) / .45);
}
.pos-person-avatar { width: 46px; height: 46px; margin-bottom: 5px; flex: 0 0 auto; }
.pos-person-avatar img,
.pos-person-avatar .initials {
  width: 46px; height: 46px; border-radius: 50%;
  object-fit: cover; display: flex; align-items: center; justify-content: center;
}
.pos-person-avatar .initials {
  background: linear-gradient(135deg, var(--jg-primary-dark), var(--jg-primary-fade));
  color: #fff; font-weight: 600; font-size: .85rem;
}
.pos-person-name {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.2em;
  font-size: .76rem; font-weight: 500; line-height: 1.12;
  color: var(--jg-gray-dark);
}
/* Two children can share a name; the identifier is what tells them apart. */
.pos-person-code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .6rem; color: var(--jg-text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.pos-person-class {
  font-size: .64rem; color: var(--jg-text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.pos-person-balance {
  margin-top: 4px;
  font-size: .82rem; font-weight: 600; color: var(--jg-success); white-space: nowrap;
}
.pos-person-balance.low { color: var(--jg-danger); }

.pos-cart-line { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--jg-border); font-size: .85rem; }
.pos-total { font-size: 1.6rem; font-weight: 600; color: var(--jg-gray-dark); }
.pos-student-card { display: flex; gap: 14px; align-items: center; }
/* A headline money figure — what was spent, what is owed at the till. */
.pos-figure { font-size: 1.35rem; font-weight: 600; color: var(--jg-success); }
.category-pill {
  border: 1px solid var(--jg-border);
  background: var(--jg-surface);
  color: var(--jg-gray-dark);
  padding: 5px 13px; border-radius: 20px;
  font-size: .78rem; font-weight: 500; white-space: nowrap;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.category-pill:hover { border-color: var(--jg-gray); background: var(--jg-surface-alt); }
.category-pill.active { color: #fff; border-color: transparent; }

/* =========================================================== dark theme = */
body.dark {
  --jg-surface:      #1c2438;
  --jg-surface-alt:  #232c44;
  --jg-body-bg:      #141926;      /* canvas sits below the cards here too */
  --jg-text:         #b8c2cc;
  --jg-text-muted:   #7d8799;
  --jg-border:       #2e3852;
  --jg-border-soft:  #273047;
  --jg-gray-light:   #161b29;
  --jg-gray-medium:  #12172333;
  --jg-nav-active:   #141926;
  --jg-card-shadow:  0 1px 2px rgba(0, 0, 0, .3), 0 10px 28px -12px rgba(0, 0, 0, .55);
  --jg-card-shadow-lift: 0 2px 6px rgba(0, 0, 0, .35), 0 18px 38px -14px rgba(0, 0, 0, .6);
}
body.dark html, body.dark { background: var(--jg-body-bg); color: var(--jg-text); }
body.dark { --jg-sidebar-bg: #1a2133; }
body.dark .main-sidebar { box-shadow: none; }
body.dark .sidebar-content ul { background: transparent; }
body.dark .sidebar-header .brand-text .t1,
body.dark .main-content > .title,
body.dark .card .card-header h4,
body.dark .kpi .kpi-value,
body.dark table.table thead tr th { color: var(--jg-text); }
body.dark .sidebar-content > ul > li > a,
body.dark .sidebar-content .sub-menu li a { color: var(--jg-text); }
body.dark .sidebar-content li.open > a { background: var(--jg-nav-active); }
body.dark .sidebar-content .sub-menu li.active a { background: var(--jg-nav-active); color: #fff; }
body.dark .header-navbar .header-wrapper { box-shadow: 0 0 15px #12172a; }
body.dark .header-navbar .header-left,
body.dark .header-navbar .notification > a > i,
body.dark .header-navbar .user-dropdown .label,
body.dark .header-navbar .user-dropdown .label div,
body.dark .theme-switch-icon { color: var(--jg-text); }
body.dark .table-striped > tbody > tr:nth-of-type(odd) > * { background-color: rgba(255,255,255,.02); }
body.dark .table-hover > tbody > tr:hover > * { background-color: var(--jg-surface-alt); }
body.dark .text-muted { color: var(--jg-text-muted) !important; }
body.dark .btn-light { background: var(--jg-surface-alt); color: var(--jg-text); border-color: var(--jg-border); }
body.dark .form-control::placeholder { color: #5d6779; }
body.dark .badge-soft-dark { background: rgba(255,255,255,.07); color: var(--jg-text); }

/* ======================================================= camera scanner = */
.scanner-viewport {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: #12172a;
  border-radius: var(--jg-radius);
  overflow: hidden;
}
.scanner-viewport video {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* Corner brackets: tells the cashier where to hold the card without hiding it. */
.scanner-frame {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 78%; height: 42%;
  pointer-events: none;
  border-radius: 6px;
  box-shadow: 0 0 0 2000px rgba(0, 0, 0, .35);
}
.scanner-frame::before,
.scanner-frame::after {
  content: "";
  position: absolute;
  width: 26px; height: 26px;
  border: 3px solid var(--jg-primary);
  filter: drop-shadow(0 0 4px var(--jg-primary));
}
.scanner-frame::before { top: -2px; left: -2px;  border-right: none; border-bottom: none; border-radius: 6px 0 0 0; }
.scanner-frame::after  { bottom: -2px; right: -2px; border-left: none;  border-top: none;    border-radius: 0 0 6px 0; }

/* Sweep line, so a frozen preview is obviously distinguishable from a live one. */
.scanner-frame > i,
.scanner-viewport::after {
  content: "";
  position: absolute;
  left: 11%; right: 11%;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--jg-primary), transparent);
  box-shadow: 0 0 8px var(--jg-primary);
  animation: scansweep 2.4s ease-in-out infinite;
}
@keyframes scansweep {
  0%, 100% { top: 30%; opacity: .3; }
  50%      { top: 68%; opacity: 1; }
}

/* ====================================================== SweetAlert theme = */
/* All feedback is a toast or a dialog — these inherit the ArFa language:
   Montserrat, 4px radius, borderless surfaces on a wide soft shadow. */
.swal2-container { font-family: "Montserrat", sans-serif; }
.swal2-popup.jg-swal {
  border-radius: var(--jg-radius);
  box-shadow: 0 4px 34px 0 rgba(0, 0, 0, .18);
  border: none;
  font-size: .9rem;
  padding: 1.6em;
}
.swal2-popup.jg-swal .swal2-title { font-size: 1.15rem; font-weight: 600; }
.swal2-popup.jg-swal .swal2-html-container { font-size: .875rem; line-height: 1.55; margin-top: .6em; }
.swal2-popup.jg-swal .swal2-actions { gap: .5rem; margin-top: 1.4em; }
.swal2-popup.jg-swal .swal2-actions .btn { min-width: 110px; }
.swal2-popup.jg-swal .swal2-icon { margin: .4em auto .8em; }

/* Toasts: compact, top-right, tinted rail in the message's own colour */
.swal2-popup.swal2-toast.jg-swal {
  padding: .85em 1em;
  box-shadow: 0 4px 24px 0 rgba(0, 0, 0, .16);
  border-left: 3px solid var(--jg-primary);
}
.swal2-popup.swal2-toast.jg-swal .swal2-title { font-size: .85rem; font-weight: 400; margin: 0; }
.swal2-popup.swal2-toast.jg-swal .swal2-html-container { font-size: .85rem; margin: 0; }
.swal2-popup.swal2-toast.jg-swal .swal2-icon { width: 1.5em; height: 1.5em; margin: 0 .5em 0 0; }
.swal2-popup.swal2-toast.jg-swal.swal2-icon-success { border-left-color: var(--jg-success); }
.swal2-popup.swal2-toast.jg-swal.swal2-icon-error   { border-left-color: var(--jg-danger); }
.swal2-popup.swal2-toast.jg-swal.swal2-icon-warning { border-left-color: var(--jg-warning); }
.swal2-popup.swal2-toast.jg-swal.swal2-icon-info    { border-left-color: var(--jg-info); }
.swal2-timer-progress-bar { background: rgb(var(--jg-primary-rgb) / .35); }

/* Icon strokes need re-tinting against the dark surface */
body.dark .swal2-popup.jg-swal .swal2-title { color: #e7ecf3; }
body.dark .swal2-popup.jg-swal .swal2-html-container { color: var(--jg-text); }

/* ============================================================== printing = */
@media print {
  .main-sidebar, .header-navbar, .shadow-header, footer, .no-print, .toolbar { display: none !important; }
  .main-content { padding: 0 !important; }
  .card { box-shadow: none !important; }
  body { background: #fff; font-size: 12px; }
}

/* ================================================================= brand = */
/* The school crest. One rule set so the mark sits identically in the sidebar,
   on the sign-in screen, on a printed card and atop every report. */
.brand-logo { flex: 0 0 auto; }
.auth-brand img { display: block; margin: 0 auto 12px; }
.header-statistics img { display: block; margin: 0 auto; }

/* A favicon-sized crest keeps its detail better on a light ground */
body.dark .brand-logo,
body.dark .auth-brand img { filter: brightness(1.08); }

@media print {
  .header-statistics { background: none !important; border-bottom: 1px solid #ddd !important; }
}

/* ========================================================= order tickets = */
/* One card per pupil waiting at the counter. Deliberately chunky: the canteen
   reads these at arm's length while serving. */
/* ========================================================= payment panel = */
/* Sits under the basket total. The cash figure is the one the person at the
   desk acts on, so it is the only thing here at full size. */
.pay-panel {
  background: var(--jg-surface-alt);
  border: 1px solid var(--jg-border-soft);
  border-radius: var(--jg-radius);
  padding: 10px 12px;
}
.pay-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 5px 0;
}
.pay-row + .pay-row { border-top: 1px dashed var(--jg-border); }
.pay-amount { font-weight: 600; font-size: .9rem; white-space: nowrap; }
.pay-due .pay-amount { font-size: 1.25rem; color: var(--jg-primary); }
.pay-panel .form-label { color: var(--jg-text-muted); }
.pay-panel .form-control-plaintext { padding: .375rem 0; }

.order-ticket {
  border: 1px solid var(--jg-border);
  border-left: 4px solid var(--jg-primary);
  border-radius: 8px;
  padding: 12px;
  background: var(--jg-surface);
  height: 100%;
  transition: box-shadow .16s ease;
}
.order-ticket:hover { box-shadow: var(--jg-card-shadow); }
.order-ticket.has-allergy { border-left-color: var(--jg-danger); }
.order-ticket-items { font-size: .85rem; font-weight: 500; color: var(--jg-gray-dark); line-height: 1.35; }
.min-w-0 { min-width: 0; }

/* =========================================================== login scene = */
/* A branded ground behind the sign-in card: the school's green, a soft crest
   watermark, and a subtle grid so the card reads as lifted rather than floating
   on flat colour. */
body.auth-page {
  background:
    radial-gradient(1100px 620px at 12% -10%, rgb(var(--jg-brand-rgb) / .34), transparent 60%),
    radial-gradient(900px 560px at 92% 108%, rgba(19, 121, 103, .17), transparent 62%),
    linear-gradient(160deg, #f4f8ee 0%, #edf1ea 55%, #e6ecf0 100%);
  position: relative;
  min-height: 100vh;
}
/* The crest, very faint, large, behind everything */
body.auth-page::before {
  content: "";
  position: fixed; inset: 0;
  background-image: var(--jg-auth-crest, none);
  background-repeat: no-repeat;
  background-position: center 46%;
  background-size: min(560px, 78vw);
  opacity: .05;
  pointer-events: none;
}
/* A hairline grid for texture */
body.auth-page::after {
  content: "";
  position: fixed; inset: 0;
  background-image:
    linear-gradient(rgba(16, 24, 40, .028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(16, 24, 40, .028) 1px, transparent 1px);
  background-size: 46px 46px;
  pointer-events: none;
}
body.auth-page .auth-wrap { position: relative; z-index: 1; }
body.auth-page .auth-card .card {
  border: 1px solid rgba(255, 255, 255, .7);
  box-shadow: 0 2px 6px rgba(16, 24, 40, .05), 0 26px 60px -22px rgba(16, 24, 40, .35);
  backdrop-filter: blur(2px);
}
body.auth-page .auth-brand h1 { color: #34493a; }

body.dark.auth-page {
  background:
    radial-gradient(1100px 620px at 12% -10%, rgb(var(--jg-brand-rgb) / .17), transparent 60%),
    radial-gradient(900px 560px at 92% 108%, rgba(19, 121, 103, .16), transparent 62%),
    linear-gradient(160deg, #131a26 0%, #141926 55%, #10151f 100%);
}
body.dark.auth-page::after { background-image: none; }
body.dark.auth-page .auth-card .card { border-color: var(--jg-border); backdrop-filter: none; }
