*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}
h1, h2, h3, h4, h5, h6 { margin: 0 0 var(--space-2); font-weight: 600; line-height: 1.3; }
h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-md); }
p { margin: 0 0 var(--space-3); }
a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }
small { font-size: var(--text-xs); color: var(--color-text-secondary); }
hr { border: none; border-top: 1px solid var(--color-border); margin: var(--space-4) 0; }
img { max-width: 100%; }
::selection { background: var(--color-primary-light); }
[hidden] { display: none !important; }

.container { max-width: 1440px; margin: 0 auto; padding: 0 var(--space-5); }
.text-muted { color: var(--color-text-muted); }
.text-secondary { color: var(--color-text-secondary); }
.text-danger { color: var(--color-danger); }
.text-warning { color: var(--color-warning); }
.text-success { color: var(--color-success); }
.font-mono { font-family: var(--font-mono); }
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: var(--space-1); } .gap-2 { gap: var(--space-2); } .gap-3 { gap: var(--space-3); } .gap-4 { gap: var(--space-4); }
.w-full { width: 100%; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1;
  padding: 10px 16px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
  white-space: nowrap;
  min-height: 40px;
  /* Every button in the app is tappable on a touchscreen/all-in-one, not
     just clickable — manipulation skips the ~300ms double-tap-to-zoom delay
     mobile browsers otherwise wait out on every tap, which reads as
     sluggish on a kiosk where a cashier is tapping rapidly. */
  touch-action: manipulation;
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-text-inverse); }
.btn-primary:hover:not(:disabled) { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
.btn-secondary { background: var(--color-surface); border-color: var(--color-border-strong); color: var(--color-text); }
.btn-secondary:hover:not(:disabled) { background: var(--color-surface-alt); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--color-text-secondary); }
.btn-ghost:hover:not(:disabled) { background: var(--color-surface-alt); color: var(--color-text); }
.btn-danger { background: var(--color-danger); border-color: var(--color-danger); color: #fff; }
.btn-danger:hover:not(:disabled) { background: #b52f2f; }
.btn-danger-ghost { background: transparent; border-color: var(--color-border-strong); color: var(--color-danger); }
.btn-danger-ghost:hover:not(:disabled) { background: var(--color-danger-light); }
.btn-sm { min-height: 32px; padding: 6px 12px; font-size: var(--text-xs); border-radius: var(--radius-sm); }
.btn-lg { min-height: 48px; padding: 12px 20px; font-size: var(--text-base); }
.btn-block { width: 100%; }
.btn-icon { padding: 8px; min-width: 44px; min-height: 44px; }

/* ---------- Forms ---------- */
.form-group { margin-bottom: var(--space-4); }
.form-label { display: block; font-size: var(--text-sm); font-weight: 600; margin-bottom: var(--space-2); color: var(--color-text); }
.form-hint { font-size: var(--text-xs); color: var(--color-text-muted); margin-top: var(--space-1); }
.form-error { font-size: var(--text-xs); color: var(--color-danger); margin-top: var(--space-1); }
.form-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.form-row > .form-group { flex: 1 1 200px; }

.input, .select, textarea.input {
  width: 100%;
  font-family: inherit;
  font-size: var(--text-base);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  min-height: 42px;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.input::placeholder { color: var(--color-text-placeholder); }
.input:focus, .select:focus, textarea.input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-light);
}
.input.has-error, .select.has-error { border-color: var(--color-danger); }
.input:disabled, .select:disabled, textarea.input:disabled {
  background: var(--color-surface-alt);
  color: var(--color-text-disabled);
  opacity: 1;
  cursor: not-allowed;
}
.input-lg { min-height: 52px; font-size: var(--text-md); padding: 12px 16px; }
select.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%235c6370'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; padding-right: 32px; }
.checkbox-row { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
textarea.input { min-height: 90px; resize: vertical; }

/* ---------- Stock tracking mode picker (Product form — see
   backoffice/products/_form.php) — two mutually-exclusive, clearly labeled
   cards instead of a single checkbox whose "on" state had to be read as
   "off" for the opposite (untracked/BOM) meaning. ---------- */
.stock-mode-options { display: flex; flex-direction: column; gap: var(--space-2); }
.stock-mode-option { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid var(--color-border-strong); border-radius: var(--radius-md); cursor: pointer; }
.stock-mode-option:has(input:checked) { border-color: var(--color-primary); background: var(--color-primary-light); }
.stock-mode-option input { width: 18px; height: 18px; flex-shrink: 0; }
.stock-mode-option-title { font-weight: 600; font-size: var(--text-sm); }
.stock-mode-option-desc { flex-basis: 100%; margin-left: 26px; font-size: var(--text-xs); color: var(--color-text-secondary); }

/* ---------- BOM ingredient rows ---------- */
#bom-section { margin-bottom: var(--space-5); padding-bottom: var(--space-2); }
#bom-rows { margin-bottom: var(--space-3); }
.bom-row { display: flex; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-2); }
.bom-row .form-group { margin-bottom: 0; }
#add-ingredient-btn { margin-bottom: var(--space-2); }

/* ---------- Product variant rows (same shape as BOM rows above) ---------- */
#variant-section { margin-bottom: var(--space-5); padding-bottom: var(--space-2); }
#variant-rows { margin-bottom: var(--space-3); }
.variant-row { display: flex; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-2); }
.variant-row .form-group { margin-bottom: 0; }
#add-variant-btn { margin-bottom: var(--space-2); }

/* ---------- Card ---------- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}
.card-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--color-border); gap: var(--space-3); flex-wrap: wrap; }
.card-header h2, .card-header h3 { margin: 0; }
.card-body { padding: var(--space-5); }
.card-compact .card-body { padding: var(--space-4); }

/* ---------- Alert (flash messages) ---------- */
.alert-success, .alert-error, .alert-warning {
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  margin-bottom: var(--space-4);
}
.alert-success { background: var(--color-success-light); color: var(--color-success); }
.alert-error { background: var(--color-danger-light); color: var(--color-danger); }
.alert-warning { background: var(--color-warning-light); color: var(--color-warning); }

/* Success/failure icon used by result screens (payment success, install
   finish, import result) — lives here (not auth.css) since it's used from
   the POS and Backoffice layouts too, neither of which load auth.css. */
.install-success-icon { width: 56px; height: 56px; border-radius: 50%; background: var(--color-success-light); color: var(--color-success); display: flex; align-items: center; justify-content: center; font-size: 1.75rem; margin: 0 auto var(--space-4); }

/* ---------- Badge ---------- */
.badge { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); font-weight: 600; padding: 3px 10px; border-radius: var(--radius-full); line-height: 1.6; }
.badge-success { background: var(--color-success-light); color: var(--color-success); }
.badge-danger { background: var(--color-danger-light); color: var(--color-danger); }
.badge-warning { background: var(--color-warning-light); color: var(--color-warning); }
.badge-info { background: var(--color-info-light); color: var(--color-info); }
.badge-neutral { background: var(--color-surface-alt); color: var(--color-text-secondary); border: 1px solid var(--color-border); }

/* ---------- Table ---------- */
.table-wrap { overflow-x: auto; border-radius: var(--radius-lg); border: 1px solid var(--color-border); background: var(--color-surface); }
table.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); min-width: 640px; }
table.table th, table.table td { padding: var(--space-3) var(--space-4); text-align: left; border-bottom: 1px solid var(--color-border); }
table.table th { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); font-weight: 600; background: var(--color-surface-alt); white-space: nowrap; }
table.table tbody tr:last-child td { border-bottom: none; }
table.table tbody tr:hover { background: var(--color-surface-alt); }
table.table td.actions { white-space: nowrap; text-align: right; }
table.table .cell-num { text-align: right; font-variant-numeric: tabular-nums; }

/* Responsive card-table: on small screens, JS toggles .table-as-cards */
.table-cards { display: none; }
.table-cards .row-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-4); margin-bottom: var(--space-3); }
.table-cards .row-card dl { margin: 0; display: grid; grid-template-columns: 1fr auto; gap: var(--space-1) var(--space-2); }
.table-cards .row-card dt { font-size: var(--text-xs); color: var(--color-text-muted); }
.table-cards .row-card dd { margin: 0; font-size: var(--text-sm); text-align: right; }
.table-cards .row-card .row-card-title { font-weight: 600; font-size: var(--text-base); margin-bottom: var(--space-2); grid-column: 1 / -1; text-align: left; }
.table-cards .row-card .row-card-actions { grid-column: 1 / -1; display: flex; gap: var(--space-2); margin-top: var(--space-3); }

@media (max-width: 720px) {
  .table-wrap.is-responsive { display: none; }
  .table-cards.is-responsive { display: block; }
}

/* ---------- Pagination ---------- */
.pagination { display: flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; }
.pagination a, .pagination span { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 34px; padding: 0 8px; border-radius: var(--radius-sm); font-size: var(--text-sm); color: var(--color-text-secondary); border: 1px solid transparent; }
.pagination a:hover { background: var(--color-surface-alt); text-decoration: none; }
.pagination .active { background: var(--color-primary); color: #fff; font-weight: 600; }
.pagination .disabled { opacity: 0.4; pointer-events: none; }

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--color-border); overflow-x: auto; }
.tabs .tab { padding: var(--space-3) var(--space-4); font-size: var(--text-sm); font-weight: 600; color: var(--color-text-secondary); border-bottom: 2px solid transparent; cursor: pointer; white-space: nowrap; background: none; border-top: none; border-left: none; border-right: none; }
.tabs .tab.active { color: var(--color-primary); border-bottom-color: var(--color-primary); }

/* ---------- Dropdown ---------- */
.dropdown { position: relative; display: inline-block; }
.dropdown-menu { position: absolute; right: 0; top: calc(100% + 6px); min-width: 180px; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); box-shadow: var(--shadow-md); padding: var(--space-2); z-index: 40; display: none; }
.dropdown-menu.open { display: block; }
.dropdown-menu a, .dropdown-menu button { display: flex; width: 100%; text-align: left; align-items: center; gap: var(--space-2); padding: 8px 10px; border-radius: var(--radius-sm); font-size: var(--text-sm); color: var(--color-text); background: none; border: none; cursor: pointer; }
.dropdown-menu a:hover, .dropdown-menu button:hover { background: var(--color-surface-alt); text-decoration: none; }
.dropdown-menu .divider { height: 1px; background: var(--color-border); margin: var(--space-2) 0; }

/* The sidebar user-menu dropdown is anchored inside a sidebar that stays
   dark in BOTH light and dark theme — using the regular (theme-flipping)
   surface color here means a stark white popup lands directly against the
   dark sidebar in light mode. Match it to the sidebar's own palette instead. */
.pos-sidebar .dropdown-menu, .bo-sidebar .dropdown-menu {
  background: var(--sidebar-active-bg);
  border-color: var(--sidebar-border);
}
.pos-sidebar .dropdown-menu a, .pos-sidebar .dropdown-menu button,
.bo-sidebar .dropdown-menu a, .bo-sidebar .dropdown-menu button {
  color: var(--sidebar-text);
}
.pos-sidebar .dropdown-menu a:hover, .pos-sidebar .dropdown-menu button:hover,
.bo-sidebar .dropdown-menu a:hover, .bo-sidebar .dropdown-menu button:hover {
  background: var(--sidebar-bg);
  color: #fff;
}
.pos-sidebar .dropdown-menu .divider, .bo-sidebar .dropdown-menu .divider {
  background: var(--sidebar-border);
}

/* ---------- Modal ---------- */
.modal-backdrop { position: fixed; inset: 0; background: rgba(15, 18, 25, 0.5); display: none; align-items: center; justify-content: center; padding: var(--space-4); z-index: 100; transition: bottom 0.15s ease; }
.modal-backdrop.open { display: flex; }
.modal { background: var(--color-surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); width: 100%; max-width: 480px; max-height: calc(100vh - 2 * var(--space-4)); display: flex; flex-direction: column; }
.modal-lg { max-width: 720px; }
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--color-border); }
.modal-header h3 { margin: 0; }
.modal-body { padding: var(--space-5); overflow-y: auto; }
.modal-footer { padding: var(--space-4) var(--space-5); border-top: 1px solid var(--color-border); display: flex; justify-content: flex-end; gap: var(--space-2); flex-wrap: wrap; }
.modal-close { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; background: none; border: none; cursor: pointer; color: var(--color-text-muted); font-size: 1.25rem; line-height: 1; touch-action: manipulation; }

@media (max-width: 560px) {
  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal { max-width: 100%; width: 100%; border-radius: var(--radius-lg) var(--radius-lg) 0 0; max-height: 92vh; }
  .modal-backdrop.modal-fullscreen-mobile { align-items: stretch; }
  .modal-backdrop.modal-fullscreen-mobile .modal { border-radius: 0; max-height: 100vh; height: 100%; }
}

/* ---------- Drawer ---------- */
.drawer-backdrop { position: fixed; inset: 0; background: rgba(15, 18, 25, 0.5); display: none; z-index: 90; }
.drawer-backdrop.open { display: block; }
.drawer { position: fixed; top: 0; bottom: 0; left: 0; width: 260px; max-width: 84vw; background: var(--sidebar-bg); transform: translateX(-100%); transition: transform var(--transition-base); z-index: 95; display: flex; flex-direction: column; }
.drawer.open { transform: translateX(0); }
.drawer-right { left: auto; right: 0; transform: translateX(100%); background: var(--color-surface); }
.drawer-right.open { transform: translateX(0); }

/* ---------- Toast ---------- */
.toast-stack { position: fixed; top: var(--space-4); right: var(--space-4); z-index: 200; display: flex; flex-direction: column; gap: var(--space-2); max-width: 340px; }
.toast { background: var(--color-text); color: #fff; padding: 12px 16px; border-radius: var(--radius-md); font-size: var(--text-sm); box-shadow: var(--shadow-md); display: flex; align-items: flex-start; gap: var(--space-2); animation: toast-in 160ms ease; }
.toast-success { background: var(--color-success); }
.toast-danger { background: var(--color-danger); }
.toast-warning { background: var(--color-warning); color: #24160a; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 560px) {
  .toast-stack { left: var(--space-3); right: var(--space-3); top: var(--space-3); max-width: none; }
}

/* ---------- Empty / Loading / Error states ---------- */
.state-block { text-align: center; padding: var(--space-8) var(--space-4); color: var(--color-text-secondary); }
.state-block h4 { color: var(--color-text); margin-bottom: var(--space-1); }
.state-block p { margin: 0; font-size: var(--text-sm); }
.spinner { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--color-border); border-top-color: var(--color-primary); animation: spin 0.7s linear infinite; display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }
.skeleton { background: linear-gradient(90deg, var(--color-surface-alt) 25%, var(--color-border) 37%, var(--color-surface-alt) 63%); background-size: 400% 100%; animation: skeleton 1.4s ease infinite; border-radius: var(--radius-sm); }
@keyframes skeleton { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ---------- Confirm dialog reuses .modal ---------- */
.confirm-icon { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--color-danger-light); color: var(--color-danger); font-size: 1.25rem; margin-bottom: var(--space-3); }

/* ---------- Filter bar ---------- */
.filter-bar { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-end; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--color-border); }
.filter-bar .form-group { margin-bottom: 0; min-width: 140px; }

/* ---------- KPI ---------- */
.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
.kpi-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg); padding: var(--space-4) var(--space-5); }
.kpi-card .kpi-label { font-size: var(--text-xs); color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: var(--space-2); }
.kpi-card .kpi-value { font-size: var(--text-2xl); font-weight: 700; }
.kpi-card .kpi-sub { font-size: var(--text-xs); color: var(--color-text-secondary); margin-top: var(--space-1); }
@media (max-width: 1024px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .kpi-grid { grid-template-columns: 1fr; } }

/* Utility: visually hide but keep for screen readers */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* Plain CSS hamburger (three bars, no icon asset) */
.hamburger-icon { display: block; position: relative; width: 18px; height: 2px; background: currentColor; border-radius: 1px; }
.hamburger-icon::before, .hamburger-icon::after { content: ''; position: absolute; left: 0; width: 18px; height: 2px; background: currentColor; border-radius: 1px; }
.hamburger-icon::before { top: -6px; }
.hamburger-icon::after { top: 6px; }

/* ---------- On-screen keyboard (touch-only text/numeric entry) ---------- */
.osk-panel { position: fixed; left: 0; right: 0; bottom: 0; z-index: 300; background: var(--sidebar-bg); box-shadow: var(--shadow-lg); padding: var(--space-2) var(--space-3) calc(var(--space-3) + env(safe-area-inset-bottom)); }
.osk-header { display: flex; justify-content: flex-end; margin-bottom: var(--space-2); }
.osk-done { min-height: 40px; padding: 0 var(--space-4); border-radius: var(--radius-md); border: none; background: var(--color-primary); color: #fff; font-weight: 600; font-size: var(--text-sm); cursor: pointer; }
.osk-row { display: flex; gap: 6px; margin-bottom: 6px; }
.osk-row:last-child { margin-bottom: 0; }
.osk-key { flex: 1; min-height: 48px; border-radius: var(--radius-md); border: 1px solid var(--sidebar-border); background: var(--sidebar-active-bg); color: #fff; font-size: var(--text-md); font-weight: 600; cursor: pointer; text-transform: none; }
.osk-key:active { background: var(--color-primary); }
.osk-key-wide { flex: 1.6; }
.osk-key-shift.osk-active { background: var(--color-primary); }
.osk-key-space { flex: 1; }
.osk-body-numeric .osk-row { max-width: 320px; margin-left: auto; margin-right: auto; }
@media (max-width: 560px) {
  .osk-key { min-height: 44px; font-size: var(--text-base); }
}

/* When the keyboard is open, treat it as real UI viewport taken up at the
   bottom of the screen rather than an overlay sitting on top of whatever
   was already there — every app shell shrinks by exactly the keyboard's
   measured height (--osk-height, set by keyboard.js), and every layout
   inside it re-flows into the smaller box on its own via normal flex/scroll
   rules, so nothing has to be repositioned by hand per-field.
   - .modal-backdrop centers/bottom-docks its .modal via flexbox, so
     shrinking the backdrop re-flows the modal to fit — covers the
     desktop-centered modal, the mobile bottom-sheet modal, AND the
     fullscreen-mobile payment modal (whose .modal height:100% becomes 100%
     of the shrunk backdrop) — so a modal's footer button (e.g. "Complete
     Payment") never ends up hidden behind the keyboard.
   - .pos-shell is height:100vh with .pos-main/.pos-cart stretched to fill
     it (flex default align-items:stretch). Shrinking .pos-shell itself
     shrinks both columns together, which is what actually fixes the
     desktop/tablet cart column: at that width .pos-cart is a normal static
     flex child (not position:fixed), so it was never affected by shifting
     "bottom" — only shrinking the shell it lives in moves its bottom-pinned
     .cart-summary (discount input, Hold/Payment) up above the keyboard.
     The .pos-cart "bottom" shift below still handles the <=1100px bottom-
     sheet cart, which IS position:fixed and lives outside this shell box.
   - .bo-shell/.auth-shell get the same treatment for parity on any
     Backoffice or login field that ever gains data-osk — harmless no-ops
     today since neither currently overflows a short viewport. */
body.osk-open .modal-backdrop { bottom: var(--osk-height); }
body.osk-open .pos-cart { bottom: var(--osk-height); }
body.osk-open .pos-shell { height: calc(100vh - var(--osk-height)); }
body.osk-open .bo-shell { min-height: calc(100vh - var(--osk-height)); }
body.osk-open .auth-shell { min-height: calc(100vh - var(--osk-height)); }

/* Theme toggle switch (plain text label, no icon) */
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; height: 44px; padding: 0 14px; border-radius: var(--radius-md); border: 1px solid var(--color-border-strong); background: var(--color-surface); cursor: pointer; color: var(--color-text-secondary); font-size: var(--text-xs); font-weight: 600; flex-shrink: 0; touch-action: manipulation; }
.theme-toggle:hover { background: var(--color-surface-alt); }
.theme-toggle .theme-label-dark { display: inline; }
.theme-toggle .theme-label-light { display: none; }
:root[data-theme="dark"] .theme-toggle .theme-label-dark { display: none; }
:root[data-theme="dark"] .theme-toggle .theme-label-light { display: inline; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .theme-label-dark { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .theme-label-light { display: inline; }
}

/* Fullscreen ("immersive mode") toggle (plain text label, no icon) — same
   pill style as .theme-toggle above, label text is swapped by
   fullscreen.js. This is deliberately a page-level CSS state, not the
   browser's Fullscreen Web API — see fullscreen.js for why (its exit proved
   unreliable on real --app= kiosk hardware). Always shown: unlike the old
   Fullscreen-API version, a plain class toggle works in every browser, so
   there's no unsupported case to hide it for. */
.fullscreen-toggle { display: inline-flex; align-items: center; justify-content: center; height: 44px; padding: 0 14px; border-radius: var(--radius-md); border: 1px solid var(--color-border-strong); background: var(--color-surface); cursor: pointer; color: var(--color-text-secondary); font-size: var(--text-xs); font-weight: 600; flex-shrink: 0; touch-action: manipulation; }
.fullscreen-toggle:hover { background: var(--color-surface-alt); }

/* While immersive mode is active (html.is-fullscreen, toggled only by
   fullscreen.js), this button is the cashier's only way out, so it must
   never be coverable — it stays in its normal topbar slot (never
   relocated, so it can never drift on top of the Payment button or the
   cart header) but gets a z-index above every overlay in this file
   (.modal-backdrop 100, .drawer 95, .osk-panel 300), so a modal, drawer or
   on-screen keyboard opened while active can never visually or
   functionally cover it. Primary-colored so it reads as "the way out", not
   just another passive header pill. Everything else in the topbar (menu
   button, page title, other buttons) is hidden so the effect is actually
   visible at a glance — a couple of small buttons disappearing was too
   subtle to read as "something changed" — leaving only this one button,
   right-aligned same as always (.pos-topbar's own space-between would
   otherwise snap a lone remaining child to the left). Nothing in this
   app's own page content needs hiding since the sidebar/cart are already
   off-canvas until opened. */
html.is-fullscreen .pos-topbar { justify-content: flex-end; }
html.is-fullscreen .pos-topbar > div:first-child,
html.is-fullscreen .pos-topbar [data-pwa-install],
html.is-fullscreen .pos-topbar [data-theme-toggle] { display: none; }
html.is-fullscreen .fullscreen-toggle { position: relative; z-index: 1000; background: var(--color-primary); border-color: var(--color-primary); color: #fff; box-shadow: var(--shadow-md); }
html.is-fullscreen .fullscreen-toggle:hover { background: var(--color-primary-hover); }
